Budowa platform agentowych dla prawdziwych klientów, przy prawdziwym budżecie, w prawdziwe poranki.
by Mat Siems
PARTS I–X · CHAPTERS 1–100 · MATSIEMS.COM
Part I
Konfiguracja
Dlaczego buduję tak, jak buduję. Dwadzieścia godzin, bloki tematyczne, nocna zmiana, jedne drzwi wejściowe i decyzja o traktowaniu pakietu umiejętności jak systemu operacyjnego, a nie szuflady narzędzi.
Chapter 1
20-godzinny tydzień
Nie mam czterdziestu godzin. Mam ich dwadzieścia, w dobrym tygodniu, od poniedziałku do czwartku rano i część środy spędzam przed klientami, a nie przy klawiaturze. To ograniczenie jest powodem istnienia tej książki. Gdybym miał nieograniczony czas, prawdopodobnie budowałbym w sposób, w jaki buduje większość ludzi – rozległy, eksploracyjny, reaktywny – i nigdy nie byłbym zmuszony myśleć o dźwigni. Niedobór zadecydował za mnie.
Pierwszą rzeczą, której nauczył mnie niedobór, było to, że godzina pracy i godzina efektywna to różne waluty. Godzina poświęcona na podejmowanie decyzji, co zbudować, to nie to samo, co godzina na budowanie tego, a godzina na budowanie czegoś, co maszyna mogłaby zbudować w ciągu jednej nocy, jest prawie zmarnowana. Zacząłem więc audytować swoje poranki w taki sam sposób, w jaki audytuje się centrum kosztów. Gdzie podziała się ta godzina? Czy chodziło o decyzję, którą tylko ja mogłem podjąć, czy o przepisanie czegoś, co dobrze przeszkolony agent mógłby napisać, kiedy spałem?
Ten audyt jest niewygodny, ponieważ większość tego, co wydaje się pracą, nie jest częścią niezastąpioną. Niezastąpiona część jest niewielka. Dla mnie sprowadza się to do trzech rzeczy: porannej decyzji o połączeniu — co jest wystarczająco dobre, aby wysłać — kształtu systemu klienta i historii, którą opowiadam mu w środę. Wszystko inne można delegować. Nie można go „delegować pewnego dnia”, można go teraz delegować do członków zespołu, do automatyzacji z dnia na dzień, do zestawu umiejętności, które opiszę później.
Błąd, który popełniłem na początku, polegał na traktowaniu dwudziestu godzin jako pułapu. Dwadzieścia godzin to dwadzieścia godzin pracy, więc jak zdobyć więcej godzin? Złe pytanie. Właściwe pytanie brzmi: jak uczynić te dwadzieścia godzin godzinami usuwania wąskich gardeł i całkowicie odsuwać wszystko inne od normy. Kiedy wkroczyły prace z dnia na dzień, moje dwadzieścia efektywnych godzin zaczęło generować wydajność bliższą całodobowej wydajności — nie dlatego, że pracowałem więcej, ale dlatego, że przestałem być obecny przy częściach, które mnie nie potrzebowały.
To jest główne twierdzenie całej książki, więc wyrażę to tutaj jasno i poświęcę na to kolejnych dziewięćdziesiąt dziewięć rozdziałów: Inżynieria sztucznej inteligencji, wykonana dobrze, w coraz mniejszym stopniu polega na pisaniu, a coraz bardziej na temat obecności tylko tam, gdzie twoja obecność jest ograniczeniem. Narzędzia są teraz niezwykłe. Rzadkie zasoby nigdy nie były podstawą obliczeń. Zawsze była to moja uwaga i dyscyplina, dzięki której mogłem poświęcić ją na trzy rzeczy, a resztę delegować bez mrugnięcia okiem.
Dwadzieścia godzin to nie ograniczenie, za które przepraszam. To specyfikacja projektu.
Fig 1.1 — Where the Twenty Hours Go. A quadrant of does-it-need-me × how-often-it-recurs. The focal cell is the frequent, only-I-can-do-it corner — the three things. Everything in the bottom band goes to a teammate or the overnight queue.
Chapter 2
Poms i nocna zmiana
Rano biegam w 24-minutowych blokach. Nazywam je poms, a liczba nieparzysta jest zamierzona — okrągła 25 zaprasza do zaokrąglania w górę, a 30 zaprasza do czeku telefonicznego „między” blokami. Dwadzieścia cztery minuty to na tyle krótko, że start jest tani i na tyle długi, że można zrobić coś prawdziwego. Typowy tydzień to około dwudziestu osób: kilka osób zajmujących się selekcją i trasowaniem, duża grupa we wtorki i czwartki zajmująca się załatwianiem spraw, garstka w środę wokół klientów i trochę bufora, który udaję, że będę chronić, a rzadko to robię.
Blok nie jest jednak interesującą częścią. Timeboxing to stara rada. Interesujące jest to, co dzieje się z blokami, gdy połączysz je z nocną zmianą.
Oto zmiana w myśleniu. Pompon jest drogi — to kawałek z nielicznych dwudziestu. Zatem pytanie w przypadku dowolnego zadania brzmi: czy to potrzebuje pomponu, czy może działać, kiedy śpię? Renderowanie filmu wideo nie wymaga mojej oceny po zapoznaniu się z nim. Kompilacja wsadowa oparta na jasnej specyfikacji nie wymaga nadzoru. Pobieranie danych, eksport, pierwsza wersja czegoś, co będę edytować jutro – nic z tego nie zasługuje na blokadę na żywo. Zasługują na kolejkę.
Wyrobiłem sobie więc nawyk dzielenia pracy na dwa stosy. Stos pomp to wszystko, co wymaga mojej oceny na bieżąco: decyzja, narracja klienta, rozmowa projektowa, recenzja. Stos nocny to wszystko, co ma na tyle jasną specyfikację, że maszyna może to rozdrobnić i przekazać mi wynik rano. Moim zadaniem w przypadku nocnego stosu nie jest wykonywanie całej pracy — chodzi o napisanie briefu na tyle dobrze, aby praca mogła zostać wykonana beze mnie.
To przeformułowanie zmieniło znaczenie „produktywnego poranka”. Kiedyś oznaczało to, że dużo pisałem. Teraz oznacza to, że podjąłem decyzje, które tylko mogłem podjąć, i dobrze przygotowałem się na kolejny nocny przejazd. Niektóre z moich najlepszych poranków wiążą się z bardzo niewielkim budowaniem. Przeglądam to, co przyszło z dnia na dzień, łączę to, co dobre, podsumowuję to, co wyjdzie wieczorem, a resztę wydaję na jedną trudną rzecz, która naprawdę potrzebuje człowieka. Budynek powstał w ciemności.
Warto wymienić tutaj tryb awaryjny. Nocna sterta działa tylko wtedy, gdy brief jest naprawdę kompletny — jeśli nie, budzisz się z pewnymi śmieciami, co jest gorsze niż nic, ponieważ diagnoza kosztuje Cię mnóstwo pieniędzy. Zatem dyscyplina przeniosła się w górę rzeki, do odprawy. Wolałbym spędzić cały dzień na pisaniu szczelnej specyfikacji przez noc, niż spędzić trzy następnego dnia na sprzątaniu niejasnej. Specyfikacja jest jest już gotowa.
Pompony i nocna zmiana to dwie połowy jednego pomysłu: skup swoją rzadką uwagę na osądach i umieść wszystko, co mechaniczne, w kolejce, która kursuje bez ciebie. Zegar wskazuje dwadzieścia godzin. Dane wyjściowe nie zachowują się jak dwadzieścia godzin. Ta luka – między przepracowanymi godzinami a wytworzoną wartością – to cała gra, a odprawa polega na tym, jak ją powiększyć.
Fig 2.1 — The Sorting Decision. One question — does it need my judgement in the loop? — splits every task into the pom pile (focal, live 24-min blocks) or the overnight queue. The caption is the whole discipline: the queue only works if the brief is airtight.
Chapter 3
Jedne drzwi wejściowe
Przez jakiś czas miałem szufladę pełną narzędzi. Umiejętność przekształcenia transkrypcji w brief. Umiejętność budowania diagramów. Umiejętność przygotowania propozycji. Umiejętność przesyłania rzeczy do Google Workspace. Każdy działał. I każdego ranka stawałam przed szufladą i zastanawiałam się: którą otworzyć jako pierwszą?
To pytanie — które narzędzie teraz? — jest podatkiem. Jest niewielka, ale płacisz ją za każdym razem i jest ona opłacana z dokładnie tych zasobów, których nie możesz oszczędzić: oceny na początku sesji, kiedy jest najświeższa. Najostrzejsze minuty spędzałem na nawigacji.
Poprawka nie była lepszym narzędziem. To były drzwi wejściowe. Jedno polecenie, które wprowadzam za każdym razem, a którego jedynym zadaniem jest sprawdzenie, jak się sprawy mają i skierowanie mnie do następnego ruchu w prawo. Nie decyduję, co otworzyć – otwieram jedną rzecz, a ona mi mówi. Status cross-workspace, co warto zbudować dalej, co na mnie czeka, co przyszło z dnia na dzień. Decyzja o routingu wyleciała z mojej głowy i trafiła do systemu.
To brzmi jak mała zmiana ergonomii. To nie jest. To jest różnica pomiędzy posiadaniem zestawu narzędzi a uruchomieniem systemu operacyjnego. Zestaw narzędzi to zbiór funkcji, które za każdym razem składasz ręcznie. System operacyjny to rzecz, którą wchodzisz i to on ponosi odpowiedzialność za przeniesienie cię we właściwe miejsce. W chwili, gdy przestałem odwoływać się do umiejętności ad hoc i zacząłem wchodzić przez jedne drzwi wejściowe, cały apartament przestał przypominać szufladę, a zaczął przypominać maszynę, którą obsługuję.
Głębszą korzyścią jest konsekwencja. Kiedy każda sesja rozpoczyna się w ten sam sposób, system może nauczyć się kształtu sesji. Może przyjąć kolejność rurociągów. Może przygotować wstępny etap prawdopodobnego następnego kroku. Wywołanie ad hoc rezygnuje z tego wszystkiego — każda sesja to zimny start, każde narzędzie to wyspa. Drzwi wejściowe sprawiają, że sesje są dla siebie czytelne.
Jest też korzyść psychologiczna, którą na początku nie doceniłem. Stanie przed szufladą nie jest po prostu powolne, to wyczerpywanie. Wybór jest męczący. Zanim zdecydowałem, które narzędzie otworzyć, zużyłem całą siłę woli, której potrzebowałem, do właściwej pracy. Usunięcie wyboru spowodowało usunięcie drenażu. Otwieram drzwi wejściowe, kierują mnie, idę. Zmęczenie decyzjami, które gromadziło się przez cały poranek, w większości wyparowało.
Przyznam, że kiedy je budowałem, wydawało mi się, że drzwi wejściowe wymagały zbyt dużej inżynierii. Miałem może tuzin narzędzi – czy naprawdę potrzebowałem routera do tuzina rzeczy? Tak, jak się okazało, ponieważ kosztem, który ustalałem, nie była liczba narzędzi, ale powtarzający się akt wyboru spośród nich, mnożony w nieskończoność podczas każdej sesji. Dwanaście narzędzi wybranych na świeżo sto razy to dwieście małych podatków. Jedne drzwi wejściowe to jeden nawyk.
Za każdym razem wchodzisz tymi samymi drzwiami. Niech Cię poprowadzi. Taka jest zasada.
Fig 3.1 — One Front Door. Every session enters through a single focal node that reads state and routes into the pipeline (Frame → Produce → Make + Act). The dashed note is the killed old way — standing at the drawer, choosing a tool by hand.
Chapter 4
Umiejętności jako system operacyjny, a nie zestaw narzędzi
Jeśli rozdział 3 dotyczył drzwi wejściowych, ten dotyczy tego, co jest za nimi – i tego, dlaczego układ jest równie ważny jak elementy.
Kiedy uczciwie skatalogowałem swoje umiejętności, pierwszą rzeczą, którą zauważyłem, było nakładanie się i luki w równym stopniu. Dwie umiejętności, które w połowie wykonały tę samą pracę. Praca, która do niczego nie należała. Stos rósł w wyniku akrecji — rozwijałem każdą umiejętność, kiedy jej potrzebowałem i nigdy nie cofałem się, by zapytać, czy set ma sens. Zestaw narzędzi to toleruje. System operacyjny tego nie robi.
Więc podzieliłem zestaw na filary i sprawiłem, że filary wzajemnie się wykluczały i łącznie były wyczerpujące — MECE, stara dyscyplina konsultingowa, która okazuje się mieć znacznie większe znaczenie w przypadku zestawu umiejętności niż kiedykolwiek w przypadku slajdu. Wzajemnie wykluczające się oznacza, że każda umiejętność ma dokładnie jedno miejsce; jeśli mogłyby tego domagać się dwa filary, to filary są w błędzie. Zbiorowo wyczerpujące oznacza, że w moim rzeczywistym przepływie pracy nie ma zadania, które wpada między pęknięcia i nie ma umiejętności, aby je złapać.
W moim przypadku filary to: orkiestracja (same drzwi wejściowe), kadrowanie (przekształcanie surowych danych wejściowych w ustrukturyzowany projekt), produkcja (zdobywanie pracy – propozycje, treść, przepływy sprzedaży), tworzenie (tworzenie artefaktów – aplikacje, diagramy, wykresy agentów, wideo) i działanie (ręce – faktycznie wysyłają e-mail, rezerwują miejsce, aktualizują arkusz). Pięć filarów. Każda umiejętność ląduje w jednej. Nic ważnego nie ma domu.
Wartością MECE nie jest tutaj porządek. Polega to na tym, że czysty rozkład mówi ci, czego brakuje. Kiedy ułożyłem umiejętności w filarach, puste miejsca były oczywiste – praca, którą wykonywałem ręcznie co tydzień, nie mając za nią żadnych umiejętności, rozświetliła się jako luka w siatce. Struktura przygotowała dla mnie plan działania. Oto powtarzająca się nagroda za dobrą dekompozycję: przekształca ona pytanie „co powinienem zbudować dalej?” z pytania otwartego do widocznej dziury.
Wyłączność ma znaczenie z innego powodu – zaufania. Kiedy każda umiejętność ma dokładnie jedno miejsce, nigdy nie zastanawiam się, po które z dwóch nakładających się narzędzi sięgnąć, ponieważ zawsze jest tylko jedno. Drzwi wejściowe mogą być wyznaczane w sposób deterministyczny. Nakładanie się ponownie wprowadza dokładnie taki podatek od wyboru narzędzi, jaki miały wyeliminować drzwi wejściowe, więc nakładanie się nie jest tylko nieporządne, ale jest nieszczelnością w całym projekcie.
Skrzynka narzędziowa jest oceniana na podstawie jakości każdego narzędzia. System operacyjny ocenia się na podstawie tego, czy narzędzia się komponują — czy wynik jednego z nich jest czystym wejściem do następnego, czy nie ma luk ani nakładania się, czy można wejść i zostać przekierowanym bez zastanowienia. Przestałem oceniać swoje umiejętności indywidualnie i zacząłem oceniać zestaw. Czy to MECE? Czy słupek ramy ręcznie czyści projekty do produkcji? Czy produkuje ręcznie prawdziwe produkty do wykonania? Czy ręcznie robione rzeczy, które filar aktorski faktycznie może wysyłać?
Umiejętności indywidualne zawsze były w porządku. Ułożenie ich w system — ekskluzywny, wyczerpujący i dający się komponować — zamieniło kompetentną szufladę w coś, co działa.
Fig 4.1 — Five Pillars, One Home Each. The skill suite as a layer stack — Orchestrate (focal) over Frame, Produce, Make, Act & Run. Every skill sits in exactly one band; an empty band is next week's roadmap.
Chapter 5
Skłonność do żeglugi
Ostatni rozdział przygotowań to ten, który stanowi podstawę wszystkich pozostałych: w razie wątpliwości, statek.
Mówię to ostrożnie, ponieważ „działaj szybko” to najczęściej nadużywane wyrażenie w tej branży, zwykle używane w celu usprawiedliwienia niechlujstwa. Nie to mam na myśli. Mam na myśli coś węższego i, jak sądzę, łatwiejszego do obrony: koszt odwracalnej decyzji podjętej szybko jest prawie zawsze niższy niż koszt namysłu wymaganego do jej powolnego podjęcia. Większość decyzji podejmowanych w budownictwie jest odwracalna. Dlatego większość decyzji powinna być podejmowana szybko, natychmiastowo i korygowana w oparciu o kontakt z rzeczywistością, a nie doskonalona przed nią.
Najjaśniejszym przykładem jest ten, któremu poświęcę całą część później: nie poleruj fałszywych danych. Kiedy tworzę nową platformę, strony pojawiają się jako wyśmiewane – w sposób widoczny, celowo fałszywe – i wysyłam je jako wyśmiewane. Instynkt urealniania fałszywych danych przed pokazaniem ich komukolwiek jest pułapką, ponieważ realistyczne fałszywe dane niczego nie uczą, a opóźniają jedyną rzecz, która uczy wszystkiego: prawdziwego użytkownika, czyli prawdziwego klienta, reagującego na prawdziwy kształt. Zadaniem kpiny jest wywołanie tej reakcji, a nie przetrwanie kontroli. Wyślij to brzydko i szczerze, a reakcja Cię przekieruje.
Ta sama stronniczość przejawia się w sposobie, w jaki traktuję klientów. Nie buduję V2 w sposób abstrakcyjny, wyobrażając sobie, czego może potrzebować przyszły klient. Czekam, aż przybędzie prawdziwy, z prawdziwym bólem i pozwalam, aby jego konkretny problem był funkcją wymuszającą, która kształtuje budowę ciała. Wymagania abstrakcyjne to sposób na ciągłe zastanawianie się pod przykrywką produktywnego wyglądu. Prawdziwym problemem klienta jest termin z twarzą. Wysyła pracę.
Istnieje dyscyplina, która musi kryć się za uprzedzeniami, w przeciwnym razie popadnie w lekkomyślność i brzmi następująco: szybka wysyłka jest bezpieczna tylko wtedy, gdy zwrot jest tani. Wkładam więc wiele wysiłku w to, aby odwrócenie było tanie — czyste interfejsy adaptera, dzięki czemu mogę zamienić źródło danych, flagi próbne/aktywne, aby móc wycofać się z decyzji o okablowaniu, artefakty strukturalne, aby złe uruchomienie pozostawiło ślad, który mogę odczytać. Szybkość to nie odwaga. To korzyść z tego, że najpierw zbudowaliśmy włazy ratunkowe. Mogę szybko wysłać decyzję właśnie dlatego, że rozładunek jest tani.
Z drugiej strony tryb niepowodzenia to ten, który częściej widzę u innych, jest cichszy i bardziej niebezpieczny: narada udająca pracowitość. Niekończące się wyjaśnianie pytań przed rozpoczęciem. Dokumenty wymagań dotyczące wyborów odwracalnych. Oczekiwanie na pewność, że dostarczona i poprawiona pętla powstałaby w ułamku czasu. Każdy z nich czuje się odpowiedzialny. Większość z nich po prostu boi się nosić odpowiedzialny kostium.
Zatem konfiguracja kończy się tam, gdzie się zaczęła: niewielka uwaga poświęcona tylko tam, gdzie jest to ograniczenie. Dzięki szybkiej wysyłce dowiesz się, gdzie faktycznie znajduje się ograniczenie — ponieważ rzeczywistość podpowiada ci i to szybciej niż myślenie. Zbuduj włazy ratunkowe, a następnie wyślij statek. Niech kontakt z rzeczywistością zrobi resztę.
No figure. This chapter is a stance, not a structure — per the diagram discipline, a clean paragraph beats a forced diagram. The shipping loop gets its proper visual in Part VI, where the MOCK-badge pattern makes it concrete.
Chapter 6
Narzędzia, od których zaczynałem
Każdy praktykujący ma stos początkowy — garść narzędzi, które skonfigurował jako pierwszy, zanim dowiedział się, co tak naprawdę buduje. Mój opowiada pewną historię, jeśli czytasz ją w kolejności, więc pozwól, że ją przedstawię.
Pierwszą rzeczą, na którą wstałem, nie był model ani konstrukcja. To była brama — pojedyncza warstwa, przez którą rozmawiało wszystko inne, więc kiedy nieuchronnie zamieniałem modele pod spodem, nic poniżej nie przejmowało się tym. Nie wiedziałam jeszcze, jak bardzo będę opierać się na tej decyzji. Wtedy wydawało mi się to niemal przedwczesne: po co budować abstrakcję na podstawie jednego modelu, którego prawie nie używałem? Ale instynkt się nie mylił i to on kryje się za połową tej książki. To, co będziesz chciał później zamienić, to to, co powinieneś umieścić za interfejsem już dziś. Modele zmieniają się co miesiąc. Bramka nie.
Następny był CLI. Nie internetowy plac zabaw, nie notatnik – wiersz poleceń. Miało to większe znaczenie, niż wtedy rozumiałem, ponieważ interfejs CLI sprawił, że wszystko można skryptować, a dzięki skryptom wszystko można zautomatyzować, a automatyzacja to cała historia nocnej zmiany z rozdziału 2. Gdybym zaczął od karty przeglądarki, wyrobiłbym sobie nawyki związane z tą zakładką: klikaj, czekaj, kopiuj, wklej. Rozpoczęcie pracy w terminalu oznaczało, że od pierwszego dnia wszystko, co mogłem zrobić ręcznie, mogłem także wykonywać w pętli, zgodnie z harmonogramem, beze mnie. Interfejs, dzięki któremu poznasz narzędzie, kształtuje to, o co go kiedykolwiek poprosisz.
Następnie integracja chat-bota z narzędziem do przesyłania wiadomości, z którego korzystał już zespół. Lekcja dotyczyła spotkania z pracą tam, gdzie jest . Nikt nie chciał sprawdzić nowego celu podróży. Chcieli, aby możliwość pojawiła się w kanale, w którym już się znajdowali. Od tego czasu każda integracja kieruje się tą zasadą: nie buduj miejsca, do którego ludzie muszą się udać, umieść możliwości tam, gdzie już się znajdują. Najlepszym interfejsem jest często brak nowego interfejsu.
Patrząc wstecz, uderza mnie to, jak duża część ostatecznej architektury była implikowana przez te trzy wcześniejsze wybory. Bramka, która oddziela się od dowolnego modelu. Interfejs CLI, który sprawia, że wszystko można skryptować. Integracja, która przenosi możliwości na istniejące powierzchnie. Można poprowadzić linię prostą od tych trzech do platformy, którą obecnie prowadzę dla wielu najemców — te same trzy pomysły, tylko większe. Oddziel, napisz, osadź.
Narzędzia, po które sięgasz w pierwszej kolejności, nie są neutralne. Wprowadzają nawyki, a nawyki się kumulują. Widziałem, jak ludzie zaczynali od dopracowanego interfejsu internetowego, a rok później nadal klikali te same ręczne czynności, ponieważ narzędzie nigdy nie sugerowało im, że pracę można zautomatyzować – interfejs nie miał w sobie pętli. Miałem szczęście, a może dobrze mi doradzono: zacząłem od miejsca, które można skryptować, a wszystko, co można skryptować, w końcu staje się czymś, co działa bez ciebie.
Wybierz swoje pierwsze narzędzia pod kątem nawyków, które zainstalują, a nie wersji demonstracyjnej, którą Ci dadzą.
Fig 6.1 — The Origin Stack. Three founding choices — decouple (gateway), script (CLI, focal), embed (integration). The scriptable middle is what made the overnight shift possible; the line runs straight from here to the platform.
Chapter 7
Tokeny marki jako ograniczenia
To jest rozdział o kolorze, co wydaje się trywialne w przypadku książki o inżynierii sztucznej inteligencji, ale takie nie jest — ponieważ tak naprawdę jest to rozdział o tym, jak ograniczenia przyspieszają pracę.
Na początku każdy artefakt, który zbudowałem, podejmował od podstaw własne decyzje estetyczne. Jaki niebieski? Jak okrągłe są rogi? Jaka czcionka do podpisu? Indywidualnie są to decyzje podejmowane w ciągu dwóch minut. Pomnożone na każdym diagramie, aplikacji i talii, stanowiły powolny podatek od dokładnie tej skąpej uwagi, której ochrona ma chronić cała ta książka. Co gorsza, wyniki wyglądały, jakby pochodziły od dziesięciu różnych osób, bo rzeczywiście tak było – dziesięciu różnych wersji mnie, z których każda sprawiała, że rozmowa była świeża.
Dlatego zamroziłem decyzje. Jeden akcent w kolorze niebieskim. Jedna pomarańcza dla innej linii produktów. Stały zestaw czcionek — szeryf do wyświetlania, bez treści, mono do wszelkich zastosowań technicznych. Stałe promienie narożników. Zasada mówiąca, że każda współrzędna na diagramie znajduje się na czteropikselowej siatce. Żadne z nich nie budziło udręki; nie chodziło o znalezienie idealnego niebieskiego, chodziło o to, aby przestać wybierać niebieskiego. Zdecydowany jednorazowo token jest wart więcej niż nieco lepszy token rozstrzygany za każdym razem.
Część sprzeczna z intuicją polega na tym, że ograniczenia sprawiły, że praca była lepsza, a nie tylko szybsza. Kiedy nie możesz sięgnąć po nowy kolor, żeby coś wystrzelić, jesteś zmuszony rozwiązać rzeczywisty problem – hierarchię, odstępy, to, na czym powinien skupiać się wzrok – za pomocą struktury zamiast dekoracji. Zasada pojedynczego akcentu jest najwyraźniejszym przykładem. Jeden kolor akcentujący, zarezerwowany dla jednej lub dwóch rzeczy, które w danym artefakcie są najważniejsze, zmusza Cię do zdecydowania, co jest najważniejsze. Paleta z pięcioma akcentami pozwala uniknąć tej decyzji. Paleta z jedną sprawi, że dasz radę.
Jest to ogólna zasada, która wykracza daleko poza kolor i dlatego ten rozdział znajduje się tutaj, a nie w jakimś załączniku projektowym. Ograniczenia są formą z góry podjętej decyzji, a z góry podjęte decyzje są dokładnie tym, co chroni twoją uwagę podczas podejmowania decyzji, które naprawdę cię potrzebują. System żetonów jest dla pracy wizualnej tym, czym drzwi do umiejętności: sposobem na uniknięcie ponownego decydowania o ustalonych sprawach. Każde ograniczenie, które zaakceptujesz, jest decyzją, której nigdy więcej nie będziesz musiał podejmować.
Istnieje koszt dyscypliny, który polega na tym, że musisz faktycznie trzymać się linii. System tokenów opłaca się tylko wtedy, gdy nie zastąpisz go po cichu „tylko ten raz”, ponieważ raz staje się drugim, de facto drugim systemem, a teraz wybierasz między dwoma systemami, co jest gorsze niż brak żadnego. Ograniczenia oszczędzają czas tylko wtedy, gdy są naprawdę ograniczające. Wytyczna, którą łamiesz, gdy jest to wygodne, jest po prostu sugestią noszenia ubrań z podręcznika.
Zatem: podejmijcie raz ustalone sprawy, zapiszcie je i trzymajcie się granicy. Nie dlatego, że konsekwencja jest ładna – chociaż jest – ale dlatego, że każda zamrożona decyzja powoduje skupienie uwagi na decyzjach, które w rzeczywistości należy do Ciebie.
No figure. The token system's whole argument is restraint — a diagram here would be decoration proving the opposite of its point. The single-accent discipline is on display in every other figure in this book instead.
Chapter 8
Trzej najemcy, jedna maszyna
Moment, w którym moja mała firma przestała być zbiorem projektów i zaczęła być platformą, był momentem, w którym umieściłem więcej niż jednego klienta za tym samym kodem. Wcześniej każdy klient był odrębną rzeczą, którą utrzymywałem. Po tym nowy klient był już prawie darmowy. Ta zmiana — od projektów do najemców — jest warta całego rozdziału, ponieważ stanowi różnicę między konsultingiem a sprzedażą produktu.
Mechanizm jest nudny i o to właśnie chodzi: każdy wiersz danych ma identyfikator organizacji, a reguła na poziomie bazy danych gwarantuje, że zapytanie z jednej organizacji nigdy nie zobaczy wierszy drugiej. Wielu dzierżawców z zabezpieczeniami na poziomie wiersza. Brzmi to jak hydraulika i rzeczywiście tak jest, ale konsekwencje są strategiczne. Gdy izolacja zostanie wymuszona przez bazę danych, a nie przez pamiętanie o poprawnym filtrowaniu w kodzie aplikacji, dodanie dzierżawcy przestaje stanowić ryzyko. Nie mam nadziei, że dobrze odfiltrowałem każde zapytanie. Podłoga systemu nie pozwoli na wyciek.
Ta gwarancja sprawia, że „prawie za darmo” jest prawdziwe. Nowy klient to nie nowa baza kodu, nowe wdrożenie, nowy zestaw rzeczy do utrzymania. To nowy identyfikator organizacji i przełącznik obszaru roboczego. Koszt krańcowy czwartego klienta jest ułamkiem pierwszego, ponieważ pierwszy klient zapłacił za maszynę, a czwarty dopiero się do niej wprowadza. To najstarsza koncepcja ekonomii oprogramowania – buduj raz, sprzedawaj wiele – ale zupełnie inne jest to uczucie, gdy jesteś samodzielnym operatorem i obserwujesz, jak Twoje obciążenie konserwacyjne a nie rośnie wraz ze wzrostem liczby klientów.
Dyscyplina, której to wymaga, znajduje się na samym dole stosu, co jest niewygodnym miejscem do umieszczenia najważniejszej gwarancji, a także jedynym miejscem, w którym należy. Izolacja dzierżawy nie może być dobrą intencją warstwy aplikacji, ponieważ warstwy aplikacji zawierają błędy, a ja mam poranki, w których nie jestem bystry. Należy go egzekwować tam, gdzie popełnienie błędu jest niemożliwe, a nie tylko zniechęcać. Przesuń gwarancję tak nisko, jak to możliwe — do bazy danych, do systemu typów, do platformy — tak aby pomyłka nie wchodziła w grę, a nie bycie w błędzie było czymś, czego starasz się uniknąć.
Wraz z najmem następuje także zmiana sposobu myślenia, wykraczająca poza kwestię techniczną. Przestajesz myśleć „jak zbudować rzecz tego klienta” i zaczynasz myśleć „jaki jest ogólny kształt, którego jednym z przykładów jest ten klient”. To przeformułowanie jest na początku niewygodne – wydaje się wolniejsze, ponieważ rozwiązujesz większy problem niż ten, który stoi przed tobą. Ale to przeformułowanie zmienia firmę usługową w coś, co wykracza poza Twoje godziny pracy, co dla kogoś, kto ma ich tylko dwudziestu, jest całą grą.
Projekty zwiększają obciążenie konserwacyjne liniowo wraz z liczbą klientów. Najemcy nie. Zbuduj maszynę raz, wyegzekwuj izolację na podłodze i pozwól każdemu nowemu klientowi się wprowadzić.
Fig 8.1 — Three Tenants, One Machine. Every tenant lives in one codebase, isolated by an org identifier. The focal band is the guarantee — row-level security enforced at the database floor, so a leak isn't discouraged, it's impossible.
Chapter 9
Co właściwie oznacza „gotowe”.
„Gotowe” to najczęściej nadużywane słowo w oprogramowaniu i szczerość w tej kwestii zmieniła sposób, w jaki wysyłam przesyłki. Przez długi czas „gotowe” oznaczało „działa, kiedy to uruchomię”. Definicja ta ma lukę na tyle dużą, że może przebić się przez nią nieudane demo klienta i mniej więcej w ten sposób nauczyłem się ją zamykać.
Problem z „działa, gdy go uruchomię” polega na tym, że I nie jest środowiskiem, w którym musi działać. Działa z moimi zmiennymi środowiskowymi, stanem pamięci podręcznej i moją szczególną sekwencją kliknięć, których nawet nie zauważam. „Gotowe” zdefiniowane na mojej własnej maszynie to definicja, która cicho wyklucza każdy warunek, który faktycznie ma znaczenie: nowa płatność, inne źródło danych, użytkownik, który klika w niewłaściwej kolejności, bieganie o trzeciej nad ranem i nikt nie patrzy.
Więc przesunąłem słupki bramkowe. Gotowe oznacza, że działa, gdy nie go uruchamiam — gdy działa bezmyślnie, zgodnie z harmonogramem, w oparciu o prawdziwe dane i przekazuje wynik, któremu mogę zaufać, bez konieczności oglądania tego. To znacznie wyższa poprzeczka i większość rzeczy, które nazywałem gotowymi, jej nie przekracza. Ale to jest właściwy drążek, bo z niego korzysta rzeczywistość. Nocna zmiana z rozdziału 2 działa tylko wtedy, gdy „ukończono” oznacza „działa bez nadzoru i prawidłowo”, a gdy zastosujesz automatyzację nocną, nie będziesz już mógł się oszukiwać, że zostało już zrobione — harmonogram powie ci prawdę rano.
Częścią nowej definicji jest to, że przebieg musi pozostawić ślad. Rzecz, która została wykonana, nie tylko kończy się sukcesem lub porażką — po drodze emituje coś uporządkowanego: co zrobiła, co wyprodukowała, łącze, ścieżkę, podsumowanie, które mogę przeczytać. To nie jest rejestrowanie w celu debugowania. Chodzi o to, że procesowi bez nadzoru, który nie pozostawia śladów, tak naprawdę nie można ufać, ponieważ zaufanie wymaga dowodów, a cichego sukcesu nie da się odróżnić od cichej porażki, dopóki nie jest za późno. Gotowe obejmuje pozostawienie dowodu, że zostało to zrobione.
Pod tym wszystkim kryje się dyscyplina weryfikacji, której musiałem się nauczyć na własnej skórze: nie mów, że sprawa została wykonana, dopóki nie obejrzysz dowodów. Nie „powinno działać” — uruchom go, przeczytaj dane wyjściowe i potwierdź, że artefakt istnieje tam, gdzie powinien. Wystarczająco często się zawstydzałem, twierdząc, że odniosłem sukces, którego nie zweryfikowałem, że teraz traktuję „skończone” jako twierdzenie wymagające dowodu, w taki sam sposób, w jaki traktowałbym każde inne twierdzenie oparte na faktach. Dowód przed stwierdzeniem, zawsze. Większość uszkodzonych wersji demo to luka między „Myślę, że to działa” a „Widziałem, jak to działa”.
Zatem robocza definicja, ta, której właściwie się obecnie trzymam: gotowe oznacza, że działa bez nadzoru, w rzeczywistych warunkach, pozostawia czytelny ślad, który widziałem na własne oczy. Wszystko poza tym nie jest jeszcze zrobione – to pełna nadziei wersja robocza, która tak się składa, że raz zadziałała na mojej maszynie, kiedy to oglądałem.
Fig 9.1 — The Four Gates of Done. A task isn't done until it clears all four: unattended, on real data, leaving a readable trace, and personally witnessed. The final gate is focal — evidence before assertion is the one people skip.
Chapter 10
Połączenie poranne
Ostatni rozdział konfiguracji dotyczy najważniejszych dwudziestu minut mojego tygodnia: porannego łączenia, kiedy patrzę, co przyniosło nocne przejazdy i decyduję, co jest wystarczająco dobre, aby je zatrzymać.
Powiedziałem, że człowiek powinien być obecny tylko tam, gdzie stanowi ograniczenie. Poranne połączenie jest najwyraźniejszym przykładem miejsca, w którym naprawdę jestem. W ciągu nocy maszyna się buduje. Podąża za wytycznymi, tworzy artefakty, pozostawia ślad. Czego nie może zrobić – czego celowo nie próbowałem zautomatyzować – to ocena smaku: czy to rzeczywiście jest dobre? Czy wysyła? Kompilacja jest delegowalna. jest-to-dobre takie nie jest, przynajmniej jeszcze nie, a udawanie, że jest inaczej, kończy się dostarczaniem pewnej przeciętności.
Fuzja jest zatem przeglądem i jest bezwzględna. Wydajność w ciągu nocy oznacza, że budzę się z większą ilością, niż kiedykolwiek byłbym w stanie wysłać, co brzmi jak luksus i w rzeczywistości stanowi problem z dyscypliną: kiedy maszyna może wyprodukować dziesięć wersji, rzadkim aktem jest odrzucenie, a nie produkcja. Moja poranna praca nie polega na celebrowaniu objętości. Ma zabić większość. Najlepsze poranki polegają na wyrzuceniu większej ilości rzeczy, niż trzymam, ponieważ wyrzucanie jest teraz krokiem w stronę dodawania wartości – każdy lub cokolwiek może wygenerować; wybór jest tym, co mi pozostało.
To odwraca starą relację między wysiłkiem a efektem. Kiedy sam budowałem, utrzymanie czegoś było tanie — włożyłem już w to wysiłek, więc oczywiście wysłałem, ponosząc koszty i w ogóle. Teraz produkcja jest bezpłatna, a utrzymanie jest kosztowną decyzją, co jest prawidłowym rozwiązaniem. Wysiłek powinien opierać się na ocenie, a nie na produkcji. Nocna zmiana przeniosła wysiłek we właściwe miejsce: najostrzejsze minuty spędzam na podejmowaniu decyzji, a nie na pisaniu.
Scalanie chroni również system przed specyficznym trybem awarii, jakim jest dryf. Kiedy maszyna produkuje w sposób ciągły i wszystko, co wytwarza, jest wysyłane, jakość spada w sposób niewidoczny, jeden akceptowalny, ale niezbyt doskonały artefakt na raz, aż cała produkcja przesunie się w miejsce, w które nigdy nie zdecydowałbyś się celowo. Połączenie jest bramą, która zatrzymuje poślizg. To człowiek stojący przy wyjściu i mówiący nie to, nie to, ten tak — a ta brama jest tak dobra, jak smak i uwaga, jaka się za nią kryje, dlatego właśnie spędzam w niej najświeższe dwadzieścia minut, a nie ostatnie zmęczone dziesięć.
Oto konfiguracja, wszystkie dziesięć rozdziałów, które sprowadzają się do jednego kształtu: pozwolić maszynie pracować przez noc, bez nadzoru, z pełną głośnością — a rano stanąć przy bramie ze świeżym spojrzeniem i gotowością do odrzucenia. Wszystko techniczne w poniższych częściach służy temu kształtowi. Buduj bez Ciebie. Sędzia z tobą. Chroń sędziowanie.
No figure. The morning merge is a ritual, not a structure; Part X returns to it with the full overnight-to-merge loop drawn end to end.
Part II
Drabina Architektury
Trzy szczeble — artefakt, bezserwerowy, niestandardowy backend — i dyscyplina polegająca na staniu na najniższym, który może wykonać zadanie. Plus nawyki strukturalne, które sprawiają, że wspinaczka jest tania: jeden mózg, wiele cienkich interfejsów, głupi interfejs, strumień i router.
Chapter 11
Drabina
Każdy system, który zbudowałem, opiera się na jednym z trzech szczebli, a większość problemów, jakie sobie sprawiłem, wynikała ze stania na niewłaściwym — zwykle o szczebel za wysoki, czasem o szczebel za niski. Zatem przed konkretnymi wzorami, oto sama drabina, ponieważ wiedza, na którym szczeblu się znajdujesz, to ponad połowa architektury.
Dolny szczebel to artefakt. Pojedynczy, samodzielny plik — komponent React, strona HTML — który działa w całości w przeglądarce, bezpośrednio komunikuje się z modelem, nie ma żadnych tajemnic i nie pamięta niczego pomiędzy sesjami. To najszybsza rzecz na świecie w budowie i najtańsza w wyrzuceniu. Jego zadaniem jest uwidocznienie pomysłu na tyle szybko, aby ktoś mógł na niego zareagować. Błąd polega na tym, że wymaga się czegoś więcej: w momencie, gdy chcesz uzyskać autoryzację, współdzielony stan lub zaplanowane uruchomienie, artefakt znajduje się na niewłaściwym szczeblu i żadna spryt nie sprawi, że będzie on właściwy.
Środkowy szczebel jest bezserwerowy i zawiera hostowaną bazę danych. Teraz masz miejsce na przechowywanie sekretów, miejsce do przechowywania stanu, który przetrwa odświeżenie, i punkt końcowy, z którego mogą korzystać inne rzeczy. To właśnie tam żyje większość prawdziwych produktów i to właśnie ten szczebel ludzie zbyt chętnie pomijają w drodze do czegoś, co według nich jest bardziej „poważne”. W przypadku szerokiego zakresu zadań — uwierzytelniania, przechowywania, interfejsu API, aktualizacji w czasie rzeczywistym — ten szczebel nie jest kompromisem, jest rozwiązaniem. Skaluje się dalej, niż oczekują początkujący, i kosztuje mniej, niż się obawiają.
Najwyższy szczebel to niestandardowy backend na maszynie, którą kontrolujesz. Wspinasz się tutaj z jednego powodu: musisz zrobić coś, czego strukturalnie nie da się osiągnąć na środkowym szczeblu. Długotrwałe procesy. Tworzenie podprocesów. Trzymanie połączenia strumieniowego otwartego przez kilka minut. Uruchamianie pętli agenta, która myśli przez chwilę. To nie są preferencje, to możliwości, których nie mają niższe szczeble, a potrzeba choćby jednego z nich uzasadnia wspinaczkę — nie ambicja, nie porządek, nie poczucie, że prawdziwi inżynierowie obsługują własne serwery.
Dyscyplina, jaką wymusza drabina, jest następująca: wspinaj się tylko wtedy, gdy zmusza cię do tego zdolność, której naprawdę potrzebujesz, i nigdy ze względu na status. Każdy szczebel wiąże się z kosztami operacyjnymi — więcej do zabezpieczenia, więcej do monitorowania i więcej, które mogą się zepsuć o trzeciej nad ranem. Artefakt nie może ujawnić tajemnicy, ponieważ żadnej nie kryje. Niestandardowy backend może przeciekać na wiele sposobów. Zatem właściwy szczebel nie jest najpotężniejszy, lecz najmniej zdolny, który nadal może wykonać swoją pracę, ponieważ ma najmniejszą powierzchnię ataku i najmniej wymaga konserwacji.
Obserwowałem, jak ludzie — sam byłem tą osobą — budują niestandardowy backend dla czegoś, co poradziłaby sobie funkcja bezserwerowa, i codziennie płacą za tę próżność w ramach kosztów ogólnych operacji. Drabina to zmuszające pytanie, które należy zadać przed zbudowaniem: jaki jest najniższy szczebel, który faktycznie może to zrobić? Zacznij tam. Wspinaj się tylko wtedy, gdy rzeczywistość, a nie próżność, popycha Cię w górę.
Fig 11.1 — The Ladder. Three rungs, cheap to heavy. The top rung is focal because it's the one people climb to for status rather than need — the discipline is to stop at the lowest rung that can actually do the job.
Chapter 12
Przetestuj raz, odkryj dwa razy
Oto najbardziej przydatny nawyk strukturalny, jaki mam, i jest on niemal żenująco prosty: logika znajduje się w jednym miejscu, a sposoby dotarcia do niej to cienkie opakowania, które nie zawierają żadnej logiki.
Konkretnie. Istnieje warstwa usług — proste funkcje, zwykłe klasy, brak importu frameworka, brak wiedzy o tym, jak będą wywoływane. To tam dzieje się właściwa praca: zasady biznesowe, orkiestracja, istota systemu dla. Następnie, owijając to, są punkty wejścia. Internetowy interfejs API, z którego może korzystać przeglądarka. Narzędzie wiersza poleceń, które mogę wywołać. Może później zaplanowana praca lub obsługa chat-bota. Każdy punkt wejścia nie robi prawie nic: analizuje określony rodzaj danych wejściowych, wywołuje warstwę usług i formatuje wynik pod kątem określonego rodzaju danych wyjściowych. Cała inteligencja znajduje się poniżej; wszystkie punkty wejścia to głupi tłumacze.
Nazwę, której używam na określenie tej zasady, to: „testuj raz, eksponuj dwa razy”. Ponieważ logika nie jest splątana w ramach frameworka, mogę ją przetestować bezpośrednio — wywoływać funkcje, potwierdzać wyniki, bez serwera WWW, bez kpiny z obiektu żądania, bez okablowania CLI. A ponieważ jest wyraźnie oddzielony, wyświetlenie go za pośrednictwem drugiego lub trzeciego interfejsu jest prawie bezpłatne: nowy punkt wejścia to kilka linijek tłumaczenia logiki, która już działa i została już przetestowana. Przetestuj trudną część raz; eksponuj go tyle razy, ile masz odbiorców.
Tryb awarii, którego można uniknąć, to ten, w którym logika wycieka do punktu wejścia — gdzie moduł obsługi sieci sam zaczyna podejmować decyzje, aranżować i ustalać reguły. W chwili, gdy to się dzieje, dwie rzeczy się psują. Nie można już testować logiki bez uruchomienia warstwy internetowej, co sprawia, że testy są powolne i kruche. A kiedy potrzebujesz drugiego interfejsu — CLI, zadania cron — odkrywasz, że logika jest uwięziona w pierwszym i albo go duplikujesz (teraz masz dwie kopie do synchronizacji, czego nie zrobisz), albo wykonujesz niezręczny refaktoryzację w terminie. Jedno i drugie jest podatkiem, który płacisz za umożliwienie bezpiecznikowi logiki i jej opakowania.
Istnieje głębszy powód, dla którego ma to znaczenie szczególnie w przypadku pracy ze sztuczną inteligencją. Zarówno mój CLI, jak i mój internetowy interfejs użytkownika obsługują te same uruchomienia agenta i muszę, aby zachowywały się identycznie — uruchomienie, które uruchamiam z terminala w celu debugowania, powinno wykonywać dokładnie to samo, co uruchamiane przez klienta z interfejsu użytkownika, w przeciwnym razie debuguję inny system niż ten, który zawodzi. Gwarantuje to wspólna logika. Dwa punkty wejścia, jeden mózg, oznaczają, że terminal i przeglądarka to okna na tej samej maszynie, a nie dwie maszyny, które są do siebie podobne.
Zatem: utrzymuj logikę w czystości i bez ram, i spraw, aby każdy interfejs był nad nią cienkim tłumaczem. Wymaga to trochę dyscypliny na początku — pokusa, aby po prostu poradzić sobie z tym w programie obsługi, jest prawdziwa — i zwraca się ona za każdym razem, gdy dodajesz odbiorców, piszesz test lub debugujesz przebieg z innych drzwi niż te, za którymi się włamał.
Fig 12.1 — Test Once, Expose Twice. Three thin translator entrypoints over one focal service layer. The intelligence lives below; each interface only parses in and formats out — so a new door is nearly free and every door drives the identical brain.
Chapter 13
Głupi frontend
Chcę, żeby mój frontend był jak najgłupszy i jest to dla mnie najwyższy komplement. Im mniej wie, tym mniej może wyciekać, tym mniej może pójść nie tak w jednym miejscu, nad którym mam najmniejszą kontrolę — przeglądarce użytkownika, której nie jestem właścicielem, nie mogę ufać i nie mogę zachować tajemnicy.
Zasada jest prosta: frontend nie ma tajemnic i nie podejmuje żadnych ważnych decyzji. Nie ma w nim żadnych kluczy API. Nie dzieje się w nim żadna aranżacja. Żadna istotna zasada biznesowa nie jest przez nią egzekwowana. Jego zadaniem jest renderowanie tego, co jest dane i przekazywanie tego, co robi użytkownik — szyba między osobą a systemem, a nie uczestnik logiki systemu. Wszystko, co wymaga zaufania, dzieje się po drugiej stronie punktu końcowego, na sprzęcie, który kontroluję, za uwierzytelnieniem, które wymuszam.
Powodem jest to, że przeglądarka jest zasadniczo niezaufanym środowiskiem i udawanie, że jest inaczej, szkodzi ludziom. Wszystko, co do niego zostanie wysłane, można odczytać — każdy klucz, każde ukryte pole, każdy „chroniony” fragment logiki jest widoczny dla każdego, kto otworzy narzędzia programistyczne. Zatem pytanie zabezpieczające nie brzmi: „Jak ukryć ten sekret w interfejsie”, ponieważ nie można; pytanie brzmi: „jak mogę się upewnić, że sekret nigdy nie znajduje się w interfejsie użytkownika”. Klucz, który dociera do przeglądarki, to klucz, który należy wziąć pod uwagę, że już wyciekł, a projektowanie wokół tej rzeczywistości, a nie przeciwko niej, to cała gra.
Wiąże się to bezpośrednio z drabiną z rozdziału 11. Powodem, dla którego szczebel artefaktu nie może wykonywać pracy klienta, nie jest wydajność — artefakt komunikujący się bezpośrednio z modelem nie może przechowywać swoich danych uwierzytelniających poza przeglądarką, co w prawdziwym przypadku jest dyskwalifikujące. Wspinaczka na szczebel bezserwerowy polega w dużej mierze na przekazywaniu sekretów w bezpieczne miejsce: funkcja po stronie serwera przechowuje klucz, przeglądarka wywołuje tę funkcję, a klucz nigdy nie dociera do klienta. Szczeble drabiny są, w jednym świetle, coraz lepszą odpowiedzią na pytanie: „gdzie kryją się tajemnice”.
Głupi frontend ma zaletę projektową wykraczającą poza bezpieczeństwo, a mianowicie interfejs, który tylko renderuje i przekazuje, jest znacznie łatwiejszy do zrozumienia. Kiedy w kliencie nie ma żadnej ważnej logiki, nigdy nie musisz się zastanawiać, czy klient i serwer nie zgadzają się co do reguły, ponieważ tylko jeden z nich ma zdanie. Błędy mają mniej miejsc do ukrycia. Klient jest widokiem; serwer jest prawdą; a prawda mieszka dokładnie w jednym miejscu.
Dlatego tworzę frontendy, które są wspaniałe, responsywne i pełne ignorancji. Wiedzą, jak pokazać różne rzeczy i jak poprosić serwer o wykonanie określonych czynności. Nie wiedzą nic, co warto ukraść i nie decydują o niczym, co byłoby warte popełnienia błędu. Prześlij każdy sekret i każdą prawdziwą decyzję przez punkt końcowy na teren, nad którym masz kontrolę. Utrzymuj szkło czyste i głupie.
No figure. The trust boundary this chapter argues for is the very seam drawn in Fig 12.1 — everything above the service layer is glass, everything at it and below is truth. Redrawing it here would only restate that line.
Chapter 14
Przesyłanie strumieniowe to interfejs
Różnica między produktem AI, który sprawia wrażenie żywego, a produktem, który sprawia wrażenie zepsutego, często nie polega na modelu – chodzi o to, czy odpowiedź pojawia się od razu po długiej ciszy, czy też wypływa symbol po znaku podczas oglądania. Przesyłanie strumieniowe nie jest optymalizacją wydajności. To interfejs. A kiedy to zrozumiałem, zmieniło to sposób, w jaki zaprojektowałem całą tylną połowę moich systemów.
Naiwny kształt to żądanie-odpowiedź: przeglądarka pyta, serwer myśli przez trzydzieści sekund, przeglądarka otrzymuje odpowiedź. W przypadku szybkiego zapytania jest w porządku. Dla agenta, który myśli przez minutę, uruchamia kompilację lub przechodzi przez kilka etapów, jest to śmierć — trzydzieści sekund obracania jest nie do odróżnienia od trzydziestu sekund zawieszenia, a palec użytkownika już zmierza w stronę odświeżenia. Problem nie polega na tym, że jest powolny. Problem w tym, że jest to cichy, a cisza jest odczytywana jako porażka, niezależnie od tego, jak dobra jest ostateczna odpowiedź.
Zatem kształt, po który sięgam, to strumień. Serwer utrzymuje połączenie otwarte i przekazuje zdarzenia w miarę ich występowania — token, ukończony krok, wywołanie narzędzia, częściowy wynik — a frontend renderuje je natychmiast po ich wylądowaniu. Praca trwa dokładnie tyle samo, co wcześniej, ale doświadczenie ulega zmianie, ponieważ użytkownik obserwuje, co się dzieje, a nie czeka w ciemności. Postęp, który widzisz, jest szybki; postęp, którego nie widzisz, wydaje się zepsuty. Ten sam czas trwania, przeciwne uczucie.
Architektonicznie to pcha cię w górę po drabinie i warto być szczerym, że tak się dzieje. Utrzymywanie otwartego połączenia i wypychanie zdarzeń przyrostowych to w zasadzie funkcja najwyższej klasy — to jedna z konkretnych rzeczy, która uzasadnia przejście bez serwera na sterowaną przez ciebie maszynę, ponieważ funkcja, która musi szybko powrócić, nie może czekać minuty na strumieniowaniu. Kiedy powiedziałem w Rozdziale 11, że wspinasz się tylko wtedy, gdy zmuszają Cię możliwości, streaming jest jedną z najwyraźniejszych sił. Doświadczenie użytkownika tego wymaga, a zapotrzebowanie na doświadczenie sprawdza się tak samo, jak zapotrzebowanie na architekturę.
Wzorzec, który to łączy, jest taki, że ten sam strumień zasila każdy interfejs. Serwer emituje sekwencję wpisanych zdarzeń i jest mu obojętne, kto słucha — mój terminal renderuje je jako przewijające się linie, interfejs sieciowy renderuje je jako kanał aktywności na żywo i oba oglądają ten sam strumień. To jest test-raz-ekspozycja-dwa razy, jedna warstwa wyżej: jeden strumień zdarzeń, wiele modułów renderujących. Mózg emituje zdarzenia; interfejsy po prostu decydują, jak je narysować.
Lekcja, którą dałbym każdemu, kto tworzy produkty agentowe: najpierw zaprojektuj strumień zdarzeń, jako coś pierwszorzędnego, a nie jako refleksję związaną z systemem żądanie-odpowiedź, który okazał się uszkodzony. Zdecyduj, jakie zdarzenia emituje system — rozpoczęte, myślące, wywołane narzędziem, wyprodukowane, wykonane — i spraw, aby każda powierzchnia renderowała ten strumień. Zapewnij odpowiednią transmisję strumieniową, a średnie opóźnienia będą w porządku. Zrozum źle, a żadna prędkość nie sprawi, że cisza będzie przypominać coś innego niż zawieszenie.
Fig 14.1 — Streaming Is the Interface. The focal server emits one sequence of typed events; every surface is just a renderer watching the same stream. Same duration as request-response — opposite feeling, because silence reads as failure and visible progress reads as speed.
Chapter 15
Kieruj według kosztów, a nie lojalności
Nie każde zadanie zasługuje na ten sam model, a najszybszym sposobem na pozbycie się marginesu jest wysłanie trywialnej klasyfikacji do najdroższego modelu tylko dlatego, że mu ufasz. Dyscypliną, która rozwiązuje ten problem, jest router: cienka warstwa, która przygląda się zadaniu i wybiera najtańszy model, który faktycznie może to zrobić. Routing uwzględniający koszty to jedna z elementów systemu agentowego, która daje największe korzyści i prawie nikt nie tworzy jej wystarczająco wcześnie — ja z pewnością tego nie robiłem.
Kształt to drabina modeli, od tanich do drogich i zasada wyboru. Mały, szybki i tani model radzi sobie z ogromną ilością łatwej pracy — klasyfikacją, ekstrakcją, decyzjami o routingu „czy to tak, czy nie”. Model średniego szczebla radzi sobie ze zwykłym rozumowaniem. Duży, drogi i powolny model jest zarezerwowany dla naprawdę trudnych problemów, które go rzeczywiście potrzebują. Okazuje się, że większość zadań to łatwe zadania w kostiumie trudnych, a wysłanie ich wszystkich do top modelki jest jak wzięcie taksówki, żeby sprawdzić skrzynkę pocztową – działa i jest absurdalne, a absurd zauważa się dopiero, gdy przychodzi rachunek.
Ma to większe znaczenie w systemach AI niż w klasycznym oprogramowaniu, ponieważ koszt połączenia różni się o rzędy wielkości w zależności od modelu, który je obsługuje, a w pętli agentowej wykonuje się ogromną liczbę połączeń. W ramach jednej operacji agent może wykonać dziesiątki połączeń modelowych, a jeśli każdy z nich przejdzie na najwyższy poziom, koszt jednej sesji może być dziesięciokrotnie lub dwudziestokrotnie większy niż powinien — różnica, która jest niewidoczna w przypadku jednej rozmowy i katastrofalna w przypadku floty agentów. Routing to różnica między produktem z marżą a produktem, który traci pieniądze tym bardziej efektywnie, im więcej osób z niego korzysta.
Abstrakcja, która umożliwia routing, to brama z rozdziału 6 — ten sam instynkt oddzielania, który teraz procentuje dokładnie tak, jak obiecano. Ponieważ wszystko komunikuje się z modelami poprzez jedną warstwę, a nie koduje na stałe konkretny model w każdym miejscu połączeń, mogę zmienić reguły routingu w jednym miejscu, dodać nowy model jako nowy szczebel lub zmienić dostawcę bez dotykania logiki, która wymagała „modelu do tego”. Router znajduje się wewnątrz bramy. Wczesne oddzielenie umożliwia późniejsze trasowanie; system pełen zakodowanych na stałe nazw modeli nie ma połączenia, w które można by włożyć router.
Istnieje uwaga dyscyplinująca, która polega na tym, że reguły routingu stają się nieaktualne w miarę zmiany modeli, a zmieniają się one stale. Model, który w zeszłym kwartale był najwyższej klasy i drogi, teraz może być średniej klasy i tani; tańszy model mógłby być na tyle dobry, że awansowałbyś do pracy, którą rezerwowałeś dla czegoś większego. Zatem tablica routingu jest żywą rzeczą, do której należy celowo wracać, a nie ustawianą raz i zapomnianą. Traktuj to jak posiadaną konfigurację i dostrojenie, a nie decyzję, którą podejmujesz raz.
Wysyłaj łatwą pracę do tanich modeli, ciężką pracę do drogich, prowadź przez jeden szew i utrzymuj aktualność tabeli. To większość kontroli kosztów w systemie agentowym, która komplikuje każde pojedyncze połączenie.
Fig 15.1 — Route by Cost. A focal router — living inside the gateway from Ch.6 — sorts each task to the cheapest model that can do it. In an agentic loop of dozens of calls, this is the line between a margin and losing money faster the more people use you.
Chapter 16
Adaptery, czyli jak później zmienić zdanie
W rozdziale 5 powiedziałem, że szybka wysyłka jest bezpieczna tylko wtedy, gdy zawrócenie jest tanie, a następnie obiecałem pokazać ci włazy ratunkowe. To pierwszy i najważniejszy: adapter. Adapter to cienki, ustalony kształt znajdujący się pomiędzy podmiotem żądającym danych a podmiotem, który je dostarcza, dzięki czemu dostawca może zostać zmieniony bez zauważenia przez konsumenta. To mechanizm, który zamienia nieodwracalną decyzję w odwracalną.
Oto konkretna wersja, ponieważ abstrakcja przesłania, jakie to proste. Załóżmy, że potrzebuję danych bestsellerów. Definiuję interfejs — kształt funkcji fetchBestsellers(), który zwraca znaną strukturę. Wszystko powyżej zależy tylko od tego kształtu, a nie od tego, skąd pochodzą dane. Potem piszę za tym jedną implementację: może źródło z eBay, bo to jedyne, z czym mogę się dzisiaj zmierzyć. Później, gdy potrzebuję innego źródła, piszę drugą implementację o tym samym kształcie i zamieniam to, do którego jest podłączone. Nic się nie zmienia. Konsument pytał o bestsellery i je dostawał; nigdy nie wiedziało ani nie przejmowało się tym, że dostawca zmienił się pod spodem.
Dyscyplina polega na narysowaniu interfejsu w punkcie niepewności — dokładnie przy tych decyzjach, co do których podejrzewasz, że będziesz je ponownie rozważać. Nie owijasz wszystkiego adapterem; to przesadna inżynieria, która grzebie kod w sposób pośredni, którego nikt nie potrzebuje. Obejmujesz konkretne połączenia, w których możesz poczuć zmianę przyszłości: źródło danych wybrane pod presją czasu, dostawca modeli, z którym nie jesteś w związku małżeńskim, wybrany podmiot przetwarzający płatności, ponieważ klient już z niego korzystał. Gdziekolwiek dokonałeś wyboru wzruszając ramionami i mówiąc „na razie to wystarczy”, umieść tam adapter, ponieważ „na razie” jest obietnicą złożoną twojemu przyszłemu ja, że zmiana będzie tania.
Powodem, dla którego ma to tak duże znaczenie w pracy AI, jest to, że ziemia stale się porusza. Najlepszy model pracy zmienia się co kilka miesięcy. Dostawca danych zmienia warunki, ceny albo zamyka swój interfejs API. Narzędzie, na którym zbudowałeś, staje się przestarzałe. Jeśli system zakoduje te opcje na stałe w każdej witrynie wywołań, każda zmiana będzie polegać na wyszukiwaniu i zamianie w całej bazie kodu i modlitwie o wyłapanie ich wszystkich. Jeśli pozostają za adapterami, każda zmiana jest nową implementacją znanego kształtu i zamianą jednej linii. Tempo zmian w tym obszarze jest właśnie powodem, dla którego adapter zarabia tutaj szybciej niż gdziekolwiek indziej.
Zaletą testowania jest także to, że adapter zapewnia naturalne miejsce na włożenie podróbki. Ponieważ konsument zależy tylko od kształtu, mogę udostępnić mu implementację kodu pośredniczącego, która zwraca gotowe dane, a teraz mogę testować wszystko na początku bez konieczności kontaktu z prawdziwym dostawcą — bez wywołań API na żywo, bez ograniczeń szybkości i niestabilności. Szew, który zbudowałem do zmiany dostawców, okazuje się tym samym szwem, którego potrzebuję do testowania. Tego typu włazy ratunkowe są zazwyczaj wielofunkcyjne.
Narysuj interfejs tam, gdzie nie jesteś pewien. Napisz jedną prawdziwą implementację i fałszywą. Swobodnie wymieniaj. W ten sposób zachowujesz prawo do zmiany zdania.
Fig 16.1 — The Adapter Seam. The consumer depends only on the focal interface; implementations swap behind it — a real source today, a different one tomorrow, a fake for tests. The same seam that makes providers swappable makes upstream code testable.
Chapter 17
Przełącznik próbny/na żywo
Drugi właz ratunkowy to pojedyncza flaga, która decyduje, czy system działa naprawdę, czy tylko udaje, a prawidłowe wykonanie tego pozwala mi wysłać działającą skorupę na długo przed powstaniem stojącego za nią silnika. Jest to mechaniczny wyraz instynktu „nie poleruj drwin” z rozdziału 5 i zasługuje na osobny rozdział, ponieważ sposób, w jaki go budujesz, decyduje o tym, czy ci to pomoże, czy po cichu zniszczy twój kod.
Zły sposób — tak jak to zrobiłem na początku — polega na rozproszeniu w kodzie warunków warunkowych: jeśli kpisz, zrób to, w przeciwnym razie zrób tamto, powtórz w każdym miejscu zachowanie jest inne. Działa to przez około tydzień, a potem staje się koszmarem, ponieważ ścieżki próbne i żywe rozchodzą się. Każdą nową funkcję trzeba zbudować dwa razy, raz dla każdej gałęzi, i nieuchronnie jedna gałąź zostanie naprawiona, a druga nie, i teraz twoja próbna wersja zachowuje się inaczej niż twój system na żywo w sposób, którego nie zobaczysz, dopóki demo nie pójdzie źle. Rozproszone warunki warunkowe pokazują, jak tryb próbny staje się drugim, subtelnie uszkodzonym produktem, którym zarządzasz przez przypadek.
Właściwy sposób wykorzystuje adapter z poprzedniego rozdziału. Próba kontra wersja na żywo nie jest zjawiskiem powszechnym wszędzie — jest to wybór dokonany raz, przy uruchomieniu, dotyczący tego, którą implementację podłączyć za interfejsem. Istnieje adapter próbny, który zwraca dane w puszkach, oraz adapter działający na żywo, który wykonuje rzeczywistą czynność, spełniają one identyczny kształt, a pojedyncza flaga decyduje, który z nich jest podłączony. Reszta systemu nie ma pojęcia, z kim rozmawia, i nie zawiera ani jednego warunku związanego z próbą. Przełącznik znajduje się dokładnie w jednym miejscu, a wszystko poniżej jest błogą ignorancją.
Zapłata jest taka, że mogę zbudować i przedstawić całe doświadczenie w formie próbnej, przedstawić je klientowi, zebrać reakcje i udoskonalić kształt – a wszystko to zanim nastąpi rzeczywista integracja. Frontend jest prawdziwy. Przepływ jest prawdziwy. Interakcje są prawdziwe. Tylko dane znajdujące się za szwem są konserwowane, a ponieważ szew jest czysty, późniejsze zastąpienie puszkowych danymi prawdziwymi jest zamianą, a nie przebudową. Wysyłałem rzeczy, które były całkowicie przekonujące i całkowicie wyśmiewane, a w dniu, w którym wylądował adapter na żywo, nic się nie zmieniło. To jest przełącznik, który działa zgodnie z projektem.
Towarzyszy temu wymóg uczciwości, którego trzymam się mocno: jeśli z czegoś ktoś się wyśmiewa, musi to być wyraźnie i bezbłędnie wyśmiewane dla każdego, kto na to patrzy. Plakietka, etykieta, baner — coś, co sprawia, że „te dane nie są jeszcze prawdziwe” nie da się przeoczyć. Przełącznik próbny/na żywo to narzędzie do szybkiego budowania, a nie narzędzie do oszukiwania ludzi co do tego, co jest prawdziwe. W chwili, gdy kpina zostaje wzięta za żywą – przez klienta, kolegę z zespołu, a nawet przeze mnie w ciągu trzech tygodni – przestaje być klapą ratunkową, a zaczyna być kłamstwem. Zaznacz to wyraźnie, a przełącznik pozostanie uczciwy.
Jedna flaga, jedna decyzja o okablowaniu, jedna widoczna plakietka. To przełącznik próbny/na żywo, który przyspiesza, zamiast powoli cię zatruwać.
Fig 17.1 — The Mock/Live Switch. One focal flag picks the adapter at startup; downstream code holds not a single mock conditional. The mock path carries a visible badge — the switch speeds you up only as long as no one mistakes canned for real.
Chapter 18
Zostaw ślad
W trzecim luku ratunkowym nie chodzi o zmianę zdania – chodzi o to, aby móc zaufać pracy, której nie widziałeś. Kiedy proces przebiega bez nadzoru, jedyną rzeczą stojącą między tobą a ślepą wiarą jest ślad, jaki ona po sobie pozostawia. Przebieg, który zakończy się sukcesem po cichu, i przebieg, który zakończy się po cichu niepowodzeniem, z zewnątrz wyglądają identycznie, a tej dwuznaczności nie można tolerować w systemie, nad którym celowo przestaliście nadzorować. Zatem każdy znaczący przebieg musi generować uporządkowany dowód tego, co zrobił.
Przez konstrukcję mam na myśli coś więcej niż ścianę z bali. Dzienniki służą do debugowania, gdy coś już poszło nie tak; ślad służy do potwierdzania, że wszystko poszło dobrze, bez konieczności czytania czegokolwiek. Dobrym śladem są same artefakty i ich manifestacja: utworzone pliki wraz z ich ścieżkami. Wygenerowane linki. Krótkie podsumowanie prostym językiem tego, co się wydarzyło. Wystarczająco, żebym mógł rzucić okiem na wynik nocnego biegu i w ciągu kilku sekund z całą pewnością dowiedzieć się, czy wykonał to, o co prosiłem — nie wnioskować, nie mieć na to nadziei, wiedzieć to.
To zamyka pętlę otworzoną w rozdziale 9, gdzie zdefiniowałem „gotowe” jako zawierające czytelny ślad. Oto mechanizm stojący za tą definicją. Powodem, dla którego konieczne jest śledzenie, jest to, że nienadzorowany system bez żadnego systemu zmusza cię do ponownego nadzorowania go — jeśli na podstawie danych wyjściowych nie możesz stwierdzić, czy zadziałało, musisz obserwować, jak działa, i teraz tracisz całą korzyść z wykonywania bez nadzoru. Ślad jest tym, co odkupi twoją nieobecność. To właśnie dzięki temu nocna zmiana faktycznie przebiega w nocy, ponieważ oznacza to, że rano można sprawdzić pracę w nocy, nie będąc tam.
Pod tym kryje się zasada projektowania, która wykracza daleko poza sztuczną inteligencję: proces powinien czynić czytelnym swój sukces lub porażkę. Nie buduj rzeczy, które wymagają eksploracji jaskini, aby dowiedzieć się, co zrobili. Twórz rzeczy, które Ci mówią. Trace nie jest dodatkiem, którego można używać, gdy debugowanie staje się bolesne; jest to pierwszorzędny wynik biegu, będący w równym stopniu efektem końcowym, jak i celem biegu. Kiedy teraz projektuję umiejętność lub automatyzację, „co to emituje, abym mógł temu później zaufać” jest od początku częścią specyfikacji, a nie refleksją.
Związek z porannym połączeniem z rozdziału 10 jest bezpośredni i warty wyraźnego podkreślenia. Scalanie — mój bezlitosny poranny przegląd wyników z nocy — jest możliwe tylko wtedy, gdy dane wyjściowe docierają w postaci czytelnych śladów. Nie mogę ocenić dziesięciu kompilacji z dnia na dzień, jeśli ocenianie każdej z nich oznacza zrekonstruowanie tego, co zrobiła na podstawie rozproszonych dowodów. Mogę je szybko ocenić, jeśli każdy z nich przekaże mi czyste podsumowanie i wyszczególnione w nim artefakty. Dzięki śladowi połączenie jest wystarczająco szybkie, aby można je było przeprowadzić każdego ranka, co sprawia, że cała pętla typu „noc plus łączenie” jest zrównoważona, a nie aspiracyjna.
Emituj dowody jako produkt najwyższej jakości. Spraw, aby sukcesy i porażki były czytelne na pierwszy rzut oka. Bieg, którego nie da się zweryfikować na podstawie śladów, to bieg, podczas którego będziesz opiekować się dzieckiem — a opieka nad dziećmi jest tym, czym to wszystko miało się zakończyć.
Fig 18.1 — Leave a Trace. The unattended run emits a focal structured trace — artifacts, links, a readable summary — which is exactly what makes the morning merge fast enough to do daily. Without it, you're back to babysitting.
Chapter 19
Dowiedz się, ile kosztuje każdy bieg
Czwarty właz ratunkowy chroni co innego: nie twoją zdolność do zmiany zdania lub zaufania biegowi, ale twój margines. W systemie agentycznym koszty są rzeczywiste, zmienne i niewidoczne, chyba że celowo je uwidocznisz — tworzysz więc księgę rejestrującą, ile kosztuje każde uruchomienie, w chwili, gdy to kosztuje, albo wpadasz na ślepo do firmy, która może tracić pieniądze na każdym kliencie bez Twojej wiedzy.
Pułapka jest specyficzna dla sposobu rozliczania tych systemów i zaskoczyła mnie. Różne rodzaje wykorzystania czerpią z różnych pul po różnych stawkach – połączenie interaktywne i automatyczne połączenie bezgłowe mogą być liczone całkowicie osobno, na różnych licznikach i po różnych cenach. Jeśli w Twojej księgowości założono, że wszystkie zastosowania są takie same, Twoje liczby są po cichu błędne i mylą się w najbardziej niebezpiecznym kierunku: wyglądają dobrze aż do momentu otrzymania faktury i wykazania, że zautomatyzowana flota, z której byłeś tak dumny, czerpie z puli, której nie śledziłeś, w tempie, którego nie modelowałeś. Dowiedziałem się o tym na tydzień przed zmianą rozliczeń, która spowodowałaby urzeczywistnienie tej luki i tylko dlatego jest to lekcja książkowa, a nie dziura w moich rachunkach.
Dlatego też księga musi uwzględniać koszty w zakresie faktycznej struktury fakturowania, a nie takiej, jaką sobie życzysz. Każde uruchomienie rejestruje nie tylko to, co się wydarzyło, ale także to, z której puli zostało pobrane i jaka jest stawka tej puli, więc przypisany mu koszt jest prawdziwym kosztem, a nie średnią, która sprowadza tanie i drogie użycie na pocieszający, fałszywy środek. Mapa stawek — która pula ile kosztuje — znajduje się w jednym miejscu, jest przypisana do poszczególnych puli i jest sprawdzana przy każdym obliczaniu kosztu przebiegu. Gdy zmienią się stawki lub pojawi się nowa pula, aktualizujesz mapę w jednym miejscu, a koszt każdego przyszłego uruchomienia będzie prawidłowy.
Powodem, dla którego jest to ucieczka, a nie tylko księgowość, jest to, że pozwala zachować zdolność podejmowania rozsądnych decyzji w obliczu zmieniającej się sytuacji ekonomicznej. Jeśli znasz prawdziwy koszt jednostkowy, możesz zdecydować, jakie opłaty pobierać, które funkcje warto uwzględnić, czy dany klient jest opłacalny i czy flota jednodniowa się opłaca. Bez tego każda z tych decyzji jest domysłem, a domysły dotyczące ekonomii jednostkowej składają się na biznes, który skaluje swoje straty. Widoczność kosztów sprawia, że istnieje możliwość podjęcia dobrych decyzji – i właśnie do tego służy luk ratunkowy.
Dyscyplina polega na tym, aby zbudować księgę wcześnie, zanim będzie ona desperacko potrzebna, ponieważ moment, w którym jej potrzebujesz, jest momentem, w którym najmniej możesz pozwolić sobie na jej rekonstrukcję na podstawie historycznych domysłów. Oszacuj koszt z pierwszego rzeczywistego przebiegu. Wprowadź to do prawdziwej struktury rozliczeniowej. Utrzymuj aktualność mapy szybkości w taki sam sposób, w jaki aktualizujesz tablicę routingu, ponieważ oba dryfują z tego samego powodu: ekonomia, która się pod tym kryje. Dowiedz się, ile kosztuje każdy przebieg, tak jak to kosztuje, a marża przestanie być tajemnicą.
Fig 19.1 — Know What Every Run Costs. Different usage draws from different pools at different rates; the focal rate map — keyed by pool, kept in one place — turns each run into its true cost rather than a blended average that hides where the money goes.
Chapter 20
Kiedy kończy się szczebel
Część II kończy się tam, gdzie się zaczęła, czyli na drabinie, ale patrząc w górę: po czym poznajesz, że wyrosłeś ze szczebla, na którym się znajdujesz i rzeczywiście nadszedł czas, aby się wspiąć? Ponieważ dyscyplina z rozdziału 11 — stój na najniższym szczeblu, który działa — ma odpowiednią dyscyplinę, która jest równie ważna i łatwiejsza do popełnienia błędu: rozpoznanie uczciwego momentu, w którym szczebel się skończył, i nie mylenie z tym momentem zwykłego dyskomfortu.
Sygnałem są możliwości, a nie ból. Wspinasz się, gdy szczebel, na którym się znajdujesz, strukturalnie nie może zrobić tego, czego naprawdę potrzebujesz — nie wtedy, gdy jest to denerwujące, nie wtedy, gdy kod staje się niewygodny, nie wtedy, gdy wyższy szczebel wydawałby się bardziej imponujący. Niezręczny kod na wystarczającym szczeblu jest problemem związanym z refaktoryzacją, a rozwiązaniem jest refaktoryzacja, a nie wspinanie się; wspinanie się w celu uniknięcia bałaganu po prostu przenosi bałagan w miejsce droższe w utrzymaniu. Szczebel naprawdę się wyczerpał tylko wtedy, gdy można wskazać konkretną możliwość – strumieniowanie przez kilka minut, tworzenie podprocesów, utrzymywanie długotrwałego stanu, którego platforma nie wytrzyma – której nie ma ten szczebel, a następny ma.
Podjąłem złą decyzję w obu kierunkach i oba bolały. Wspiąłem się na górę zbyt wcześnie, uwiedziony poczuciem, że prawdziwy backend jest poważniejszy niż funkcja bezserwerowa, i zapłaciłem za to wagą operacyjną, której nie potrzebowałem — maszyną do zabezpieczania, monitorowania i budzenia, a wszystko to po to, aby uruchomić coś, co niższy szczebel poradziłby sobie, gdy spałem. I siedziałem zbyt długo, wykrzywiając szczebel, aby udawać możliwości, których nie miał, stosując obejścia wśród obejść, aż do momentu, gdy wykrzywienie kosztowało więcej, niż kosztowałaby wspinaczka. Umiejętność polega na rozróżnieniu: czy to bałagan, który powinienem posprzątać, czy sufit, w który uderzyłem?
O tym, że to prawdziwy sufit, można powiedzieć, że obejścia tego problemu przestają być brzydkie i zaczynają być kruche. Brzydki, ale solidny kod na prawym szczeblu jest w porządku — po prostu nie jest ładny, a ładny jest tani w odroczeniu. Ale kiedy Twoje rozwiązania zaczną zawodzić w sposób, którego nie możesz w pełni kontrolować, kiedy walczysz z podstawową naturą platformy, a nie tylko z jej szorstkimi krawędziami, kiedy potrzebujesz czegoś, do czego szczebel nigdy nie został zbudowany – to nie bałagan, to sufit i uczciwym posunięciem jest wspinanie się. Sygnałem jest kruchość, a nie brzydota.
A kiedy już się wspinasz, włazy ewakuacyjne z tej części sprawiają, że można tu przetrwać. Ponieważ logika znajduje się w warstwie usług pozbawionej ram, przeniesienie jej na nowy szczebel oznacza ponowne opakowanie, a nie przepisanie. Ponieważ dostawcy siedzą za adapterami, nowe środowisko dziedziczy te same wymienne szwy. Ponieważ biegi pozostawiają ślady, a koszty są rejestrowane, możesz stwierdzić, czy wspinaczka rzeczywiście pomogła. Dyscypliny, które utrzymywały dyscyplinę na niskich szczeblach, są dokładnie tym, co sprawia, że wspinaczka jest tania, gdy jest w końcu uzasadniona. Oto cała drabina architektury: zacznij od niskiego poziomu, zbuduj włazy i wspinaj się tylko wtedy, gdy prawdziwy sufit – a nie twoje ego, nie bałagan – nie pozostawia ci uczciwego wyboru.
No figure. This chapter is a judgement call — climb or refactor — not a structure; the ladder it refers back to is already drawn in Fig 11.1, now read from the top down.
Part III
Bezgłowy Claude
Na najwyższym szczeblu: agent działający bez nadzoru ludzi. Czego potrzeba, aby umieścić go za serwerem — wzorzec podprocesu, strumień w praktyce, pułapka środowiskowa i fakturowanie, które się pod tobą przesuwa.
Chapter 21
Agent za serwerem
Część II zakończyła się na szczycie drabiny. Część III trafia do środka, ponieważ na najwyższym szczeblu żyje najciekawsza i najbardziej niezrozumiała rzecz, którą buduję: agent działający bez głowy, za serwerem, wykonujący pracę, której nikt nie obserwuje w czasie rzeczywistym. To jest maszynownia wszystkiego i warto zwolnić, aby wyjaśnić, co tak naprawdę oznacza „bezgłowy” i dlaczego zmienia kształt tego, co można zbudować.
Bezgłowy agent to taki, przed którym nie siedzi żaden człowiek. Nie ma okna czatu, w którym ktoś pisze, nikt nie czyta wyników i nie popycha ich dalej. Zamiast tego jest wywoływany przez program — mój serwer go wywołuje, zleca mu zadanie i pozwala mu działać. Ta sama podstawowa zdolność, która napędza interaktywnego asystenta, jest teraz podprogramem w większym systemie, nazywanym w sposób, w jaki wywołuje się każdą inną funkcję, z tą różnicą, że ta funkcja może rozumować, używać narzędzi i wytwarzać prawdziwe artefakty. To przeformułowanie — od partnera rozmowy do możliwości, które można wywołać — jest całym odblokowaniem.
Ma to znaczenie, ponieważ człowiek w pętli jest wąskim gardłem, a część I dotyczyła wyłącznie usuwania wąskich gardeł, które nie muszą tam występować. Agent interaktywny może działać tylko tak szybko, jak osoba potrafi czytać i odpowiadać. Bezgłowy agent nie ma takich ograniczeń — może działać o trzeciej nad ranem, działać dziesięć równolegle, działać zgodnie z harmonogramem, działać w odpowiedzi na zdarzenie. W momencie, gdy agent przestaje potrzebować ludzkiego nadzoru, staje się czymś, co można skomponować w systemy, a kompozycja jest tym, co wywiera wpływ na związki. Agent, z którym rozmawiasz, jest narzędziem. Sto agentów, które organizujesz, to fabryka.
Kształt architektoniczny przypomina ten z rozdziału 12, teraz z agentem jako pakowaną rzeczą. Znajduje się tam serwer — najwyższy szczebel — i wewnątrz niego wywoływany jest agent w ramach realizacji żądania. Użytkownik uruchamia przejście przez głupi interfejs; żądanie przechodzi przez punkt końcowy do serwera; serwer wywołuje agenta bezgłowego; agent działa, produkuje, a wyniki płyną z powrotem. Agent to mózg, serwer to ciało, które go nosi, a frontend to twarz. Ta sama anatomia co poprzednio, ze znacznie sprawniejszym narządem pośrodku.
Tym, co naprawdę różni się od zwykłej pracy serwera — i o czym tak naprawdę jest reszta Części III — jest to, że działanie agenta jest długie, przesyłane strumieniowo, zawiera stany i czasami jest kosztowne w sposób, w jaki nie jest to normalne wywołanie funkcji. Nie zwraca w ciągu milisekund; myśli przez chwilę. Nie daje jednej odpowiedzi; emituje sekwencję kroków. Nie działa w izolacji; rodzi narzędzia i dotyka świata zewnętrznego. Każda z tych właściwości przełamuje założenie, na którym zbudowane są zwykłe serwery typu żądanie-odpowiedź, a każda z nich stanowi rozdział: podproces, strumień, środowisko, w którym działa, pula kosztów, z której czerpie.
Oto mapa części III. Umieściliśmy agenta za serwerem. Teraz dowiadujemy się, czego to właściwie wymaga.
Fig 21.1 — An Agent Behind a Server. Same anatomy as the dumb-frontend / service-layer split, with a far more capable organ in the middle. The focal brain has no human in front of it — which is exactly what lets it run at 3am, in parallel, on a schedule.
Chapter 22
Wzorzec podprocesu
Najbardziej bezpośredni sposób uruchamiania agenta bezgłowego jest również tym, który najbardziej zaskakuje ludzi: uruchamiam to samo narzędzie wiersza poleceń, którego programista używałby interaktywnie, z tą różnicą, że mój serwer uruchamia go jako podproces i programowo odczytuje jego dane wyjściowe. Nie ma osobnej „wersji serwerowej” agenta. Jest narzędzie i mój serwer steruje narzędziem w sposób, w jaki zrobiłby to bardzo szybki i bardzo cierpliwy operator. Zrozumienie, dlaczego to działa — i dlaczego jest lepsze niż oczywista alternatywa — jest warte osobnego rozdziału.
Oczywistą alternatywą jest bezpośrednie wywołanie interfejsu API modelu i samodzielne zbudowanie całego zachowania agenta: pętli użycia narzędzia, obsługi plików, szkieletu wnioskowania, ponownych prób. Ludzie sięgają po to, ponieważ wydaje im się to bardziej „właściwe”, bardziej przypomina prawdziwą inżynierię. Oznacza to jednak odbudowanie, a następnie utrzymanie ogromnej liczby zachowań, które narzędzie wiersza poleceń już zaimplementowało i które są ulepszane przy każdej aktualizacji narzędzia. Zamiast tego uruchamiając narzędzie jako podproces, dziedziczę to wszystko za darmo. Kiedy narzędzie staje się lepsze w używaniu narzędzi, mój system staje się lepszy w używaniu narzędzi, a ja nic nie zrobiłem. Zamiast przestawiać jego nogi, stoję na ramionach narzędzia.
Mechanizm jest skromny i solidny. Mój serwer uruchamia narzędzie jako proces potomny, przekazuje mu zadanie, a narzędzie przesyła z powrotem ustrukturyzowane dane wyjściowe — nie dowolny tekst, ale czytelną maszynowo sekwencję zdarzeń opisującą, co robi. Mój serwer odczytuje ten strumień linia po linii, a każda linia jest zdarzeniem, na które może zareagować: przekazać do frontendu, zapisać w śladzie, obliczyć koszt, zaktualizować stan. Podproces to silnik; mój serwer stanowi wiązkę wokół niego, zapewniającą komunikację między światem narzędzia a resztą mojego systemu. To najskromniejsza możliwa integracja i właśnie z tego powodu jedna z najtrwalszych.
Właściwość, która nadaje temu wzorowi blasku, polega na tym, że ustrukturyzowane dane wyjściowe zmieniają narzędzie konwersacyjne w programowalne. Gdyby narzędzie emitowało tylko prozę, utknąłem na analizowaniu języka angielskiego, który jest kruchy i smutny. Ponieważ emituje uporządkowane zdarzenia, mogę traktować agenta jako dobrze zachowujący się komponent posługujący się protokołem — a gdy tylko coś porozumiewa się protokołem, można na nim niezawodnie budować. Granica podprocesu, która brzmi jak ograniczenie, to tak naprawdę czysta spoina, która pozwala dwóm niezależnie rozwijającym się systemom współpracować: narzędzie ewoluuje na boku, moja uprząż ewoluuje na mojej, a uporządkowany strumień stanowi kontrakt między nimi.
Należy przestrzegać zasady dyscypliny, zgodnie z którą tworzenie podprocesów jest w zasadzie umiejętnością najwyższej klasy — nie można tego robić na niższych szczeblach, co jest jednym z konkretnych powodów, dla których maszynownia znajduje się tam, gdzie się znajduje. Funkcja bezserwerowa, która musi wrócić w ciągu kilku sekund, nie może tam sterować podprocesem, który myśli przez minutę. Zatem wzorzec podprocesu i niestandardowy backend łączą się; potrzeba tego pierwszego jest często tym, co uzasadnia przejście do tego drugiego.
Stwórz prawdziwe narzędzie. Przeczytaj jego uporządkowany strumień. Bądź uprzężą, a nie ponownym wdrożeniem. Dziedzicz każde ulepszenie za darmo.
Fig 22.1 — The Subprocess Pattern. The server is a harness around the focal real tool — spawn it, read its structured event stream, act on each line. You inherit every improvement to the tool for free instead of reimplementing its agent loop.
Chapter 23
Strumień w praktyce
W rozdziale 14 argumentowano, że przesyłanie strumieniowe jest interfejsem. W tym rozdziale opisano, czego tak naprawdę potrzeba, aby przenieść strumień od podprocesu w maszynowni do pikseli poruszających się w czyjejś przeglądarce, ponieważ zasada jest prosta, a hydraulika to miejsce, w którym ludzie nie mogą utknąć. Istnieją trzy przeskoki i każdy z nich może upuścić strumień na podłogę, jeśli nie zrobisz tego celowo.
Pierwszy przeskok to podproces prowadzący do serwera. Narzędzie emituje na wyjściu swoje uporządkowane zdarzenia wiersz po wierszu, a mój serwer odczytuje je w miarę ich nadejścia — nie czekając na zakończenie procesu, a następnie czytając wszystko na raz, co jest błędem, który po cichu przekształca system przesyłania strumieniowego z powrotem w system typu żądanie-odpowiedź. Cały sens polega na tym, aby reagować na każde zdarzenie w chwili jego wystąpienia, więc serwer odczytuje przyrostowo, analizuje każdą linię w wydarzenie i natychmiast coś z nim robi. Jeśli buforujesz tutaj, wszystko poniżej odziedziczy opóźnienie i utracisz strumień już przy pierwszym przeskoku.
Drugi przeskok to serwer do przeglądarki. Serwer utrzymuje długotrwałe połączenie otwarte z frontendem i przesyła przez nie każde zdarzenie w trakcie jego przetwarzania. To jest skok, który wymaga najwyższego szczebla, ponieważ utrzymywanie tego połączenia otwartego przez minutę biegu jest właśnie tym, na co nie pozwalają niższe szczeble. Każde zdarzenie, które nadeszło z podprocesu, jest przekazywane dalej, przekształcane pod kątem potrzeb frontendu i wysyłane do otwartego połączenia, gdy tylko będzie gotowe. Po stronie serwera jest to przekaźnik: wejście z procesu do przeglądarki, z możliwie najmniejszymi opóźnieniami pomiędzy nimi.
Trzecim przeskokiem jest renderowanie przeglądarki. Frontend odbiera każde zdarzenie i natychmiast aktualizuje widok — do tekstu dołączany jest token, w kanale aktywności podświetla się krok, pojawia się wytworzony artefakt. Tutaj cała dyscyplina wyższego szczebla opłaca się lub nie: jeśli każdy wcześniejszy przeskok zachowuje transmisję strumieniową, a frontend renderuje się chętnie, użytkownik ogląda na żywo przebieg pracy. Jeśli jakikolwiek przeskok zostanie zbuforowany, użytkownik na końcu otrzyma serię i zastanawia się, dlaczego czekał. Doświadczenie jest tak samo strumieniowe, jak najmniej strumieniowe przeskakiwanie.
Ideą jednoczącą, którą przyczepiłbym do całego rozdziału, jest to, że strumień jest łańcuchem i każde ogniwo musi go chronić. Nie wystarczy, że narzędzie będzie przesyłać strumieniowo, a frontend będzie w stanie przesyłać strumieniowo; każdy przeskok pomiędzy nimi musi przekazywać zdarzenia bez ich gromadzenia. Jedno łącze buforujące w dowolnym miejscu łańcucha po cichu pokonuje wszystkie łącza do transmisji strumieniowej wokół niego, a awaria jest niewidoczna podczas przeglądu kodu — wygląda na to, że działa, ale wydaje się po prostu zepsuta. Jeśli więc system, który powinien przesyłać strumieniowo, nie przesyła strumieniowo, pytanie dotyczące debugowania jest zawsze takie samo: które łącze gromadzi zasoby?
Zaprojektuj cały łańcuch, aby chętnie przepuszczał wydarzenia. Czytaj stopniowo, przekazuj natychmiast, renderuj chętnie. Wykonaj poprawnie wszystkie trzy przeskoki, a minutowe myślenie w maszynowni stanie się minutą widocznego, żywego i godnego zaufania postępu.
Fig 23.1 — The Stream in Practice. Three hops, all accent because all must preserve the stream: read incrementally, relay immediately, render eagerly. The experience is only as streaming as its least streaming hop — and a buffering link is invisible in review.
Chapter 24
Pułapka środowiskowa
To jest rozdział o kategorii błędów, która upokorzyła mnie bardziej niż jakikolwiek inny błąd logiczny: błąd środowiska, w którym kod jest doskonały, a system nadal robi źle z powodu czegoś w środowisku, w którym działa, czego nie można zobaczyć, czytając kod. W pracy agenta bezgłowego są one szczególnie niebezpieczne, ponieważ agent działa tam, gdzie nie patrzysz, a otoczenie, które dziedziczy, jest niewidoczne, dopóki nie ugryzie.
Specyficzna pułapka, która nauczyła mnie najwięcej, polegała na umieszczeniu referencji w otoczeniu. Zachowanie, które uzyskałem, zależało całkowicie od tego, czy podczas działania agenta była obecna konkretna zmienna środowiskowa — a jej obecność lub brak nie zmieniła ani jednego wiersza kodu, więc przeczytanie kodu nic mi nie dało. Gdy zmienna była ustawiona w jedną stronę, agent korzystał z jednego konta i rozliczał się w jedną stronę. Ustawił inny sposób, korzystał z zupełnie innego konta, rozliczając się inaczej, z innymi limitami. Ten sam kod, to samo polecenie, zupełnie inne konsekwencje w świecie rzeczywistym i jedyna różnica tkwiła w niewidzialnym środowisku, w którym narodził się proces.
Powodem, dla którego ta klasa błędów jest tak niebezpieczna, jest to, że jest cicha i kontekstowa. Nie zgłasza błędu — system działa, po prostu działa źle, czerpiąc z niewłaściwych zasobów lub niewłaściwego konta. Jest też kontekstowy, co oznacza, że może działać doskonale w środowisku, w którym go testowałeś, i zawieść w środowisku, w którym faktycznie działa, ponieważ te dwa środowiska różnią się jakąś zmienną, o której nawet nie pomyślałeś, żeby je porównywać. Różnica między „pracami na mojej maszynie” z rozdziału 9 a „pracami w produkcji” bardzo często wygląda dokładnie tak: różnica w środowisku nie jest ani oczywista, ani zarejestrowana.
Dyscyplina, która mnie ratuje, polega na traktowaniu środowiska jako wyraźnego, sprawdzonego wkładu w każdy bieg, a nie jako warunków otoczenia, mam nadzieję, że są odpowiednie. Przed uruchomieniem bezgłowym chcę dokładnie wiedzieć, jakie środowisko odziedziczy — jakie zmienne są ustawione, jakie dane uwierzytelniające wchodzą w zakres i za jakie konto zostanie naliczona opłata. Higiena otoczenia nie jest efektowna, ale zbłąkana zmienna może kosztować prawdziwe pieniądze lub przedostać się na niewłaściwe konto, a nadzieja nie jest kontrolą. Spraw, aby środowisko było czymś, co potwierdzasz i weryfikujesz, a nie czymś, co zakładasz.
To łączy się ze śladem z rozdziału 18 w sposób, którego musiałem się nauczyć na własnej skórze. Częścią tego, co powinien rejestrować dobry ślad, jest odpowiednie środowisko, w którym jest wykonywane — oczywiście nie same sekrety, ale które konto, w jakim trybie i jaka konfiguracja. Ponieważ kiedy bieg bez głowy powoduje coś zaskakującego, pierwszym pytaniem jest: „w jakim właściwie środowisku to się działo”, a jeśli ślad tego nie rejestruje, po fakcie pozostajesz zmuszony do zgadywania o niewidzialnych warunkach. Ślad przebiegu powinien sprawić, że jego środowisko będzie tak samo czytelne, jak jego dane wyjściowe.
Traktuj środowisko jako dane wejściowe, sprawdź je, zanim mu zaufasz, i zapisz je w śladzie. Poprawny kod nie wystarczy, gdy środowisko, w którym działa, może po cichu sprawić, że właściwy kod zrobi coś złego.
Fig 24.1 — The Environment Trap. Identical code forks into different real-world outcomes at the focal environment — a single invisible variable decides which account bills and at what rate. Treat the environment as an inspected input, and record it in the trace.
Chapter 25
Podział puli kredytów
Ostatni rozdział tej początkowej części Części III dotyczy konkretnego, ciężko zdobytego fragmentu wiedzy, który można uogólnić w szerszą lekcję: sposób rozliczania użytkowania może się zmienić pod Twoim wpływem, a jeśli Twój mentalny model „jak jestem obciążany” jest błędny, każda podjęta na nim decyzja również jest błędna. Moja edukacja tutaj wzięła się z odkrycia, że bezgłowe i interaktywne użycie niekoniecznie czerpie z tego samego miejsca.
Sytuacja była taka. Założyłem, rozsądnie, ale błędnie, że całe użycie mojego agenta jest zmienne — że uruchomienie jest uruchomieniem, rozliczanym z jednego segmentu, według jednej stawki, niezależnie od sposobu, w jaki zostało wywołane. Następnie dowiedziałem się, że użycie bezobsługowe, czyli przebiegi oparte na podprocesach, z rozdziału 22, pobierane jest z oddzielnej puli liczników niż użycie interaktywne, we własnym tempie i w ramach własnych limitów. Te dwa rodzaje pracy, które traktowałem jako identyczne, dla celów rozliczeniowych były dwiema różnymi rzeczami, zależnymi od dwóch różnych kont. I nie było to zjawisko statyczne — nadchodziła zmiana w sposobie działania podziału, która powiększyłaby przepaść w momencie, gdy moja nocna flota najmocniej opierała się o bezgłowy basen.
Natychmiastową lekcją jest ta z rozdziału 19, teraz z konkretną przyczyną: księgowanie kosztów musi modelować strukturę rozliczeń taką, jaka jest w rzeczywistości, łącznie z podziałami, o których istnieniu nie miałeś pojęcia. Gdybym w dalszym ciągu kalkulował koszty każdego przebiegu według jednej stawki mieszanej, moje liczby odbiegałyby od rzeczywistości dokładnie wtedy, gdy skalowałem stronę bez głowy — im bardziej skłaniałbym się ku automatyzacji z dnia na dzień, tym bardziej błędne byłyby moje koszty i odkryłbym to na podstawie faktury, a nie księgi rachunkowej. Wiedza o podziale puli pozwoliła mi poprawnie wpisać mapę stawek i zachować uczciwość księgi.
Szersza lekcja jest ciekawsza i trwalsza, ponieważ określone struktury rozliczeniowe będą się zmieniać, a ta książka stałaby się natychmiastowa, gdyby dotyczyła jakiejś konkretnej. Trwała lekcja jest taka, że ekonomia systemu sztucznej inteligencji jest ruchomym celem utrzymywanym przez kogoś innego niż ty i musisz aktywnie je śledzić, zamiast zakładać, że dzisiejszy model sprawdzi się jutro. Zmiany cenowe. Pule dzielą się i łączą. Ceny się poruszają. Pojawiają się nowe poziomy. Nic z tego nie jest pod Twoją kontrolą i wszystko ma bezpośredni wpływ na to, czy Twój produkt zarabia pieniądze. Traktuj model rozliczeniowy jako zewnętrzny, wersjonowany i podlegający zmianom — coś, co celowo sprawdzasz ponownie, a nie coś, czego nauczyłeś się raz i możesz teraz zignorować.
Warto jasno powiedzieć, że nawyk, który to buduje. Kiedy ekonomia użytkowania ma znaczenie dla Twojej firmy — a w systemie agentowym zawsze ma znaczenie — wyznacz sobie stałe zadanie polegające na zrozumieniu bieżącej rzeczywistości rozliczeniowej, a nie tej, którą zinternalizowałeś na początku. Złapałem podział puli na tydzień przed tym, zanim mogło to zaszkodzić, a jedynym powodem, dla którego to zauważyłem, było to, że zacząłem traktować rozliczenia jako coś, co należy monitorować, a nie zakładać. Ten tydzień ostrzeżenia zadecydował o różnicy między lekcją a raną.
Śledź ekonomię pod kątem tego, czy mogą się zmienić, bo mogą, a tak się stanie, i nie możesz ich zamrozić.
No figure. This chapter is a cautionary lesson about vigilance, not a structure to diagram; the mechanism it feeds — the pool-keyed rate map — is already drawn in Fig 19.1.
Chapter 26
Brakujący środek: wznowienie sesji
Cechą długotrwałej pracy agenta, której docenienie zajęło mi najwięcej czasu, jest to, że w rzeczywistości jest ona długoterminowa – a to słowo nie tylko opisuje czas trwania, ale po cichu redefiniuje, co oznacza porażka. W krótkiej pracy porażka kończy pracę; w długiej pracy awaria powinna zakończyć jedynie bieżący krok i praca będzie kontynuowana. To zupełnie inny projekt.
Naiwny kształt traktuje przebieg jako atomowy: albo zakończy się sukcesem jako jednostka, albo poniesie porażkę jako jednostka. W przypadku wywołania API trwającego 200 milisekund jest to w porządku — nikogo nie obchodzi wznowienie połączenia, które miało powrócić w czasie potrzebnym do zauważenia. W przypadku 45-minutowego działania agenta atomowość jest katastrofalna. Ponowne uruchomienie serwera w czterdziestej minucie oznacza utratę trzydziestu dziewięciu minut myślenia, wywołań narzędzi i wytworzonych artefaktów, a jeśli dzieje się to z jakąkolwiek regularnością – co ma miejsce w rzeczywistych wdrożeniach – cała ekonomia floty załamuje się pod ciężarem ponownego wykonywania pracy, która prawie została ukończona.
To, czego chcesz, to wznowienie. Po ponownym uruchomieniu agent sprawdza, dokąd dotarł, rekonstruuje stan i kontynuuje działanie od ostatniego trwałego punktu kontrolnego, a nie od początku. Mechanizm jest nudny: w miarę postępu przebiegu zapisuje znaczniki postępu w trwałej pamięci masowej — nie każdy token, ale każdy znaczący krok (ukończone wywołanie narzędzia, wyprodukowany artefakt, odznaczony cel cząstkowy). Znaczniki opisują stan na tyle dobrze, że nowy proces może rozpocząć działanie bez konieczności przeżywania tego, co było wcześniej. Tanie w pisaniu, bezcenne, gdy nadejdzie krach.
Dyscypliną jest wybór tego, co stanowi znaczący krok. Zbyt drobnoziarniste i piszesz więcej znaczników niż postępu, przeciągając przebieg i zaśmiecając sklep. Zbyt gruba i awaria pomiędzy punktami kontrolnymi kosztuje Cię dużo pracy. Właściwa szczegółowość to „w przybliżeniu to, co człowiek uznałby za etap” — granice, na których, jeśli musiałbyś wyjaśnić, co robi teraz agent, zmieniłbyś swoją odpowiedź. To są szwy; to są punkty kontrolne.
CV sesji również komponuje się ze śladem z rozdziału 18 w sposób bardziej przejrzysty, niż się wydaje. Ślad już rejestruje to, co się wydarzyło, dla dobra człowieka; stan wznowienia jest tym, co się wydarzyło, w formie, którą maszyna może zjeść. Jeśli ślad jest dobrze zorganizowany — a powinien taki być — nie potrzebujesz osobnej warstwy przechowywania do wznowienia; sam ślad pełni także funkcję dziennika punktu kontrolnego. Jeden ustrukturyzowany artefakt służy zarówno do porannego łączenia, jak i odzyskiwania po awarii, co jest dokładnie tym rodzajem czystego projektu, który przynosi korzyści.
Warto wymienić subtelny tryb awarii. Wznowienie jest tak dobre, jak założenie, że świat nie zmienił się między awarią a ponownym uruchomieniem. Jeśli plik wejściowy został nadpisany, konto docelowe zostało przeniesione, model stał się przestarzały — wznowienie będzie szczęśliwie kontynuowane w świecie, którego już nie ma. Zatem wznowienie biegu powinno sprawdzić jego założenia przed ponownym zanurzeniem się i sprawdzenie, czy elementy, od których wcześniej zależało, są nadal tymi, od których zależy teraz. Ślepe CV to sposób na przekształcenie małej awarii w subtelnie błędny wynik.
Załóż, że każdy długi okres można przerwać, pisz tanie znaczniki w znaczących krokach i sprawdzaj, zanim będziesz kontynuować. Przerwanie kosztuje wówczas sekundy, a nie godziny, a ekonomika floty zaczyna działać.
Fig 26.1 — Resume, Not Redo. The run's checkpoints turn a catastrophic 40-minute redo into the cost of one interrupted step. The resume arrow is focal — it's the difference between fleet economics that work and ones that collapse under any real crash rate.
Chapter 27
Biegi równoległe
Jeden bezgłowy agent jest narzędziem. Setka działających jednocześnie to fabryka — taka była puenta rozdziału 21, a to jest rozdział o tym, co faktycznie zmienia się, gdy przekroczysz tę linię. Ponieważ flota równoległych przebiegów nie jest po prostu „jednym przebiegiem wykonywanym wiele razy”. To inne zwierzę, z własnymi trybami awarii, wąskimi gardłami i własną dyscypliną.
Pierwszą rzeczą, która musi się zmienić, jest izolacja. Kiedy uruchomienia korzystają ze wspólnego katalogu roboczego, wspólnego pliku tymczasowego lub wspólnego stanu, zanieczyszczają się nawzajem w sposób, który objawia się niestabilnymi, nie powtarzalnymi awariami — tego rodzaju awarie, w których ponownie uruchamiasz te same dane wejściowe i otrzymujesz inny wynik w zależności od tego, co jeszcze działo się w tym samym czasie. Zatem każde uruchomienie równoległe ma swój własny obszar roboczy, własne poświadczenia o ściśle określonym zakresie i własną ścieżkę śledzenia. Nie mogą na siebie nadepnąć, bo od początku nie stoją w tym samym miejscu. Izolacja nie jest przyjemna; to właśnie sprawia, że równoległość jest obserwowalna.
Drugą rzeczą, która się zmienia, jest wąskie gardło. Naiwnie można by pomyśleć, że flota składająca się ze stu przebiegów jest wąskim gardłem ze względu na obliczenia, i myliłbyś się. W systemie agentowym wąskim gardłem jest prawie zawsze limit szybkości modelu – ile tokenów na minutę faktycznie obsłuży Twój dostawca – plus, w dalszej części, Twój własny budżet uwagi na sprawdzenie, co wyszło. Podwojenie wielkości floty, gdy osiągnęłeś już pułap stawek, nie powoduje niczego poza zwiększeniem ich w kolejce. Zatem wielkość floty nie jest wybierana na podstawie ambicji; jest wybierany z uczciwego sufitu nad nim, który zwykle jest znacznie niższy, niż sugerowałyby obliczenia.
Trzecia sprawa to koordynacja. Sto niezależnych przebiegów jest łatwych; sto przebiegów, w których B zależy od wyników A, to moment, w którym orkiestracja zamienia się w problem z wykresem. Moją dyscypliną jest utrzymywanie jak największej liczby przebiegów w pełni niezależnych, ponieważ niezależność jest tym, po co jest równoległość. Kiedy zależności są autentyczne — B naprawdę potrzebuje ustrukturyzowanych danych wyjściowych A — wyrażam je jawnie jako krawędź zależności w orkiestratorze, a nie jako ukryte „no cóż, B działa później, więc wszystko będzie dobrze”. Niejawne porządkowanie pozwala uzyskać subtelnie błędne wyniki, gdy koordynator zmieni swój harmonogram.
Jest tryb awaryjny, który zaskoczył mnie po raz pierwszy. Kiedy sto przebiegów kończy się niepowodzeniem w ten sam sposób w tym samym czasie — ponieważ model ma złą godzinę lub awaria dostawcy wpływa na wszystkie z nich — awaria floty wygląda jak pojedyncze zdarzenie systemowe, a nie sto niezależnych problemów. Ale logika ponawiania prób w każdym uruchomieniu tego nie wie; każdy spróbuje ponownie, każdy ponownie zakończy się niepowodzeniem, a teraz wzmocniłeś problem, tworząc młotek w ścianę, która już się nie poruszyła. Zatem flota potrzebuje wyłącznika na poziomie koordynatora: jeśli wskaźnik awaryjności gwałtownie wzrośnie, należy wycofać się w całej flocie, a nie tylko na poszczególne przebiegi.
Ostatnią rzeczą wartą powiedzenia jest to, że równoległe przebiegi sprawiają, że ślad z rozdziału 18 nie podlega negocjacjom, a nie jest ładny. Kiedy jeden bieg robi coś zaskakującego w setce floty, nie można go powtórzyć, aby się odtworzyć – stan, który wywołał niespodziankę, minął. Jedynym dowodem, jaki kiedykolwiek będziesz mieć, będzie to, co zapisał ten bieg, gdy żył. Floty przekształcają stwierdzenie „później będę debugować” na „śledzenie było sesją debugowania” i to przeformułowanie przede wszystkim wymusza dyscyplinę zapisywania dobrych śladów.
Daj każdemu wybiegowi własny pokój. Dopasuj wielkość floty do uczciwego pułapu stawek, a nie do swoich ambicji. Wyrażaj zależności jawnie. Przerwa w obwodzie na poziomie floty. I zapisz ślad, jakby to był jedyny dowód, jaki będziesz mieć, bo zwykle tak jest, gdy flota się przemieszcza.
Fig 27.1 — A Fleet Runs In Rooms. Every run gets its own workspace so they can't contaminate each other; the focal orchestrator merges results and holds the circuit-breaker that trips when a systemic failure hits the whole fleet at once.
Chapter 28
Brama akceptacji
Nie wszystko, co robi system, powinno być autonomiczne, a udawanie, że jest inaczej, powoduje, że pewne oprogramowanie powoduje powstawanie kosztownych błędów. Gdzieś w każdym znaczącym procesie istnieje co najmniej jedna czynność, na którą człowiek musi zwrócić uwagę, zanim to nastąpi — wiadomość e-mail wysyłana do klienta, wdrożenie mające wpływ na produkcję, płatność opuszczająca konto. Bramka zatwierdzająca to mechanizm, który pozwala maszynie robić wszystko inne z pełną prędkością, zatrzymując się dokładnie w tych punktach.
Kształt bramy jest prosty: agent produkuje proponowaną akcję w całości, gotową do wykonania – ale jej nie wykonuje. Czeka, aż człowiek powie tak lub nie. Zatwierdzenie włącza przełącznik i rozpoczyna się akcja; odrzucenie go zabija, a bieg zauważa, dlaczego. Wszystko poniżej bramki traktuje „zatwierdzone” jako wyzwalacz, a nie „przybył do bramki”. Bramą jest twarda pauza, a nie sugestia, a wyzwalaczem jest ludzki zamiar, a nie przekroczenie limitu czasu.
Bardziej interesujące jest to, gdzie umieścić bramy, niż jak je zbudować. Moja zasada jest taka: dokładnie na granicy, gdzie zaczyna się nieodwracalność. Wewnątrz strefy odwracalnej maszyna pracuje swobodnie, korygując się, odrzucając dane wyjściowe, iterując; w momencie, gdy danej czynności nie można cofnąć — ponieważ wiadomość została przeczytana, przesunięto pieniądze lub rozprzestrzeniła się konfiguracja — brama stoi. Działania odwracalne nie zapewniają bram; nieodwracalność tak. Umieszczenie bramki jest tak naprawdę ukrytym audytem odwracalności.
Najczęstszym rodzajem awarii jest nadmierne bramkowanie. Kiedy zbyt wiele trywialnych rzeczy prosi o akceptację, ludzie uczą się klikać „tak” bez czytania, ponieważ głośność wymusza przeglądanie. Teraz brama jest teatrem – nominalnie obecna, skutecznie omijana – i jedyny moment, w którym zgoda faktycznie się liczyła, to ten jedyny raz, kiedy nikt nie patrzył. Under-gating to problem odwrotny: pominięcie zgody na coś, co okazało się nieodwracalne, i odkrycie tego dopiero po uszkodzeniu. Obydwa błędy niszczą wartość bramki i nakładają się na siebie, ponieważ reakcją na brak zatwierdzenia jest często dodanie większej liczby bramek w innym miejscu, co zwiększa współczynnik przeglądania.
Rozwiązaniem jest projekt: niech bramy są rzadkie i znaczące. Jeśli dana kategoria działania wymaga za każdym razem akceptacji, zapytaj, czy jest ona naprawdę nieodwracalna, czy tylko budzi strach — często „nieodwracalność” jest nawykiem, a nie faktem, a bramę można opuścić. I odwrotnie, jeśli istnieje bramka, w praktyce uniemożliwiaj jej obejście: stan domyślny jest zablokowany, nie ma przekroczenia limitu czasu, nie ma automatycznego zatwierdzania, nie ma sprytnego „nie odpowiedziałeś w ciągu pięciu minut, więc założyliśmy, że tak”. Zakładane „tak” nie jest zgodą, a system, który traktuje ją jako „tak”, przestał być bezpieczny.
Dobrze rozmieszczone bramy przynoszą subtelną korzyść, której się nie spodziewałem, gdy ją budowałem po raz pierwszy. Ponieważ brama zmusza agenta do pełnego przygotowania akcji przed czekaniem, artefakt, który przeglądają ludzie, jest znacznie bardziej konkretny niż wszystko, co zobaczyliby w trakcie lotu. Przeglądasz w pełni napisaną wiadomość e-mail, a nie plan jej napisania; konkretną różnicę wdrożeniową, a nie opis tego, co zostanie zmienione. Konkretność zaostrza decyzję tak lub nie, co wyostrza samą bramę. Przygotowanie przed przerwą sprawia, że przerwa jest produktywna.
Bramy umieszczaj tylko w przypadku nieodwracalności. Zanim zaczniesz czekać, przygotuj w pełni akcję. Nigdy nie zatwierdzaj automatycznie, nigdy nie przekraczaj limitu czasu na „tak”. Staraj się, aby były rzadkie, aby człowiek, który je zobaczy, rzeczywiście spojrzał.
Fig 28.1 — Gates Live at Irreversibility. Reversible work flows through untouched; the focal gate stands at the exact point where undo stops being possible. Rare, meaningful, impossible to bypass — that's what keeps the pause from becoming theatre.
Chapter 29
Obsługa niepowodzeń & Ponowne próby
Ostatni rozdział operacyjny dotyczy awarii, a konkretnie błędu, który popełniałem przez długi czas, traktując wszystkie awarie tak samo. W systemie agentowym nie są one takie same, a udawanie, że są, pozwala zaoszczędzić koszty ponawiania prób czegoś, co nigdy się nie powiedzie, niezależnie od tego, ile razy tego próbowałeś. Dyscypliną jest klasyfikacja: nazwij kształt awarii, zanim zdecydujesz, co z nią zrobić.
Warto rozróżnić trzy kształty, a każdy chce innej reakcji. Pierwszy jest przejściowy — sieć przestała działać, dostawca miał problemy, a ogranicznik szybkości stwierdził, że „nie teraz”. Nic w tym zadaniu nie było niewłaściwe; świat na krótko odmówił współpracy. Właściwą reakcją jest ponowienie próby, najlepiej z wykładniczym wycofywaniem, tak aby ponowne próby nie powodowały kumulacji awarii, na którą czekają. Awarie przejściowe to awarie niewidoczne — dobrze zaprojektowane systemy są w stanie zostać pochłonięte tak, że osoba dzwoniąca nawet nie zauważy problemu.
Drugi kształt jest semantyczny. Wywołanie dotarło do modelu, model rozważył zadanie i coś w interakcji nie powiodło się — odmowa, zniekształcony argument narzędzia, wynik, którego nie można było przeanalizować. Ponowienie dokładnie tego samego żądania raczej nie pomoże, ponieważ to nie świat jest problemem; żądanie lub stan jest. Pomocna jest odmiana: przeformułowany monit, inny model, plan awaryjny. Traktowanie błędów semantycznych jako przejściowych — po prostu ponawianie prób na ślepo — to jeden z najkosztowniejszych nawyków w systemach agentowych, ponieważ spędza się prawdziwe pieniądze i czas na wbijaniu żądania, które nigdy nie miało szans powodzenia w niezmienionej postaci.
Trzeci kształt jest końcowy. Streszczenie było błędne. Plik wejściowy nie istniał. Poświadczenia zostają cofnięte. Żadna liczba ponownych prób, żadna sprytna zmiana nie sprawi, że to się powiedzie, ponieważ problem leży przed samym uruchomieniem. Właściwą reakcją jest głośne przerwanie, ujawnienie przyczyny i pozwolenie człowiekowi na naprawienie danych wejściowych. Awarie terminali powinny przypominać uderzenie w ścianę — oczywiste, natychmiastowe i bez zbędnych ponownych prób — ponieważ zaletą systemu jest to, że nie analizuje on po cichu uszkodzonych wejść przez wiele godzin, zanim wykryje awarię przy pierwszym sprawdzeniu.
Mechanizmem umożliwiającym klasyfikację są wpisane sygnały błędów. Jeśli wszystkie Twoje błędy to ciągi znaków — „coś poszło nie tak” — nie możesz ich skierować, a każda awaria powoduje tę samą pętlę awaryjną. Jeśli Twoje błędy zawierają znaczniki strukturalne — rodzaj (przejściowy/semantyczny/terminalny), wskazówka dotycząca ponownej próby, wskazówka dotycząca wycofania — procedura obsługi może przyjrzeć się znacznikowi i deterministycznie wybrać właściwą odpowiedź. Błędy podczas pisania brzmią jak biurokracja, dopóki nie zobaczysz, że pętla ponawiania prób kosztuje sto dolarów, usuwając błąd semantyczny, którego nigdy nie rozwiąże.
Istnieje subtelny tryb awarii, który występuje ponad poszczególnymi kategoriami, a mianowicie burze ponownych prób. Gdy wiele przebiegów naraz kończy się niepowodzeniem semantycznym lub końcowym — zły szablon podpowiedzi przekazany do środowiska produkcyjnego, uszkodzony adapter — lokalna logika ponawiania każdego przebiegu nie wie, że ma to wpływ na flotę, i każdy z nich wycofuje się. Wyłącznik na poziomie floty z rozdziału 27 jest tym, co to powstrzymuje: gdy wskaźnik awaryjności floty przekroczy próg, należy wstrzymać ponowne próby w całej flocie, a nie tylko dla każdego przebiegu. Indywidualna powściągliwość nie pomaga; powściągliwość musi być zbiorowa.
Klasyfikuj, zanim odpowiesz. Ponów próbę tylko tymczasowo. Różni się semantycznie. Przerwij głośno dla terminala. A kiedy zawodzi cała flota, należy przerwać obwód na poziomie floty, ponieważ sto powściągliwych przejazdów i tak tworzy burzę.
Fig 29.1 — Three Shapes, Three Responses. The focal classifier routes each failure by kind — transient retries, semantic varies, terminal aborts. Untyped errors collapse the three into one bucket and burn cost on failures no retry could ever resolve.
Chapter 30
Orkiestrator
Część III zamyka się na warstwie powyżej poszczególnych przebiegów – na styku, w którym „jeden agent robi coś” zamienia się w „operację”. Nazywam tę warstwę orkiestratorem i to cienki, nieestetyczny element infrastruktury decyduje, co będzie działać, kiedy, w jakiej kolejności, w czyim imieniu i przy jakim budżecie. Właściwe wykonanie tego sprawia, że wzorzec podprocesu z rozdziału 22. staje się flotą, którą można faktycznie zarządzać.
Orkiestrator utrzymuje trzy stany i utrzymywanie ich w czystości to większość jego pracy. Po pierwsze, kolejka prac do wykonania — zadań oczekujących na pracownika. Po drugie, rejestr tego, co aktualnie się dzieje – którzy pracownicy są zajęci jakimi zadaniami i od kiedy. Po trzecie, historia tego, co zostało zrobione — zakończone serie, ich wyniki, ich ślady, ich koszty. Razem te trzy stany odpowiadają na podstawowe pytania operatora w dowolnym momencie: co się dzieje, co jest na żywo i co się stało. Odpowiedz dobrze na te trzy pytania, a większość obciążenia operacyjnego floty wyparuje.
Kiedy budujesz taki program po raz pierwszy, pojawia się pokusa, aby uczynić orkiestratora mądrym. Niech określi dokładny model dla każdego zadania, przepisz podpowiedzi, spróbuj ponownie ze zmianami, wykonaj klasyfikację niepowodzeń z rozdziału 29. Odporność. Zadaniem orkiestratora jest planowanie i księgowanie, a nie myślenie. Cała inteligencja – routing, klasyfikacja, ponowne próby – należy do przebiegów, w których żyje indywidualny kontekst; orkiestrator siedzi powyżej i popycha pracę. Cienki orkiestrator w bogatych seriach to projekt, który jest trwały; inteligentny koordynator w przypadku głupich przebiegów to monolit z większą liczbą trybów awarii niż którakolwiek połowa.
Pytanie o zależność dotyczy tego, gdzie orkiestratorzy stają się naprawdę użyteczni, a nie tylko wygodni. Kiedy przebieg B potrzebuje danych wyjściowych A, orkiestrator utrzymuje przewagę i odmawia zaplanowania B przed zakończeniem A. Gdy wiele niezależnych uruchomień może odbywać się równolegle, koordynator planuje je jednocześnie w oparciu o pułap stawek floty. Jeśli dobrze go zbudujesz, otrzymasz mały silnik DAG, który szanuje zależności i wydajność — dokładnie to, co robi kierownik fabryki, przełożone na oprogramowanie.
Powiązanie z argumentem dotyczącym nocnej zmiany w Części I jest bezpośrednie i warte nawiązania do nazwy, ponieważ w tym miejscu utwór techniczny spotyka się z dziełem filozoficznym. Nocna zmiana jest możliwa tylko dlatego, że koordynator może utrzymać stan floty, kiedy ja śpię — kolejkować dzisiejsze prace, uruchamiać każde zadanie w miarę otwierania się mocy produkcyjnych, zbierać wyniki i ślady, być gotowym do przekazania rano czystego stosu ukończonych przebiegów z dołączonymi dowodami. Bez orkiestratora „pozwól mu działać przez noc” jest życzeniem. W przypadku tego zadania „pozwól mu działać przez noc”.
Istnieje dyscyplina dotycząca tego, czego orkiestrator nie powinien robić. Nie powinien trzymać się logiki biznesowej. Nie powinien wiedzieć, jak wygląda „dobry” bieg. Nie powinna decydować, kiedy wydać więcej pieniędzy. Te osądy należą do ludzi i ucieczek; Zadaniem orkiestratora jest być niezawodnym i głupim — planować, co mu się powie, śledzić, o co go prosi, i zejść mu z drogi. Każda reguła biznesowa, która wślizguje się do orkiestratora, staje się regułą trudną do zmiany, ponieważ teraz program planujący jest połączony z domeną, a domena porusza się szybciej, niż kiedykolwiek powinien.
Nazwij orkiestratora. Zachowaj szczupłość. Daj mu trzy stany i żadnych opinii. Pozwól mu utrzymać flotę podczas snu i niech poranek dokona oceny, gdy się obudzisz.
No figure. The orchestrator's shape is drawn already in Fig 27.1 — the hub between rooms and the merge — this chapter is the case for keeping that hub small, an argument that a diagram would only add box-count to.
Part IV
Pieniądze
Księgi kosztów, warunki świadczenia usług, subskrypcja a interfejs API, wycena dowodu słuszności koncepcji, kiedy faktycznie opłaca się przepustowość z dnia na dzień, oraz ekonomia jednostkowa decydująca o tym, czy agentowy produkt drukuje pieniądze, czy je wycieka.
Chapter 31
Księgi rachunkowe, które łączą się w coś
W rozdziale 19 wyjaśniono, dlaczego potrzebna jest księga kosztów. W tym rozdziale opisano, jak go zbudować, aby zarabiał na utrzymanie — ponieważ źle ukształtowana księga jest gorsza niż żadna, dając fałszywą pewność liczb bez możliwości odpowiedzi na jakiekolwiek rzeczywiste pytania na ich temat.
Kształt, na którym wylądowałem, jest matowy, co jest właściwym kształtem księgi głównej. Jeden wiersz na każdy znaczący przebieg, oznaczony znacznikiem czasu i zawierający każdy wymiar, który może mieć znaczenie później, jako osobna kolumna: która pula, jaki model, który najemca, jaki cel, ile tokenów wpłynęło, ile tokenów wypłynęło, jaka stawka obowiązywała i jaki był wynikowy koszt. Żadnych podsumowań. Brak agregacji. Żadnych ładnych etykiet ukrywających leżące pod spodem atomy. Księga jest surową prawdą; wszystko inne jest zapytaniem.
Pułapka agreguje zbyt wcześnie. Kuszące jest, gdy po zakończeniu okresu wynajmu podniesiesz miesięczną kwotę najemcy i pójdziesz dalej. Ale teraz suma jest stratnym podsumowaniem rzeczywistości, której już nie masz, i w chwili, gdy pojawia się nowe pytanie — ile kosztowały w całej flocie zautomatyzowane przejazdy nocne w porównaniu z interaktywnymi przejazdami w ciągu dnia — podsumowanie jest bezużyteczne. Nie zarejestrował wymiaru, od którego zależy nowe pytanie. Przechowuj atomy i agregaty w czasie odczytu; księga pozostaje elastyczna w przypadku pytań, o których jeszcze nie pomyślałeś.
Drugą pułapką jest nadawanie znaczenia nazwie biegu. Jeśli przebieg nazywa się „overnight-tenant-a-report-v2”, a ten ciąg znaków koduje dzierżawcę, tryb i cel, nie można wysłać do niego zapytania bez analizowania tekstu. Każdy wymiar zasługuje na osobną kolumnę. Analizowanie tekstu w twojej własnej księdze to zapach, który mówi, że wzdrygnąłeś się przy projektowaniu schematu, podczas gdy powinieneś był stworzyć kolumnę i przejść dalej.
Istnieje dyscyplina dotycząca tego, co uwzględnić poza tym, co oczywiste. Koszt, tokeny, najemca – jasne. Ale także: która wersja szablonu podpowiedzi obowiązywała, jaki model został wybrany, czy uruchomienie zakończyło się sukcesem za pierwszym podejściem, czy po ponownym. Te wymiary wydają się przesadą do dnia, w którym regresja modelu powoduje, że połowa twojej floty zaczyna spalać żetony, a ty musisz odpowiedzieć „kiedy to się zaczęło i na który szablon ma to wpływ”. Ta odpowiedź jest trywialna przy zarejestrowanych wymiarach i bez nich niemożliwa. Rejestruj więcej, niż myślisz, że potrzebujesz; dyski są tanie, a żale drogie.
Ostatnią zasadą jest to, że księga jest przeznaczona wyłącznie do dopisywania. Nigdy nie przepisujesz wiersza; jeśli dowiesz się czegoś później – stawka była błędna, cel został błędnie oznaczony – piszesz wiersz korekty, który odwołuje się do oryginału. Niezmienność oznacza, że księgę można traktować jako dowód, co oznacza, że może ona stanowić potwierdzenie rozmowy z zespołem finansowym klienta, gdy nadejdzie pytanie dotyczące faktury. Przepisana księga to księga, której nikt nie może obronić.
Atomy nie podsumowania. Kolumny, a nie ciągi nazw. Więcej wymiarów niż myślisz. Tylko dołączanie. To księga, która łączy; cokolwiek mniej jest fałszywym narratorem noszącym arkusz kalkulacyjny.
Fig 31.1 — One Row, All Dimensions. The focal row carries every fact you might query on — model, template version, retry attempt, gate outcome — because aggregation is a read-time act and the ledger is the underlying truth those reads depend on.
Chapter 32
Linia ToS
Każdy dostawca modeli ma dokument z warunkami korzystania z usługi, a jego uczciwa nazwa to „lista rzeczy, które spowodują zamknięcie Twojego konta, gdy ktoś w końcu spojrzy”. Przez większość czasu nikt nie patrzy. Czasami ktoś patrzy i jeśli działasz w sposób technicznie zabroniony – automatyczne skrobanie, agresywne używanie modelu bez głowy, wprowadzanie modelu do konkurencyjnej usługi – egzekwowanie prawa nie jest stopniowane. Konta nie są ostrzegane. Zamykają się.
Niebezpieczny kształt ryzyka ToS polega na tym, że jest ono asymetryczne i opóźnione. Przez długi czas nic się nie dzieje; wzorzec naruszający ToS po prostu działa, tanio i cicho, a każdy dzień „nadal działa” buduje pewność, że będzie działał dalej. Pewnego dnia tak się nie dzieje i egzekwowanie prawa następuje bez powiadomienia. Nie ma gradientu konsekwencji, na które możesz zareagować — przechodzisz od pełnej wydajności do zera. Każda firma zbudowana w oparciu o naruszenie ToS to firma, której pozostał jeden cichy dzień, a milczenie jest całym problemem.
Raz odmówiłem współpracy z klientem w tej sprawie i okazało się, że była to jedna z lepszych decyzji biznesowych, jakie podjąłem. Poproszono o pobranie dużej witryny strony trzeciej, przepuszczenie jej zawartości przez model i ponowne opublikowanie przetworzonych wersji. Technicznie wykonalne w popołudnie; atrakcyjne komercyjnie; prawie na pewno sprzeczne zarówno z ToS źródła, jak i dostawcą modelu. Odpowiedziałem, że nie, i klient znalazł kogoś innego, a operacja tego kogoś innego trwała około ośmiu miesięcy, zanim przestała działać. Tymczasem moje konto u dostawcy jest nadal otwarte, a kosztu reputacji osoby, która utraciła konto, nigdy nie pokryłem.
Lekcja nie jest taka, że dokumenty ToS są święte. Chodzi o to, że reprezentują kategorię ryzyka, której promień wybuchu jest asymetryczny – niewielka zaleta przekroczenia granicy, katastrofalna wada w dniu, w którym ktoś to zauważy. W każdej innej decyzji dotyczącej ryzyka możesz rozważyć wielkość razy prawdopodobieństwo. W tym przypadku prawdopodobieństwo wyegzekwowania w dowolnym krótkim okresie jest na tyle niskie, że można je zignorować, ale skala w dniu, w którym to nastąpi, jest całkowita. Rzadkie, ale katastrofalne nie jest rodzajem ryzyka, na które się narażasz i widzisz, co się stanie; jest to rodzaj, w którym kierujesz się strukturalnie.
Dyscyplina praktyczna jest nudna: przeczytaj Warunki korzystania. Nie przeglądaj, czytaj. Ani razu, w dniu rejestracji – okresowo, bo warunki się zmieniają, a branża porusza się szybciej. Jeśli coś w warunkach jest niejednoznaczne, zapytaj i uzyskaj odpowiedź na piśmie, zanim zaczniesz skalować. Jeśli coś jest jednoznacznie zabronione, nie rób tego, niezależnie od tego, jak atrakcyjny jest klient. Klient, który prosi Cię o naruszenie warunków dostawcy, jest klientem proszącym Cię o poniesienie ryzyka, którego sam nie chce ponosić. To nie jest partnerstwo; to jest odciążenie.
Zaletą tej dyscypliny jest to, że ToS staje się pomocą, a nie ograniczeniem. Znajomość linii oznacza, że możesz śmiało do niej dążyć, bez obawy przed zasadzką. Ludzie, którzy chodzą na palcach wokół tego, co ich zdaniem może być zakazane, marnują tyle samo energii, co ludzie, którzy przekraczają tę granicę i się martwią — uczciwa lektura pozwala znaleźć złoty środek, agresywnie, ale bezpiecznie. Najlepsza jest agresja na twardym podłożu.
Przeczytaj warunki. Trasa wokół ostrych zakrętów. Powiedz „nie” klientom, którzy proszą Cię o zjedzenie ich ryzyka. Konto, które zachowasz, to konto, które pozwala Ci kontynuować działalność.
No figure. This chapter is a stance about a category of risk; the diagram it deserves is Fig 28.1's gate, read a different way — the ToS is a gate someone else placed, and the punishment for ignoring it is not a pause but a shutdown.
Chapter 33
Subskrypcja vs API
Na stronach cenowych większości dostawców sztucznej inteligencji znajdują się obok siebie dwa sposoby płacenia za zasadniczo te same możliwości, a wybór między nimi nie jest oczywisty, dopóki nie znajdziesz się po złej stronie. Subskrypcja to stała opłata miesięczna z miękkim ograniczeniem przepustowości. Interfejs API jest zależny od tokenu, bez górnej i dolnej granicy. Żadne z nich nie jest uniwersalnie tańsze, a najczęściej spotykanym błędem jest zakładanie, że któryś z nich jest tańszy.
Kształt abonamentu jest przewidywalny i nieco nieefektywny. Płacisz tyle samo za wolny miesiąc, co za pracowity, co oznacza, że niedostateczne wykorzystanie subsydiuje nadmierne wykorzystanie. Jeśli Twoja średnia miesięczna wyniesie znacznie poniżej limitu, zostawiasz pieniądze na stole, nie zużywając więcej – token marginalny jest faktycznie darmowy, dopóki nie osiągniesz limitu. Jeśli Twoja średnia uderzy w górną granicę, otrzymasz agresywną stawkę, ale musisz utrzymać prawdziwy pułap. Subskrypcja jest dobrą ofertą, jeśli korzystanie z niej jest stałe, przewidywalne i wystarczająco wysokie, aby uzyskać ryczałt.
Kształt API jest nieprzewidywalny i precyzyjnie proporcjonalny. Płacisz dokładnie za to, czego używasz, bez podłogi w ciche dni i bez sufitu w głośne dni. Jest to przydatne, gdy wykorzystanie jest różne — tydzień demonstracyjny, kampania u klienta, duża partia nocna — ponieważ nie płacisz za pojemność, której nie wykorzystujesz. To brzydkie, gdy uciekająca pętla lub źle ukształtowany agent przepala tokeny bez nadzoru; licznik nie kończy się na przyjacielskiej wartości. Interfejs API jest dobrym rozwiązaniem, gdy użycie jest gwałtowne lub gdy masz przepływy pracy, które szczególnie korzystają z bezobsługowej operacji o dużej równoległości, której subskrypcja nie obejmuje.
Punkt przecięcia następuje wtedy, gdy przestaje to być filozofią, a zaczyna być arytmetyką. Istnieje pewien poziom wykorzystania, przy którym zryczałtowany koszt subskrypcji jest równy kosztowi użycia interfejsu API; poniżej API jest tańsze, powyżej abonament. Ta liczba to punkt, w którym podejmujesz decyzję, a wiedza o tym, gdzie ona się znajduje w kontekście Twojego rzeczywistego obciążenia pracą, decyduje o różnicy między mądrym a modnym wyborem. Modeluj swoje wykorzystanie — nie zgaduj. Weź prawdziwy miesiąc, policz prawdziwe żetony, oblicz w obie strony. Odpowiedź jest często zaskakująca i często zmienia się w miarę skalowania.
Błąd, który popełniłem na początku, polegał na założeniu, że subskrypcja przeznaczona jest do „poważnej” pracy, a interfejs API do eksperymentów, czyli odwrotnie. Subskrypcja nagradza przewidywalne, stałe obciążenie — dojrzałe przepływy pracy ze znaną przepustowością. API nagradza elastyczny, kolczasty ładunek — nową pracę, której kształtu wciąż się uczysz. Jeśli już, prawidłowym postępem będzie najpierw API, dopóki nie poznasz wzorca, a następnie subskrypcja, gdy wzorzec będzie stabilny. Zaangażowanie się w subskrypcję, zanim dowiesz się, jaki jest Twój kształt użytkowania, wiąże się z osiągnięciem minimalnego poziomu kosztów, na który nie zarobiłeś.
Warto wspomnieć o podejściu hybrydowym, zgodnie z którym wielu praktyków celowo stosuje jedno i drugie. Subskrypcja interaktywnej strony „człowiek w pętli”, w której wykorzystanie jest mierzone na podstawie uwagi człowieka i w naturalny sposób pozostaje ograniczone. Interfejs API dla floty bezgłowej, w przypadku którego pula oddzielona od rozdziału 25 i tak wymaga innego licznika. Korzystanie z obu nie jest kompromisem; dopasowuje kształt płatności do kształtu użytkowania na każdej warstwie. Inna praca, inny licznik.
Modeluj użycie. Skrzyżuj liczby z cenami. Wybierz odpowiedni kształt i nie wahaj się uruchomić obu, gdy sama praca ma dwa kształty.
Fig 33.1 — The Crossover. Subscription is a flat cost line; API is a per-use line rising from zero. The focal circle is the crossover — the volume where they meet, and where your honest usage pattern decides which side of the intersection you actually live on.
Chapter 34
Wycena PoC
Pierwsza płatna współpraca z nowym klientem jest potwierdzeniem koncepcji, a jej cena jest najważniejszą liczbą w całej relacji, ponieważ wyznacza wszystko, co potem nastąpi. Niedostatecznie obciążysz i powiesz im, że prawdziwa praca powinna być podobnie tania. Przepłacają i nie kupują. Właściwa liczba to taka, która uwzględnia powagę obu stron, nie wyceniając przy tym rozsądnego klienta.
Moja robocza heurystyka jest taka, że cena PoC powinna być na tyle wysoka, aby odpowiedź „tak” zobowiązała klienta do faktycznego zaangażowania się w wyniki, i na tyle niska, aby odpowiedź „nie” nie wymagała wyjaśnień od sali konferencyjnej. W moim przypadku mieści się to w zakresie, w którym czek nie jest błędem zaokrąglenia, ale nie jest też decyzją o alokacji kapitału. Jeśli powiedzą tak, kupili skórkę w grze; jeśli odmówią, powiedzą mi, że nie są gotowi, i to jest informacja, której potrzebuję w tygodniu zerowym, a nie w trzecim miesiącu.
Tryb awarii na najniższym poziomie jest subtelny. Kiedy cena PoC jest wystarczająco niska, aby czuć się swobodnie, klient nie traktuje tego poważnie. Nie zbierają danych wejściowych. Nie biorą udziału w recenzjach. Przychodzą wyniki, przeglądają je, umieszczają w kategorii „interesujące” i nigdy nie zabierają się za prawdziwy projekt. Niska cena nie kupiła wstępu do prawdziwej rozmowy; dzięki temu klient może tanio powiedzieć, że odkrył sztuczną inteligencję. To nie jest to, co sprzedaję, a odpowiednia cena jest sposobem, w jaki przestaję to sprzedawać.
Tryb awarii na najwyższym poziomie jest bardziej oczywisty i mniej niebezpieczny. Cytujesz wysoko, oni odmawiają, idziesz dalej. Jedynym kosztem jest zainwestowany cykl sprzedaży, który jest realny, ale możliwy do odzyskania. Zbyt agresywne zawyżanie filtrów dla klientów; filtry zaniżające ceny dla niewłaściwego rodzaju klienta. Biorąc pod uwagę asymetryczne koszty, błąd jest wysoki.
Wraz z ceną pojawia się pytanie o zakres, a błędne postawienie sprawy polega na tym, w jaki sposób PoC przekraczają budżet po stronie sprzedawcy. Zakres PoC powinien być wystarczająco wąski, aby można go było ukończyć w naprawdę krótkim czasie — dni, a nie miesięcy — a produktem powinien być konkretny, konkretny artefakt, a nie ogólna zdolność. „Pokaż mi prototyp asystenta” to zakres, który poszerza się w nieskończoność. „Narysuj pięć przykładowych wyników dla tych pięciu podpowiedzi w tym formacie” to zakres, który się kończy. Rozwiązanie umowy sprawia, że cena jest możliwa do obrony; wszystko bez twardych dryfów granicznych.
Jeszcze jedna dyscyplina: naliczaj opłatę za PoC jako oddzielną pozycję, a nie jako kredyt na poczet przyszłego zaangażowania. Kiedy cena PoC zostanie uwzględniona w przyszłej umowie („odliczymy to od rzeczywistego projektu”), cena przestaje być liczbą rzeczywistą i staje się gestem marketingowym, a klient przestaje ją traktować jako jedną. PoC to samodzielny produkt z własną ceną i własnym kryterium sukcesu; traktowanie tego jako rabatu na coś większego obniża jedno i drugie. Jeżeli klient nie dokona konwersji, Ty zatrzymujesz opłatę; jeśli tak, obciążasz prawdziwy projekt jego wartościami merytorycznymi.
Wyceniaj PoC jako filtr, a nie zniżkę. Zawęź zakres do czegoś, co się kończy. Wystawiaj to jako osobną rzecz. Właściwy numer to ten, który wykryje poważnych klientów, a jednocześnie wykluczy tych, którzy nie traktowali poważnie.
No figure. Price setting is a judgement call about a market you're standing inside — a diagram of it would either be a fake curve or a truism. The relevant structure is the trust ladder, which gets its proper visual in Chapter 57.
Chapter 35
Kiedy wydajność nocna faktycznie się opłaca
Argument dotyczący nocnej zmiany z Części I jest piękny w teorii. W tym rozdziale przedstawiono arytmetykę, która decyduje, kiedy jest to rzeczywiście prawdą. Ponieważ automatyzacja ma stały koszt konfiguracji – napisanie briefu, śledzenie śledzenia, przygotowanie potoku – a pokrycie tego kosztu opłaca się tylko wtedy, gdy przepływ pracy powtarza się wystarczająco dużo razy, aby go zamortyzować. Poniżej tego progu automatyzacja jest stratą ubraną w postęp.
Kształt jest kalkulacją progu rentowności. Koszt ręcznego wykonania zadania to stawka godzinowa pomnożona przez liczbę godzin na instancję i liczbę instancji. Koszt automatyzacji to duża, jednorazowa konfiguracja plus niewielki koszt krańcowy na uruchomienie. Porównaj obie wartości z liczbą wykonań zadania: instrukcja to linia liniowa rosnąca od zera; zautomatyzowany to płaski koszt konfiguracji plus płytka linia. Gdzieś się krzyżują i to skrzyżowanie jest punktem decyzji. Poniżej zrób to ręcznie; nad nim zautomatyzować.
Przejście jest zwykle wyższe, niż myślą praktycy. Koszty konfiguracji naprawdę niezawodnego potoku nocnego nie są trywialne — wystarczy napisać krótki opis raz, udoskonalić go pod kątem zastosowań brzegowych, dodać ponowne próby, okablować ścieżkę, przetestować tryby awarii. Te godziny sumują się, a krańcowy koszt uruchomienia nie wynosi zero. Ogólna zasada jest taka, że przepływ pracy musi zostać powtórzony co najmniej pięć do dziesięciu razy, zanim automatyzacja przebije wykonanie ręczne, a dokładna liczba zależy od tego, jak drogie jest każde ręczne uruchomienie i jak krucha okazuje się wersja zautomatyzowana.
Pułapką w drugą stronę jest heroiczne ręczne powtarzanie. Kiedy zadanie powtarza się co tydzień przez rok – ponad pięćdziesiąt przypadków – arytmetyka zdecydowanie faworyzuje automatyzację, a mimo to praktycy nadal wykonują to ręcznie, ponieważ za każdym razem „to tylko kilka godzin”. Te kilka godzin tygodniowo składa się na krótką karierę polegającą na robieniu w kółko tego samego, a koszt jest realny, mimo że żaden pojedynczy przypadek nie wydaje się drogi. Jeśli zauważysz, że wykonujesz tę samą pracę więcej niż sześć razy, zatrzymaj się i odpowiednio wycenij automatyzację. Instynkt, by działać ręcznie, to zazwyczaj niechęć do straty udająca pragmatyzm.
Istnieje drugi koszt automatyzacji, który łatwo przeoczyć, a mianowicie bieżąca konserwacja. Zautomatyzowane potoki psują się, gdy przesuwają się ich dane wejściowe, gdy modele stają się przestarzałe lub gdy adaptery przesuwają się pod spodem. Zatem całkowity koszt cyklu życia to nie tylko konfiguracja i przebieg; jest to konfiguracja plus przebieg i opór konserwacyjny proporcjonalny do liczby konserwowanych rurociągów. W pewnym momencie dodanie rurociągów powoduje, że rachunki za konserwację przewyższają oszczędności. Zautomatyzuj to, co się opłaca, wycofuj to, co nie, i nie pozwól, aby stos urósł ponad to, co możesz obsłużyć.
Kształt przepływu pracy, który w oczywisty sposób warto zautomatyzować, to ten, który powtarza się zgodnie z harmonogramem, ma jasny opis i za każdym razem generuje konkretny artefakt. Cotygodniowe raporty. Codzienne pokolenie. Miesięczne uzgodnienia. Oto najlepsze punkty: powtarzający się na tyle, że konfiguracja się opłaca, na tyle zorganizowany, że brief pozostaje kompletny i na tyle zauważalny, że ślad mówi, że zadziałał. Jednorazowe działania, prace badawcze i wszystko, co wymaga osądu na żywo, nie ma odpowiedniego kształtu — należą do stosu pomponów z rozdziału 2, a nie do nocnej kolejki.
Kosztuj szczerze obie strony. Automatyzacja nad przejazdem. Przytnij to, co się nie opłaca. Wydajność w nocy to dźwignia, a nie reguła — pociągnij ją tam, gdzie tak mówi matematyka i zostaw ją tam, gdzie matematyka mówi, że ręczny pompon jest tańszy.
Fig 35.1 — The Break-Even. Manual cost rises linearly from zero; automation carries a large focal setup cost with a shallow slope. Below the crossing, hands beat automation; above it, the overnight shift earns its place.
Chapter 36
Ekonomia jednostkowa tokenów
Naiwnym sposobem obliczania kosztów runa jest pomnożenie tokenów przez stawkę i nazwanie produktu kosztem. Ta liczba jest zawsze błędna i zawsze błędna w tym samym kierunku – za niska. Realistyczny koszt uruchomienia jest mniej więcej półtora do dwóch razy większy od naiwnego, a różnica wynika z zestawu ukrytych kosztów, które nie pojawiają się w żadnym pojedynczym wywołaniu interfejsu API, ale konsekwentnie pojawiają się na fakturze.
Pierwszym ukrytym kosztem są ponowne próby. Nawet dobrze dostrojony potok ponawia pewien procent swoich wywołań — przejściowe awarie, przekroczenia limitu czasu, cofnięcia limitów szybkości. Każda ponowna próba przynosi realne korzyści, a jeśli współczynnik ponownych prób wynosi pięć procent, efektywny koszt udanego uruchomienia wynosi jeden pięć procent tego, co wynika z naiwnych obliczeń. Dziesięć procent ponownych prób, jedno dziesięć procent. Sumuje się to szybciej, niż mogłoby się wydawać, a odsetek ponownych prób jest często wyższy, niż mogłoby się wydawać, ponieważ nie jest mierzony, chyba że mierzysz go celowo.
Drugim ukrytym kosztem jest kontekst. Every agent run loads a context — a prompt, examples, system instructions, prior conversation. Te żetony się liczą. Krótkie pytanie użytkownika, które kosztuje sto tokenów danych wyjściowych, może najpierw załadować tysiące tokenów kontekstu, a wejściową stronę tego współczynnika łatwo zapomnieć, gdy patrzysz, ile kosztuje uruchomienie. Długie konteksty są szczególnie kosztowne, ponieważ większość dostawców pobiera opłaty zarówno za dane wejściowe, jak i wyjściowe; ciężki monit systemowy to podatek za uruchomienie, który płacisz za każdym razem.
Trzecim ukrytym kosztem są nieudane klasyfikacje i ponowne monity w ramach pętli agenta. Kiedy agent próbuje wywołać narzędzie, które kończy się niepowodzeniem, próbuje ponownie z innym argumentem lub cofa się, aby przemyśleć jeszcze raz, każdy z tych wewnętrznych kroków to tokeny wydane na niegenerujące bezpośrednio użytecznych wyników. Dziesięcioetapowy agent, który odniesie sukces, kosztuje mniej niż dziesięcioetapowy agent, który odniesie sukces po dwukrotnym cofnięciu się, mimo że oba wytworzą ten sam końcowy artefakt. Objazdy wewnętrzne są niewidoczne dla naiwnego hrabiego i doskonale widoczne na rachunku.
Czwarty to koszty ogólne. Początkowo w ogóle nie liczyłem ich jako kosztów: monity na rozgrzewkę, kontrole stanu, przebiegi ewaluacyjne, niewielki ruch związany z porządkowaniem, jaki generuje dobrze oprzyrządowany system. Indywidualnie trywialne, zbiorowo znaczące i konsekwentnie nieobecne w naiwnych kalkulacjach, ponieważ dzieją się poza głównym przepływem. Jeśli potoki monitorowania są w dobrym stanie, używają tokenów; jeśli nie policzysz tych żetonów, ekonomia twoich jednostek będzie wyłączona.
Właściwą reakcją na to wszystko jest zaprzestanie pomiaru na poziomie tokena i dokonanie pomiaru na poziomie uruchomienia. Pojedynczą jednostką rachunku kosztów jest ukończony przebieg, a jego prawdziwy koszt to wszystko, co pochłonął przebieg — główne wywołanie, ponowne próby, kontekst, wycofanie się, przyległe czynności porządkowe — podzielone przez liczbę udanych przebiegów. Liczba ta jest większa niż naiwny koszt tokena i jest to jedyna liczba, która jest na tyle uczciwa, że można na niej opierać decyzje cenowe. Oprzyj cenę na naiwnej liczbie, a różnicę odkryjesz w dniu, w którym liczba ponownych prób gwałtownie wzrośnie, a Twoja marża wyparuje.
Pomiar na bieg. Uwzględnij niepowodzenia, ponowne próby, kontekst i porządek. Numer naiwny jest numerem marketingowym; uczciwy to ten, który prowadzi biznes.
Fig 36.1 — What "Per Run" Actually Costs. The naive bar shows the main call only; the focal realistic stack adds retries, context, interior detours, and housekeeping traffic — the invisible bands that turn a promising unit economic into a losing one at scale.
Chapter 37
Pułapka rabatowa
Tańsze modele to pokusa, która wbija się w arkusz kalkulacyjny. Przyjrzyj się stawce za token, spójrz na stawkę najlepszego modelu, zwróć uwagę, że jeden jest ułamkiem drugiego i dojdź do wniosku, że powinieneś skierować więcej pracy do tańszego, aby zaoszczędzić pieniądze. To naturalny instynkt, który najczęściej jest błędny — ponieważ oś, na której dokonujesz optymalizacji, jest niewłaściwą osią.
Prawidłowa oś nie jest kosztem za token. To koszt w przeliczeniu na wynik. Tani model, który wymaga trzech prób, aby wykonać zadanie, kosztuje trzykrotność stawki za token dla tego zadania, a jeśli droższy model powiódłby się za pierwszym razem, „tani” wybór był w rzeczywistości droższy. Każdy dodatkowy obrót, jaki wykonuje tani model, aby uzyskać właściwą odpowiedź, osłabia pozorną okazję i często odpryski trwają dalej aż do punktu przecięcia, w którym drogi model był przez cały czas szczerze tańszą opcją.
Sposób, w jaki objawia się to w pętlach agentycznych, jest szczególnie karalny. Tani model znajdujący się w środku pętli użycia narzędzia agenta, który błędnie analizuje odpowiedź, wywołuje narzędzie z nieprawidłowym argumentem lub generuje zniekształcone dane wyjściowe, powoduje nie tylko jego własną ponowną próbę, ale potencjalnie serię takich prób, przechodzących kaskadowo przez pętlę do czasu, aż agent odzyska siły lub pętla się zakończy. Każde wewnętrzne potknięcie kosztuje więcej żetonów niż bezpośrednie połączenie, a ekonomia pętli staje się gorsza, im więcej jest potknięć. Model tani w przeliczeniu na token, który ciągle się potyka, nie jest okazją sugerowaną w arkuszu kalkulacyjnym.
Istnieje drugi tryb awarii, który dotyczy głośności, a nie obrotów. Tanie modele kuszą praktyków do większego wykorzystania – wykonywania większej liczby połączeń, ponieważ każdy z nich wydaje się niedrogi. Tak zwiększony wolumen może zwiększyć całkowite wydatki powyżej kosztów bardziej zdyscyplinowanego i rzadszego korzystania z drogiego modelu. Rabat zmienił zachowanie, a zmiana zachowania pochłonęła oszczędności. Zakotwiczenie się w koszcie jednostkowym za każdym razem to zaciemnia.
Właściwym sposobem rozumowania jest zmierzenie kosztu pomyślnego wyniku, a nie kosztu tokena lub połączenia. Jaki jest koszt wyprodukowania tego artefaktu od początku do końca, łącznie ze wszystkimi próbami i objazdami, na tym modelu? Oblicz tę liczbę dla każdego modelu kandydującego w tym samym zadaniu, a model tani w przeliczeniu na token często przegrywa. Jeśli nie przegrywa — gdy jest to naprawdę właściwy wybór — możesz bez obaw skierować do niego pracę, ponieważ Twój ranking opiera się na faktycznie wydanych pieniądzach na rzeczywisty produkt.
Łączy się bezpośrednio z routerem z rozdziału 15, czyli tam, gdzie pomiar kosztu wyniku jest skuteczny, jeśli działa prawidłowo. Router nie sortuje według ceny tokena; to sortowanie według zmierzonej wydajności w określonej klasie zadań, aktualizowane w miarę zmiany modeli. Trasa oparta na uczciwej metryce i taniość, która przetrwa, jest prawdziwa; trasę w arkuszu kalkulacyjnym, a spędzisz kwartał na pogoni za okazją, która nigdy nie była.
Kupuj wynik, a nie token. Pomiar od końca do końca dla udanego artefaktu. Tani za token, który się potyka, jest drogi; kosztowny za token, który ląduje przy pierwszej próbie, może być uczciwą okazją. Trasuj odpowiednio.
No figure. The correct diagram already exists as Fig 15.1 — the router — with the note that it sorts by cost-per-outcome, not cost-per-token. Repeating it here would only re-say the caption in different words.
Chapter 38
Cena stała vs T&M
Dwa sposoby rozliczania zaangażowania klienta leżą po obu stronach bardzo realnej alokacji ryzyka, a wybór między nimi mówi klientowi — i Tobie — kto zje niespodzianki. Ustalona cena mówi, że je jesz; cena pozostaje taka sama, niezależnie od tego, co faktycznie dzieje się wewnątrz dzieła. Czas i materiały mówią, że klient je zjada; rozliczasz się za to, co wydasz, a jeśli praca zajmie dwa razy dłużej, płacą dwa razy więcej. W pracy ze sztuczną inteligencją te wybory mają większą wagę niż w tradycyjnym doradztwie, ponieważ licznik działa na korzyść obu stron w sposób, w jaki nie ma to miejsca w przypadku stałego zespołu ludzi.
Stała cena jest właściwym kształtem, gdy zakres jest naprawdę jasny i znany. Robiłeś już tę pracę wcześniej, wiesz, ile godzin i ile tokenów to zajmie, i możesz z pewnością podać cenę, która odzwierciedla rzeczywisty koszt plus marżę. Klient zyskuje przewidywalność. Otrzymujesz nagrodę w postaci wydajności — jeśli możesz dostarczyć produkty w czasie o połowę krótszym, zachowasz różnicę. Obie strony czerpią korzyści z przejrzystości, czyli tego, co faktycznie sprzedaje stała cena.
T&M ma właściwy kształt, gdy zakres nie jest wyraźny. Nowy klient, nowatorska praca, specyfikacja, której nie można cytować z poważną miną, bo można się domyślić. W tych warunkach T&M chroni obie strony: nie zaniżasz wyceny i nie bankrutujesz, próbując dostarczyć towar, a klient nie przepłaca za wyimaginowane ryzyko, które musiałeś wycenić. Handel polega na tym, że traci on przewidywalność, a ty bierzesz na siebie ciężar dokładnego śledzenia i raportowania swoich wydatków, ponieważ jego zaufanie opiera się na uczciwości Twojej księgi rachunkowej.
Komplikacja związana ze sztuczną inteligencją polega na tym, że nawet w przypadku zaangażowania o nominalnie ustalonej cenie koszty modelu przesuwają się po obu stronach. Umowa o stałej cenie podana w pierwszym kwartale może skutkować podniesieniem stawek przez bazowego dostawcę w trzecim kwartale i teraz cena, na którą się zgodziłeś, nie pokrywa już realnego dostarczenia dzieła. Klasyczna umowa o stałej cenie zakładała, że Twoje nakłady – głównie Twoje godziny pracy – są stabilne. W AI nie są; znaczna część kosztów dostawy to stawka zmienna, nad którą nie masz kontroli. Zatem stała cena w przypadku sztucznej inteligencji musi wiązać się z większą marżą niż stała cena w przypadku tradycyjnego doradztwa lub zawierać klauzulę umożliwiającą przepływ zmian cen modelu do klienta.
Najczęściej obserwowany przeze mnie tryb awarii to stała cena i niejasny zakres. Z pewnością cytujesz specyfikację, która brzmi solidnie, rozpoczynają się prace i po tygodniu staje się oczywiste, że rzeczywista praca jest trzykrotnie większa niż opisana specyfikacja. Teraz jesteś skazany na cenę, która gwarantuje stratę, a każda godzina spędzona na jej wydobywaniu to godzina, której nie możesz przeznaczyć na płacenie za pracę. W tym momencie instynktownie podpowiadamy, żeby to zjeść i mieć nadzieję, a właściwym posunięciem jest renegocjacja – szczerze mówiąc, gdy zakres zamówienia się rozszerza – ponieważ spalanie dobrej woli poprzez spóźnianie się i tanie dostawy jest gorsze niż niezręczna rozmowa o cenie w trakcie projektu.
Moją zasadą jest domyślne ustawienie T&M w przypadku nowych relacji i nowych form pracy oraz przejście na stałą cenę, gdy wykonamy razem kilka cykli i obie strony będą wiedziały, jak wygląda dobry wynik. Drabina zaufania z rozdziału 57 pokrywa się ze strukturą cenową: T&M za pracę pierwszego kontaktu, mieszaną dla znanych klientów w nowych kształtach, stała cena tylko wtedy, gdy każdy może wycenić pracę z powagą. Dopasuj model cenowy do modelu zaufania, a niezręczne renegocjacje w trakcie projektu w większości znikają.
Ustalaj cenę tylko taką, jaką możesz naprawdę wycenić. Rachunek za czas, gdy kształt jest naprawdę nieznany. Wbuduj miejsce na zmienne koszty modelu. I wspinaj się po drabinie świadomie, a nie z zapałem.
Fig 38.1 — Who Eats the Surprise? Fixed-price puts every kind of variance on you; the focal T&M column moves it to the client. In AI work, model-rate risk is the newest column — and the one that most quietly breaks fixed-price contracts that didn't build room for it.
Chapter 39
Licznik Klienta
Jest licznik, o którym zapomniałem podczas mojej pierwszej rozmowy z klientem i nie był mój. To była faktura klienta — faktura od jego własnego dostawcy, znajdująca się pod naszą pracą i sumująca się w miarę, jak obsługiwaliśmy jego najemcę. Moja praca techniczna była czysta; mój własny rachunek był rozsądny; a potem po miesiącu klient wysłał mi zrzut ekranu rachunku, który naprawdę ich zaskoczył, i musiałem spędzić następną godzinę na wyjaśnianiu, dlaczego wydajny system kosztował ich tak dużo, ich zdaniem.
Lekcja jest taka, że w przypadku działań związanych ze sztuczną inteligencją klient często ma swój własny licznik – konto dostawcy, rachunek za hosting, licencję na stanowisko, opłatę za przesyłanie danych – który działa równolegle z tym, co mu naliczasz. Twój rachunek to tylko połowa obrazu. Zbudowany przez Ciebie system może być cudem wydajności, a mimo to zapewniać klientowi miesięczną sumę, która go zaskoczy, ponieważ jego licznik zarejestrował objętość, którą w niego włożyłeś. Jeśli nie śledzisz ich licznika tak samo jak swojego, udaje ci się uzyskać częściowy widok.
Niepowodzenie, jakie to powoduje, nie ma charakteru technicznego — jest to utrata zaufania. Klient nie zarejestrował się w systemie, który generował niespodziewane rachunki. Zarejestrowali się w systemie, który działał, a część „działała” polegała na tym, że „nie kosztował więcej, niż się spodziewaliśmy”. Nawet jeśli nigdy nie spojrzysz na ich licznik, oni to zrobią i ocenią Twój profesjonalizm na podstawie tego, czy liczba odpowiadała ich oczekiwaniom. Zarządzanie rachunkiem, którego nie widzisz, jest niemożliwe; ignorowanie tego sprawia, że klient czuje się niekomfortowo; właściwą reakcją jest przyjrzenie się temu, przewidzenie i określenie oczekiwań z góry.
Mechanizm, na który się zdecydowałem, polega na włączeniu na początku współpracy pulpitu nawigacyjnego kosztów wspólnych, który pokazuje oba liczniki — mój (mój rachunek dla nich) i ich (rachunek ich dostawcy za zbudowany przeze mnie system). Deska rozdzielcza to mały, nudny artefakt, ale usuwa niespodziankę. Kiedy liczba się porusza, widzimy to razem. Kiedy planujemy cięższy miesiąc – kampanię, uruchomienie partii, test skali – prognozujemy reakcję licznika, zanim podejmiemy decyzję. Żadna ze stron nigdy nie dowiaduje się o tym w momencie wystawienia faktury; oboje wiedzą wcześniej i rozmowa dotyczy planowania, a nie kontroli szkód.
Wynika z tego konsekwencja projektowa, a mianowicie, że systemy, które budujesz dla klientów, powinny być dla nich czytelne pod względem ekonomicznym. Interesariuszowi nietechnicznemu powinno być łatwo przyjrzeć się działaniom w zeszłym miesiącu i z grubsza zrozumieć, dlaczego liczba ta była taka, jaka była. Które przepływy pracy podniosły koszty? Którzy najemcy wykorzystali ile? Które kategorie są trendy? System generujący rachunki-niespodzianki to system, którego ekonomia nie jest wystarczająco czytelna, a rozwiązaniem jest zapewnienie jej takiego stanu — zwykle przy użyciu wymiarów atrybucji kosztów, o których mowa w rozdziale 31, na poziomie księgi głównej.
Warto od razu wymienić szerszą zasadę: Twoja praca jako inżyniera podczas współpracy z klientem nie polega tylko na poprawieniu oprogramowania, ale na zapewnieniu przewidywalności całkowitego kosztu obsługi oprogramowania. Prawidłowy system generujący rachunki-niespodzianki częściowo nie spełnił swojego zadania, a częścią dojrzałości zawodowej w tej dziedzinie jest traktowanie licznika klienta w ramach swojej odpowiedzialności, a nie tylko jego. Nikt nie chce rachunku, którego się nie spodziewał, a prognozowanie jest tanie; zrób to.
Obserwuj licznik klienta. Przewiduj ruchy. Spraw, aby ekonomia była czytelna. Związek przetrwał niespodzianki; nie przetrwa niespodziewanych faktur.
No figure. The client's meter is a habit of attention rather than a structure; the ledger it feeds is already drawn in Fig 31.1, and the shared dashboard it implies is just that same ledger with the client's view added as a filter.
Chapter 40
Uzgodnienie na koniec miesiąca
Część IV kończy się rytuałem – ostatni dzień każdego miesiąca lub pierwszy dzień następnego, spędzany na porównywaniu tego, co widnieje w mojej księdze, z tym, co widnieje na fakturach moich dostawców. Pojednanie brzmi jak księgowa harówka i mechanicznie nią jest; ze strategicznego punktu widzenia jest to najbardziej niezawodny sposób, w jaki mogę dowiedzieć się, co zmieniło się pode mną w ciągu ostatnich trzydziestu dni.
Mechanika jest prosta. Pobierz zagregowany koszt księgi za miesiąc, na dostawcę, na pulę. Wyciągnij fakturę za ten sam okres, od tego samego dostawcy. Porównywać. W idealnym miesiącu pasują, a ja zamykam pojednanie w ciągu dwudziestu minut i idę dalej. W prawdziwym miesiącu nie są one zgodne, a rozbieżność polega na tym, gdzie znajdują się przydatne informacje. Rozbieżność oznacza, że moja księga jest błędna (błąd w rejestratorze, gdzieś nieoznaczony przebieg) lub że rozliczenia dostawcy uległy zmianie (nowa stawka, nowa pula, nowa opłata), a w obu przypadkach liczy się fakt, że złapałem to podczas uzgodnienia, a nie miesiące później.
Dyscyplina polega na tym, że dzieje się to bez przerwy co miesiąc. Nie „kiedy sobie przypomnę” czy „kiedy będę miał czas” – co miesiąc, w ustalony dzień, jako kwestia nie podlegająca negocjacjom. Powodem jest to, że rozbieżności się kumulują. Jeśli w marcu przemknęła niewielka zmiana stóp procentowych, a ja pogodziłem się dopiero w czerwcu, przez trzy miesiące błędnie wyceniałem stawki, a każda decyzja na dalszym etapie łańcucha dostaw – wyceny klientów, obliczenia dotyczące utrzymania, czy rozszerzać flotę – była podejmowana w oparciu o błędne liczby. Miesięczna kadencja oznacza, że największa rozbieżność, jaką kiedykolwiek będziesz musiał usunąć, ma głębokość trzydziestu dni, co jest złe, ale możliwe do naprawienia. Głębokie sześć miesięcy to pełny kryzys finansowo-higieniczny.
Nauka płynąca z rytuału sprawia, że warto poświęcić na niego czas. Każde uzgodnienie uczy mnie czegoś o obecnej rzeczywistości rozliczeniowej — pojawiła się nowa opłata, stawka, która została po cichu dostosowana, pula z innym licznikiem — a te obserwacje trafiają bezpośrednio do mapy stawek z rozdziału 19 i tabeli routingu z rozdziału 15. Ekonomia stale się zmienia; Właściwie to zauważam pojednanie, zamiast zakładać, że dzisiejsze liczby nadal się utrzymują. Praktycy, którzy się nie godzą, nie mylą się co do aktualnej ceny; po prostu bazują na zeszłorocznym modelu mentalnym.
Z czasem pojawia się bonus, którym jest intuicja. Po wystarczającej liczbie uzgodnień zbudowałem przybliżony model sposobu wystawiania rachunków przez każdego dostawcę, kiedy ma on tendencję do zmiany stawek oraz które pozycje na fakturze są stabilne, a które zmienne. Ta intuicja jest na wagę złota — oznacza, że mogę z większą pewnością wyceniać klientów, dokładniej prognozować ich liczniki i szybciej wykrywać anomalie, ponieważ wiem, jak wygląda normalność. Nic z tego nie jest dostępne dla kogoś, kto nigdy nie usiadł i nie porównał swojej księgi rachunkowej z fakturami.
Ostatnią rzeczą, którą warto powiedzieć o rytuale, jest to, że powinien on zakończyć się pisemną notatką. Nie arkusz kalkulacyjny pełen liczb; zdanie lub dwa opisujące, co zmieniło się w tym miesiącu, co obejrzeć w przyszłym miesiącu i czy cokolwiek wymaga działania poza potwierdzeniem. Pojednania, które nie pozostawiają śladów, to ten sam tryb niepowodzenia, co biegi bez nadzoru, które nie pozostawiają śladów — pamięć o tym, co zauważyłeś, szybko zanika, a w następnym miesiącu odkryjesz na nowo to samo, co już wiedziałeś. Notatka sprawia, że intuicja jest złożona, a nie resetowana.
Uzgodnij co miesiąc. Zbadaj każdą niezgodność. Podaj mapę stawek. Napisz notatkę. W ten sposób zapobiegasz zaskoczeniu ekonomii i sprawiasz, że niespodzianka, gdy w końcu nadejdzie, będzie mała i czytelna, a nie katastrofalna i ukryta.
Fig 40.1 — The Monthly Ritual. Ledger and invoice enter; the focal delta is where the useful information lives — the changes that update the rate map and the notes that let the intuition compound rather than reset.
Part V
Pakiet umiejętności
Filary MECE w praktyce, potoki od początku, interfejs adaptera, wymienne źródła danych, GitHub jako źródło prawdy i dyscyplina, która zamienia szufladę skryptów w komponowalny system operacyjny.
Chapter 41
MECE w praktyce
W Rozdziale 4 opowiadano się za MECE – wzajemnie wykluczającymi się, zbiorowo wyczerpującymi – jako dyscypliną, która zamienia stos umiejętności w system operacyjny. W tym rozdziale tak to wygląda, gdy faktycznie zastosuję go w zestawie na żywo, ponieważ abstrakcyjna zasada jest łatwa, a codzienna praktyka kończy się większością prób. MECE nie jest audytem jednorazowym; to ciągła praca w ogrodzie.
Najbardziej przydatnym ruchem, który wykonuję co kilka miesięcy, jest ułożenie wszystkich posiadanych umiejętności na siatce – filary z boku, umiejętności na górze – i zaznaczenie, do którego filaru należy dana umiejętność. To, czego szukam, to wzór wierszy i kolumn: każda umiejętność powinna znajdować się dokładnie w jednym filarze (pojedynczy znak na kolumnę), a każdy filar powinien mieć pewne umiejętności (bez pustych wierszy). Kiedy dwie umiejętności wyznaczają ten sam filar, a jedną z nich można uzasadnić także w innym, mamy do czynienia z nakładaniem się; kiedy filar nie ma nic skierowanego w jego stronę, mam lukę.
Nakładanie się elementów jest łatwiejsze do naprawienia. Kiedy dwie umiejętności rzeczywiście nakładają się na siebie, jedna z nich pochłania drugą, a przegrany staje się przestarzały. Jedyne, czego nie możesz zrobić, to pozwolić, aby nakładało się na siebie — ponieważ w momencie, gdy dwie umiejętności rozwiązują ten sam problem, drzwi frontowe z rozdziału 3 nie mogą wyznaczać trasy w sposób deterministyczny i za każdym razem wracam do wyboru między nimi. Nakładanie się nie stanowi problemu czystości; jest to problem funkcjonalny warstwy routingu.
Luki są bardziej interesujące, ponieważ wyznaczają następną rzecz do zbudowania. Pusty filar oznacza, że co tydzień wykonuję ręcznie pracę, za którą nie wymagają umiejętności, a kiedy zobaczysz pustkę w siatce, nie możesz jej odzobaczyć. Ta luka automatycznie staje się szczytem kolejki budowania umiejętności — nie muszę decydować, nad czym pracować, mówi mi brakujący filar. Planowanie planu działania poprzez audyt MECE to jedna z najlepiej strzeżonych tajemnic tej dyscypliny: nie wymyślasz planu działania, czytasz go poza siecią.
Dyscypliną, która utrzymuje to w działaniu przez długi czas, jest chęć ponownego wzmocnienia, gdy świat się porusza. Pięć filarów, które wymieniłem w rozdziale 4, nie jest świętych; stanowią obecnie najlepszą dekompozycję pracy, którą aktualnie wykonuję. Kiedy zmienia się moja praca – nowy rodzaj zaangażowania, nowa klasa artefaktów, zmiana źródła wartości – być może konieczna będzie zmiana także filarów. Trzymanie się wczorajszych filarów, ponieważ są znajome, sprawia, że pakiet MECE po cichu staje się pakietem starszej wersji. Co kilka audytów pytaj, czy same filary nadal są aktualne, a nie tylko czy umiejętności do nich pasują.
Istnieje subtelna dyscyplina dotycząca nazewnictwa, która polega na tym, że nazwy umiejętności powinny opisywać ich funkcję w słownictwie filaru, a nie ich wewnętrzny mechanizm. Umiejętność nazwana na cześć tego, co robi w środku — „uruchamia podproces z flagami” — to umiejętność, której nie można zamienić na lepszą implementację, ponieważ nazwa wiąże się z jej tożsamością. Umiejętność nazwana na cześć jej zadania – „przyjęcie” lub „propozycja” – może zostać całkowicie przebudowana pod spodem i nadal będzie tą samą umiejętnością z zewnątrz. Nazwa dla roli, a nie dla maszyn, a pakiet pozostaje plastyczny.
Audyt sieci. Zabij nakładanie się. Buduj luki. Ponownie filar, gdy świat się porusza. Nazwij umiejętności według roli. To MECE nie jako slogan, ale jako miesięczny zwyczaj ogrodniczy.
Fig 41.1 — The MECE Grid. Skills across the top, pillars down the side, one focal dot per column marking where each skill lives. Empty rows name the next skill to build; overlapping columns are the tidy failure that breaks the front-door router.
Chapter 42
Rurociągi wlotowe
Każdy prawdziwy rurociąg, który zbudowałem, zaczyna się od etapu wlotowego i zajęło mi trochę czasu, zanim zrozumiałem, dlaczego ten wzorzec pojawiał się sam. Intake — krok, który przekształca surowe, nieustrukturyzowane dane wejściowe w dobrze ukształtowaną reprezentację wewnętrzną — to interfejs między bałaganem a uporządkowaną maszyną. Pomiń to lub zrób to źle, a każdy kolejny krok odziedziczy bałagan.
Naiwny kształt potoku polega na tym, że każdy krok działa bezpośrednio na podstawie tego, co wytworzył poprzedni krok, od pierwotnych danych wejściowych do końcowego artefaktu. Działa to w przypadku małych potoków z przewidywalnymi danymi wejściowymi. Rozpada się w momencie, gdy zmieniają się dane wejściowe — różni klienci dostarczają różne formaty plików, różne kształty danych, różne poziomy kompletności — ponieważ każdy kolejny krok musi teraz defensywnie obsługiwać każdą odmianę tego, co napływa. Bałagan się rozprzestrzenia.
Intake rozwiązuje ten problem, umieszczając odmianę dokładnie w jednym miejscu. Zadaniem etapu przyjmowania jest zaakceptowanie wszelkich dziwnych kształtów, jakie wysyła świat, znormalizowanie go do wewnętrznej reprezentacji i przekazanie tego czystego obiektu wszystkim dalej. Teraz reszta rurociągu widzi tylko czysty kształt, niezależnie od tego, co weszło. Cała brzydota prawdziwego świata żyje w wlocie, tam, gdzie powinno być, a wnętrze systemu pozostaje zdrowe.
Towarzyszy temu zasada projektowania, której zaufałem bardziej niż większość: umieść brzydkie elementy na krawędziach, zachowaj piękny środek. Prawdziwe systemy nie mogą wybierać danych wejściowych, ale mogą wybierać, gdzie je normalizują. Potok, którego wewnętrzny kod stara się obsłużyć każde dziwactwo każdego możliwego wejścia, jest potokiem, w którym będą pojawiać się brodawki w miarę pojawiania się nowych dziwactw. Rurociąg, którego wnętrze ma ustalony, czysty kształt, to rurociąg, który pozostaje elegancki w miarę mnożenia danych wejściowych — ponieważ każdy nowy sygnał wejściowy dodaje wariant wlotowy, a nie brodawkę na środku.
Subtelna dyscyplina polega na tym, że spożycie musi być rygorystyczne. Musi przyjrzeć się przychodzącym danym i ostatecznie zdecydować, czy nadają się do użytku, a następnie odrzucić to, co nie jest. Zbyt liberalny pobór pozwala zniekształconym danym przedostać się do wnętrza, w którym to momencie obietnica „odtąd czystego kształtu” zostaje zerwana i kod niższego szczebla musi się ponownie bronić. Odrzuć wcześnie, odrzuć głośno i stwórz wiadomość o odrzuceniu na tyle jasną, aby nadawca wiedział, co poprawić. Ścisłe spożycie jest gwarancją, od której zależy wszystko inne.
Spożycie staje się także naturalnym miejscem umieszczania pewnych cech jakości życia. Śledzenie pochodzenia – skąd pochodzą te dane, kiedy i od kogo – jest zadaniem spożycia, ponieważ to moment, w którym dane przepływają z zewnątrz do wewnątrz. Deduplikacja tam należy. Podobnie jest z konwersją postaci kanonicznej (daty w ISO, jednostki w SI, identyfikatory w tym samym kształcie). Zrób to wszystko podczas przyjmowania i nigdy więcej nie będziesz musiał tego robić; zrób to w dół rzeki, a zrobisz to częściowo w pięciu różnych miejscach.
Rozpocznij każdy rurociąg od etapu wlotowego. Niech będzie to jedyny krok, który dotyka brudnego świata. Normalizuj do ustalonego kształtu wewnętrznego, odrzucaj agresywnie i pozwól, aby wnętrze pozostało czyste. Wszystko inne w zestawie staje się łatwiejsze, gdy spożycie niesie ze sobą ciężar.
Fig 42.1 — Intake First. Messy inputs on the left funnel into the focal intake step; the normalised shape flowing right is the only thing downstream code ever sees. Variation is contained where it belongs — at the boundary — not smeared across the pipeline.
Chapter 43
Interfejs adaptera, ponowna wizyta
W rozdziale 16 przedstawiono adapter jako właz ratunkowy, dzięki któremu decyzje są odwracalne. Ten rozdział dotyczy zastosowania tego samego pomysłu o jeden poziom wyżej, na granicy między umiejętnością a usługami zewnętrznymi, od których jest ona zależna, ponieważ umiejętność, która na stałe koduje swoich dostawców, jest umiejętnością, która źle się starzeje, a umiejętności są na tyle długotrwałe, że poważne starzenie się jest prawdziwym problemem.
Każda umiejętność, którą przechowuję w pakiecie dłużej niż kilka miesięcy, kończy się komunikacją z co najmniej jedną usługą zewnętrzną — dostawcą modelu, interfejsem API, bazą danych lub zasobnikiem pamięci. Naiwnym sposobem budowania umiejętności jest bezpośrednie powiązanie tych usług: umiejętność zna konkretnego dostawcę, nazywa go po imieniu i ponosi konsekwencje, gdy dostawca się zmieni lub stanie się przestarzały. Wersja adaptera otacza każdą usługę zewnętrzną małym, uzgodnionym interfejsem, a podstawowa logika umiejętności komunikuje się tylko z interfejsem. Ten sam argument co w rozdziale 16, ale w innym zakresie.
Zapłata na poziomie umiejętności jest szczególnie wysoka, ponieważ umiejętności to elementy, które chcę ponownie wykorzystać w różnych zadaniach i bazach kodu. Umiejętności polegającej na zakodowaniu na stałe dostawcy specyficznego dla klienta — konkretnego CRM, określonego zasobnika na dane — nie można ponownie wykorzystać, ponieważ następny klient nie ma tego dostawcy. Umiejętność, która otacza dostawcę adapterem, może być ponownie wykorzystana wszędzie, ponieważ każde zaangażowanie umożliwia podłączenie własnej konkretnej implementacji za tym samym interfejsem. Możliwość ponownego użycia jest bezpośrednią korzyścią z oddzielenia.
Tryb niepowodzenia, który obserwowałem kilka razy, to umiejętności, które stopniowo rozwijają adaptery i ostatecznie są w połowie przystosowane. Pierwsza wersja wiąże się bezpośrednio z dostawcą. Później potrzebny jest drugi dostawca, dlatego dodawany jest warunek – „jeśli dostawca A, wykonaj X, w przeciwnym razie Y”. Teraz umiejętność ma ukryty adapter, ale jest rozprzestrzeniana w kodzie jako logika rozgałęziająca, a nie czysty interfejs. Dodanie trzeciego dostawcy jest bolesne, ponieważ każdy oddział w każdej lokalizacji wymaga aktualizacji. Stan częściowo przystosowany jest gorszy niż wersja w czystej postaci (która była przynajmniej uczciwa) lub prawdziwy adapter (który zawierałby tę odmianę).
Dyscypliną pozwalającą uniknąć na wpół przystosowanego bagna jest wcześniejsze narysowanie adaptera, nawet jeśli jest tylko jeden dostawca. Zdefiniowanie małego interfejsu i umieszczenie za nim pierwszego dostawcy nie kosztuje prawie nic, a w chwili pojawienia się drugiego dostawcy jesteś już gotowy. Alternatywa — poczekanie, aż drugi dostawca wymusi problem, a następnie doposażenie adaptera w bazę kodu, w której zwiększono logikę rozgałęzień — jest kosztowna i łatwa do przecenienia, dopóki nie zrobisz tego kilka razy.
Istnieje korzyść z testów, która szczególnie mocno uderza w warstwę umiejętności. Ponieważ każda usługa zewnętrzna znajduje się za interfejsem, umiejętność można przetestować na adapterze pośredniczącym, który zwraca gotowe odpowiedzi bez żadnych wywołań na żywo, przy zerowym koszcie tokena w milisekundach. Zestawy testów, które w przeciwnym razie byłyby powolne, niestabilne i drogie, stają się szybkie i tanie. A ponieważ kod pośredniczący jest pierwszorzędną implementacją interfejsu, ten sam zestaw testowy działa niezależnie od tego, czy dostawca jest prawdziwy, czy fałszywy — co oznacza, że sam test nie musi się zmieniać, gdy dostawca to zrobi.
Adaptery na poziomie umiejętności działają na tej samej zasadzie, co adaptery gdziekolwiek indziej — narysuj interfejs tam, gdzie świat jest niepewny, zawiń za nim konkretne implementacje, utrzymuj rdzeń w czystości. W skali umiejętności ponowne użycie i testowalność się opłacają, ponieważ umiejętności żyją wystarczająco długo, aby ich składanie stało się rzeczywiste.
No figure. The shape is drawn already in Fig 16.1 — consumer, interface, implementations, stub — and applies identically at the skill layer. Redrawing it would only re-title the same boxes.
Chapter 44
Wymienne źródła danych
Jeśli rozdział 43 dotyczył w zasadzie opakowania dostawców za adaptery, ten dotyczy konkretnego przypadku, który pojawia się najczęściej w praktyce: zamiany źródła danych pod umiejętnością bez zmiany czegokolwiek, co faktycznie robi ta umiejętność. Źródła danych to najbardziej niestabilna zależność zewnętrzna, jaką posiadam, a budowanie ich możliwości wymiany od początku stanowi różnicę między umiejętnością, którą mogę przełączać się między zadaniami, a umiejętnością, która utknie w starciu, w którym się urodziła.
Betonowy wzór jest prosty. Niezależnie od tego, jakie zadanie ma dana umiejętność — wzbogacanie profilu osoby, wyszukiwanie produktu, pobieranie dokumentu — zadanie to wyraża się jako wywołanie interfejsu, a nie konkretnego źródła danych. Za interfejsem może dzisiaj znajdować się aktywne API, jutro wyczyszczona pamięć podręczna, a pojutrze własna baza danych klienta. Umiejętność nie ma znaczenia; jego logika działa zgodnie z kształtem, jaki obiecuje interfejs, a implementacje interfejsu są tym, co się zmienia. Źródło danych staje się wtyczką, a nie sztywną zależnością.
Powodem, dla którego źródła danych zasługują na najsilniejszą formę oddzielenia, jest to, że są to elementy, które najprawdopodobniej ulegną zmianie wbrew Twojej woli. Interfejsy API stają się przestarzałe. Warunki świadczenia usług zaostrzają się. Zmiany cenowe. Klient nalega, abyś zamiast zewnętrznego źródła korzystał z własnej hurtowni danych. Każde z tych zdarzeń byłoby katastrofalne, gdyby umiejętność została połączona z konkretnym źródłem, a każde z nich staje się rutynową wymianą implementacji, gdy źródło znajduje się za interfejsem. To nie jest hipotetyczne — zdarzyło mi się to więcej razy, niż mogę zliczyć, i za każdym razem umiejętności, które miały adaptery, przetrwały bez żadnych problemów, podczas gdy umiejętności, które nie wymagały przepisywania.
Na granicy kształtu należy zwrócić uwagę na konkretny problem. Różne źródła w różny sposób reprezentują podobne dane — jeden interfejs API nazywa je „e-mailem”, inny „adresem_e-mail”, jeszcze trzeci zagnieżdża je w obiekcie „kontakt”. Jeśli interfejs ujawnia kształt źródła, wówczas zamiana źródeł wymaga aktualizacji każdego dalszego konsumenta w celu dopasowania do nowego kształtu, co mija się z celem. Interfejs musi ukazywać wewnętrzny kształt niezależny od jakiegokolwiek źródła; Zadaniem każdej implementacji jest przełożenie kształtu źródła na kształt wewnętrzny. Najpierw interfejs, potem pasujące implementacje — nigdy na odwrót.
Wzorzec wykracza poza zwykłe interfejsy API. Stosuję tę samą dyscyplinę w przypadku przechowywania — czasami piszę do S3, czasami do udziału plików klienta, czasami do katalogu lokalnego podczas programowania. Wszystkie trzy mają ten sam interfejs: „umieść gdzieś ten artefakt i oddaj mi odniesienie”. Umiejętność nie wie i nie przejmuje się tym; implementacja obsługuje specyfikę. Ta sama historia dotyczy baz danych (pamięć w pamięci do testów, prawdziwy Postgres w produkcji), wyszukiwania (tutaj Elasticsearch, tam wektorowa baza danych) i dostawców uwierzytelniania. Jakakolwiek zewnętrzna zależność, która mogłaby zostać przeniesiona, powinna znajdować się za interfejsem, ponieważ „może zostać przeniesiona” okazuje się „ostatecznie się przesunie”.
Istnieje pewna dyscyplina projektowa dotycząca kształtu reprezentacji wewnętrznej, którą warto nazwać: kształt wewnętrzny powinien być kształtem, jakiego faktycznie oczekuje logika twoich umiejętności, a nie kompromisem między tym, co ujawniają różne źródła. Jeśli umiejętność wymaga osoby z adresem e-mail, nazwiskiem i rolą, interfejs w przejrzysty sposób obiecuje te trzy pola. Jeśli jakieś źródło nie ma „roli”, jego implementacja tworzy coś rozsądnego lub zwraca wartownika — ale możliwości interfejsu nie ulegają pogorszeniu. Zaprojektuj to, czego potrzebuje wnętrze; niech wdrożenia dostosują rzeczywistość do tej obietnicy.
Owiń każde źródło danych interfejsem. Zaprojektuj interfejs wokół kształtu, jakiego pragnie Twoja logika, a nie tego, co ujawnia jakiekolwiek źródło. Pozwól, aby wdrożenia przełożyły świat na Twoją obietnicę. Źródła przychodzą i odchodzą; umiejętność pozostaje.
No figure. This is the adapter shape from Fig 16.1 again, applied to a specific class of dependency. The recurring picture in this book is that the same seam pays off in more places than any one drawing can show — which is itself the case for drawing it once and reusing the concept everywhere.
Chapter 45
GitHub jako źródło prawdy
Każda umiejętność, którą przechowuję, znajduje się w Git, a każde repozytorium Git jest w GitHub, a to rozwiązanie nie jest nostalgią za narzędziami dla programistów — to konkretny wybór dotyczący tego, gdzie znajduje się kanoniczna wersja każdej umiejętności, ponieważ gdy prawda jest rozproszona po laptopach, zrzutach ekranu i wiadomościach na Slacku, prawdy nie ma nigdzie. GitHub jest źródłem prawdy, ponieważ to jedyne miejsce, w którym „aktualna wersja” jest dobrze zdefiniowaną koncepcją.
Naiwną alternatywą jest przechowywanie umiejętności w postaci plików lokalnych, edytowanie ich na miejscu i od czasu do czasu tworzenie kopii zapasowych. Działa to w przypadku osoby prowadzącej jednoosobową działalność gospodarczą z jedną maszyną aż do momentu zakupu drugiej maszyny, awarii laptopa, nowego podwykonawcy, który potrzebuje tych samych umiejętności, lub klienta, który chce sprawdzić, czego używasz podczas jego zlecenia. W każdym z tych momentów model plików lokalnych psuje się w sposób, którego rozbicie jest kosztowne, ponieważ rekonstrukcja historii z martwego dysku to projekt, na który nikt nie przewidział budżetu.
Umieszczenie umiejętności w Git-i-GitHub nie kosztuje prawie nic, a konfiguracja zwraca się w momencie pojawienia się dowolnego z tych punktów przegięcia. Historia jest zachowywana automatycznie — każda zmiana jest zatwierdzeniem, każdą wersję można odzyskać, każdą różnicę można sprawdzić. Współpraca jest banalna — kolega klonuje repo, ma to samo, co ja. Recenzja klienta to adres URL — pokazuję mu repozytorium, a oni widzą rzeczywisty kod, który został uruchomiony podczas ich zaangażowania. A kiedy maszyna umrze, przywrócenie zestawu umiejętności to nowy klon, a nie operacja poszukiwawczo-ratownicza.
Istnieje dyscyplina dotycząca tego, co należy do repo, a co nie. Kod umiejętności należy. Konfiguracja umiejętności należy do. Testy umiejętności należą. To, co nie należy, to wszystko, co jest tajne — klucze API, dane uwierzytelniające, tokeny — i wszystko, co jest przejściowe — katalogi pamięci podręcznej, wygenerowane artefakty, wyniki działania. Błędny podział po stronie tajnej to najpoważniejszy błąd, jaki można popełnić w przypadku publicznego lub współdzielonego repozytorium, a dyscyplina polegająca na utrzymywaniu tajemnic w tajemnicy musi być wbudowana w przepływ pracy od pierwszego dnia, a nie zapamiętywana po wycieku.
Warstwa GitHub na Git dodaje zestaw funkcji, które okazują się mieć większe znaczenie, niż się spodziewałem. Problemy stają się sposobem na śledzenie błędów i żądań funkcji w odniesieniu do umiejętności bez zanieczyszczania kodu. Żądania ściągnięcia stają się miejscem, w którym zmiana jest sprawdzana przed wprowadzeniem na rynek. Akcje stają się sposobem na automatyczne uruchamianie testów przy każdym naciśnięciu. Żadne z nich nie jest niezbędne w tym sensie, w jakim jest sam Git, ale każdy z nich jest rodzajem delikatnej dyscypliny, która chroni zestaw umiejętności przed cichym gniciem w miarę ich wzrostu.
Konsekwencją tego, że cały ten układ działa, jest to, że gdy GitHub jest źródłem prawdy, lokalna kopia na moim laptopie jest kopią roboczą, a nie artefaktem. Jeśli odbiega od tego, co jest w pilocie, zdalny wygrywa, a moje lokalne zmiany muszą zostać uzgodnione — wyciągnięte, scalone, wypchnięte — aż do ponownego dopasowania tych dwóch elementów. Traktowanie pilota jako autorytatywnego wydaje się oczywiste i jest specyficznym nawykiem umysłowym, który powstrzymuje rozwój rozproszony przed przekształceniem się w zbiór rozbieżnych rozwidleń bez jasnej wersji kanonicznej.
Umieść każdą umiejętność w Git. Przekaż każde zatwierdzenie do GitHub. Trzymaj tajemnice na zewnątrz. Traktuj pilota jak prawdę. Zestaw umiejętności staje się aktywem, który przetrwa Twoją maszynę, laptop, system operacyjny i – ostatecznie – Twoją karierę.
Fig 45.1 — One Truth, Many Copies. The focal centre is the remote — laptops, CI, clients all pull from and push to the same canonical version. Local disks are working copies of the truth, not the truth itself.
Chapter 46
Rusztowanie umiejętności
Każda umiejętność, którą buduję, zaczyna się od tego samego rusztowania, a rusztowanie nie jest sprytne – jest nudne, oczywiste i nie podlega negocjacjom. Katalog testów, katalog src, manifest, plik README, mały zestaw adapterów. Nic egzotycznego; nic, czego projektowanie zajęłoby miesiąc. Powodem, dla którego nalegam na ten sam kształt dla każdej umiejętności, jest to, że wspólny kształt pozwala umiejętnościom komponować, a kompozycja jest źródłem dźwigni.
Manifest to utwór, który najdłużej nie doceniałem. Jest to mały plik metadanych stanowiący podstawę każdej umiejętności, który deklaruje, do czego dana umiejętność jest przeznaczona, do jakiego filaru należy, jakie są jej dane wejściowe, jakie są jej wyniki i z jakimi innymi umiejętnościami się łączy. Maszyny czytają manifest, aby kierować pracą; ludzie czytają to, aby zrozumieć, co robi umiejętność, bez otwierania kodu. Kiedy manifesty są spójne w całym pakiecie, drzwi frontowe z rozdziału 3 mogą wykonać swoje zadanie w sposób deterministyczny, ponieważ każda umiejętność deklaruje się w tym samym słownictwie.
Katalog testów również nie jest opcjonalny, nawet w przypadku umiejętności, których myślę, że użyję tylko raz. Umiejętność bez testów to umiejętność, której nie mogę bezpiecznie zrefaktoryzować, nie mogę z całą pewnością zdeprecjonować ani przekazać współpracownikowi. Testy to pas bezpieczeństwa, który pozwala mi zmienić umiejętność bez nadziei, że zapamiętam każdy przypadek Edge. Konkretne testy, które piszę, różnią się w zależności od umiejętności, ale zawsze jest co najmniej jeden — test złotej ścieżki, który przeprowadza umiejętność od początku do końca na standardowych danych wejściowych i potwierdza, że artefakt działa prawidłowo. Ten pojedynczy test wychwytuje większość regresji i jest wielokrotnie wart swojej wagi.
Plik README to trzeci element, którego wartości muszę wciąż uczyć się na nowo. Nie dla mnie – dla przyszłej wersji mnie, za sześć miesięcy, która zapomni, do czego i dlaczego służy ta umiejętność. Plik README jest wiadomością od „ja teraźniejszego” do „ja z przyszłości” i powinien zakładać, że „ja z przyszłości” nie pamięta żadnych wyborów projektowych, kompromisów ani klienta, który zainspirował tę pracę. Plik README każdej umiejętności wyjaśnia, do czego służy, jak ją uruchomić, czym ją karmić, co daje w zamian i — co najważniejsze — dlaczego projekt wylądował tam, gdzie się znalazł.
Folder adapterów to miejsce, w którym fizycznie ląduje dyscyplina z rozdziałów 43 i 44. Każda zależność zewnętrzna to plik w tym folderze, otoczony małym interfejsem. Tutaj dodawane są nowe adaptery; starsi tutaj przechodzą na emeryturę. Jednolitość oznacza, że na odpowiedź na pytanie „dowiedz się, jak ta umiejętność rozmawia ze światem zewnętrznym” można odpowiedzieć, otwierając pojedynczy, przewidywalny folder, a nie przeglądając całą bazę kodu.
Ostatni element należy do rusztowania, czyli wersja. Każda umiejętność ma jedną i pojawia się przy każdej znaczącej zmianie. Wersjonowanie semantyczne jest w porządku — główne w przypadku łamania, drugorzędne w przypadku dodatków, łatka w przypadku poprawek — ale konkretny schemat ma mniejsze znaczenie niż fakt, że wersja istnieje. Ponieważ gdy zmienia się zachowanie umiejętności, wszystko, co od niej zależy, musi wiedzieć, a zmiana wersji jest zapowiedzią zmiany.
Manifest, testy, README, adaptery, wersja. Ten sam kształt, wszystkie umiejętności. Jednolitość wydaje się być narzucana, gdy masz trzy umiejętności, i ogromnie się opłaca, gdy masz ich trzydzieści. Zbuduj rusztowanie raz, stosuj je zawsze.
Fig 46.1 — The Skill Scaffold. The focal directories — manifest, adapters, tests — are the ones that make the skill composable, swappable, and refactorable. Same shape for every skill; that shape is what lets the suite behave as one system rather than thirty islands.
Chapter 47
Wspólne idiomy
Jeśli rozdział 46 był fizycznym rusztowaniem, w którym uczestniczy każda umiejętność, ten rozdział dotyczy rusztowania językowego — małego zestawu idiomów, które powtarzają się w przypadku każdej umiejętności i sprawiają, że zestaw sprawia wrażenie języka, a nie zbioru skryptów. Idiomy w sensie „jak tu mówimy”: standardowy sposób rejestrowania przebiegu, standardowy kształt błędu, standardowa struktura wyniku. Spójność na tym poziomie sprawia, że później komponowanie wydaje się łatwe.
Pierwszym idiomem jest kształt wyniku. Każda umiejętność zwraca wynik w tej samej formie: status (sukces lub porażka), ładunek (artefakt lub przyczyna niepowodzenia), wskaźnik śledzenia (gdzie znaleźć dowody przebiegu) i rekord kosztów (ile zużył ten przebieg). Różne umiejętności dają oczywiście różne ładunki, ale otoczka wokół ładunku jest identyczna. Dalsi konsumenci wiedzą, jak postępować z wynikami każdej umiejętności, ponieważ wyniki każdej umiejętności mają ten sam kształt. Jednolite koperty sprawiają, że kompozycja jest bezpieczna.
Drugi idiom to kształt błędu. Kiedy umiejętność zawiedzie, dzieje się to w sposób wpisany na klawiaturze — niepowodzenie niesie ze sobą kategorię (przejściową, semantyczną, terminalną, jak z rozdziału 29), komunikat, który można bezpiecznie pokazać człowiekowi, powód wewnętrzny, który jest bardziej przydatny do debugowania, oraz wskazówkę dotyczącą ponownej próby, jeśli ma to zastosowanie. Osoby wywołujące mogą reagować na błędy w sposób deterministyczny, ponieważ błędy opisują się same w sposób, w jaki osoby wywołujące mogą je sprawdzić. Niewpisane ciągi błędów są drogą do chaosu, w którym każdy dzwoniący analizuje je inaczej.
Trzeci idiom to rejestrowanie. Każda umiejętność emituje postęp w ten sam zorganizowany sposób — strumień zdarzeń z wpisanymi nazwami i ładunkami, pasujący do struktury zdarzeń z rozdziału 23. Drzwi wejściowe i dowolny koordynator mogą renderować, agregować i uzasadniać zdarzenia z dowolnej umiejętności, nie wiedząc, czym jest ta umiejętność, ponieważ kształt jest stabilny. Jeśli nowa umiejętność wprowadza własny format rejestrowania, łamie obietnicę dotyczącą kompozycji; zasada jest taka, że kształt kłody jest kształtem zestawu, a nie poszczególnych umiejętności.
Czwartym idiomem jest nadawanie nazw. Umiejętności używają tych samych słów do określenia tych samych rzeczy. „Bieg” oznacza wszędzie to samo — wywołanie umiejętności w oparciu o dane wejściowe, dające wynik. „Artefakt” oznacza to samo — trwały wynik, jaki może przechowywać magazyn artefaktów. „Ślad” oznacza to samo – ustrukturyzowany dowód pozostawiony przez bieg. Dryfowanie słownictwa jest jedną z najcichszych form zaniku zestawu, ponieważ mała zmiana nazwy każdej umiejętności nie wydaje się szkodliwa, dopóki połowa zestawu nie nazwie tego samego pojęcia trzema różnymi nazwami i każda dyskusja będzie musiała zostać przetłumaczona.
Sposób awarii, który zaobserwowałem w przypadku idiomów, polega na tym, że są one utrzymywane przez uwagę, a nie przez mechanizm, a uwaga jest kruchą gwarancją. Zatem praktyczną rzeczą jest umieszczenie idiomów w kodzie — współdzielonej bibliotece, małym zestawie typów, zestawie funkcji pomocniczych — które importuje każda umiejętność. Konsekwencja nie jest dyscypliną, o której muszę pamiętać; jest to zależność, która sama się narzuca. Gdy umiejętność odbiega od współdzielonej biblioteki, jest to widoczne; w momencie, gdy zależy to od biblioteki, jest wyrównane konstrukcyjnie.
Koperta wyników, kształt błędu, strumień dziennika, słownictwo — cztery idiomy, które zamieniają zestaw umiejętności w zestaw. Umieść je w bibliotece udostępnionej. Niech indywidualność każdej umiejętności żyje w jej logice, a nie w tym, jak mówi o sobie. Kompozycja jest o tyle prosta, o ile idiomy są spójne, a dzięki udostępnionej bibliotece są takie proste.
No figure. Idioms are linguistic conventions; a diagram of them would end up either as a code listing (belongs in a repo, not a book) or an abstract "consistency" cloud that says nothing. The point is invisible on purpose — well-set idioms disappear into the background of every skill.
Chapter 48
Wycofanie umiejętności
Apartamenty gromadzą umiejętności z biegiem czasu, a także umiejętności, których nie powinno już tam być. Deprecjacja — celowy akt wycofania umiejętności z aktywnej służby — jest zdyscyplinowanym odpowiednikiem budowania, a zaniedbanie tego powoduje, że odchudzony pakiet po cichu staje się nadęty. Każda umiejętność, która przetrwa swoją przydatność, odwraca uwagę od sieci i utrudnia routing.
Powody, dla których dana umiejętność zasługuje na emeryturę, są różnorodne i warte wymienienia. Czasami podstawowe zadanie znika (klient odchodzi, przepływ pracy zmienia kształt). Czasami lepsza umiejętność przejmuje pracę starej (dwie nakładające się umiejętności, jedna wygrywa w Rozdziale 41). Czasami podstawowy dostawca, od którego zależy umiejętność, zniknął, a przepisanie umiejętności pod kątem nowego dostawcy nie jest warte swojej ceny. Czasami patrzę na umiejętność, którą rozwinąłem dwa lata temu, i zdaję sobie sprawę, że nie pamiętam dlaczego. Każdy z nich jest ważnym sygnałem przejścia na emeryturę, a uhonorowanie tego sygnału sprawia, że apartament nie stanie się muzeum.
Mechanizm amortyzacji nie jest dramatyczny. Manifest umiejętności otrzymuje przestarzałą flagę z datą i przyczyną. Wszystko, co tworzy się za pomocą tej umiejętności, otrzymuje ostrzeżenie w czasie kompilacji lub w czasie wykonywania, że jego zależność wycofuje się. Nowe wywołania umiejętności powodują zachętę do migracji. Po okresie karencji — zwykle kilku miesiącach — kod umiejętności zostaje przeniesiony do archiwum repozytorium i przestaje być możliwy do trasowania z poziomu drzwi wejściowych. Ważne jest, aby każda scena była publiczna i transmitowana telegraficznie, aby nikt w apartamencie nie był zaskoczony zniknięciem umiejętności.
Muszę się nauczyć pewnej dyscypliny, aby niczego nie usuwać. Wycofane umiejętności trafiają do archiwum, a nie do kosza. Powodem jest to, że sześć miesięcy po przejściu na emeryturę od czasu do czasu odkrywam scenariusz, w którym przestarzała umiejętność faktycznie poradziła sobie dobrze, a przywrócenie jej — nawet w celach informacyjnych — jest trywialne, jeśli kod nadal gdzieś istnieje. Usunięcie jest nieodwracalne; archiwizacja jest odwracalna; gdy krańcowy koszt przechowywania wynosi kilka kilobajtów dysku w repozytorium, które już przechowujesz, tanim posunięciem jest archiwizacja.
Tryb niepowodzenia, który chcę nazwać, jest jego przeciwieństwem — umiejętności, które pozostają w pamięci już dawno poza swoją rzeczywistą przydatnością, ponieważ deprecjonowanie wydaje się niezręczne i niewdzięczne. Rezygnacja z własnej pracy, zwłaszcza tej, która kiedyś miała znaczenie, wiąże się z niewielkimi kosztami psychologicznymi. Ale alternatywa jest gorsza: zestaw pełen półaktywnych umiejętności, których nikt nie chce usunąć, to zestaw, w którym tablica routingu jest zagmatwana, siatka MECE to kłamstwo, a każda nowa umiejętność musi bronić swojego istnienia przed hałasem w tle. Przejście na emeryturę sprzyja przejrzystości pakietu; potraktuj to jako takie, a przestaniesz odczuwać odrzucenie przeszłej pracy.
Istnieje zasada nazewnictwa, która pomaga zasygnalizować zmianę: przestarzała umiejętność nie tylko otrzymuje flagę, ale także wyraźną notatkę w pliku README o treści „ta umiejętność została wycofana; zamiennik to X” lub „brak zamiennika — przepływ pracy, który obsługiwała, już nie istnieje”. Notatka jest przeznaczona dla mnie z przyszłości oraz dla każdego, kto natknie się na zarchiwizowany kod i zastanawia się, czy jest on nadal aktualny. Ciche archiwa są niebezpiecznymi archiwami; udokumentowane są użytecznymi odniesieniami.
Odejdź na emeryturę to, co przestaje zasługiwać na swoje miejsce. Archiwizuj zamiast usuwać. Telegrafuj o zmianie, aby nic w zależności od umiejętności nie było zaskoczeniem. Udokumentuj przejście na emeryturę. Apartament pozostaje szczupły dzięki dyscyplinie, a nie przez przypadek.
No figure. Deprecation is a change of state — a manifest flag flipping — not a structure. The visible half of the practice is the MECE grid from Fig 41.1, with retired skills disappearing from the columns; the invisible half is the archived branch that keeps the deletion reversible.
Chapter 49
Telemetria umiejętności
Umiejętność bez telemetrii jest umiejętnością działającą z założenia. Myślisz, że to przydatne; myślisz, że w większości przypadków to się udaje; myślisz, że niepowodzenia są rzadkie i wystarczająco rzadkie. Wszystkie trzy z tych myśli są opiniami, dopóki nie zostaną zmierzone, a telemetria umiejętności zamienia je w fakty. Nie efektowne; nie jest opcjonalny powyżej określonego rozmiaru pakietu.
Pomiary, na których mi zależy na poziomie umiejętności, są celowo nudne. Ile razy ta umiejętność została przywołana w ciągu ostatniego tygodnia? Jaki procent wywołań zakończyło się sukcesem? Jaki jest średni koszt udanego wywołania? Jaki jest średni czas trwania? Jaki jest współczynnik ponownych prób? Te pięć liczb, aktualizowanych co tydzień, mówi mi większość tego, co muszę wiedzieć o kondycji umiejętności, a ich brak powoduje, że umiejętności cicho gniją bez mojej wiedzy.
Powodem, dla którego telemetria jest szczególnie ważna w przypadku umiejętności, a nie tylko systemów, w których są osadzone, jest to, że umiejętności stanowią możliwą do komponowania jednostkę pakietu. Pojedynczą umiejętność można wywołać z tuzina różnych potoków, każdy z inną częstotliwością i różną krytycznością. Łączenie wykorzystania na poziomie umiejętności pozwala mi zobaczyć, które umiejętności są przydatne — od których zależy każdy rurociąg — a które są niszowe. Umiejętności przenoszenia obciążeń zasługują na więcej testów, większe hartowanie i dokładniejsze projektowanie adapterów; umiejętności niszowe mogą być lżejsze. Bez widoku zbiorczego każda umiejętność jest traktowana tak samo, co nie jest skuteczne w żadnym kierunku.
Mechanizm, którego używam, polega na tym, że koperta wyników każdej umiejętności (rozdział 47) jest rejestrowana przy każdym wywołaniu w centralnej księdze — w rzeczywistości tej samej księdze z rozdziału 31, oznaczonej nazwą umiejętności. Co tydzień zapytanie agregatora pobiera wiersze z ostatniego tygodnia według umiejętności i generuje pięć liczb. Liczby są dostarczane mi w formie małego raportu w każdy poniedziałek. Nic nadzwyczajnego — chcę, żeby była tak tania w produkcji, aby zawsze była produkowana, i tak tania w czytaniu, że zawsze ją czytam.
Jedyną liczbą, która okazuje się zaskakująco diagnostyczna, jest wskaźnik sukcesu. Umiejętności, których wskaźnik powodzenia maleje z biegiem czasu, to umiejętności, których podstawowe założenia ulegają erozji — adapter, który zaczyna się psuć, zmienia się dystrybucja danych wejściowych, zmienia się model zachowania. Wyłapanie tego dryfu, gdy jest on wciąż stopniowy, jest znacznie tańsze niż wykrycie go, gdy uruchomienie klienta w sposób widoczny kończy się niepowodzeniem. Telemetria to system wczesnego ostrzegania przed cichą zgnilizną.
Drugą liczbą wartą uwagi jest współczynnik ponownych prób. Wysoka liczba ponownych prób oznacza albo przejściowy problem ze środowiskiem, albo problem semantyczny prześlizgujący się obok klasyfikatora, a każda interpretacja jest możliwa do zastosowania — pierwsza poprawia infrastrukturę niezawodnościową, druga poprawia obsługę błędów umiejętności. Umiejętności charakteryzujące się stosunkowo wysokim współczynnikiem ponownych prób są także umiejętnościami o stosunkowo zawyżonych kosztach (zgodnie z rozdziałem 36), więc liczba ponownych prób jest wiodącym wskaźnikiem pogorszenia się ekonomii jednostki.
Rejestruj każde wywołanie. Łącznie co tydzień. Obserwuj wskaźnik sukcesu, współczynnik ponownych prób i koszt wyniku. Umiejętności, które po cichu gniją, stają się widoczne w telemetrii – ale tylko wtedy, gdy telemetria istnieje. Zbuduj go, zanim będzie Ci potrzebny.
Fig 49.1 — Weekly Skill Digest. Five focal columns per skill — invocations, success, retries, and cost per outcome — turn silent rot into a visible signal. The red row is a skill whose numbers say "retire me" without a human having to notice individually.
Chapter 50
Kiedy umiejętność chce być usługą
Część V kończy się pytaniem, które w końcu pojawia się w przypadku każdego dojrzałego pakietu: kiedy umiejętność powinna przestać być umiejętnością i stać się usługą samą w sobie? Obaj są bliskimi kuzynami pod względem architektonicznym, ale różnią się rodzajem, a wiedza, kiedy dana umiejętność chce zostać ukończona, stanowi różnicę między rozwojem Twojej firmy a przerastaniem Twojej architektury.
Umiejętność to fragment maszyny, którą można komponować, wywoływany z poziomu przepływu pracy i działający w trakcie wraz z resztą maszyn. Usługa to niezależna, zawsze włączona funkcja udostępniana za pośrednictwem interfejsu, wywoływana przez wiele przepływów pracy, w tym te, nad którymi nie masz kontroli. Granica między nimi nie jest ostra — wiele rzeczy przez długi czas funkcjonuje wygodnie jako umiejętności, a potem w pewnym momencie fakt, że są to umiejętności, zaczyna wydawać się raczej ograniczeniem niż wygodą.
Sygnały, że umiejętność chce być usługą, są specyficzne i warte nazwania. Po pierwsze: jest wywoływany z wielu przepływów pracy, które nie powinny wymagać osobnego łączenia go w pakiety. Kiedy umiejętność jest używana przez dziesięć różnych potoków, a każdy potok musi zawierać kod umiejętności i zależności, narzut związany z kopiowaniem stanowi prawdziwy koszt, a centralizacja możliwości, gdy usługa zaczyna wyglądać atrakcyjnie. Po drugie: musi utrzymywać stan podczas wywołań — pamięć podręczną, indeks, ogranicznik szybkości — który nie może w rozsądny sposób przetrwać w krótkotrwałym procesie każdego potoku. Po trzecie: musi działać nieprzerwanie, a nie tylko na żądanie — musi być słuchaczem, obserwatorem, harmonogramem, który budzi się po zdarzeniach zewnętrznych. Każdy z tych trzech powodów jest uzasadnionym powodem ukończenia studiów.
Równie ważne są sygnały, że umiejętność a nie chce być usługą. Umiejętność wywoływana z jednego miejsca, nie posiadająca stanu wywołania krzyżowego i działająca tylko na żądanie, to umiejętność, która nie zyskałaby nic na ukończeniu, poza większym obszarem operacyjnym. Przedwczesna obsługa serwisowa jest kosztowna — teraz masz usługę, którą możesz zabezpieczyć, monitorować, wdrażać, skalować i płacić — a zapłata musi być tego warta. Większość moich umiejętności pozostanie umiejętnościami na zawsze, ponieważ większość moich umiejętności, szczerze mówiąc, nie musi być usługami. Ukończenie szkoły jest wyjątkiem, a nie domyślnym.
Mechanika przejścia, jeśli faktycznie nastąpi, jest mniej dramatyczna, niż się wydaje. Ponieważ umiejętność została zbudowana w oparciu o adaptery i idiomy z wcześniejszych rozdziałów, jej interfejs jest już przejrzysty. Wystawienie go jako usługi oznacza opakowanie tego interfejsu w transport sieciowy – punkt końcowy HTTP lub konsument kolejki – i uruchomienie go jako trwałego procesu. Podstawowa logika się nie zmienia; otaczająca go skorupa tak. Jest to ten sam wzór „przetestuj raz, ujawnij dwa razy” z rozdziału 12, zastosowany na granicy umiejętności/usługi: logika jest stabilna, zmienia się tylko powierzchnia wywołania.
Nazywanie od razu wiąże się z pewnym ryzykiem, które polega na tym, że gdy umiejętność stanie się usługą, jej ewolucja zwalnia. Usługi niosą ze sobą obietnice kompatybilności, zobowiązania dotyczące czasu sprawności i koszty ogólne związane z zarządzaniem zmianami, których nie wiążą się z umiejętnościami w trakcie procesu. Zatem ukończenie szkoły to w praktyce droga jednokierunkowa — technicznie możliwe jest zdegradowanie usługi z powrotem do umiejętności, ale ze społecznego punktu widzenia jest to przyznanie się do przesady, które jest trudne do pokonania. Co oznacza, że decyzja o ukończeniu studiów zasługuje na uwagę; to moment, w którym element Twojego zestawu zmienia się z taniego do wymiany na drogi do wymiany.
Uważaj na sygnały — wielu dzwoniących, stan wywołań krzyżowych, zawsze dostępna potrzeba. Ukończ szkołę, gdy się pojawią, a nie wtedy, gdy nadejdzie pokusa. I zaakceptuj, że ukończenie szkoły to awans, na który dzieło musi zasłużyć, bo w momencie przekroczenia granicy ergonomia eksperymentów ustępuje ergonomii produkcji. Większość umiejętności pozostaje umiejętnościami; to cecha.
No figure. This is a judgement call about scope, not a structural pattern; the two shapes involved are drawn already — the composable skill in Fig 46.1 and the always-on service in Fig 22.1. The chapter's argument is about which of the two a piece of work belongs in, not a new picture.
Part VI
Klienci
Odkrycie w grafiku, wymuszająca funkcja prawdziwego klienta, uczciwa odznaka na próbie, obecność człowieka w pętli jako moment rozliczeniowy oraz specyficzne mechanizmy przekształcania dowodu słuszności koncepcji w trwałe zaangażowanie.
Chapter 51
Odkrycie w składzie
Każda relacja z klientem zaczyna się jako nieznajomy, a kończy jako członek personelu lub grzeczna osoba nieodpowiednia. Jest to proces ustalania, co nazywam odkrywaniem. To przemyślane, ustrukturyzowane pierwsze kilka rozmów mówi obu stronom, czy istnieje prawdziwe zaangażowanie do zbudowania. Właściwe odkrywanie to miejsce, w którym najwięcej zwycięstw i najwięcej strat ma miejsce; faktyczna dostawa jest łatwa w porównaniu z ustaleniem, komu ją dostarczyć.
Sposób, w jaki strukturyzuję odkrywanie, jest niewielki i specyficzny. Pierwsza rozmowa: czego właściwie chce klient, własnymi słowami, bez mojej interpretacji i przeformułowania? Druga rozmowa: jak wygląda świat wokół ich problemu – ograniczenia, obowiązujące rozwiązania, zaangażowani ludzie, pieniądze? Rozmowa trzecia: jak konkretnie miałby wyglądać sukces za trzy miesiące, a jak wygląda porażka? Trzy ukierunkowane rozmowy, każda z jasnym pytaniem, każda nie dłuższa niż to konieczne. To zwykle wystarczy, żeby wiedzieć.
Celem odkrycia nie jest sprzedaż, ale sprawdzenie, czy warto szukać czegoś odpowiedniego. Nauczyłam się opierać instynktowi przekonywania podczas tych rozmów. Jeśli dopasowanie jest odpowiednie, ogłasza się to samo; Obie strony wychodzą z trzeciej rozmowy jasne, że jest coś do zbudowania. Jeśli krój nie jest odpowiedni, to również daje znać o sobie, a etycznym posunięciem jest powiedzieć to i rozstać się w dobrych stosunkach. Próba narzucenia złego dopasowania na dobre jest dla mnie kosztowna, gorsza dla klienta i niezawodnie kończy się nieudaną umową, która szkodzi obu reputacjom.
Sygnały, że dopasowanie jest realne, okazują się proste. Klient ma realny problem, a nie mgliste ambicje. Potrafią nawet w przybliżeniu określić, jak wyglądałoby rozwiązanie. Mają władzę i budżet, aby faktycznie się zaangażować – a nie „będziemy musieli tym zająć się trzy komisje”. I są gotowi wykonać pracę, której wymaga samo odkrycie: pojawić się, odpowiedzieć na pytania, być uczciwym. Kiedy ta czwórka jest obecna, trzecia rozmowa zwykle kończy się pytaniem obu stron „co dalej”, co jest dobrym znakiem.
Sygnały złego dopasowania są równie proste i łatwiej je przeoczyć. Problem zmienia się pomiędzy rozmowami. Budżet jest niejasny. Interesariusze ciągle się zmieniają. Pytania wydają się wymijające. Każdy z nich sam w sobie może być niewinny; dwa lub więcej razem to zazwyczaj wszechświat każe ci iść dalej. Kiedy ignoruję te sygnały, za każdym razem za to płacę i nauczyłem się szybciej im ufać.
Pytanie dotyczące składu – podjęcie decyzji, których klientów zatrzymać na dłużej – to ta sama ocena, która jest przeprowadzana w sposób ciągły po odkryciu. Co trzy lub sześć miesięcy patrzę, kto jest w składzie i pytam: czy to nadal odpowiednie dopasowanie? Czy oboje dostaniemy to, po co przyszliśmy? Czy zgodziłbym się na odkrywanie z tym klientem, gdybyśmy zaczynali dzisiaj? Szczere „tak” podtrzymuje ich na duchu; szczere „nie” jest zachętą do podjęcia trudnej rozmowy na temat wyciszenia się. Składy, które nigdy się nie zmieniają, to składy, które po cichu przechodzą w przeciętne starcia, których żadna ze stron nie chce nazwać.
Trzy rozmowy. Obserwuj sygnały. Powiedz nie, gdy jest to nie. Kontynuuj przegląd składu. Klienci, którym dobrze służysz, to ci, których wybrałeś uczciwie.
No figure. Discovery is a sequence of conversations, not a structure; the honest visual is a calendar with three named slots, and calendars don't earn diagram treatment in this book. The roster it feeds into is a list, not a picture.
Chapter 52
Fuzja jako funkcja wymuszająca
Istnieje specyficzny rodzaj zaangażowania klienta, który nazywam fuzją — taki, w którym ambicje są znacznie większe niż zasoby, a cały zespół będzie musiał nagiąć się przed ograniczeniami, aby to zadziałało. Te zaręczyny mnie przerażają i bez wyjątku dają najlepszą pracę, jaką kiedykolwiek wykonałem. Ograniczenie jest najważniejsze.
Klientów Fusion łączy to, że przychodzą z realnym, konkretnym, trudnym problemem i realnym, konkretnym, niewystarczającym budżetem na standardowe rozwiązanie. Gdybyśmy zrobili to w normalny sposób doradczy – zespół składający się z sześciu, sześciu miesięcy, plan projektu, seria warsztatów – koszt byłby zaporowy. Klienci Fusion nie szukają normalnej drogi; szukają kogoś, kto może mieć te same ambicje, ale znaleźć zupełnie inną drogę do osiągnięcia celu. Na tej „zupełnie innej drodze” prace oparte na sztucznej inteligencji po cichu wyróżniają się, ponieważ dobrze przeszkolony potok agentów może wchłonąć pracę, która wcześniej wymagała sześcioosobowego zespołu.
Funkcja wymuszająca jest tym, co dzieje się pod tym ograniczeniem. Kiedy nie możesz po prostu zwiększyć personelu, musisz chirurgicznie jasno określić, co jest naprawdę ważne i odpuścić wszystko inne. Każde spotkanie musi znaleźć swoje miejsce. Każdy produkt musi mieć minimalny kształt, który odpowiada na rzeczywiste pytanie klienta. Każdą abstrakcję trzeba uzasadnić pytaniem: „czy znalazłaby się także tutaj, w mniejszej wersji tego projektu?” Niedobór nie jest ciężarem – jest tym, co rozjaśnia pracę, ponieważ wymusza ciągłe pytanie, co byśmy wycięli, gdybyśmy absolutnie musieli, a odpowiedź na to pytanie zwykle brzmi „większość”.
Tryb niepowodzenia, jaki tworzą klienci Fusion, polega na tym, że przyciągają niewłaściwego konsultanta — takiego, który zgadza się z ambicjami, nie ponosząc uczciwych kosztów, i dostarcza rozwodnioną wersję normalnego projektu w ramach ograniczonego budżetu. To nie jest Fuzja; to zaręczyny o złej wartości, udające takie. Prawdziwa Fuzja oznacza restrukturyzację samej realizacji, tak aby ograniczony budżet faktycznie sfinansował ambitny wynik, który wymaga naprawdę innego sposobu pracy, a nie obniżonej wersji starego sposobu. Jeśli nie możesz przeprowadzić restrukturyzacji, nie podejmuj się zaręczyn.
Restrukturyzacja wygląda w praktyce na podstawie intensywnego stosowania dyscypliny, o której traktuje cała książka. Praca mechaniczna odbywa się na nocnej zmianie; stos pomp jest zarezerwowany dla wywołań oceny skierowanych do klienta; po drabinie artefaktów wspina się tylko tak wysoko, jak wymaga tego konkretny wynik. Projekt Fusion wykorzystuje maszynę do wykonywania zadań, które w innym przypadku wymagałyby zaangażowania zespołu, a także ludzi — mnie i klienta — tam, gdzie ich miejsce jest niezastąpione. Jest to argument dotyczący systemu operacyjnego, a nie zestawu narzędzi, sformułowany przez klienta z myślą o konkretnym wyniku.
Istnieje konsekwencja wyboru klienta, której zdobycie zaufania zajęło mi trochę czasu. Klienci Fusion są zwykle najlepszymi klientami właśnie dlatego, że ograniczenie działa jak filtr po obu stronach. Tylko klienci, którzy potrafią zaakceptować prawdziwą restrukturyzację – klient spotyka się z mniejszą liczbą osób, produkt ma inny kształt, a proces wydaje się inny – zaangażują się w ten sposób. A klienci, którzy potrafią zaakceptować tę restrukturyzację, to zazwyczaj ci, którzy jasno myślą o tym, czego tak naprawdę potrzebują, czyli o kliencie, którego pragniesz.
Ograniczenia czasowe ambicji równają się przejrzystości. Klienci Fusion oferują jedno i drugie. Zrestrukturyzuj dostawę uczciwie lub powiedz nie; nie ma rozcieńczonej środkowej wersji, która by działała.
No figure. Fusion is a stance about which engagements to take, not a structure; the diagram it points at is the twenty-hour week from Fig 1.1, seen from the client's side rather than mine.
Chapter 53
Odznaka MOCK
W rozdziale 17 przedstawiono przełącznik próbny/na żywo jako mechanizm i określono zasadę, której chcę poświęcić cały rozdział: wyśmiewane dane muszą być wyśmiewane w sposób widoczny i bezbłędny. Ten rozdział dotyczy plakietki — specyficznej konwencji wizualnej, którą stosuję na każdej stronie i każdym artefakcie przedstawiającym gotowe dane, oraz tego, dlaczego ta plakietka zasługuje na swoje miejsce w projekcie.
Sama odznaka jest niewielka i nie da się jej przeoczyć. Krótka etykieta — „MOCK” lub „PRÓBNE DANE” — w kolorze wyróżniającym się na tle otaczającego interfejsu użytkownika, umieszczona w miejscu, którego nie można nie zauważyć. Ani w przypisie, ani w podpowiedzi, ani w subtelnej szarości. Musi być na tyle głośno, aby rozsądna osoba spoglądająca na ekran zauważyła to w ciągu sekundy, bo plakietka wymagająca uwagi to nie plakietka, tylko dekoracja.
Powodem, dla którego standard widoczności musi być tak wysoki, jest to, że wyśmiewane dane są bardziej przekonujące, niż zwykle sądzą praktycy. Dobrze wykonane makiety wyglądają realistycznie. Często są zaprojektowane tak, aby wyglądały prawdziwie, ponieważ celem ich pokazania jest ukonkretnienie ostatecznego doświadczenia. Napięcie polega na tym, że te same właściwości, które czynią kpiny użytecznymi – wiarygodność, kompletność, estetyczny połysk – czynią je niebezpiecznymi, gdy zostaną błędnie odczytane jako rzeczywiste dane. Odznaka jest przeciwwagą, dzięki której wiarygodność nie staje się oszustwem.
Tryb niepowodzenia, który widziałem wiele razy, polega na tym, że subtelna odznaka pozwala raz na wzięcie kpiny za prawdziwą przez kogoś, kto się liczy. Może to być interesariusz, który zobaczy zrzut ekranu w raporcie i błędnie zinterpretuje liczby. Może to być współpracownik, który zrzut ekranu makiety prześle do wiadomości e-mail klienta. To mógłbym być ja, trzy miesiące później, zapominający, które strony nadal zawierają dane w puszkach. Każde z nich powoduje dalszy koszt zaufania, który jest nieproporcjonalny do tego, jak mała musiałaby być plakietka, aby temu zapobiec. Głośno jest tanie; niejednoznaczność jest kosztowna.
Warto wymienić następujący wniosek: plakietka pozostaje włączona do czasu rzeczywistego udostępnienia danych, a jej usunięcie jest działaniem celowym. Nie „cóż, interfejs API prawdopodobnie już działa, możemy wyciągnąć odznakę”. Usunięcie następuje po potwierdzeniu, że prawdziwe dane przepływają dokładnie przez stronę, na której znajduje się plakietka. Odznaka stanowi obietnicę, że ta strona jest wyśmiewana; zdjęcie go w chwili, gdy obietnica przestanie być prawdziwa, jest dokładnie wtedy, gdy ktoś zobaczy złą liczbę. Ostrożne usuwanie to właściwy instynkt.
Poza aspektem wizualnym, plakietka jest funkcją wymuszającą projektowanie, która w cichy sposób ulepsza cały produkt. Ponieważ wiem, że plakietka będzie widoczna dla każdego, kto zobaczy stronę, mniej mnie kusi, aby przesadnie wypolerować wyśmiewany stan — nie chodzi o ukrycie kpiny, ale o przekazanie kształtu. Decyzje dotyczące produktu podejmowane na podstawie uczciwie oznakowanych kpin są lepszymi decyzjami, ponieważ każdy, kto je recenzuje, wie, co jest prawdziwe, a co symboliczne. Ta wiedza zmienia rozmowę z „czy liczba wygląda dobrze” na „czy kształt przepływu działa”, co jest rozmową, która faktycznie ma znaczenie na tym etapie.
Głośna odznaka. Nie da się przegapić. Znika dopiero wtedy, gdy obietnica przestaje być prawdziwa. A za dyscypliną kryje się korzyść z designu — szczere kpiny prowadzą do lepszych rozmów o produkcie niż kpiny udające prawdziwe. Zawsze wysyłaj odznakę.
Fig 53.1 — Ship the Badge. Same page, two states. The focal MOCK label on the right makes the canned data unmistakable — impossible to screenshot into a client email and be misread. Loud is cheap; ambiguity is expensive.
Chapter 54
Human-in-the-Loop jako moment podlegający rozliczeniu
W przypadku każdego kontaktu z klientem jest określony moment, za który tak naprawdę płaci klient, i nie jest to moment, w którym maszyna wytwarza produkt. To moment, w którym człowiek – zwykle ja, czasem oni – przegląda wydajność maszyny, ocenia ją i decyduje, co stanie się dalej. Przegląd ten jest momentem rozliczeniowym, a zrozumienie, dlaczego jest tym, co odróżnia zlecenia, które cenią klienci, od zleceń, które powoli przestają cenić.
Instynkt w pracy AI polega na cenieniu pracy maszyny jako produktu. Agent wyprodukował tyle artefaktów, dlatego właśnie za to płacimy. Ceny oparte na wolumenie wydają się naturalne, ponieważ to maszyna generuje wolumen. Jednak sama wielkość nie jest wartością dla klienta; tom, który został sprawdzony i za który ręczono, jest. Niezrecenzowany artefakt jest wersją roboczą; sprawdzony artefakt jest produktem dostarczanym. Rozbieżność między nimi wynika wyłącznie z ludzkiego osądu i to ten osąd jest tym, czego klient faktycznie potrzebuje w związku ze zleceniem.
Konsekwencją wyceny jest to, że struktura rozliczania powinna odzwierciedlać przegląd, a nie tylko generację. Klient nie płaci mi za sto wersji roboczych generowanych przez sztuczną inteligencję tygodniowo; płacą za dwudziestkę, która przeszła przez moją recenzję, i skupienie się wokół tej dwudziestki – najsilniejszej, najbardziej ryzykownej, która odpowiada na konkretną kwestię, nad którą muszą się zastanawiać w tym miesiącu. Maszyna mogła wyprodukować tysiąc; moja rola polega na skompresowaniu tego do niewielkiej liczby niosącej użyteczny sygnał, a wycena uwzględnia, że warto płacić za kompresję.
To zmienia argument, który regularnie pojawia się w doradztwie dotyczącym sztucznej inteligencji: „czy sztuczna inteligencja nie wykonuje większości pracy?” Nie, nie ta część, za którą warto płacić. Sztuczna inteligencja wykonuje większość pracy mechanicznej — produkcję masową, wstępne wersje robocze, pobieranie i przekształcanie. Cenna praca — decydowanie, które wyniki zostaną przesłane, dopasowywanie wyników do kontekstu, wyłapywanie subtelnych błędów, które wprawiłyby klienta w zakłopotanie — pozostaje pracą ludzką i to jest część, którą klient płaci za to, aby dobrze ją wykonać. Kiedy praktycy zaniżają cenę swojej pracy, zakładając, że większość pracy wykonuje sztuczna inteligencja, wyceniają część mechaniczną, a połowę oddają osądy za darmo.
Z tego schematu wynika schemat dostarczania. Zamiast pokazywać klientom wszystko, co wyprodukowała maszyna, pokazuję im, co wybrałem z tego, co wyprodukowała maszyna – z krótkimi notatkami dlaczego. Format prezentacji opowiada tę historię: „maszyna wygenerowała sto wariantów; oto siedem, które polecam na ten miesiąc, uszeregowane, z akapitem na temat uzasadnienia każdego z nich”. Klient od razu widzi wartość recenzji. Oni nie patrzą na wysypisko; patrzą na ocenę dotyczącą objętości, która jest zasadniczo innym produktem.
Konsekwencją, której przyswojenie sobie zajęło mi najwięcej czasu, jest to, że takie ramy chronią ekonomiczną opłacalność zaangażowania. Jeśli klient zacznie postrzegać sztuczną inteligencję jako produkt, w końcu zapyta, dlaczego mnie potrzebuje — sztuczna inteligencja jest tam, generuje wyniki, może po prostu uruchomić ją samodzielnie. Jeśli recenzja jest produktem, sztuczna inteligencja jest narzędziem, którego używam, aby skuteczniej pracować nad recenzją; zaangażowanie opiera się na moim osądzie, wzmocnionym przez maszyny, a nie na samej maszynie. Pierwszy argument to ten, który ostatecznie przegrywasz; ten ostatni jest stabilny.
Wyceniaj recenzję, a nie generację. Dostarczaj wyselekcjonowane selekcje, a nie zrzuty. Skonstruuj zaangażowanie wokół osądu wspomaganego przez maszyny, a nie maszyny, które sprawiają, że osądy stają się przestarzałe. To jest moment rozliczeniowy; to jest trwałe zaręczyny.
No figure. This chapter is an argument about framing rather than structure; the shape it belongs to is Fig 14.1's stream, seen from the client's side — everything downstream of "produced" is where the human review lives, and it's that human bar that the client is paying for.
Chapter 55
Konwersja PoC
Weryfikacja koncepcji została ukończona, przebiegła pomyślnie, a teraz pojawia się pytanie, czy zaręczyny przeciągną się na dłużej. Ten rozdział dotyczy konwersji — specyficznej mechaniki przekształcania udanego PoC w trwałą relację — ponieważ pozostawienie tego przejścia przypadkowi powoduje, że wiele dobrych PoC kończy się, nie stając się niczym więcej.
Moment zakończenia PoC to moment, w którym rozpoczyna się rozmowa o tym, „co dalej” musi się wydarzyć, w przeciwnym razie to się nie stanie. Jeśli między dostawą PoC a zaproponowaniem kolejnego kroku upłynie kilka tygodni, energia opadnie, uwagę klienta przyciągną inne priorytety, a rozmowa o przedłużeniu stanie się czymś, co obie strony muszą na nowo rozpalić z zimna. Moją zasadą jest teraz rozpoczynanie rozmowy na temat kolejnego kroku, zanim wylądują ostateczne produkty PoC — podczas przeglądu ostatniego artefaktu, a nie po nim — tak aby dynamika płynąca z przeglądu przeniosła się bezpośrednio na planowanie tego, co będzie dalej.
Kształt propozycji konwersji ma znaczenie i nauczyłem się, że specyfika przewyższa opcjonalność. Zamiast przedstawiać menu możliwych kolejnych zleceń i prosić klienta o wybór, polecam konkretny następny krok – jeden kształt, jedną cenę, jeden czas trwania – i pozwalam mu zaakceptować, odrzucić lub przeciwstawić się. Menu powoduje paraliż decyzyjny; konkretne zalecenie tworzy konkretną decyzję, a konkretne decyzje to te, które faktycznie zostają podjęte. Jeśli będą chcieli innego kształtu, powiedzą mi, a teraz negocjujemy konkretną alternatywę, zamiast przyglądać się opcjom.
To, jaki powinien być konkretny następny krok, zależy od wyniku PoC, ale obowiązuje heurystyka: następny krok powinien odnosić się do naturalnego pytania, które właśnie podniósł PoC. Jeśli PoC udowodni, że kształt działa, następnym krokiem jest przekształcenie go w coś, na czym klient może naprawdę polegać. Jeśli PoC okazał się rynkiem dla możliwości, następnym krokiem jest zbudowanie możliwości na dużą skalę. Jeśli PoC podniósł nowe pytanie, którego wcześniej nie miał klient, następnym krokiem może być drugie PoC dotyczące tego nowego pytania. W każdym przypadku następnym krokiem jest konkretne rozszerzenie tego, co właśnie odkrył PoC, a nie ogólne „kontynuowanie współpracy”.
Rozmowa o cenie konwersji różni się od wyceny PoC (rozdział 34), ponieważ PoC wykonał większość pracy związanej z budowaniem zaufania. Klient wie, jak teraz pracuję; Wiem, jak wygląda ich środowisko; obie strony mają realne dowody na to, czy warto kontynuować zaangażowanie. Ceny za bieżące zaangażowanie mogą i powinny być proporcjonalne do rzeczywistej wartości, a nie ceny filtrowanej, jak miało to miejsce w przypadku PoC. Zbyt niskie obciążenie przy konwersji jest częstym błędem — praktycy są tak wdzięczni, że klient chce kontynuować, że ustalają niską stałą stawkę. PoC był filtrem; konwersja polega na tym, że zarabiasz uczciwą, profesjonalną stawkę.
Warto wymienić scenariusz, czyli PoC, który nie poszedł dobrze. Czasami dowód koncepcji dowodzi, że koncepcja nie działa, że kształt wymaga zasadniczej zmiany lub że rzeczywisty problem klienta różni się od tego, co opisał. W każdym przypadku uczciwym posunięciem jest powiedzenie tego i zaproponowanie zmiany kierunku następnego kroku lub rozstanie się z wdziękiem. Wypracowanie konwersji z nieudanego PoC to początek złych, długoterminowych relacji; Porażka z wdziękiem to sposób, w jaki zostajesz skierowany do klienta, który lepiej pasuje.
Otwórz rozmowę dotyczącą następnego kroku, gdy trwa dynamika. Zaproponuj konkretny kształt, a nie menu. Wyceniaj rozszerzenie ze względu na wartość, a nie jako filtr. A jeśli PoC nie doczeka się przedłużenia, powiedz to szczerze. Nawrócenie to moment, który albo ląduje, albo się rozprasza; traktuj to jako pierwszorzędny produkt samego PoC.
No figure. The conversion is a conversation, not a structure; the visual that captures it is the trust ladder in Fig 57.1, where the conversion is the step from "delivered a PoC" to "on the roster" — the specific rung that this chapter is entirely about.
Chapter 56
Specyfikacja pierwszych 30 dni
Każde trwające zaangażowanie zaczyna się od pierwszych trzydziestu dni, a prawidłowe wykorzystanie tych trzydziestu dni wyznacza kształt wszystkiego, co następuje. Na tę fazę piszę specjalny dokument — specyfikację na pierwsze 30 dni — ponieważ niejednoznaczność w miesiącu otwarcia bardzo szybko staje się bardzo kosztowna, a pisemna specyfikacja to najtańszy sposób na przekształcenie tej niejednoznaczności w uzgodnione decyzje.
Specyfikacja pierwszych 30 dni odpowiada na mały, celowy zestaw pytań. Jaki wynik chcemy osiągnąć w tym pierwszym miesiącu? Jaki produkt będzie dostępny trzydziestego dnia, czego nie było pierwszego dnia? Kto ze strony klienta jest pojedynczym punktem kontaktowym? Jaka jest częstotliwość aktualizacji i recenzji? Jaki jest budżet na ten etap, zarówno pod względem finansowym, jak i godzinowym? Co stanie się trzydziestego dnia – czy planowana jest kontynuacja, przegląd, naturalny koniec?
Powodem, dla którego nalegam, aby zapisać to zwykłymi zdaniami, a nie szablonem planu projektu, jest to, że słowa pisane są artefaktem, na który obie strony mogą wskazać, gdy pojawi się nieporozumienie. Ustne ustalenia dotyczące zakresu są błędnie zapamiętywane w ciągu kilku tygodni nie dlatego, że którakolwiek ze stron jest nieuczciwa, ale dlatego, że ludzka pamięć rekonstruuje rozmowy w różny sposób dla różnych potrzeb. Pisemna specyfikacja usuwa tę rekonstrukcję — albo mówi X, albo nie, a obie strony patrzą na te same dowody.
Klauzula dotycząca pojedynczego punktu kontaktowego zasługuje na własną obronę, ponieważ, jak się przekonałem, ma ona największe znaczenie. Kiedy w przypadku klienta zaangażowanego jest trzech lub czterech interesariuszy, którzy mogą kierować moją pracą, priorytety stają się niespójne — jedna osoba mówi mi, że priorytetem jest X, inna twierdzi, że Y, trzecia ciągnie mnie do Z — i w rezultacie ponoszę koszty koordynacji rozwiązywania sprzeczności, które istnieją tylko dlatego, że klient nie rozwiązał ich wewnętrznie. Pojedynczy punkt kontaktowy rozwiązuje problem u źródła: oni mają priorytet, rozwiązują wewnętrzne spory, a ja mam jeden spójny głos, przeciwko któremu mogę pracować. To nie jest ruch kontrolny; to kierownictwo projektu klienta przybywa na czas.
Pytanie trzydziestego dnia to element, który praktycy najczęściej pomijają i przy którym teraz nalegam. Co dzieje się pod koniec pierwszych trzydziestu dni? Idealnie byłoby, gdyby odbyło się konkretne spotkanie przeglądowe, podczas którego obie strony porównają to, co zostało osiągnięte w porównaniu z obiecanymi, i wspólnie zdecydują, czy kontynuować, dostosować, czy zakończyć. Bez zaplanowanego z góry spotkania zaręczyny przechodzą w drugi miesiąc w wyniku bezwładności, a bezwładność nie jest tym samym, co świadoma kontynuacja. Rezerwacja przeglądu trzydziestego dnia w ramach wstępnej specyfikacji wymusza celową odprawę, która gwarantuje uczciwość zaręczyn.
Specyfikacja wyraźnie określa również, co będzie poza zakresem przez te trzydzieści dni. Nie wszystko, czego może chcieć klient; a nie ambitny plan działania na przyszłość; po prostu konkretny wynik, do którego przeznaczony jest ten miesiąc. Elementy wykraczające poza zakres są zgłaszane jako kandydaci do przyszłych faz i wszyscy wiedzą, że nie są częścią tego, co obecnie budujemy. Jest to antidotum na dryfowanie zakresu, które szczegółowo omówimy w rozdziale 58 — nie zapobiega dryfowi, ale sprawia, że dryf jest widoczny i możliwy do negocjacji, a nie cichy i jednostronny.
Zapisz to. Odpowiedz na niewielki zestaw szczegółowych pytań. Nazwij punkt kontaktowy. Zarezerwuj recenzję dnia trzydziestego. Powiedz, co jest poza zakresem. Dobrze zaplanowane trzydzieści dni zwykle daje miesiące drugi i trzeci, które warto mieć.
Fig 56.1 — The Six Questions. The focal spec is a one-page document answering six specific questions. Verbal agreements decay; written ones are what both sides can point to when a misunderstanding arrives, which it will.
Chapter 57
Drabina zaufania
Zaufanie w relacji z klientem nie jest pojedynczym stanem – to drabina o odrębnych szczeblach, a miejsce, w którym klient siedzi na tej drabinie, determinuje to, na co się zgodzi, a przed czym się wzdrygnie. Zrozumienie szczebli i celowe wspinanie się po nich, zamiast zakładać, że zaufanie istnieje, gdy go nie ma, sprawia, że jednorazowe zaangażowanie staje się trwałe.
Dolny szczebel jest obcy. Klient słyszał o Tobie, być może widział Twoje prace i zastanawia się, czy przeprowadzić pierwszą rozmowę. Oceniają, czy jesteś wystarczająco kompetentny, aby być wartym ich czasu. Na tym szczeblu jesteś kandydatem, a nie partnerem. To, co mówisz, ma mniejsze znaczenie niż to, co demonstrujesz – portfolio, studium przypadku, konkretny przykład odnoszący się do problemu. Zaufanie na tym poziomie buduje się na podstawie dowodów, a nie stwierdzeń.
Następny szczebel to kupujący PoC. Zdecydowali się kupić mały, zawierający dowód koncepcji. Teraz oceniają nie tylko kompetencje, ale styl pracy, komunikację, czy partnerstwo będzie wygodne. Ten szczebel testuje szczególnie niezawodność na małą skalę — czy dostarczasz to, co powiedziałeś, kiedy powiedziałeś, w takiej formie, jaką powiedziałeś. Każda dotrzymana mała obietnica podnosi ich w górę; każde małe złamanie obietnicy przesuwa je w dół, szybciej, niż sugerowałby rozmiar obietnicy.
Szczebel powyżej to członek składu. PoC uległ konwersji; masz miesięczne wynagrodzenie stałe lub stałą umowę. Teraz oceniają nie tylko niezawodność, ale także osąd — czy wychwytujesz rzeczy, które przeoczyli, czy kierujesz pracą w kierunkach, o których by nie pomyśleli, czy ułatwiasz im życie w sposób, którego nie potrafią wyrazić, ale mogą poczuć. Ten szczebel sprawdza wartość wykraczającą poza wykonanie, a to klienci na tym szczeblu to klienci, u których zaangażowanie ma charakter strategiczny, a nie transakcyjny.
Najwyższy szczebel to zaufany doradca. Relacja przekroczyła próg, w którym klient pyta Cię o problemy wykraczające poza ścisły zakres zlecenia, ponieważ sam Twój osąd stał się częścią tego, co kupuje. Na tym szczeblu nie tylko dostarczasz to, do dostarczenia czego zostałeś zatrudniony; jesteś głosem, z którym konsultują się w sprawie decyzji sąsiadujących, czasami decyzji znacznie wykraczających poza twoją pierwotną domenę. Status zaufanego doradcy zdobywa się latami, a można go stracić w jedno popołudnie, udzielając porad, które okażą się błędne w temacie, w którym nie powinieneś się wypowiadać.
Najczęstszym błędem, jaki widzę, jest traktowanie klienta znajdującego się wyżej w hierarchii niż w rzeczywistości i bycie zaskoczonym, gdy zachowuje się inaczej. Kupujący PoC nie zaakceptuje strategicznej rekomendacji tak, jak zrobiłby to zaufany doradca; usłyszą to jako pełzanie zasięgu lub arogancję. Członek zespołu nie podpisze nowego dużego zobowiązania przez telefon, tak jak zrobiłby to zaufany doradca. Każdy szczebel ma swój pułap, na który zgodzi się klient, a przekroczenie tego pułapu przed zdobyciem szczebla szkodzi całej relacji. Prawidłowo odczytaj szczebel i odpowiednio skalibruj.
Istnieje błąd odwrotny, polegający na niedostatecznym traktowaniu zaufanego doradcy jako zwykłego członka personelu. Kiedy klient faktycznie osiągnie najwyższy szczebel, traktowanie go jak pracę, którą obsługujesz, a nie relację, którą kierujesz, wydaje się lekceważące i stopniowo się wycofuje. Rozpoznanie, kiedy związek się poprawił, jest równie ważne, jak rozpoznanie, kiedy nie.
Dowiedz się, na którym szczeblu znajduje się klient. Przesuń się celowo w górę. Nie przesadzaj; nie lekceważ. Zaufanie zdobywa się w określonych krokach, a traci w nieokreślonych.
Fig 57.1 — The Trust Ladder. Four rungs, each with its own ceiling on what a client will say yes to. The focal top rung is the one that produces the durable engagements — and the one most often forfeited by overreaching from a lower rung.
Chapter 58
Dryf zakresu
Każde zaangażowanie będzie dryfować, a dryf nie jest problemem; jest niepotwierdzony dryf. Dryfowanie zakresu to powolne, kumulatywne odchodzenie prac od pierwotnie uzgodnionych i zdarza się w każdym prawdziwym projekcie, ponieważ rzeczywistość nie przestrzega początkowej specyfikacji. Dyscyplina nie polega na zapobieganiu dryfowaniu – to daremne – ale na uwidocznieniu go i negocjowaniu na bieżąco.
Mechanizm dryfu jest niewielki i stopniowy. W środowej rozmowie klient wspomina „och, czy moglibyśmy też…”, a ja odpowiadam, że tak, a dodanie to wydaje się banalne w kontekście. Za tydzień kolejny mały dodatek. Tydzień później jeszcze jeden. Indywidualnie żaden z nich nie zasługuje na rozmowę dotyczącą zakresu. Łącznie składają się one na znaczną zmianę kształtu tego, co zapewnia zaangażowanie, i zanim całość stanie się widoczna, obie strony po cichu zgodziły się na inny projekt, nigdy nie wymieniając nazwy zmiany.
Trybem niepowodzenia nie jest samo dryfowanie – chodzi o to, że obie strony zapominają o pierwotnym zakresie. Brałem udział w spotkaniach, podczas których po czterech miesiącach klient zapytał, kiedy mamy zamiar dostarczyć coś, co było w pierwotnej specyfikacji, i zdałem sobie sprawę, że oboje pozwoliliśmy, aby dryfujące dodatki wypchnęły to z planu, nie przyznając się do tego, że coś się zmieniło. Nikt nie był zdenerwowany, ale nikt też nie wyraził się jasno, a dwuznaczność pochłonęła tydzień ponownego ustawienia, którego nie powinniśmy byli spędzać. Nienazwany dryf stał się długiem, który trzeba było spłacić dokładnie w niewłaściwym momencie.
Dyscyplina, która rozwiązuje ten problem, jest niewielka i tania: za każdym razem, gdy pojawia się pytanie „och, czy my też moglibyśmy”, nazywam to zmianą zakresu, na miejscu, w tej chwili. Nie jako sprzeciw – jako potwierdzenie faktu. „Tak, możemy to dodać; odnotowując to jako zmianę planu, co oznacza, że X i Y z oryginału staną się tygodniem piątym, a nie trzecim”. Dodatek jest mile widziany; nazewnictwo sprawia, że obie strony mają ten sam obraz tego, co jest dostarczane. Kiedy rozmowa na temat zakresu stanie się pięciosekundowym nawykiem, przestaje być niezręczna i staje się częścią działania zaangażowania.
W przypadku zaangażowania w sztuczną inteligencję istnieje specyficzna pułapka, której tradycyjne doradztwo nie jest tak wyraźne. Ponieważ prace natywne w oparciu o sztuczną inteligencję mogą tanio generować nowe możliwości, klienci często dodają funkcje, zakładając, że „sztuczna inteligencja po prostu może to zrobić”. Czasami mają rację, a dodatek jest naprawdę trywialny. Czasami się mylą i uzupełnienie wymaga nowej, znaczącej instalacji wodno-kanalizacyjnej. Klient nie widzi różnicy z zewnątrz, więc moim zadaniem jest ujednoznacznić — powiedzieć szczerze, czy zapytanie jest trywialne, umiarkowane czy istotne, a następnie odpowiednio wycenić i zaplanować. Zaniżanie opłat za żądania „tylko dodaj”, ponieważ wydawały się małe, to jeden z najczęstszych sposobów utraty marży w pracy ze sztuczną inteligencją.
Wniosek jest taki, że nie każdy dryf jest zły. Pewnym dryfem jest dostosowanie zaangażowania do tego, czego klient faktycznie potrzebuje, a nie do tego, czego myślał, że potrzebuje na początku. Rezygnacja z dryfowania w ogóle — trzymanie się sztywno początkowej specyfikacji — to sposób na dostarczenie dokładnie tego, czego nie chcesz, dokładnie zgodnie z harmonogramem. Celem nie jest zastój; to wynegocjowana ewolucja. Potwierdzenie, cena, zmiana terminu; następnie dostosuj się.
Nazwij każdy dryf w chwili, gdy się pojawi. Wyceń to uczciwie. Renegocjuj plan. Dostosuj się świadomie. Cichy dryf jest trybem awaryjnym; celowe dryfowanie oznacza, że zaangażowanie spełnia swoje zadanie.
No figure. Drift is a temporal phenomenon best captured in the specific accounting of what changed each week, which is a table rather than a diagram; the discipline it names — acknowledge the moment it arrives — doesn't get sharper from being drawn.
Chapter 59
Test „Jeszcze jedna rzecz”.
Na zakończenie każdej rozmowy z klientem przeprowadzam mały test, który pozwala zaoszczędzić więcej czasu na rozmowę niż jakakolwiek inna większa dyscyplina opisana w tej książce. Nazywam to testem jeszcze jednej rzeczy: zanim się rozłączymy, pytam głośno: „Czy masz na myśli coś jeszcze, czego nie poruszyliśmy?” Pytanie jest banalne. Odpowiedzi, zebrane na przestrzeni lat, ukształtowały mój skład bardziej niż jakikolwiek strategiczny ruch, jaki podjąłem.
Pytanie to ma znaczenie dlatego, że klienci często mają wątpliwości, których nie planowali zgłaszać. Coś ich dręczy od początku tygodnia. Komentarz kolegi, który utknął. Lekka obawa co do kierunku pracy. Żaden z nich nie jest wystarczająco duży, aby wywołać go bez podpowiedzi — mieliby ochotę dokuczać lub przesadzać. Jednak biorąc pod uwagę konkretne otwarcie, większość klientów nada im nazwę, a gdy już zostaną nazwane, można się nimi zająć, gdy są małe, a nie wtedy, gdy urosną do prawdziwego problemu.
Niepowodzenie braku pytania polega na tym, że te niewyjaśnione obawy się kumulują. Małe lęki stają się większymi. Niewypowiedziane zmartwienia stają się po cichu postrzępionymi związkami. W końcu klient albo porusza tę kwestię, gdy wyrósł na coś wymagającego trudnej rozmowy, albo – co gorsza – po cichu się rozłącza, ponieważ nie czuł się słyszany w mniejszych sprawach. Obu rezultatów można uniknąć, a uniknięcie to jedno trzydziestosekundowe pytanie na koniec spotkania.
To, czego nauczyłem się robić z odpowiedziami, jest równie ważne jak pytanie. Kiedy coś wychodzi na jaw, traktuję to poważnie podczas tego spotkania, bez odkładania na później ani minimalizowania. Nawet jeśli problem jest niewielki, zajęcie się nim od razu sygnalizuje, że drobne uwagi klienta są warte uwagi – co zwiększa prawdopodobieństwo, że zgłosi następny, czyli tę pętlę, której chcę. Alternatywa — „zostawmy to i porozmawiajmy o tym następnym razem” — uczy klientów, że nie warto zgłaszać drobnych wątpliwości, więc przestaję słyszeć o problemach, gdy są jeszcze małe.
Test jest przydatny także w drugą stronę, jako dyscyplina dla mnie. Przed zakończeniem spotkania zadaję sobie pytanie – po cichu – czy jest coś, co ukrywam? Coś, co zauważyłem w tym tygodniu, o czym postanowiłem nie wspominać. Coś, co kolega powiedział na temat pracy klienta, a o czym czułem się niezręcznie. Ta sama zasada: taniej jest podnieść tę kwestię teraz, niż przerodzić się w późniejszą rozmowę. Test „jeszcze jednej rzeczy” przebiega w obie strony.
Wiąże się z tym większy sens filozoficzny, a mianowicie fakt, że tryb konserwacji jest kłamstwem, które klienci rozpoznają. Rozmowy w stylu „po prostu robimy to, co do nas należy”, bez okresowych okazji do nazwania obaw obu stron, po cichu gniją, ponieważ rzeczywistość ciągle się zmienia, a przestrzeń do uznania tych zmian została zamknięta. Pytanie składające się z jeszcze jednej rzeczy to niewielki akt strukturalny mający na celu utrzymanie otwartej przestrzeni, spotkanie za spotkaniem, bez konieczności przeprowadzania specjalnej retrospektywy lub formalnego przeglądu w celu uzasadnienia tego.
Pytaj na każdym spotkaniu, czy jest coś jeszcze. Zajmij się tym, co pojawia się w danej chwili. Wykonaj tę samą samokontrolę po swojej stronie. Dzięki konsekwentnie utrzymywanym drobnym otwarciom relacje pozostają uczciwe – a uczciwe relacje to te, które przetrwają dryf, niespodziewany rachunek, niezręczną recenzję trzydziestego dnia i wszystko inne, co w przeciwnym razie mogłoby je zniszczyć.
No figure. This chapter is a habit, not a structure — the visible ritual is a single question at the end of each meeting, which resists diagramming and gains nothing from the attempt.
Chapter 60
Klienci referencyjni
Część VI kończy się na konkretnym atucie, który zmienia kompetentną praktykę w samonapędzającą się: klienci referencyjni. Są to klienci, których kontakty przebiegły na tyle dobrze, a których relacje ze mną są na tyle silne, że będą aktywnie polecać nowych potencjalnych klientów, przyjmować telefony referencyjne i pozwolić, aby ich historia stała się częścią mojej rozmowy sprzedażowej. Budowanie bazy klientów referencyjnych nie jest przyjemnością — to infrastruktura marketingowa, dzięki której wszystko inne przestaje być zimną wyprzedażą.
Mechanizm, dzięki któremu liczą się klienci referencyjni, jest złożony. Nowi potencjalni klienci dowiadują się o mnie dzięki ciepłemu przedstawieniu przez istniejącego klienta. Dochodzą do odkrycia już ufając zarysowi tego, co robię, ponieważ powiedział im to ktoś, komu ufają. Współczynniki konwersji u potencjalnych klientów, którzy otrzymali ciepłe polecenia, są znacznie wyższe niż w przypadku zimnych klientów, a relacje są zdrowsze, ponieważ obie strony zaczynają wyżej po drabinie zaufania z rozdziału 57. Każdy klient referencyjny to kapitał złożony, generujący więcej klientów, których zaangażowanie ma większe szanse powodzenia.
To, co sprawia, że klient jest klientem referencyjnym, nie jest wynikiem jednego zaangażowania – jest to ogólny kształt relacji. Klienci referencyjni mają zwykle trzy cechy: zaręczyny rozwiązały dla nich prawdziwy problem i mogą to konkretnie powiedzieć, relacja w pracy była na tyle przyjemna, że dobrowolnie zrobiliby to ponownie, a ja utrzymuję kontakt od zakończenia narzeczeństwa (lub w jego trakcie), więc nie proszę o przysługę kogoś, kto zapomniał o moim istnieniu. Dowolny z trzech bez pozostałych daje słabsze odniesienie.
Wynikający z tego element działania jest taki, że rozwój klienta referencyjnego jest nawykiem, a nie planem. Utrzymywanie kontaktu oznacza okazjonalne meldowanie się — a nie namawianie do sprzedaży, autentyczne wiadomości typu „jak leci, myślę, że może Cię to zainteresować” rozmieszczone na tyle daleko od siebie, że sprawiają wrażenie rozważenia, a nie pościgu. W większości przypadków raz na kwartał jest w zupełności odpowiedni; częściej ma wrażenie pingowania konserwacyjnego, rzadziej ma wrażenie zniknięcia. Chodzi o to, że kiedy przychodzi telefon referencyjny od potencjalnego klienta, klient jest na tyle życzliwy, aby go przyjąć i ma wystarczającą wiedzę na temat mojej obecnej pracy, aby wypowiadać się na ten temat rzetelnie.
Tryb niepowodzenia polega na traktowaniu referencji jako relacji jednokierunkowej — proszeniu o nie bez dawania czegokolwiek w zamian. Rozmowy referencyjne zajmują czas klienta. Ciepłe wprowadzenie spala niewielką część kapitału społecznego klienta wraz z potencjalnym klientem. Upewnienie się, że wymiana jest rzeczywiście dwustronna — że wysyłam im polecenia, kiedy tylko mogę, udostępniam im odpowiednie materiały i jestem dla nich przydatny w sposób, który nie jest związany z moją własną działalnością — jest tym, co utrzymuje zdrową relację referencyjną przez lata. Ekstrakcyjne wydobycie referencyjne szybko wyczerpuje ławkę; związki budujące wzajemne odniesienia.
Warto wymienić konkretny ruch, czyli pełne wdzięku pytanie. Kiedy pojawia się potencjalny klient, z którym chciałbym przeprowadzić rozmowę referencyjną z istniejącym klientem, najpierw pytam go otwarcie, czy byłby skłonny podjąć konkretną rozmowę z konkretnego powodu. Nie jest to ogólne pytanie „czy byłbyś ogólnie punktem odniesienia” – łatwiej odmówić i tworzy zobowiązanie w tle. Konkretne zapytanie z konkretną okazją szanuje czas klienta i pozwala mu otwarcie powiedzieć „nie”, jeśli jest to nieodpowiedni moment. Większość twierdzi, że tak; tym, którym nie jest ciepło, bo nie przesadziłem.
Rozwiązuj prawdziwe problemy. Spraw, aby związek był przyjemny. Kontaktować się. Odwzajemnij wartość. Zapytaj grzecznie. Kilkunastu prawdziwych klientów referencyjnych to silnik marketingowy, którego nie musisz utrzymywać, ponieważ oni go utrzymują za Ciebie – jedno ciepłe wprowadzenie na raz.
No figure. Reference relationships are network effects that build over years, and any static diagram of them would only misrepresent the shape by making it look neat. The pattern is time-based and social; the honest illustration is the composite trust ladder in Fig 57.1, applied across a bench of clients.
Part VII
Historie wojenne
Konkretne zdarzenia, które nauczyły mnie rzeczy, których nie nauczyłbym się w żaden inny sposób — skrobak, któremu odmówiłem, klif rozliczeniowy, na który wpadłem przez tydzień, demonstracja, która uratowała transakcję, oraz klient, któremu odmówiłem. Nie o historie tu chodzi; lekcje pod nimi są.
Chapter 61
Skrobak, któremu odmówiłem
Klient był poważny, budżet realny, prace techniczne proste. Przeszukaj dużą witrynę strony trzeciej, przepuść jej zawartość przez model i opublikuj przetworzone wersje na swojej platformie. Na papierze było to dwutygodniowe zaręczyny za rozsądne wynagrodzenie. Odpowiedziałem, że nie, i była to jedna z lepszych decyzji biznesowych, jakie podjąłem, i chcę poświęcić rozdział na wyjaśnienie dlaczego, ponieważ uzasadnienie jest ważniejsze niż wynik.
Problem nie był techniczny. Budowa zgarniacza zajęłaby jedno popołudnie. Integracja modelu była rutynowa. Strona wydawnicza była standardowa. Nic w mechanice nie było trudne i gdyby mechanika obejmowała cały obraz, zgodziłbym się i otrzymałem ładną fakturę do wysłania w ciągu dwóch tygodni. Jedyne, czego nie mogłem ominąć, to warunki świadczenia usług — zarówno źródła, jak i dostawcy modelu — które cały układ musiał naruszać, aby działał.
Warunki korzystania z witryny źródłowej wyraźnie zabraniają automatycznego pobierania i ponownego publikowania. Warunki świadczenia usług dostawcy modelu niechętnie patrzą na przesyłanie zeskrobanych i ponownie opublikowanych treści stron trzecich za pośrednictwem interfejsu API. Żadne z nich nie było dwuznaczne. Obie klauzule można przeglądać bezpośrednio na stronie dostawcy i mimo wszystko przekonać się, że nie będą miały zastosowania w Twoim konkretnym przypadku — ponieważ egzekwowanie prawa jest opóźnione, promień wybuchu jest z dnia na dzień mały, a inni ludzie robią podobne rzeczy bez widocznej kary.
Warto przytoczyć rozumowanie, które przeszło mi przez myśl, ponieważ jest to to samo rozumowanie, które teraz stosuję w przypadku każdego zaangażowania na granicy. Plusem były dwa tygodnie opłat, zadowolony klient i case study, na które mogłem wskazać. Minusem, gdyby doszło do egzekucji, było zamknięcie konta modelowego – czyli tego samego konta, na którym polega każdy inny mój klient. Moje osobiste ryzyko było proporcjonalne do zaangażowania; moje ryzyko zawodowe było proporcjonalne do całego mojego biznesu, ponieważ ukarany majątek byłby tym, na którym polegał każdy klient. Asymetryczna alokacja ryzyka.
Kiedy odpowiedziałem „nie”, klient był zaskoczony, potem zaciekawiony, a w końcu pełen szacunku. Zapytali, czy mógłbym polecić kogoś innego, a ja odpowiedziałem, że nie – ponieważ ktokolwiek podejmie tę pracę, ostatecznie zapłaci te same koszty, tylko z innego konta. Mimo to znaleźli kogoś; że ktoś inny obsługiwał umowę przez około osiem miesięcy przed zamknięciem jego rachunku u dostawcy modelu, w związku z czym klient musiał w krótkim czasie zakończyć ośmiomiesięczną operację. W międzyczasie moje konto dostawcy pozostało otwarte, a inni moi klienci nie doświadczyli przestojów spowodowanych niepowiązanym zaangażowaniem.
Lekcja nie jest taka, że dokumenty ToS są zawsze święte; chodzi o to, że alokacja ryzyka w przypadku zaangażowania granicznego jest asymetryczna w sposób łatwy do błędnego odczytania. Mała zaleta, duża opóźniona wada, wada dotyczy zasobu, na którym polegają wszyscy moi klienci. Każde zaangażowanie w ten kształt jest złym interesem, nawet jeśli określone prawdopodobieństwo wyegzekwowania jest niskie. Teraz bez długiego namysłu odrzucam wszystko, co ma taki kształt — odpowiedź brzmi: nie, a szczera rozmowa jest krótka i obie strony szybko idą dalej.
Powiedz nie wcześniej. Powiedz wyraźnie nie. Nie polecaj tej pracy nikomu innemu. Zaręczyny, których odmówiłeś, to konto, które prowadziłeś, a konto jest warte znacznie więcej niż jakakolwiek pojedyncza opłata.
No figure. This chapter is a story about a decision and its consequences over time; the reasoning is drawn already in Chapter 32's argument, and the specific decision doesn't earn a diagram of its own.
Chapter 62
Billing Cliff, który złapałem przez tydzień
Zauważyłem, że na tydzień przed zmianą rozliczeń moje koszty wzrosłyby o około czterdzieści procent w przypadku bezgłowej części floty. Nie chcę tego przeceniać – nie przeżyłem heroicznego momentu wglądu; Miałem nudne miesięczne rozliczenie i akapit w informacjach o wydaniu dostawcy, którego większość moich rówieśników najwyraźniej nie czytała. Tydzień ostrzeżenia miał znaczenie, ponieważ wystarczył na renegocjację; dzień nie jest; a dowiadywanie się na podstawie faktury to dowiadywanie się o tym za późno, aby cokolwiek z tym zrobić.
Tym, co zapoczątkowało połów, był rytuał z rozdziału 40 — rozliczenie na koniec miesiąca, które w ciągu poprzedniego roku nauczyło mnie, jak „normalnie” wygląda faktura każdego dostawcy. Kiedy w ten poniedziałek usiadłem, aby uzgodnić poprzedni miesiąc, liczby się zgadzały, ale informacje o wydaniu na nadchodzący miesiąc zawierały zmianę w strukturze liczników, która po cichu przekształciłaby moje koszty. Nie jest to nagłówek ogłoszenia „podnosimy ceny”; techniczne wyjaśnienie sposobu pomiaru określonej puli, zawarte w akapicie, który większość ludzi przeoczyła. Napisano, że zmiana nie jest alarmująca i gdybym nie czytał uważnie z miejsca pojednania, też bym ją przeleciał.
Następny tydzień był pożyteczną częścią. Ponieważ wcześnie to wyłapałem, mogłem spokojnie przemyśleć odpowiedź. Czy zmiana wpłynie w równym stopniu na wszystkich moich klientów, czy tylko na niektórych? Jaki był całkowity wpływ na moją prognozę? Czy warto było docierać do klientów, absorbować, a może restrukturyzować? O których klientach trzeba było powiedzieć natychmiast, a o których można było poczekać do kolejnej zaplanowanej kontroli? Podejmowałem decyzje z czasem do namysłu i okazały się one istotnie lepsze od tych, które podjąłbym pod presją szoku fakturowego w następnym miesiącu.
Konkretnym posunięciem taktycznym, które wykonałem, było przeniesienie niektórych przepływów pracy, których to dotyczyło, do innej puli, której zmiana nie dotknęła, co złagodziło większość skutków. Nie mogłem tego zrobić w momencie wystawienia faktury, ponieważ do tego czasu wzorce uruchamiania były już ustalone, a konfiguracja puli alternatywnej zajęłaby trochę czasu. Dzięki ostrzeżeniu z wyprzedzeniem dostałem możliwość restrukturyzacji, która zamieniła czterdziestoprocentowe trafienie w coś bliższego pięcioprocentowemu trafieniu. Te pięć procent, które wchłonąłem; nikomu nie trzeba było mówić niczego trudnego.
Lekcja nie jest taka, że informacje o wydaniu są ważne, chociaż są. Lekcja jest taka, że dyscyplina miesięcznego uzgadniania nie polega tylko na dopasowywaniu liczb — ale na budowaniu modelu mentalnego dostawcy, który umożliwia wyłapanie subtelnych zmian. Praktycy, którzy nie potrafią się pogodzić, nie potrafią rozróżnić między „liczbami przesuniętymi w wyniku zmiany zużycia” a „liczbami przesuniętymi w wyniku przesunięcia licznika” i ta niemożność sprawia, że każda zmiana ceny jest niespodzianką. Pojednanie buduje intuicję; intuicja wychwytuje zmiany; połowy kupują czas na reakcję.
Z tego wynika szersza lekcja na temat czujności, którą chcę jasno przedstawić. W tej branży grunt pod tobą naprawdę się porusza, a ten ruch jest często komunikowany w sposób zakładający, że zwracasz na niego szczególną uwagę. Jeśli nie będziesz zwracać szczególnej uwagi, przekonasz się o ruchu na własnej skórze. Ludzie, którzy nie zwracają szczególnej uwagi, nie są leniwi — nadają priorytet innym rzeczom — ale kosztem takiego ustalania priorytetów jest to, że zły kwartał pojawia się bez ostrzeżenia i zanim zorientujesz się, przestrzeń do zareagowania się zamyka.
Przeczytaj informacje o wydaniu. Dokonaj pojednania. Zbuduj intuicję. Tydzień ostrzeżenia to niewiele; to dużo więcej niż nic.
Fig 62.1 — The Warning Window. The focal catch is where reconciliation earns its keep — not by finding fraud but by noticing quiet changes early enough to respond. The window between the release note and the new billing period is where restructuring is still possible.
Chapter 63
Początek akcji charytatywnej
Jedno z najbardziej pouczających zleceń, jakie kiedykolwiek wykonałem, dotyczyło małej organizacji charytatywnej, na którą ledwo było mnie stać. Wynagrodzenie było nominalne, ambicje ogromne, a wynik dostarczony w ciągu sześciu tygodni — element infrastruktury, który znacząco zmienił sposób ich działania. Nauczyło mnie to rzeczy na temat pracy pod prawdziwymi ograniczeniami, jakich nie zapewniłoby żadne dobrze finansowane zaangażowanie.
Początek meczu na papierze wyglądał jak początek katastrofy. Organizacja potrzebowała systemu, którego średniej wielkości zespół programistów potrzebowałby około sześciu miesięcy przy zwykłych stawkach za doradztwo. Ich budżet stanowił mniej więcej jedną dziesiątą tego. Każdy instynkt mówił, żeby odejść. Nie zrobiłem tego, częściowo dlatego, że misja miała dla mnie osobiste znaczenie, a częściowo dlatego, że chciałem sprawdzić, czy wzorzec opisany we wcześniejszych rozdziałach – restrukturyzacja w stylu Fusion, praca maszyn z dnia na dzień, wnikliwa kontrola człowieka – rzeczywiście może zapewnić tak duży wynik przy tak małym budżecie. W tym sensie był to w równym stopniu mój własny eksperyment, jak i ich projekt.
Warto wymienić restrukturyzację, która sprawiła, że to zadziałało. Nie byłoby sześcioosobowej drużyny; byłem ja i jeden współpracownik z ich strony na pół etatu. Nie byłoby sześciomiesięcznego harmonogramu; istniało trudne sześciotygodniowe okno, ponieważ moment operacyjny, w którym potrzebowali systemu, był kalendarzowy i nie podlegał negocjacjom. Każda abstrakcja, każda cecha „możemy też chcieć…”, każda moja wewnętrzna preferencja została obcięta przy pierwszym przejściu. Przetrwał najmniejszy możliwy system, który odpowiedziałby na ich prawdziwe pytanie – nic więcej i został dostarczony jako jeden wyraźny artefakt, a nie zestaw komponentów.
Praca mechaniczna wykonywana była na nocną zmianę. Każdej nocy partie generacji przebiegały bez nadzoru – treść, struktura, integracje – pozostawiając ślady, które mogłem przejrzeć rano. Prawie całe godziny spędzałem na przeglądaniu i specyfikacjach, a nie na pisaniu. W normalnej pracy konsultingowej spędzałbym czterdzieści godzin tygodniowo na budowaniu; w tym przypadku spędziłem może sześć godzin tygodniowo na przeglądaniu i osiem godzin tygodniowo na spotkaniach z klientem. Reszta wydarzyła się, gdy spałem, w ich imieniu, kosztem krańcowym na tyle małym, że budżet mógł sobie na to pozwolić.
Lekcja, która mnie najbardziej zaskoczyła, dotyczyła zakresu. Każdą cechę, którą wycięliśmy w pierwszym przejściu, wycinaliśmy na stałe — i żadna z nich nie została pominięta. System został dostarczony bez całego drugiego poziomu funkcji, które w dobrze finansowanej wersji wydawałyby się niezbędne, a użytkownicy o nie nie pytali. Jeśli ograniczenie jest rzeczywiste, liczy się mniejszy podzbiór tego, co zdaniem praktyków ma znaczenie. Ograniczenie zadziałało jak serum prawdy, w którym cechy faktycznie zasłużyły na swoje miejsce.
Druga lekcja dotyczyła zadowolenia klienta i fałszywej korelacji między budżetem a zachwytem. Organizacja charytatywna była bardziej zachwycona rezultatem niż większość moich dobrze finansowanych klientów, ponieważ rzeczywiście rozwiązaliśmy ich problem w ramach ograniczeń, jakie mi nałożyli. Rozbieżność pomiędzy tym, czego oczekiwali – prawdopodobnie wersją normalnego zaręczyn o obniżonej jakości – a tym, co otrzymali – drobnostką o specjalnie ukształtowanym kształcie, która w pełni odpowiadała ich potrzebom – stworzyła pozytywną lukę, której nie dałoby się otworzyć żadne drogie zaręczyny. Delight żyje w rozbieżności między oczekiwaniami a realizacją, a tanie zaręczyny czasami stwarzają największą dostępną lukę.
Teraz ufam uogólnionemu wywodowi: kiedy ograniczenie jest realne, szanuj je strukturalnie, a nie mocniej ocierając się o niewłaściwy plan. Wzorzec Fuzji z rozdziału 52. jest właściwą reakcją na prawdziwy niedobór; cokolwiek mniej, to po prostu wykonywanie normalnej pracy ze zniżką. A maszyna, dobrze wykorzystana, może zapewnić wyniki w cenach, które byłyby niemożliwe w przypadku operacji czysto ludzkiej. Na tym polega cały sens uczenia się pracy w ten sposób.
No figure. This chapter is a case study whose structural argument is Fig 1.1's twenty-hour week and Fig 27.1's parallel fleet, drawn on a specific project. Repeating either diagram here would only re-title what's already shown.
Chapter 64
Visual OS ograniczyłem do trzech delt
Klient przyszedł ze specyfikacją zajmującą dwadzieścia stron i opisał tak zwany „wizualny system operacyjny agenta”. Panele, dashboardy, orkiestratory, integracje, agenci zarządzający agentami. Był ambitny w tym sensie, w jakim to słowo zwykle oznacza: miał składać się z wielu rzeczy, żadnej z nich jeszcze precyzyjnie nieokreślonej, a cały kształt miał się zmieniać pod wpływem kontaktu z rzeczywistością. Myśleli, że moim zadaniem jest zbudowanie specyfikacji. Jak się okazało, moim zadaniem było zredukowanie specyfikacji do czegoś, co warto zbudować.
Pierwsza rozmowa była trudna, ponieważ musiałem powiedzieć — uprzejmie, ale wyraźnie — że w formie pisemnej specyfikacja będzie stanowić pięknie dopracowany dowód koncepcji, a nie faktyczny wynik biznesowy. Dwadzieścia stron funkcji nie składa się na produkt; składają się na demo, które robi wrażenie na osobie, która podpisała się na dwudziestu stronach. Zamiast tego zaproponowałem, aby pierwszy tydzień spędzić nie na budowaniu, ale na ograniczaniu: zidentyfikowaniu konkretnych trzech delt – trzech konkretnych zmian w stosunku do ich obecnego stanu – które przyniosłyby wymierną wartość, i porzuceniu wszystkich pozostałych elementów początkowego planu działania.
Rozmowa redukcyjna była rzeczywistą pracą zaręczynową. Razem przejrzeliśmy specyfikację i dla każdej funkcji zadaliśmy jedno pytanie: gdybyśmy tego nie zbudowali, czy wskaźniki operacyjne klienta zmieniłyby się mniej niż gdybyśmy to zbudowali? Zdecydowana większość funkcji nie przeszła tego testu — była interesująca, wiarygodna i mało nośna. Trzy funkcje zostały pominięte: określony przepływ pracy wykonywany ręcznie przez zespół, który dobrze zaprojektowane narzędzie mogło zautomatyzować; konkretna część danych, która, jeśli się ujawni, w istotny sposób zmieni sposób podjęcia decyzji; specyficzną integrację, której brak powodował codzienne tarcia.
Te trzy delty stały się całą pierwszą fazą starcia. Nie wizualny system operacyjny. Nie panele. Nie orkiestratorzy zarządzający orkiestratorami. Trzy konkretne, mierzalne zmiany w ich rzeczywistości operacyjnej. Pozostała część dwudziestostronicowej specyfikacji została zgłoszona jako kandydaci do późniejszych faz, pod warunkiem, że pierwsza faza wykaże wartość uzasadniającą kontynuację. Nie oznaczało to ograniczenia zakresu jako wymówki dla niższych wyników; skupiało się na zakresie, więc dostawa mogła mieć znaczenie.
Sześć tygodni później trzy delty były już aktywne. Wszyscy trzej przesunęli wskaźniki, których się spodziewali; dwa poruszyły ich bardziej, niż klient przewidywał. Zaangażowanie przedłużyło się, ale rozszerzenie nie brzmiało: „Teraz zbudujmy wizualny system operacyjny na podstawie oryginalnej specyfikacji”. Były to trzy kolejne konkretne delty utożsamiane z tą samą dyscypliną. Iterowanie rzeczywistej wartości dostarczonej w porównaniu ze wskaźnikami operacyjnymi jest lepsze od próby zbudowania wyimaginowanego systemu, którego wartość była teoretyczna.
Lekcja dotyczy tego, co właściwie oznacza „wizja” w kontaktach z klientem. Dwudziestostronicowe specyfikacje systemów o wielkim zasięgu często nie są wizją – są niepokojem. Klient martwi się, że przegapi coś ważnego, więc wylicza wszystko, co przychodzi mu na myśl, a co może być ważne. Prawdziwa wizja, w użytecznym sensie, to niewielka liczba konkretnych założeń na temat tego, co faktycznie ma znaczenie, poczynionych z wystarczającym przekonaniem, aby powiedzieć „nie” reszcie. Pomoc klientowi w odnalezieniu tej wizji – lub jej przedstawienie, jeśli nie może – jest usługą o znacznie większej wartości niż sumienne wykonywanie listy obaw, z którymi przyszedł.
Zmniejsz ambicje do określonych delt. Zbuduj delty. Zmierz ruch. Iteruj od rzeczywistej wartości, a nie od wyimaginowanego systemu. W ten sposób ambicja staje się realizacją; wszystko inne pozostaje pokładem slajdów.
Fig 64.1 — Twenty to Three. The original twenty-item spec on the left is anxiety-shaped; the focal three deltas on the right are the specific bets that actually moved the client's metrics. Reduction is not scope-shrink — it's the real work of the engagement.
Chapter 65
Rok indukcji
W środę o trzeciej nad ranem obudził mnie telefon. Zaplanowane nocne uruchomienie wielokrotnie kończyło się niepowodzeniem w odniesieniu do źródła danych klienta, a alert monitorowania nasilił się, ponieważ awaria występowała przez dwie godziny z rzędu. Następne dziewięćdziesiąt minut spędziłem przy kuchennym stole, debugując w piżamie, i ten incydent nauczył mnie więcej o dojrzałości operacyjnej niż jakakolwiek inna rozmowa w spokojnych godzinach.
Rzeczywisty problem techniczny był przyziemny. Klient zmienił dane uwierzytelniające API, nie informując mnie o tym, zbudowany przeze mnie adapter korzystał ze starych danych uwierzytelniających, a każda próba uwierzytelnienia kończyła się niepowodzeniem i wyświetlała komunikat 401, oznaczający, że logika ponawiania — zgodnie z rozdziałem 29 — poprawnie została sklasyfikowana jako terminal i przestała ponawiać próby, ale wcześniej wygenerowała wystarczającą ilość szumu w dzienniku, aby mnie wywołać. Rozwiązaniem, gdy zrozumiałem, co się stało, było zaktualizowanie danych uwierzytelniających w magazynie konfiguracji i ponowne uruchomienie potoku. Pięć minut pisania po dziewięćdziesięciu minutach dochodzenia.
Tym, co uczyniło ten incydent pouczającym, nie było rozwiązanie techniczne, ale wszystko wokół niego. Alert zadziałał prawidłowo, co oznaczało, że monitorowanie działało. Ślad z nieudanych serii był na tyle dobrze skonstruowany, że mogłem zrekonstruować to, co się stało na zimno — nie było potrzeby odtwarzania na żywo, co miało znaczenie o 3 nad ranem, kiedy reprodukcja na żywo w systemie produkcyjnym klienta i tak byłaby niewłaściwą decyzją. Wzorzec podprocesu z rozdziału 22 oznaczał, że mogłem ręcznie ponownie uruchomić pojedynczy nieudany krok, w izolacji, aby potwierdzić moją hipotezę dotyczącą poświadczeń, bez dotykania czegokolwiek innego w potoku.
Szczerze mówiąc, najbardziej użyteczna była rozmowa z klientem, która odbyła się rano. Wyjaśniłem wprost, co się stało: zmienili dane uwierzytelniające, nie informując mnie o tym, mój system to zauważył, zaalarmował i bezpiecznie zatrzymał — żadne dane nie uległy uszkodzeniu, żadne częściowe przebiegi nie pozostały w złym stanie, nie wystąpiły żadne uszkodzenia po stronie klienta. Przeprosili, a ja powiedziałem, żeby tego nie robić; incydent zadziałał dokładnie w taki sposób, w jaki zaplanowano zaangażowanie. Zamiast tego uzgodniliśmy, że dodamy wspólny wpis w kalendarzu dotyczący rotacji poświadczeń, abym wiedział, że przyjdą i mógł wstępnie przygotować nowe poświadczenia, zamiast być wzywanym o 3 nad ranem.
Lekcja, którą chcę wyraźnie wymienić, jest taka, że dojrzałości operacyjnej nie mierzy się brakiem incydentów — mierzy się ją tym, jak przebiegają zdarzenia, które się wydarzyły. Każdy długo działający system ma chwile o trzeciej nad ranem; pytanie brzmi, czy te chwile powodują uszkodzenie danych i awarie w kontakcie z klientem, czy też powodują przywołanie inżyniera, czysty ślad, pięciominutową naprawę i produktywną rozmowę uzupełniającą. Dyscypliny, za którymi opowiada się ta książka – uporządkowane ślady, błędy podczas pisania, izolowane powtórzenia podprocesów, monitorowanie prawidłowego uruchomienia – przynoszą korzyści dokładnie o 3 nad ranem. Istnieją po to, aby nudne były złe chwile.
Druga lekcja dotyczy małych porozumień operacyjnych wynikających z incydentów. Dodany przez nas wpis w kalendarzu jest banalny; zapobiegłoby to również całemu incydencie, gdyby miał on miejsce wcześniej. Większość incydentów o trzeciej nad ranem wskazuje na brak drobnego porozumienia, które by im zapobiegło, a rozmowa po zdarzeniu to moment, w którym w naturalny sposób dochodzi do zawarcia tych porozumień. Pominięcie rozmowy, ponieważ „problem techniczny został rozwiązany”, powoduje, że następny incydent jest równie prawdopodobny jak ten; dzięki temu incydent zmienia się w poprawę strukturalną.
Projekt dla rzeczywistości o trzeciej nad ranem. Spraw, aby złe chwile stały się nudne. Przeprowadź dalszą rozmowę. Każde wydarzenie zakończone nową, małą umową jest wydarzeniem, za które płaci się własne czesne.
No figure. This is a specific story with structural morals already drawn in Fig 18.1 (the trace), Fig 22.1 (the subprocess), and Fig 29.1 (the failure classifier). The chapter's argument is that those three diagrams pay their bill at 3am; a new diagram would add nothing.
Chapter 66
Regresja modelu
Umiejętność, którą z powodzeniem stosowałem przez sześć miesięcy, zaczęła dawać gorsze wyniki. Z mojej strony nic się nie zmieniło — żadnych aktualizacji kodu, żadnych zmian adaptera, żadnych szybkich edycji. Wskaźnik powodzenia telemetrii z rozdziału 49 cicho spadł w ciągu trzech tygodni z dziewięćdziesięciu siedmiu procent do osiemdziesięciu dwóch. Przyczyną okazała się zmiana wersji modelu po stronie dostawcy, którą w uwagach do wydania opisano jako ulepszenie, a która w przypadku konkretnej klasy zadań, którymi się zajmowałem, była w rzeczywistości regresją.
Tę historię warto opowiedzieć, ponieważ regresje modeli to kategoria problemów, których tradycyjna inżynieria oprogramowania nie ma w takim kształcie, jakiego można by się spodziewać. W klasycznym oprogramowaniu, jeśli mój kod się nie zmienił i środowisko się nie zmieniło, zachowanie się nie zmienia. W pracy ze sztuczną inteligencją model jest aktywną zależnością, której zachowanie może się zmienić bez ostrzeżenia, ponieważ dostawca zaktualizował wagi, routing lub domyślne ustawienia próbkowania, a wskaźnik powodzenia moich umiejętności jest rzeczą probabilistyczną, która może się zmieniać wraz z ruchem modelu.
Z satysfakcją zauważyłem, że jest dokładnie tak, jak powinienem zauważyć — cotygodniowe podsumowanie telemetryczne wskazywało umiejętność, której wskaźnik sukcesu spadał bez oczywistej przyczyny. Zanim miałem podsumowanie, problemy tej klasy pojawiały się, gdy klient skarżył się po miesiącach powolnej degradacji. W podsumowaniu zauważyłem to w trzecim tygodniu i miałem konkretną hipotezę w czwartym tygodniu. Oprzyrządowanie zasłużyło na swoje utrzymanie w najbardziej dosłownym tego słowa znaczeniu: była to różnica między reaktywną kontrolą uszkodzeń a proaktywnym dochodzeniem.
Samo badanie było interesujące, ponieważ regresje modeli wymagają innego podejścia diagnostycznego niż błędy oprogramowania. Nie mogłam przejść obojętnie obok zachowania modelki. Nie udało mi się sprawdzić jego stanu pośredniego. Jedyne, co mogłem zrobić, to skonstruować mały zestaw reprezentatywnych danych wejściowych, porównać je z bieżącym modelem i — korzystając z funkcji przypinania wersji oferowanej przez dostawcę — z poprzednią wersją i porównać wyniki obu. Różnica pomiędzy tymi przebiegami polegała na regresji, konkretnej i mierzalnej. To nie było dwuznaczne; był tam, w artefaktach, obok siebie.
Uchwała miała kilka opcji i musiałem wybrać. Mógłbym przypisać swoje umiejętności do poprzedniej wersji modelu na czas nieokreślony, ale poprzednia wersja miała zostać wycofana za kilka miesięcy. Mógłbym przepisać podpowiedzi umiejętności, aby obejść zachowanie nowego modelu, ale wydawało mi się to walką z falą. W rzeczywistości skierowałem tę konkretną klasę zadań do innego modelu — równorzędnego z tym, który uległ regresji, od tego samego dostawcy, który obsługiwał klasę zadań bez regresji — i zapisałem oryginalną tabelę routingu umiejętności do ponownego przejrzenia, gdy nowa wersja modelu będzie miała kilka tygodni na ustabilizowanie się. Czasami rozwiązaniem jest poruszenie się, a nie kłótnia.
Lekcja jest taka, że zależności modeli należy traktować bardziej jak system ruchomy niż stały, i wynikają z tego konkretne praktyki: przypinanie wersji tam, gdzie jest ona dostępna do pracy krytycznej, elastyczność routingu, dzięki czemu zadanie można przenosić między modelami bez przepisywania, oraz cierpliwość telemetryczna na tyle, aby zauważyć dryf w ciągu tygodni, a nie spodziewać się awarii w ciągu godzin. Tryby awarii specyficzne dla sztucznej inteligencji wymagają higieny charakterystycznej dla sztucznej inteligencji, a najbliższym odpowiednikiem tradycyjnego oprogramowania są prawdopodobnie aktualizacje systemu operacyjnego lub środowiska wykonawczego — kategoria, o której większość inżynierów wie, że powinna zachować ostrożność, i stosowana tutaj do czegoś, co zmienia się częściej i ciszej.
Zdarzają się regresje modeli. Zauważ je za pomocą telemetrii. Diagnozuj poprzez bezpośrednie porównanie. Omiń je, jeśli to możliwe. I zaakceptuj jako roboczą prawdę, że model nie jest stabilnym prymitywem — to usługa, której zachowanie się zmienia, a infrastruktura musi zostać zbudowana tak, aby uwzględnić ten ruch tak, abyś nie zauważył tego po fakcie.
No figure. The diagnostic pattern of side-by-side comparison is trivially depicted as two columns of outputs, which doesn't warrant a diagram; the telemetry that catches the drift is already shown in Fig 49.1.
Chapter 67
Wyciekły monit
Podpowiedź, którą starannie zaprojektowałem dla klienta — godziny iteracji, osadzone w jego produkcie, co stanowi część tego, co sprawiło, że produkt działa — skończyło się na zrzucie ekranu i udostępnieniu w mediach społecznościowych przez użytkownika końcowego, który znalazł sposób na wyodrębnienie go poprzez odpowiedź modelu. Zrzut ekranu miał około dziesięciu tysięcy wyświetleń, zanim go zobaczyłem. Podpowiedź nie była dokładnie tajna; nie miało to też być publiczne. W tym rozdziale opowiem o tym, jak myślałem o natychmiastowej poufności i o tym, jak błędne było to myślenie.
Model mentalny, który nosiłem do tej chwili, polegał na tym, że podpowiedzi działały za granicą — mój serwer je trzymał, użytkownik rozmawiał z modelem za pośrednictwem serwera, a sama zachęta była szczegółem implementacji, którego użytkownik nie mógł zobaczyć. Technicznie prawda, ale całkowicie błędna w praktyce. Wystarczająco ciekawy użytkownik, stosując standardowe techniki szybkiego wyodrębniania, mógłby nakłonić model do ujawnienia własnych instrukcji, a po ujawnieniu instrukcje te były publiczne. Poufność, którą sobie wyobrażałem, wcale nie była poufnością; była to niewielka niedogodność.
Specyficzna ekstrakcja nie była sprytna. Użytkownik poprosił model o podsumowanie własnych instrukcji, co większość modeli wykona przy jedynie niewielkim oporze, i otrzymał parafrazę, która ujęła istotę. Nie dokładne bajty mojego znaku zachęty, ale intencja, struktura i logika operacyjna. Wystarczająco, aby ktoś mógł odtworzyć podstawowe zachowanie asystenta w innym miejscu. Z perspektywy czasu zakładałem, że konkurencyjna fosa, która znajdowała się w podpowiedzi, była fosą mniej więcej tak wysoką jak krawężnik.
Lekcja, którą musiałem przyswoić sobie w niewygodny sposób, jest taka, że każdy tekst, który umieścisz w kontekście modelu, może zostać potencjalnie odnaleziony przez użytkowników tego modelu. Nie „zostaną odkryte przez każdego użytkownika”, ale „mogą zostać odkryte przez wystarczająco zdeterminowanych użytkowników”. Właściwym założeniem jest, że zachętą jest informacja publiczna – ostatecznie widoczna – i projektowanie wokół tej rzeczywistości, a nie przeciwko niej. Wszystko, na co nie możesz pozwolić sobie na wyciek, nie powinno w pierwszej kolejności pojawiać się w podpowiedzi.
Praktyczne skutki nie były tak złe, jak mogłyby być, głównie dzięki szczęściu. Monit zawierał instrukcje dotyczące zachowania i stylu, a nie poufne dane klienta, referencje czy logikę biznesową, które mogłyby wyrządzić szkody w niepowołanych rękach. Gdybym przechowywał tam wrażliwe informacje – klucze API, tajemnice handlowe klientów, dane osobowe – wyciek byłby znacznie większy. To, co niemal chybiło, nauczyło mnie kontrolować zawartość każdego podpowiedzi, które napisałem od tego momentu, traktując każdą podpowiedź jako tekst, który chętnie bym opublikował, bo mógłbym.
Wersja lekcji o przewadze konkurencyjnej jest taka, że jeśli fosa Twojego produktu jest zachętą samą w sobie, Twój produkt nie ma fosy. Wszystko, co istnieje w podpowiedzi, może zostać w prosty sposób odtworzone przez każdego, kto jest na tyle zdeterminowany, aby to wyodrębnić. Prawdziwe fosy są gdzie indziej: zastrzeżone dane, integracja przepływu pracy, trwająca relacja, zaufanie klienta do Twojej oceny. Próba obrony podpowiedzi jako klejnotów koronnych jest obroną niewłaściwego zasobu. Przenieś wartość w miejsce, którego użytkownicy nie mogą wyodrębnić, i traktuj zachętę jako tekst widoczny publicznie, którym funkcjonalnie jest.
Kolejnym działaniem, jakie podjąłem, było systematyczne przeglądanie wszystkich podpowiedzi dotyczących każdej umiejętności, usuwanie wszystkiego, co wyglądało, jakby służyło raczej jako tarcza, a nie projekt, i aktualizacja mojego modelu mentalnego, aby zakładać, że każda podpowiedź może i może zostać upubliczniona. Ta recenzja zajęła jeden dzień. Zmiana sposobu myślenia trwała dłużej, ponieważ „podpowiedzi są tajemnicą” to bardzo naturalne założenie, którego należy się aktywnie oduczyć. To nie jest; traktuj je odpowiednio.
Załóżmy, że zachęta jest publiczna. Projektuj wokół tego założenia. Przenieś wartość do fosy, której użytkownicy nie mogą wyodrębnić, ponieważ monit nią nie jest. Zrzut ekranu staje się wirusowy, jeśli musi; nic w podpowiedzi nie powinno być w stanie cię skrzywdzić, jeśli tak się stanie.
No figure. This is a story about a mental-model correction, not a structure; the shape it points at is Fig 13.1's trust boundary — the same principle that says the frontend is untrusted also says the prompt, once returned by the model, is untrusted, and both belong on the outside of anything sensitive.
Chapter 68
Demo, które uratowało transakcję
W połowie oferty konkurencyjnej — trzech dostawców, decyzja klienta miała zostać podjęta w piątek, a w środę rano kształt rozmowy był dla mnie niekorzystny. Zawodnicy mieli dopracowane slajdy i wspaniałe plany działania. Miałem działający PoC i zupełnie inną teorię na temat tego, co klient powinien kupić. Moment, który to zmienił, nie był slajdem; było to w wersji demo na żywo, której pierwotnie nie planowałem.
To, co sprawiło, że demo zadziałało, to to, że nie było dramatyczne. To nie jest pokaz sceniczny, w którym przećwiczono każdy wkład; rzeczywiste wykorzystanie systemu na żywo wobec problemu, na którym zależało klientowi, zrobione na jego oczach, z ryzykiem, że system nie zadziała. Wpisałem pytanie klienta do asystenta, obserwowaliśmy nadejście strumienia (interfejs przesyłania strumieniowego w Rozdziale 14 zarabiał na utrzymanie w najbardziej dosłowny sposób) i po około czterdziestu sekundach na ekranie pojawiła się konkretna, użyteczna i nietypowa odpowiedź. Demo trwało może dwie minuty. Energia sali wyraźnie zmieniła się pod koniec pierwszej minuty.
Powodem, dla którego to zadziałało, była nie tyle kwestia technologii, ile tego, co udowodniło demo. Konkurenci pokazali slajdy przedstawiające, co ostatecznie zrobią ich systemy; Pokazałem konkretną odpowiedź na konkretne, prawdziwe pytanie, która miała miejsce w pokoju, pod okiem klienta. Beton za każdym razem bije teorię. Demo, w którym widoczne jest ryzyko niepowodzenia, jest bardziej wiarygodne niż jakikolwiek dopracowany przewodnik, ponieważ klient wie, że nic nie jest ukryte. Jeśli to działa, to działa; jeśli się zepsuje, to również byłaby użyteczna informacja.
Głębsza lekcja dotyczy tego, jak faktycznie wygląda „gotowość do zakupu” w procesie decyzyjnym klienta. Krótko mówiąc, porównują listy funkcji i referencje dostawców. Konkretnie próbują sobie wyobrazić, czy system pomoże im w prawdziwej pracy w przyszły wtorek. Slajdy i plany działania wymagają od nich dużej wyobraźni; demonstracja na żywo umożliwia im wyobrażenie. Zadaniem wersji demonstracyjnej nie jest abstrakcyjne udowodnienie możliwości — chodzi o uczynienie mentalnego modelu korzystania z systemu klienta na tyle konkretnym, aby mógł podjąć decyzję.
Warto wymienić element zarządzania ryzykiem. Zrobiłem demonstrację, ponieważ miałem pewność, że system będzie działał z tą klasą pytań, w oparciu o tę samą klasę pytań, która działała wiele razy podczas wcześniejszych sesji. Nie zrobiłbym tego, gdybym nie był pewien – demonstracja, która zawodzi na boisku konkurencyjnym, jest gorsza niż brak demonstracji, ponieważ potwierdza wątpliwości, jakie wzbudzali konkurenci. Zaufanie do wersji demonstracyjnej wynika z wykonania pracy; każdy, kto ma pokusę wypróbowania wersji demonstracyjnej na żywo bez podstawowej niezawodności, ustala własną wiarygodność w zakresie rozbiórki.
Ostatnia lekcja jest taka, że teoria zakupów ma znaczenie. Transakcji nie udało się uratować dzięki parytetowi funkcji ani olśnieniu planu działania; zaoszczędzono, zmieniając warunki porównania z „ocena dostawcy” na „który z nich faktycznie pomoże mi w tym miesiącu”. Gdy porównanie przeniosło się na konkretne wyniki, konkretna, działająca odpowiedź mojego systemu na prawdziwe pytanie była łatwiejsza do zrozumienia niż dobrze opracowane opisy ewentualnych możliwości oferowane przez konkurencję. Przekierowanie porównania na konkretny grunt często wygrywa transakcje, które przegrywały na abstrakcyjnym gruncie.
Demo działające systemy wykonujące prawdziwą pracę. Przekieruj abstrakcyjne porównania na konkretne wyniki. Wykonaj podstawową pracę, aby demo miało coś do zademonstrowania. To właśnie uratowało tę transakcję i od tego czasu ten sam schemat uratował inne — ponieważ „spójrz, co faktycznie robi” prawie zawsze przewyższa „oto, co ostatecznie zrobi”.
No figure. This chapter is a moment, not a structure; the visual it points at is Fig 14.1's stream in the pitch room, watched live by the buyer — the diagram is already drawn, this chapter just applies it to a specific room on a specific Wednesday.
Chapter 69
Klient, który odszedł
Nie każde zaręczyny kończą się dobrze. Klient odszedł w połowie drugiego roku i chociaż istniały ku temu powierzchowne przyczyny – przegląd budżetu, wewnętrzna restrukturyzacja, nowy interesariusz o innych priorytetach – szczerze czytaliśmy, że relacje przekształciły się w coś, czego żadna ze stron nie chciała, a odejście było spóźnionym potwierdzeniem. Lekcje płynące z odejścia klienta różnią się od lekcji, jakie daje klient pozostający, i warto poświęcić im cały rozdział, ponieważ odejście uczy inaczej.
Specyficzna dynamika tego zaangażowania polegała na tym, że gdzieś w piątym miesiącu przestaliśmy publikować recenzje z rozdziału 56 w stylu trzydziestego dnia. Oboje pozwoliliśmy, aby praca szła do przodu bez okresowych kontroli, a do dwunastego miesiąca żadne z nas nie było do końca pewne, czy zaangażowanie nadal osiąga swój pierwotny cel, czy coś innego. Pozbawieni celowej struktury zatrzymywania się i patrzenia, wpadliśmy w rytm konserwacji, który wydawał się w porządku i nie do końca był tym, czego żadne z nas chciało. Odejście było naturalnym zakończeniem związku, który prywatnie zakończył się już kilka miesięcy wcześniej.
Lekcja, do której ciągle wracam, jest taka, że recenzje, wobec których byłam tak zdyscyplinowana przez pierwszy miesiąc, mają właśnie na celu temu zapobiec. Kiedy w związku trwają zorganizowane kontrole, dryf zostaje nazwany i skorygowany; jeśli tak się nie dzieje, dryf kumuluje się po cichu, a ostateczne rozliczenia są znacznie większe niż jakakolwiek pojedyncza recenzja. Kosztów ominiętych przeglądów nie pokryto wówczas – wszystko było w porządku – uiszczono je przy wyjeździe, kiedy trzeba było od razu rozliczyć rok dryfu.
Co dziwne, sama rozmowa wyjazdowa była jedną z najbardziej przydatnych rozmów podczas całego zaręczyn. Obie strony mogły być szczere w sposób, w jaki nie byliśmy od miesięcy, ponieważ wynik był już przesądzony, a nazywanie tego, co faktycznie się wydarzyło, nie wiązało się z żadnymi kosztami politycznymi. Klient powiedział mi konkretnie, co przestało w jego przypadku działać; Powiedziałem im, co zauważyłem, ale nie poruszyłem tego tematu. Żadne z nas nie było zaskoczone tym, co powiedział drugi. Informacje były dostępne przez cały czas; odejście pozwoliło nam to przyznać.
Konsekwencją tego, czego się trzymam, jest odbycie rozmowy w stylu wyjazdu przed wyjazdem, w pewnym regularnym rytmie. Nie każda recenzja musi mieć charakter egzystencjalny – większość to po prostu sprawdzenie – ale od czasu do czasu obie strony muszą być w stanie powiedzieć, co nie działa, bez ponoszenia kosztów politycznych w postaci zagrożenia dla zaangażowania. Kiedy te szczere chwile mogą wydarzyć się w związku, zwykle uniemożliwiają jego odejście. Kiedy nie mogą, wyjazd jest jedynym miejscem, w którym mogą się odbyć, a wtedy jest już za późno.
Druga lekcja dotyczy tego, jak dobrze wyjść. Rozstaliśmy się z klientem poprzez pisemne przekazanie informacji – z czym mam go zostawić, co nadal będzie działać, co ostatecznie będzie wymagało uwagi. To nic wielkiego, nie napiętnowanego politycznie, po prostu profesjonalna uprzejmość i nie zostawianie niedokończonych spraw. Sześć miesięcy później ten klient przesłał mi ciepłą rozmowę referencyjną w sprawie nowego potencjalnego klienta, co jest w przybliżeniu najlepszym wynikiem, na jaki można liczyć po odejściu. Dobre odejście sprawia, że utracone zaręczyny stają się przyszłymi.
Mieć uczciwe recenzje zgodnie z harmonogramem; nie czekaj na wyjazd, aby stworzyć otwarcie. Po zakończeniu odejdź z pisemnym przekazaniem. Potraktuj rozmowę o odejściu jako dane — uczy Cię ona rzeczy na temat zaangażowania, których nie mogła zapewnić bieżąca wersja.
No figure. The chapter's shape is the trust ladder from Fig 57.1 read backwards — a client sliding down through neglect rather than climbing through attention. The invisible half of the ladder is the departure lane; drawing it explicitly would only add gloom.
Chapter 70
Umowa, której powiedziałem nie
Część VII kończy się największą pojedynczą opłatą, jaką odrzuciłem. Zaangażowanie było duże, klient godny zaufania, prace techniczne były w mojej strefie. Powiedziałem nie, ponieważ kształt tego, o co prosili, nauczyłem się uznawać za zły dla mnie, a uhonorowanie tej lekcji liczyło się bardziej niż wynagrodzenie. W tym rozdziale opisano, jak odmówić dobrze wyglądającej umowie, która jest dla ciebie niewłaściwa, ponieważ mówienie „nie” jest umiejętnością i przez długi czas się myliłem, zanim udało mi się to zrobić dobrze.
Specyficzny wzór, który pasował do umowy, był następujący: klient chciał wyłączności. Chcieli, żebym zobowiązał się, że przez rok nie przyjmę żadnego klienta z sąsiedniego lokalu, tak aby był on jedynym beneficjentem mojej pracy w swojej branży. Oferowane przez nich wynagrodzenie zostało dostosowane tak, aby ta wyłączność była warta mojego czasu — naprawdę więcej, niż normalnie zarabiałbym z trzech lub czterech mniejszych zleceń łącznie. Na pozór było to bardzo dużo. Pod powierzchnią była to pułapka, w której byłem już wcześniej.
Moim zdaniem problem z wyłącznością polega na tym, że koncentruje ona ryzyko. Jeśli jeden klient generuje dużą część moich przychodów, a potrzeby, priorytety lub budżet tego klienta ulegają zmianie – a każda z tych sytuacji zdarza się rutynowo – w jednym przypadku tracę dużą część moich przychodów. Dywersyfikacja nie jest zasadą portfela mającą zastosowanie wyłącznie do inwestowania; odnosi się to dokładnie tak samo mocno do praktyki solowej. Posiadanie sześciu klientów, z których każdy zapewnia jedną szóstą moich przychodów, jest znacznie bezpieczniejsze niż posiadanie jednego klienta dostarczającego całość, nawet jeśli suma jest taka sama.
Drugi problem dotyczy wpływu wyłączności na samą praktykę. Zaangażowanie, którym nie mogę się podzielić, z którego nie mogę ponownie wykorzystać wzorców, wokół którego nie mogę zbudować klientów referencyjnych, jest zaangażowaniem, które się nie składa. Dyscyplina pakietu umiejętności z Części V zależy od ponownego wykorzystania umiejętności w różnych starciach; dynamika klienta referencyjnego z rozdziału 60 zależy od tego, czy klienci mogą wypowiadać się o mnie publicznie. Ekskluzywne spotkania gromadzą wszystko, czego się uczę od klienta, o którym nie mogę rozmawiać, co spowalnia łączenie, od którego zależy mi na długoterminowy rozwój.
Trzeci problem, którego zauważenie zajęło mi najwięcej czasu, polega na tym, że wyłączność zmienia równowagę sił w związku. Kiedy klient wie, że nie masz innej działalności na jego powierzchni, wie, że nie możesz chodzić. Ta wiedza jest subtelna i objawia się na sto różnych sposobów — w jaki sposób reagują na Twoje faktury, jak traktują zmianę zakresu, jak elastycznie oczekują od Ciebie, że będziesz działać w sprawach, na które nie naciskaliby, gdyby wiedzieli, że masz alternatywy. Opłata za wyłączność stanowiła rekompensatę za dokładnie tę dynamikę niewoli, a żadna opłata nie rekompensuje w wystarczającym stopniu pozycji, jaką tworzy.
Rozmowa z klientem, podczas której powiedziałam „nie”, była niewygodna – nigdy wcześniej nie odrzuciłam umowy o tak dużej wartości i zdawałam sobie sprawę, że może to zinterpretować jako udawanie wyższej opłaty. Powiedziałem szczerze, że to nie jest stanowisko negocjacyjne; było to ograniczenie strukturalne, którego nauczyłem się trzymać. Byli zaskoczeni, zadali kilka pytań i ostatecznie zaangażowali mnie na zasadzie niewyłączności za niższą opłatę – na znacznie lepszych warunkach w każdym innym wymiarze. Odmowa przerodziła się w lepsze zaręczyny, niż byłoby to w przypadku ekskluzywnej oferty.
Lekcja generalizuje. Istnieją pewne kształty umów, które są niekorzystne dla prowadzenia działalności w pojedynkę, niezależnie od związanej z nimi opłaty – wyłączność, praca na zlecenie przypisując klientowi swoje wzorce, zobowiązania wymagające ukrywania innych klientów – a nauczenie się rozpoznawania tych kształtów pozwala ci powiedzieć „nie” bez zadręczania się. Konkretne opłaty są różne; kształty nie. Kiedy już znasz kształty, odpowiedź jest szybka, rozmowa krótka, a praktyka pozostaje zdrowa.
Poznaj kształty, które niszczą praktykę. Powiedz im nie, bez względu na opłatę. Przeprowadź szczerą rozmowę. Czasami lepsza wersja umowy pojawia się, gdy odrzucisz pierwszą wersję; czasami tak się nie dzieje i to też jest w porządku. Ćwicz zdrowie jest ważniejsze niż jakakolwiek pojedyncza opłata.
No figure. This chapter is an argument about which deals to accept; the underlying discipline is Chapter 51's discovery-to-roster evaluation, made concrete against a specific bad shape. The diagram of it is a personal red-flag list, which belongs in a private document rather than a book chapter.
Part VIII
Opinie trzymane luźno
To, w co wierzę na temat narzędzi, przepływów pracy i obecnego kształtu branży – wyznaję z wystarczającym przekonaniem, aby to stwierdzić, i z wystarczającą pokorą, aby to zmienić. Obsidian, platformy LMS, dekoracja kontra powściągliwość i drobne gusta, które składają się na sposób pracy.
Chapter 71
Na Obsydianie
Swoją osobistą wiedzę przechowuję w Obsidianie. Podchodzę do tego luźno — konkretne narzędzie jest mniej ważne niż wzór trzymania — ale wypróbowałem wystarczająco dużo alternatyw, że wyrobiłem sobie pogląd na temat tego, dlaczego wiedza oparta na lokalnych informacjach, oparta na przecenach i uporządkowana w folderach, działa na mnie w sposób, w jaki nie działają alternatywy oparte na bazie danych i hostowane w chmurze. Ten rozdział dotyczy wzoru, na konkretnym przykładzie Obsydianu.
Właściwość, na której polegam, polega na tym, że wiedza to pliki tekstowe na moim dysku. Nie w zastrzeżonym formacie usługi. Nie w bazie danych, którą musiałbym wyeksportować. Pliki tekstowe w folderach, w Markdown, na moim komputerze, synchronizowane z innymi moimi komputerami za pomocą dowolnego wybranego mechanizmu. Gdyby Obsidian zniknął jutro, otworzyłbym folder w dowolnym edytorze i kontynuowałbym. Gdyby jutro zniknęła usługa, w której znajdowały się moje notatki, miałbym problem z migracją i prawdopodobnie problem z utratą danych. Priorytet lokalny nie jest ideologiczny; to ubezpieczenie.
Drugą właściwością jest to, że format lepiej znosi zmiany narzędzi niż samo oprzyrządowanie. Pisałem w Markdown przez tyle lat, że notatki sprzed dziesięciu lat są nadal czytelne w obecnym edytorze, obecny edytor nie jest tym, którego wtedy używałem, i żadna migracja nigdy nie była potrzebna, ponieważ Markdown się nie zmienił. Każde narzędzie, które obiecuje utrzymać moje myślenie przez lata, musi mieć tę właściwość; wszystko, co wiąże moje myślenie z jego specyficznymi, ewoluującymi formatami, każe mi postawić na narzędzie, które przetrwa moje potrzeby.
Trzecia właściwość, bardziej specyficzna dla projektu Obsidianu, polega na tym, że narzędzie jest przeglądarką plików, a nie kontenerem, który jest ich właścicielem. Obsidian dodaje strukturę – linki, linki zwrotne, widoki wykresów, wtyczki – do plików, ale pliki pozostają czytelne i użyteczne bez żadnej tej struktury. Dodana struktura jest bonusem, a nie zależnością nośną. Jeśli przestanę używać Obsidianu, nie stracę moich notatek; Po prostu tracę afordancje, które Obsidian dodawał wokół nich. Ta asymetria — narzędzie dodaje, a nie trzyma zakładnika — jest tym, co moim zdaniem powinno dzielić się narzędziami dysponującymi dobrą wiedzą.
Uogólnienie, które chcę wyciągnąć, nie jest takie, że każdy powinien używać Obsidianu. Chodzi o to, że właściwości, które wymieniłem — działające lokalnie, tekstowo, z narzędziem jako przeglądarką — to właściwości, które mają znaczenie w przypadku wszystkiego, co planujesz przechowywać przez lata. Oceniając narzędzie wiedzy, pytaj, czy ma ono te właściwości, a nie czy jego lista funkcji jest zgodna z twoją obecną. Listy funkcji datują się szybko; przenośność, zwykły tekst, wytrzymuje widz nad właścicielem.
W tej konfiguracji intensywnie korzystam ze sztucznej inteligencji, ale sztuczna inteligencja to narzędzie, które działa na notatkach, a nie usługa, która je przechowuje. Moje umiejętności umożliwiają czytanie i zapisywanie w katalogu notatek, tworzenie artefaktów, które żyją obok notatek i nigdy nie przejmują ich na własność. Gdybym jutro chciał zmienić dostawcę sztucznej inteligencji, moje notatki dotarłyby nietknięte. Warstwa wzmocniona sztuczną inteligencją znajduje się na tym samym podłożu lokalnym, co wszystko inne, dzięki czemu cały system można wymieniać.
Trzymaj notatki lokalnie. Zachowaj je w tekście. Niech narzędzia będą widzami, a nie właścicielami. Konkretne narzędzie ma mniejsze znaczenie niż właściwości; wszystko, co zawiera te trzy elementy, jest rozsądnym wyborem dla długoterminowej wiedzy, a wszystko bez nich jest rozsądnym założeniem, aby w końcu żałować.
No figure. This is a stance about a specific tool; a diagram of Obsidian's folder structure would be trite, and the pattern it exemplifies is better described than drawn.
Chapter 72
Przeciwko ciężkim platformom LMS
Gdy klient chce dostarczyć szkolenie lub dokumentację jako część produktu, domyślną sugestią jest często „system zarządzania uczeniem się” — solidna platforma zapewniająca zorganizowane kursy, śledzenie postępów, quizy, certyfikaty i wszystkie zalety nowoczesnego oprogramowania edukacyjnego. Doszedłem do wniosku, że w większości tych przypadków ciężki LMS ma dokładnie niewłaściwy kształt, a właściwy kształt jest bliższy dobrze zorganizowanemu zestawowi stron z przejrzystym indeksem. W tym rozdziale wyjaśniono dlaczego.
Główną obserwacją jest to, że platformy LMS optymalizują pod kątem niewłaściwych rzeczy. Optymalizują one zdolność administratora do śledzenia uczniów – procent ukończenia, wyniki quizów, wskaźniki zaangażowania – a nie zdolność ucznia do faktycznego nauczenia się materiału. Funkcje, które sprawiają, że LMS jest atrakcyjny pod względem zakupu, to te, które utrudniają jego użytkowanie, ponieważ narzucają ceremonię ponad to, co powinno być płynnym spotkaniem z treścią.
Ceremonią, którą uważam za najbardziej szkodliwą, jest bramkowanie — naleganie, aby użytkownik ukończył moduł A przed otwarciem modułu B. W prawdziwej nauce ludzie skaczą. Przychodzą po konkretną odpowiedź, której potrzebują właśnie teraz. Wracają do sekcji, którą muszą przejrzeć. Pomijają części, które już znają. Bramkowany system LMS uniemożliwia to wszystko, wymuszając liniową ścieżkę przez materiał, którego większość uczniów nie musi zużywać liniowo. Liniowość to wygoda platformy, a nie korzyść ucznia.
Alternatywa, którą zwykle proponuję, jest nudna i działa. Uporządkowany zestaw stron, z których każda jest samodzielna i czytelna oddzielnie, zorganizowanych za pomocą przejrzystego indeksu, po którym uczeń może swobodnie się poruszać. Wyszukaj, który naprawdę działa. Linki pomiędzy powiązanymi sekcjami. Żadnych pasków postępu, żadnych wymuszonych sekwencji, żadnych certyfikatów ukończenia. Uczeń potrzebuje treści, które są dokładne, dobrze napisane, łatwe do znalezienia i czytelne; prawie każda funkcja LMS wykraczająca poza ten punkt to tarcia ubrane w pedagogikę.
Kontrargumentem, jaki najczęściej słyszę, jest to, że klienci chcą śledzić zaangażowanie – ilu uczniów przeszło przez materiał, ile czasu spędzili na jego nauce, jakie zdobyli punkty. Sprawiedliwy. Argument ten łączy jednak stwierdzenie „chcemy danych” z „potrzebujemy ciężkiej platformy”, a prostsze mechanizmy – analiza odsłon stron, okazjonalne wbudowane oceny tam, gdzie są naprawdę przydatne – obejmują większość celów śledzenia, bez narzucania ceremonii każdemu uczniowi. Ciężkie śledzenie sprzedawane na platformach LMS często generuje dane, na podstawie których nikt tak naprawdę nie podejmuje działań, co świadczy o tym, że jest to raczej ceremonia niż oprzyrządowanie.
Warto podać szerszą zasadę, która głosi, że „profesjonalnie wyglądające” narzędzia często wyglądają profesjonalnie, ponieważ dodano do nich złożoność, która spełnia oczekiwania nieznanego użytkownika co do wyglądu poważnego narzędzia, a nie dlatego, że ta złożoność służy czyimś rzeczywistym potrzebom. Prosta, dobrze zorganizowana treść, która szanuje autonomię czytelnika, zwykle wydaje się mniej imponująca w wersji demonstracyjnej i radzi sobie lepiej w codziennym użytkowaniu. Imponujący interfejs nie jest skorelowany z jakością uczenia się, a często jest antykorelowany.
Dostarczaj treści strukturalne, po których uczeń może swobodnie się poruszać. Śledź lekko. Pomiń LMS, chyba że masz naprawdę uzasadniony powód do szkolenia, aby go potrzebować. Uczniowie szybciej przyswajają materiał; administratorzy otrzymują mniej imponujące pulpity nawigacyjne i bardziej przydatne zaangażowanie. Ten handel faworyzuje uczniów, bo przecież teoretycznie dla nich to wszystko jest przeznaczone.
No figure. This chapter is a taste-argument about a category of tool; drawing a comparison diagram would be uncharitable to LMS vendors and wouldn't sharpen the argument for the reader.
Chapter 73
Dekoracja kontra powściągliwość
W projektowaniu zawsze wyznaczano granicę pomiędzy dekoracją — dodatkiem mającym cieszyć oko — a powściągliwością, praktyką usuwania tego, co nie zasługuje na swoje miejsce. Narzędzia projektowe generowane przez sztuczną inteligencję sprawiły, że dekoracje stały się tanie w sposób, w jaki w przeszłości nie było, a moim roboczym poglądem jest to, że właściwą reakcją na tanią dekorację jest więcej powściągliwości, a nie więcej dekoracji. Ponieważ wartość powściągliwości nigdy nie była tak kosztowna; chodziło o to, że uwaga czytelnika jest tym, co drogie, a rozmachem to wydaje.
Specyficzny wzorzec, który zaobserwowałem przez ostatni rok, polega na tym, że sztuczna inteligencja sprawiła, że generowanie dużej różnorodności wizualnej – bohaterów, ikon, ilustracji, podnagłówków o dziwacznych stylach – stało się banalne – a wiele produktów potraktowało to jako licencję na dodanie tego wszystkiego. Rezultatem jest rodzaj wizualnego poziomu szumów, który wcześniej nie istniał, ponieważ koszt krańcowy dodania ilustracji był kiedyś zadaniem projektanta, a teraz jest to podpowiedź. Każda ilustracja wygenerowana przez sztuczną inteligencję na stronie, która jej nie potrzebowała, skupia uwagę czytelnika na dekoracji, która nie przenosi sygnału.
Moją roboczą zasadą jest to, że każdy element wizualny na stronie powinien zająć swoje miejsce, niosąc znaczenie, którego nie można skuteczniej przekazać prozą. Diagram przedstawiający strukturę, której nie da się uchwycić słowami: zasługuje na swoje miejsce. Wizerunek bohatera, który wzmacnia nastrój, w jakim powinien znajdować się czytelnik: zasługuje na swoje miejsce. Ilustracja zdobiąca tytuł sekcji, ponieważ sekcja wyglądała na pustą: nie zasługuje na swoje miejsce. Sekcja wyglądała na pustą, ponieważ nie wymagała dekoracji, a dodanie jej i tak sprawia, że czytelnik będzie musiał ciężej pracować, aby znaleźć rzeczywistą treść.
Zasada powściągliwości dotyczy zwłaszcza typografii i koloru, gdzie sztuczna inteligencja jeszcze nie spowodowała, że rzeczy stały się tańsze, ale gdzie ważniejszy jest ten sam gust. Pojedynczy kolor akcentujący, zgodnie z rozdziałem 7, zmusza projektanta do podjęcia decyzji, co jest naprawdę ważne. Ograniczona paleta czcionek wymusza tę samą dyscyplinę w innym rejestrze. Za każdym razem, gdy narzędzie oparte na sztucznej inteligencji sugeruje „urozmaicenie” typografii lub koloru, właściwą reakcją jest zwykle odmowa, ponieważ różnorodność to dekoracja, a dyscyplina to projekt.
Szerszy punkt filozoficzny dotyczy różnicy między „co mogę zrobić” a „co powinienem zrobić”. Tanie narzędzia radykalnie rozszerzają pierwsze pytanie — możesz wygenerować wizualną różnorodność, możesz dodać ozdobników, możesz udekorować wszystko. To nie znaczy, że powinieneś. Na pytanie „należy” odpowiada się, czy dodatek pomaga czytelnikowi; na pytanie można odpowiedzieć, czy narzędzie na to pozwala. Mylące jest to, że produkty stają się coraz gorsze w miarę ulepszania narzędzi, ponieważ od narzędzi wymaga się podejmowania decyzji, których narzędzia nie mogą podjąć.
Istnieje subtelny tryb niepowodzenia, w którym praktykujący bronią swojej dekoracji, mówiąc, że „sprawia, że wydaje się bardziej żywa” lub „dodaje osobowości”. Czasami to prawda, w określonych kontekstach. Często fałszywe w tym sensie, że „większa różnorodność wizualna” dodaje dekoracji bez dodawania osobowości – osobowość to konkretny głos, a nie określona liczba ilustracji. Kiedy argumentem za elementem wizualnym jest to, że dodaje on wibracji, a nie znaczenia, właściwym rozwiązaniem jest zwykle jego wycięcie i sprawdzenie, czy czytelnik jest w gorszej sytuacji. Zwykle nie są.
Zapytaj, czy każdy element zasługuje na swoje miejsce. Wytnij to, co nie. Powściągliwość nie jest preferencją estetyczną; to szacunek dla uwagi czytelnika. Tania dekoracja wykorzystuje tę uwagę; powściągliwość to honoruje. Projekt lepiej się starzeje, a czytelnik szybciej dociera do znaczenia.
No figure. This chapter is an argument for restraint — a diagram illustrating decoration versus restraint would either be a small drawing that undermines its own point or a caricature that overstates it. The absence of a figure here is itself part of the argument.
Chapter 74
Przeciwko wywołaniom ad-hoc
Chcę przedstawić konkretną opinię, która jest sprzeczna ze sposobem pracy wielu praktyków: doraźne wywoływanie narzędzi AI to zły nawyk, a dyscyplina pojedynczych drzwi wejściowych – jak argumentowano w rozdziale 3 – jest warta początkowej niezręczności związanej z budowaniem. Nawyk „po prostu otwórz Claude” lub „po prostu otwórz ChatGPT”, gdy pojawia się pytanie, bez żadnej struktury wokół tego, co stanie się dalej, powstrzymuje umiejętności przed połączeniem się w coś większego.
Powtarzający się schemat jest taki, że praktykujący ma piętnaście lub dwadzieścia rzeczy, w których sztuczna inteligencja powinna mu pomóc, a każdą z nich rozwiązuje poprzez otwarcie nowego czatu i opisanie zadania od zera. Każda sesja to zimny start. Wyniki każdej sesji znajdują się wyłącznie w transkrypcie tej sesji. Małe zwycięstwa podczas każdej sesji nie przekładają się na nic, na czym można oprzeć następną sesję. To jak robienie stolarki bez warsztatu – każda praca wymaga ustawienia narzędzi od podstaw, bez przyrządów, szablonów i nagromadzonej praktyki.
Alternatywą jest uczynienie każdego powtarzającego się zadania umiejętnością — małym, nazwanym, ustrukturyzowanym wywołaniem z określonymi danymi wejściowymi i wynikami — i przywoływanie umiejętności poprzez spójne drzwi wejściowe. Koszt początkowy jest realny: zamiast po prostu rozmawiać, musisz pomyśleć o tym, czym właściwie jest zadanie, jak wyglądają dane wejściowe, jaki powinien być wynik, gdzie należy go zapisać. Za pierwszym razem takie myślenie wydaje się dodatkową pracą. Opłaca się to w niewielkiej liczbie powtórzeń, a potem w nieskończoność.
Stanowczo podtrzymuję tę opinię dlatego, że postępowałem odwrotnie dłużej, niż powinienem. Rozmawiałem na czacie o problemie za problemem, czując się produktywnie, ponieważ każda sesja coś przyniosła, a pod koniec roku miałem tysiące transkrypcji czatów rozproszonych po historiach usług i praktycznie bez żadnej infrastruktury łączącej. Wynik każdej sesji miał miejsce; kumulacja wyniosła zero. To był moment, w którym zbudowałem drzwi wejściowe i różnica była kolosalna.
Tryb awarii, który chcę nazwać, polega na tym, że wywołanie ad hoc jest wygodniejsze niż wywołanie strukturalne, a wygoda w tym kontekście jest znakiem ostrzegawczym. Wystarczy otworzyć czat i zacząć pisać. Trudność w pisaniu umiejętności do zadania, które będziesz wykonywać tylko okazjonalnie, wydaje się marnotrawstwem. Komfort przesłania koszt, który polega na tym, że za trzecim razem, gdy wykonujesz podobne zadanie od zera, już jesteś w gorszej sytuacji, niż gdybyś za pierwszym razem zainwestował dwadzieścia minut w jakąś umiejętność. Dyskomfort związany z niewielką inwestycją początkową to uczciwa cena łączenia.
Istnieje pewien niuans dotyczący tego, kiedy działanie ad hoc jest w porządku, i warto to uszanować. W przypadku naprawdę jednorazowych zadań, które nigdy się nie powtórzą, obciążenie związane z budowaniem umiejętności nie jest uzasadnione. Otwórz czat, zrób coś, zamknij go. Jednak błąd popełniany przez większość praktyków polega na tym, że wiele zadań, które w rzeczywistości się powtarzają, charakteryzują jako jednorazowe – jest to kategoria pracy, która będzie się powtarzać, nawet jeśli nie zaplanowano dokładnie kolejnego wystąpienia. Właściwym pytaniem nie jest „czy zrobię dokładnie to samo jeszcze raz”, ale „czy zrobię jeszcze raz coś w tym stylu” i odpowiedź zwykle brzmi „tak”.
Zbuduj drzwi wejściowe. Ustrukturyzuj powtarzającą się pracę jako umiejętności. Rezerwuj ad hoc na naprawdę jednorazowe. Nawyk będzie wydawał się kosztowny przez kilka tygodni i będzie procentował przez lata. Na tym polega handel; każdy, kto w drugim roku nadal rozmawia o pracy, nie widział jeszcze składania i nie zobaczy, dopóki nie zbudują warsztatu.
No figure. The relevant structure is Fig 3.1 — the front door — and this chapter is the opinion-argument for adopting it, so redrawing it would only re-caption the same picture.
Chapter 75
Nie poleruj makiety
W rozdziale 5 ustalono nastawienie do żeglugi. W rozdziale 17 opracowano przełącznik próbny/na żywo. Rozdział 53 opowiadał się za odznaką na wyśmiewanych danych. Ten rozdział jest uproszczoną wersją tego samego argumentu: nie poprawiaj fałszywych danych. Nie sprawiaj, żeby wyglądało to na prawdziwe. Nie trać piętnastu minut na znalezienie „właściwej” wiarygodnej próbki. Wyślij najbrzydszą, najbardziej fałszywą kpinę, która nadal oddaje kształt, i niech brzydota będzie najważniejsza.
Instynkt polerowania jest silny i należy mu aktywnie się przeciwstawiać. Kiedy tworzysz stronę lub komponent, próbne dane są wprowadzane i nie wyglądają całkiem poprawnie, w związku z czym pojawia się pokusa, aby poświęcić kilka minut na sprawienie, by wyglądały jak wiarygodne, rzeczywiste dane. Imiona, które mogą należeć do prawdziwych ludzi. Kwoty, które mogą stanowić rzeczywiste transakcje. Daty, które mogą być rzeczywistymi czasami. Piętnaście minut tu, dwadzieścia minut tam, a teraz kpina jest pięknie wykonaną podróbką, którą wszyscy w recenzji będą traktować jako prawdziwą, a właśnie tej porażce miała zapobiec odznaka z rozdziału 53.
Konsekwencje projektowe dopracowanych prób są gorsze niż ryzyko oszustwa. Kiedy próbne dane wyglądają na prawdziwe, rozmowy o produkcie skupiają się na tym, czy konkretne liczby są prawidłowe – czy dane dotyczące przychodów są wiarygodne i czy stanowisko użytkownika jest odpowiednie – zamiast na tym, czy kształt strony jest odpowiedni, bo właśnie temu miała służyć ta kpina. Polska spycha recenzentów na złą oś ocen. Brzydkie kpiny – celowo, w oczywisty sposób brzydkie – zmuszają recenzentów do przyjrzenia się strukturze, ponieważ powierzchnia nie zachęca do sprawdzenia zawartości.
Moją praktyką jest agresywne używanie fałszywych fałszywych danych. Nazwa każdego użytkownika to „Użytkownik testowy”. Każda kwota jest liczbą okrągłą. Każda data jest symbolem zastępczym. Każdy obraz jest kolorowym prostokątem. Strona nadal przekazuje swój kształt – kolumny, układ, przepływ – ale nic w danych nie udaje, że są prawdziwe. Recenzenci nie mogą się mylić co do sedna sprawy, ponieważ w żadnym wypadku nie chodzi o dane, które w widoczny sposób nie są danymi.
Jest miejsce, w którym budzi to kontrowersje: pokazy sprzedaży. Specjaliści zajmujący się produktem czasami chcą dopracowanych makiet do wersji demonstracyjnych, wychodząc z założenia, że realnie wyglądające dane pomagają kupującemu wyobrazić sobie korzystanie z produktu. Nie zgadzam się; kpina udająca prawdziwą, to kpina, która ostatecznie zostanie błędnie zapamiętana jako specyficzna cecha, której produkt w rzeczywistości nie posiada. Dywidenda demo ma charakter krótkoterminowy; problem oczekiwań dotyczących cech jest długoterminowy. W demonstracjach wolę używać niewielkich ilości autentycznie aktualnych danych lub pokazywać wyraźnie wyśmiewane dane za pomocą plakietki i przedstawiać kształt produktu jako opowieść, a nie wiarygodność jakiegokolwiek konkretnego przykładu.
Ogólna lekcja jest taka, że podróbka, która wygląda na prawdziwą, jest kategorią pułapki o szerokim zastosowaniu. Fałszywe pulpity nawigacyjne, które wyglądają naprawdę, są błędnie odczytywane. Fałszywe raporty, które wyglądają na prawdziwe, są przekazywane dalej. Fałszywe głosy, które brzmią prawdziwie, są cytowane. W każdym przypadku właściwą reakcją jest uczynienie podróbki ewidentnie fałszywą — nie chodzi o to, aby oszukać, chodzi o to, aby przekazać kształt wystarczająco wcześnie, aby informacja zwrotna mogła przekierować pracę. Oszukiwanie mija się z celem; Służy temu oczywiste fałszerstwo.
Paskudne kpiny. Fałszywe nazwiska, okrągłe liczby, kolorowe prostokąty. Zachowaj lakier, aby uzyskać prawdziwe dane, gdy nadejdą. Zadaniem kpiny jest wywołanie reakcji na kształt; wszystko, co wywołuje reakcję na substancję, wykonuje niewłaściwą pracę.
No figure. This chapter argues for restraint at the mock layer; the visual it points at is Fig 53.1's badge, which already carries the "obviously fake" message a chapter earlier.
Chapter 76
Ramy jako smak
Każdy praktykujący gromadzi zestaw ram – modeli mentalnych, wzorców kodu, heurystyk decyzyjnych – po które domyślnie sięga. Te ramy nie są neutralne; są wyrazem gustu i nazywanie ich smakiem, a nie prawdą, sprawia, że praktyka jest uczciwa. Frameworki, których używam, to te, które uważam za najbardziej przydatne; nie oznacza to jednak, że są one powszechnie poprawne, a zwłaszcza nie czyni ich szablonem, który ktokolwiek inny powinien przyjąć bez tłumaczenia.
Tryb awarii, który chcę wymienić na początku, polega na traktowaniu własnych frameworków jako obiektywnie prawidłowego sposobu pracy. Kiedy stosujesz to podejście od lat i dobrze ci służy, zaczynasz mieć wrażenie, że rzeczy są takie, jakie są, a nie takie, jakie je zorganizowałeś. Jest to kategoria dryfu poznawczego, która dotyka każdego praktykującego powyżej pewnego stażu pracy, a antidotum polega na ciągłym powtarzaniu „to jest to, co działa w moim przypadku”, a nie „tak należy to robić”.
Konkretnym przykładem, którego używam w odniesieniu do siebie, jest rozkład filarowy z rozdziału 4 — Orkiestruj, kadruj, produkuj, twórz, działaj. To pięć filarów, ponieważ to pięć kategorii, które dostrzegłem, rozkładając swoją pracę. Praca kogoś innego może zostać rozłożona na sześć lub cztery filary, albo na zupełnie inny zestaw kategorii, które słabo pasują do mojej. Zasada MECE jest słuszna – pakiet każdego praktyka powinien być ekskluzywny i wyczerpujący – ale konkretnymi filarami są gust, a nie prawo.
Ma to praktyczne znaczenie dlatego, że przeniesienie ram od jednego praktyka do drugiego zwykle wymaga tłumaczenia. Młodszy kolega, który adoptował moje filary hurtowo, odziedziczyłby etykiety bez uzasadnienia, a etykiety pasowałyby do ich pracy gorzej niż świeży rozkład. Nauczyłem się przekazywać metaramę – „rozłóż swoją pracę na filary MECE i nazwij je na podstawie własnego doświadczenia” – a nie moje konkretne odpowiedzi, które zależą od mojej konkretnej pracy.
Szersza wersja tego argumentu jest taka, że Internet jest pełen pewnych opinii na temat „właściwego sposobu” projektowania sztucznej inteligencji, a większość z tych opinii wynika z czyjegoś gustu, który stał się regułą. Weź ten smak, przełóż go na swoją rzeczywistość, zachowaj to, co pasuje, odrzuć to, co nie. Praktycy, których frameworki pożyczasz, zazwyczaj sami pożyczają od kogoś innego, a autorytet frameworka wynika z tego, że został gdzieś przetestowany, a nie z jego uniwersalnego zastosowania.
Zaobserwowałem specyficzny wzorzec niepowodzeń we wdrażaniu frameworków: ktoś czyta książkę taką jak ta lub dobrze uargumentowany post na blogu i hurtowo stosuje zawarte w niej konkretne zalecenia — te same filary, te same narzędzia, ten sam przepływ pracy. Wynik jest wersją praktyki autora zaszczepioną w ich twórczości i nie pasuje do niej, ponieważ leżąca u jej podstaw praca jest inna. Sześć miesięcy później porzucają framework i dochodzą do wniosku, że autor się mylił, gdy okazało się, że framework został źle przetłumaczony. Problemem nie był framework; problem polegał na tym, że ramy są smakiem, a smak nie przenosi się bezpośrednio.
Trzymaj się swoich założeń z przekonaniem i pokorą jednocześnie. Wyraź je jasno. Tłumacz je bezlitośnie, stosując cudze. Zaktualizuj swoje, gdy zmieni się Twoja praca. Ramy określają sposób organizacji myślenia, a nie prawdę. Konkretne ramy zawarte w tej książce – każdy z nich – są moimi roboczymi odpowiedziami, przedstawionymi jako jeden, a nie jedyny kształt dobrej praktyki.
No figure. This chapter is about the limits of frameworks, and drawing a specific framework here would undercut the point that no single framework is universal.
Chapter 77
Problem z notebookiem
Notatniki Jupyter i ich odpowiedniki — komórki uruchamiane w kolejności, wyniki przeplatane kodem, dane eksploracyjne i końcowe w tym samym pliku — stały się domyślnym sposobem udostępniania dużej części pracy AI. Używam ich. Chcę także nazwać kategorię problemów, jakie stwarzają, ponieważ entuzjazm dotyczący notebooków po cichu wyparł nawyki, które moim zdaniem mają większe znaczenie, a branża nie jest neutralna.
Specyficzny problem polega na tym, że notebooki zachęcają do programowania komórka po komórce, a programowanie komórka po komórce generuje kod, który działa tylko w określonej kolejności, w jakiej programista uruchomił komórki. Nie w kolejności, w jakiej komórki pojawiają się w notatniku — w kolejności, w jakiej klikał programista, która często jest zupełnie inna, zwłaszcza gdy wrócił, aby coś naprawić i nigdy nie przeglądał ponownie kolejnych komórek. Notatnik, który „działa” w tym sensie, że wszystkie komórki zostały pomyślnie ukończone, może w ogóle nie działać, jeśli zostanie uruchomiony od góry do dołu na świeżym jądrze, a programista może o tym nie wiedzieć.
Zależność między komórkami jest niewidoczna w samym notatniku. Żaden kompilator nie powie Ci, że komórka dwunasta zależy od zmiennej, która została ostatnio przedefiniowana w komórce ósmej, ale zmodyfikowana w komórce dwudziestej trzeciej. Możesz uruchomić komórkę dwanaście w dowolnym momencie, a ona użyje dowolnej wartości zmiennej aktualnie przechowywanej w pamięci jądra, która jest funkcją historii kliknięć, a nie porządku tekstowego notatnika. Jest to kategoria stanu ukrytego, którego nie ma w klasycznym skrypcie, generująca kategorię błędów — „w moim jądrze zadziałała, w twoim nie” — która jest specyficzna dla notebooków.
Tryb awarii, który obserwowałem wiele razy, to notatnik udostępniony jako dowód metody działania, która następnie zawodzi po odtworzeniu. Odbiorca porządkuje komórki, napotyka błąd, odsyła go autorowi, który jest autentycznie zaskoczony, bo „u mnie zadziałało”. Obydwoje mówią prawdę. Notatnik działał w jednej konkretnej historii wykonania i nie sprawdza się w przypadku ogólnym. To naprawdę nie jest problem odbiorcy; to artefakt narzędzia.
Ja w związku z tym traktuję notatniki jako miejsce do eksploracji i przekształcam działające odkrycia w zwykłe skrypty lub moduły, zanim udostępnię je komukolwiek. Notatnik to miejsce, w którym sprawdzam, co działa; skrypt jest tym, co udostępniam, ponieważ kolejność wykonywania skryptu jest jednoznaczna, a jego założenia dotyczące stanu są jednoznaczne. To kosztuje krok — destylację — którego nie podejmują entuzjaści wyłącznie notebooków, i myślę, że to właśnie ten krok zapewnia powtarzalność.
Argument Steelmana na rzecz notatników, który traktuję poważnie, jest taki, że doskonale nadają się do nauczania i prezentacji odkrywczych, ponieważ przeplatanie prozy, kodu i wyników jest naprawdę przydatne, gdy chodzi o przeprowadzenie czytelnika przez proces rozumowania. W takich kontekstach notatniki są właściwym narzędziem. Nie są one odpowiednim narzędziem do pracy produkcyjnej, którą inni ludzie będą musieli wykonywać, rozszerzać lub ufać. Artefakt nauczania, tak; artefakt produkcyjny, nie; i połączenie tych dwóch jest głównym problemem notebooka.
Używaj notatników do tego, w czym są dobrzy. Szukaj w skryptach tego, czym nie są. Nie udostępniaj notatników eksploracyjnych tak, jakby były powtarzalnymi produktami pracy; tak nie jest, niezależnie od tego, jak starannie wykonałeś komórki. Nawyk destylacji odróżnia powtarzalne prace AI od pięknie zaprezentowanych, niemożliwych do odtworzenia prac AI.
No figure. The problem is temporal — an execution history — and the honest visual would be a spaghetti-diagram of click order overlaid on cell numbers, which would be more chaotic than illuminating. The rule is short enough to state in prose.
Chapter 78
Etykieta „Native AI”.
Gdzieś w zeszłym roku określenie „natywny dla sztucznej inteligencji” zaczęło być dołączane do każdego produktu, przepływu pracy i doradztwa, które zawierały gdzieś model językowy. Sam użyłem tego wyrażenia w tej książce i chcę przez cały rozdział być wobec niego podejrzliwy, ponieważ etykieta odeszła na tyle daleko od jego użytecznego znaczenia, że obecnie jest to głównie szum, a szum podający się za sygnał warto zatrzymać się i zbadać.
Pierwotnym użytecznym znaczeniem etykiety było rozróżnienie: produkty zbudowane przy założeniu, że model sztucznej inteligencji stanowi pierwszorzędny element architektury, w porównaniu z produktami, które przykręciły model do istniejącego kształtu. Natywny AI oznaczał, że model ukształtował produkt; alternatywa – nazwijmy ją wzmocnioną sztuczną inteligencją – oznaczała, że produkt ukształtował sposób wykorzystania modelu. Rozróżnienie to było realne i warte nazwania, ponieważ te dwie kategorie często powodowały bardzo różne doświadczenia, nawet jeśli ich listy funkcji wyglądały podobnie.
Etykieta stała się w praktyce przemysłowej twierdzeniem marketingowym stosowanym przez każdego, kto chce zasygnalizować, że jest nowoczesny. Każdy startup reklamuje się jako natywny dla sztucznej inteligencji. Każda firma konsultingowa twierdzi, że ma praktykę opartą na sztucznej inteligencji. Każdy plan rozwoju produktu mówi o funkcjach natywnych AI. Kiedy etykieta dotyczy wszystkich, przestaje ona cokolwiek wyróżniać i szczerą reakcją jest albo porzucenie etykiety, albo sprecyzowanie, co masz na myśli, kiedy jej używasz.
Kiedy chcę porozmawiać o zasadniczym rozróżnieniu, moim roboczym zastępcą jest opisanie, co produkt faktycznie robi z modelem. Czy model podejmuje podstawowe decyzje, czy też pomaga ludziom je podejmować? Czy model znajduje się na krytycznej ścieżce sukcesu użytkownika, czy też pełni rolę pomocniczą? Czy kształt produktu zmienia się zasadniczo bez modelu, czy też model jest cechą, nad którą produkt może pracować? Pytania te dają konkretne odpowiedzi; „czy jest natywny dla sztucznej inteligencji” już nie.
Konsekwentnym podejrzeniem, które chcę stwierdzić, jest to, że „natywny dla AI” jako samoopis jest łagodnym negatywnym sygnałem na temat mówiącego. Nie zawsze – wielu myślących ludzi używa tego słowa w jego pierwotnym znaczeniu – ale często. Praktycy, którzy opierają się na etykiecie, często zastępują twierdzenie marketingowe argumentem dotyczącym projektu, ale nie ma tam szczegółów niezbędnych do sformułowania argumentu dotyczącego projektu. Zapytaj samozwańczy produkt natywny dla sztucznej inteligencji, co czyni go natywnym, a odpowiedzi powinny być konkretne i strukturalne; jeśli są niejasne i oparte na wibracjach, wytwórnia sygnalizuje więcej, niż zarabia.
Warto wymienić szerszy wzorzec, jaki stanowi ten przykład: branża technologiczna generuje wiele etykiet, większość z nich początkowo próbuje się wyróżnić i ulega utowarowieniu w wyniku nadużywania, a uczciwy praktyk musi na bieżąco aktualizować swoje słownictwo, gdy etykiety tracą znaczenie. „Natywny dla chmury” przeszedł ten etap dziesięć lat temu. Wcześniej „skala internetowa”. „Natywna sztuczna inteligencja” to bieżąca instancja, która zostanie zastąpiona czymś innym, a to samo podejrzenie będzie dotyczyło zastąpienia. Etykiety są wyznacznikami aktualnej mody, a nie dowodem aktualnej treści.
Bądź podejrzliwy wobec etykiety. Zapytaj o szczegóły, które się za tym kryją. Mówiąc, opisz, co faktycznie robi produkt lub praktyka, zamiast sięgać po marketingowy skrót. Substancja starzeje się lepiej niż etykiety; etykiety tracą ważność w przypadku nadmiernego użycia, a wygaśnięcie ważności już trwa.
No figure. This chapter is about vocabulary; a diagram of it would be a category tree of AI-integration types, which is both trite and out of date the moment it's printed.
Chapter 79
Na certyfikatach
Branża sztucznej inteligencji zaczęła tworzyć certyfikaty — kursy, które dają pewność, że jesteś kompetentnym praktykiem, poprzez egzaminy, odznaki i określone błogosławieństwa dostawców. Mam swoje zdanie na temat certyfikatów w ogóle, a na temat certyfikatów AI w szczególności i w tym rozdziale próbuję je wyrazić szczerze, ponieważ nie są to popularne opinie, a udawanie, że takie jest, byłoby nieuczciwe.
Powszechnie przyjmuje się, że certyfikaty stanowią dowód kompetencji — sposób, w jaki praktyk może wykazać potencjalnym klientom lub pracodawcom, że opanował pewien zasób wiedzy, zatwierdzony przez niezależny organ. W dziedzinach, w których wiedza jest stabilna, a praktyka uregulowana (medycyna, lotnictwo, prawo), certyfikaty pełnią właśnie tę funkcję i mają znaczenie. W szybko zmieniających się domenach oprogramowania zazwyczaj tak się nie dzieje, ponieważ zasób wiedzy przemieszcza się szybciej, niż certyfikaty są w stanie zaktualizować, a waluta certyfikatu wygasa w momencie jego uzyskania.
Szczególnie w przypadku sztucznej inteligencji problem ten jest poważny. Certyfikat opracowany w zeszłym roku sprawdza Twoją wiedzę pod kątem wiedzy, która jest już częściowo przestarzała — zmieniły się zachowania modeli, ewoluowały najlepsze praktyki, pojawiły się całe kategorie narzędzi lub stały się one przestarzałe. Z certyfikatu wynika, że od pewnego ostatecznego terminu wiedziałeś, co grupa ekspertów uważa za ważne; nie oznacza, że wiesz, co jest teraz ważne, a „teraz” postępuje na tyle szybko, że różnica ma znaczenie.
Głębszy problem, jaki mam z certyfikatami AI, polega na tym, że zachęcają one do zastąpienia praktyki certyfikatami. Osoba posiadająca certyfikat może wskazać go jako dowód specjalistycznej wiedzy; ktoś, kto nie ma nikogo, musi opierać się na tym, co faktycznie zrobił. Certyfikat jest łatwiejszy do wyświetlenia niż portfolio, dlatego staje się sygnałem domyślnym — a teraz sygnałem są raczej referencje niż praca, co wybiera osoby, które zdobywają referencje, a nie osoby, które pracują. Jest to dokładnie odwrotna sytuacja w przypadku domeny, w której uczy się wykonywania pracy i gdzie praca przebiega szybciej, niż mogą to zrobić referencje.
Muszę przyznać, że Steelman zapewnia, że certyfikaty stanowią podstawę. Na rynku, na którym każdy może nazywać się konsultantem AI, certyfikat przynajmniej wskazuje, że jego posiadaczowi zależy na studiowaniu czegoś. To realny sygnał, słabszy niż portfel, ale silniejszy niż nic. W przypadku zatrudniania na dużą skalę certyfikaty mogą być rozsądnym filtrem — nie dowodem kompetencji, ale zastępczym potwierdzeniem, że „potraktowałem to na tyle poważnie, aby ukończyć formalny kurs”. Zatrudniłbym certyfikowanego kandydata zamiast nieposiadającego kwalifikacji, pod warunkiem, że wszystkie pozostałe warunki będą takie same, ale zamiast obu zatrudniłbym kandydata z widocznymi działającymi artefaktami.
Moja rada dla praktyków jest taka, aby przedkładać portfolio robocze nad referencje. Wysyłaj rzeczy, publikuj je, pozwól im się przyjrzeć. Pojedynczy działający system, który rozwiązuje prawdziwy problem, przekazuje więcej informacji na temat kompetencji niż jakakolwiek certyfikacja, ponieważ można sprawdzić artefakt, zamiast ufać osobie certyfikującej. Jeśli posiadasz oba dokumenty — referencje i portfel — referencje dodadzą niewielką kwotę na marginesie. Jeśli musisz wybierać, wybierz portfolio i pozwól, aby certyfikat był miłym dodatkiem, który odbierzesz później.
Certyfikaty nie są szkodliwe. Mają po prostu słabszy sygnał, niż twierdzą, szczególnie w domenie, która porusza się tak szybko. Alternatywa — zbuduj coś, pokaż to — starzeje się lepiej i komunikuje więcej. Zdobądź certyfikat, jeśli go chcesz, ale nie przestawaj budować, przygotowując się do niego.
No figure. This chapter is an opinion about credentials; the visual it might have used — a "certificate versus portfolio" quadrant — would be either trite or unfair, and prose does the job here more honestly.
Chapter 80
Jakie błędy popełniają influencerzy
Część VIII kończy się konkretną i niepożądaną opinią: większość tego, co krąży w postaci porad dotyczących inżynierii sztucznej inteligencji udzielanych przez osoby wpływowe w mediach społecznościowych, jest błędnych w sposób wprowadzający w błąd nowszych praktyków, a określenie konkretnych powodów, dla których jest to błędne, jest warte osobnego rozdziału, ponieważ wzór błędności sam w sobie ma charakter informacyjny. To nie jest sprawa osobista i nie jest to krytyka każdego, kto ma publiczność; to taksonomia konkretnych błędów, które ciągle widzę.
Pierwszym błędem jest mylenie wersji demonstracyjnych z produktami. Wersja demonstracyjna działa jednorazowo, w kontrolowanych warunkach, dla konkretnego, wybranego przykładu. Produkt działa niezawodnie, w niekontrolowanych warunkach, w szerokiej gamie przykładów, których producent nie przewidział. Influencerzy, którzy przedstawiają imponujące dema jako dowód na to, co jest możliwe w produkcji, zwykle nie kłamią — łączą dwie kategorie rzeczy, o których widzowie nie wiedzą, że są różne. Demo naprawdę zadziałało. Wersja produktowa może w ogóle nie działać.
Drugi błąd polega na niedostatecznym uwzględnieniu obciążenia operacyjnego. Obsługa systemów zintegrowanych ze sztuczną inteligencją wymaga więcej pracy, niż sugeruje demonstracja, ponieważ model jest dynamiczną zależnością z regresjami, ograniczeniami szybkości i dziwactwami. Treści skupiające się wyłącznie na stronie pracy AI typu „zobacz, co zbudowałem po południu” zawierają prawdę na temat tego popołudnia i milczą na temat kolejnych sześciu miesięcy prac konserwacyjnych. Nowi praktykujący widzą popołudnie i nie wiedzą, że istnieje sześć miesięcy; są następnie zaskoczeni, gdy ich własne systemy wymagają sześciu miesięcy, na które nigdy nie przewidziano budżetu.
Trzecim błędem jest nadmierne przypisywanie konkretnych narzędzi. Wzorzec, który działa z narzędziem X, przypisuje się temu, że narzędzie X jest magiczne, podczas gdy często wzór działa równie dobrze z narzędziem Y lub narzędziem Z. Osoby wpływowe, których dochód zależy od powiązań z określonymi narzędziami, mają prawdziwą motywację do nadmiernego przypisywania skutecznych wzorców tym narzędziom, a odbiorcy nie zawsze potrafią odróżnić „to narzędzie włączyło wzorzec” od „ten wzorzec został pokazany przy użyciu tego narzędzia”. Właściwym pytaniem jest zawsze, czy wzór jest przenośny; zazwyczaj tak jest, a narzędzie jest wymienne.
Czwarty błąd to wzorzec „oto jak zbudować [duży system] w [małym czasie]”. W tych samouczkach prawie zawsze pomijane są części wymagające czasu rzeczywistego — projektowanie schematu, obsługa przypadków brzegowych, wdrażanie, monitorowanie, bezpieczeństwo — i dostarczanie tylko najważniejszej ścieżki, tak jakby to był cały system. Nowi praktycy próbują odtworzyć samouczek, stwierdzają, że szczęśliwa ścieżka działa, a następnie trafiają do pominiętej pracy i stwierdzają, że samouczek kłamał. Dokładnie tak nie było; po prostu nie była to kompletna wersja produkcyjna, a częściową wersję uznawano za ukończoną.
Piątym błędem jest przedstawianie najnowocześniejszych technik jako bezpośrednio praktycznych. Niektóre najnowsze badania rzeczywiście mają zastosowanie w pracy produkcyjnej; niektóre są fascynujące z akademickiego punktu widzenia i wiele lat dzielą je od bezpieczeństwa i praktyczności w rzeczywistych systemach. Influencerzy, którzy nie rozróżniają tych dwóch rzeczy, tworzą treści, które są ekscytujące w czytaniu i wprowadzające w błąd w działaniu. Nowi praktycy próbują zastosować technikę, która nie jest jeszcze gotowa, i dochodzą do wniosku, że muszą robić to źle, choć szczera odpowiedź jest taka, że technika nie była od początku gotowa.
Żaden z tych błędów nie jest złośliwy. Większość z nich jest uczciwym wynikiem dopasowania wzorców, co zasługuje na zaangażowanie – imponujące demonstracje, niewielkie inwestycje czasowe, określone narzędzia, najnowocześniejsze techniki – z tym, co faktycznie wpływa na praktykę. Częściowo nakładają się one na siebie, a w częściach, w których się rozchodzą, występują błędy. Praktycy uczący się na podstawie tych treści muszą wiedzieć, że istnieje rozbieżność i odpowiednio ją skalibrować.
Traktuj treści AI w mediach społecznościowych jako źródło pomysłów do zbadania, a nie wniosków, na podstawie których można podjąć działania. Sprawdź to na podstawie własnego doświadczenia lub doświadczenia osoby, której motywacje nie są zależne od odbiorców. Wartość jest rzeczywista po skalibrowaniu; szkoda jest realna, gdy tak nie jest. Konsumuj z otwartymi oczami i podchodź do każdej osoby wpływowej – łącznie z moją – z takim samym sceptycyzmem, za którym przemawia ten rozdział.
No figure. This chapter is a taxonomy of errors, and a diagram of them would either be too tidy to represent messy reality or too messy to be useful. The list itself is the artifact.
Part IX
Weryfikacja & Craft
Specyficzne praktyki, które zapewniają wiarygodność wyników — sprawdzanie faktów o produkcie, tworzenie artefaktów, które przetrwają zewnętrzną kontrolę, zamykanie pętli od generacji do weryfikacji oraz gust projektowy, który sprawia, że diagramy i wyniki nie stają się syrenką.
Chapter 81
Sprawdzanie faktów o produkcie
Najbardziej możliwą do uniknięcia klasą niepowodzeń, jaką zaobserwowałem — zarówno w swojej pracy, jak i u innych — jest publikowanie treści zawierających błędy rzeczowe na temat opisywanego produktu. Oświadczenie o możliwościach funkcji, które nie odpowiadają rzeczywistym funkcjom produktu. Liczba różniąca się o rząd wielkości. Zrzut ekranu przedstawiający stan, którego bieżący produkt nie może osiągnąć. Nie są to wyrafinowane błędy; są zjawiskiem codziennym i podważają zaufanie w sposób, którego odzyskanie zajmuje dużo czasu.
Zawodzi to w przepływach pracy wspomaganych sztuczną inteligencją polega na tym, że model może generować pewne, wiarygodnie brzmiące zdania na temat zachowania produktu, które jest po prostu błędne — ponieważ modelu nie było podczas tworzenia produktu, nie ma dostępu do bieżącego stanu kodu i wnioskuje o zachowaniu na podstawie ogólnego kształtu podobnych produktów. Każde zdanie opisujące konkretną funkcję może być błędne, a im bardziej szczegółowe jest twierdzenie, tym ostrożniej należy je zweryfikować przed wysyłką.
Moja dyscyplina pracy polega na tym, że każde faktyczne twierdzenie dotyczące produktu zawarte w opublikowanych treściach jest sprawdzane z rzeczywistym produktem przed publikacją. Nie „Pamiętam, że tak to działało” – sprawdzane aktywnie, patrząc na bieżący stan. To brzmi oczywiste. Jest to utwór, który najczęściej pomijam, szczególnie pod presją czasu, i jest to utwór, którego pominięcie powoduje najwięcej wstydu, którego można uniknąć.
Mechanizm, którego używam, to mała lista kontrolna uruchamiana po przygotowaniu dowolnej treści. Przeczytaj każde zdanie, które zawiera fakty. W przypadku każdego z nich zapytaj: „Czy można to zweryfikować i czy to zweryfikowałem?” Weryfikowalny oznacza, że odpowiada czemuś, co mogę potwierdzić — stronie produktu, wartości konfiguracyjnej, konkretnym wynikom. Zweryfikowane oznacza, że faktycznie dokonałem potwierdzenia, a nie, że mam taki zamiar. Każde zdanie, którego nie można zweryfikować, zostaje oznaczone do weryfikacji lub usunięcia; każde niezweryfikowane zdanie zostaje zweryfikowane przed dopuszczeniem do wysyłki.
Lista kontrolna jest nudna i to właśnie dzięki niej można na niej polegać. To pięciominutowy fragment na końcu tekstu, w którym wychwytuje się większość błędów, które w przeciwnym razie wprawiłyby statek w zakłopotanie. Pomijanie tego pod presją czasu jest fałszywą oszczędnością — pięć minut zaoszczędzonych przed publikacją zamienia się później w godziny naprawy zaufania, a pojawiające się konkretne błędy często sprawiają, że cały dokument wydaje się niewiarygodny, a nie tylko błędny w jednym punkcie.
Istnieje dodatkowa dyscyplina, która ma zastosowanie w samym procesie tworzenia projektu: kiedy modelka tworzy treść na temat produktu, poproś ją, aby rozróżniła między twierdzeniami, co do których jest pewna, a twierdzeniami, które wnioskuje. Nie dlatego, że model zawsze będzie wyczuwał różnicę – często tak się nie dzieje – ale dlatego, że wymuszenie na modelu zabezpieczenia tworzy tekst, który łatwiej jest zweryfikować. Zdanie, które mówi „ta funkcja wykonuje X (weryfikuj)” jest łatwiejsze do sprawdzenia niż to samo zdanie wyrażone z pewnością, a końcowe tokeny „(weryfikuj)” stanowią tanie ubezpieczenie podczas tworzenia wersji roboczej.
Zweryfikuj każde twierdzenie oparte na faktach. Użyj nudnej listy kontrolnej. Wymuś, aby model zabezpieczył się przed niepewnością. Wykonuj kontrolę nawet pod presją czasu; zwłaszcza wtedy. Opublikowany błąd, którego unikniesz, jest wart znacznie więcej niż pięć minut potrzebnych na jego wyłapanie.
Fig 81.1 — The Fact-Check Pass. Every factual sentence in the focal check-pass gets asked two questions — verifiable, verified. Cheap in advance; expensive in retrospect if skipped, because errors in published product content are the ones that stick.
Chapter 82
Artefakty Esbuild-Clean
Ten rozdział dotyczy konkretnego paska jakości artefaktów wytwarzanych przez system, używając słowa „esbuild-clean” jako skrótu. Słowo to pochodzi z narzędzi JavaScript — esbuild to program pakujący, który odmówi ukończenia kompilacji, jeśli cokolwiek jest zniekształcone — i zacząłem używać go szerzej do opisania artefaktów, które bez reklamacji przechodzą najsurowszą rozsądną kontrolę strukturalną. Artefakt generujący ostrzeżenia, wymagający ręcznych poprawek lub powodujący problemy programowe nie jest usuwalny w trybie esbuild; poprzeczką jest to, że wytrzymuje rygorystyczne oprzyrządowanie bez ręcznej regulacji.
Ma to znaczenie, ponieważ artefakty generowane przez sztuczną inteligencję często są dostarczane z subtelnymi problemami strukturalnymi, które indywidualnie są niewielkie — nieużywany import, niedopasowany typ, brakujący średnik, przypadkowy biały znak — którymi żaden człowiek nie przejmowałby się indywidualnie, ale które kumulują się w tle niskiej jakości cruftu. Każdy z nich łatwo jest zostawić w spokoju. Łącznie sygnalizują artefakt, który został wyprodukowany niestarannie, a dalsze narzędzia, które oczekują czystych artefaktów, zaczynają się nimi dławić.
Dyscypliną jest traktowanie „przechodzi rygorystyczne oprzyrządowanie bez ostrzeżeń” jako definicję kompletności. Jeśli linter narzeka, nie jest to zrobione. Jeśli moduł sprawdzania typu ostrzeże, oznacza to, że nie jest to zrobione. Jeśli program formatujący miałby to przepisać, nie jest to zrobione. Jest to bardziej rygorystyczny standard niż większość baz kodu i to właśnie ten standard zapewnia trwałość artefaktu — ponieważ każde ostrzeżenie tolerowane obecnie w kodzie jest ostrzeżeniem, które będzie się kumulować z następnym ostrzeżeniem i następnym, aż sygnał narzędzia zatonie w szumie.
Cechą charakterystyczną sztucznej inteligencji jest to, że gdy model tworzy kod lub treść, z radością wygeneruje dane wyjściowe, które są technicznie funkcjonalne, ale niechlujne — dodatkowe importy, zbędne warunki, niespójny styl. Nieskorygowane, niechlujstwo to z czasem gromadzi się w kodzie. Moją praktyką jest poddawanie każdego artefaktu wyprodukowanego przez model rygorystycznej procedurze przed jego zaakceptowaniem oraz naprawianie lub odrzucanie wszystkiego, co generuje ostrzeżenia. Model można poprosić o naprawienie własnego wyniku; często można to zrobić niewielkim kosztem. Jedyne, czego nie może zrobić, to wiedzieć, że wynik jest nie do zaakceptowania, jeśli nie zostanie o tym poinformowany.
Mechanizm, którego używam, polega na tym, że dane wyjściowe każdej umiejętności są przesyłane przez mały krok „czystego sprawdzenia”, zanim zostaną zapisane w magazynie artefaktów. Jeśli test zakończy się pomyślnie, artefakt zostaje zapisany; jeśli się nie powiedzie, wynik kontroli jest zwracany do modelu z prośbą o naprawę, aż do pewnego limitu ponownych prób. Powyżej tego limitu przebieg kończy się niepowodzeniem i patrzę na to. Oznacza to, że artefakty, które trafiają do sklepu, są z założenia czyste po zbudowaniu; te, którym nie udało się tego osiągnąć, nigdy nie wylądowały na pierwszym miejscu.
Pod spodem kryje się szersza zasada, która głosi, że standardy jakości muszą być egzekwowane za pomocą narzędzi, gdy tylko jest to możliwe, ponieważ ludzka dyscyplina zanika pod presją czasu, a oprzyrządowanie nie. Zespół, który kieruje się zasadą „zawsze sprawdzamy X przed wysyłką”, czasami nie sprawdza X, gdy jest zajęty; system kompilacji, który nie zostanie ukończony, gdy X nie będzie czysty, zawsze będzie sprawdzał X, na zawsze. Przenieś standard z dyscypliny do egzekwowania, a standard przetrwa.
Ścisłe oprzyrządowanie, tolerowane zero ostrzeżeń. Prześlij błędy z powrotem do modelu w celu naprawy. Egzekwuj jakość poprzez konstrukcję, a nie nadzieję. Esbuild-clean nie jest terminem używanym wyłącznie w języku JavaScript; jest to wyznacznik jakości, który warto zastosować we wszystkim i warto się go bronić przed krytyką typu „no cóż, to działa, więc…”, która zawsze pojawia się, gdy ktoś nie chce naprawić małych rzeczy.
No figure. The point is a strict pass/fail check; the diagram is a trivial arrow from output through tooling to either "clean → ship" or "warnings → fix". The value is in adopting the standard, not in drawing it.
Chapter 83
Ustrukturyzowane artefakty zamykają pętlę
Każda znacząca rzecz wytwarzana przez system powinna być ustrukturyzowanym artefaktem — plikiem, rekordem, dokumentem o znanym kształcie — ponieważ ustrukturyzowane artefakty są jedynym rodzajem, który zamyka pętlę weryfikacji. Można przeglądać nieustrukturyzowane dane wyjściowe; Ustrukturyzowane wyniki można sprawdzać, porównywać, agregować i poddawać audytowi. Różnica nie jest kosmetyczna; chodzi o to, czy weryfikacja jest w ogóle możliwa.
Wzorzec, który chcę nazwać, jest taki, że gdy wyniki systemu są ustrukturyzowane, weryfikacja na dalszym etapie staje się wykonalna. Raport sporządzony według znanego schematu można sprawdzić pole po polu pod kątem oczekiwań. Wygenerowany plik pasujący do znanego formatu można porównać z poprzednimi wersjami. Do strukturalnego śledzenia można wysyłać zapytania pod kątem anomalii. Każdy z nich zależy od tego, czy wynik ma kształt, na który możesz wskazać; nieustrukturyzowane dane wyjściowe — dowolny tekst, pliki typu blob, nieoznaczone obiekty typu blob danych — nie mogą być sprawdzane systematycznie, a jedynie naocznie.
Konkretna pętla weryfikacji, na której mi zależy, wygląda następująco: system wytwarza artefakt, sprawdza artefakt, a kontrola albo potwierdza, że artefakt spełnia kryteria, albo podaje, co jest nie tak. Pętla ta musi działać automatycznie, bez interwencji człowieka, aby produkcja artefaktów była wiarygodna na dużą skalę. Ta pętla jest możliwa tylko wtedy, gdy artefakt ma wystarczającą strukturę, aby automatyczne kontrole miały coś do sprawdzenia.
W przypadku wyników generowanych przez sztuczną inteligencję istnieje pokusa zaakceptowania ich jako prozy, ponieważ model w naturalny sposób tworzy prozę. Każda akceptacja prozy, w przypadku której możliwe było ustrukturyzowane wyjście, jest małą porażką pętli weryfikacyjnej, ponieważ prozy nie można w żaden głęboki sposób automatycznie sprawdzić. Zmuszanie modelu do wytwarzania ustrukturyzowanych wyników — nawet za pewnym kosztem w przypadku szybkiej inżynierii — to dyscyplina, która umożliwia automatyzację dalszych etapów. Ustrukturyzowane dane wyjściowe są łatwiejsze nie tylko dla maszyn; jest to warunek wstępny, aby maszyny mogły pomóc w weryfikacji.
Właściwy kształt zależy od artefaktu. W przypadku raportu może to być plik JSON ze zweryfikowanym schematem i wyrenderowanym dokumentem. W przypadku fragmentu kodu jest to sam kod plus jego podpisy typów. W przypadku obrazu jest to obraz plus metadane opisujące to, co przedstawia. W przypadku diagramu jest to źródło wektora plus opis. Schemat jest zawsze taki sam — formularzowi skierowanemu do człowieka towarzyszy formularz sprawdzalny maszynowo, a pętla weryfikacyjna faktycznie działa na formularzu sprawdzalnym maszynowo.
Istnieje dodatkowa dyscyplina dotycząca tego, jakie powinny być kontrole weryfikacyjne. Nie tylko strukturalny (JSON jest prawidłowy), ale semantyczny (wartości w JSON mają sens w odniesieniu do domeny). Kontrole raportu mogą obejmować „uzgadnianie sum”, „kategorie pochodzą ze znanego zestawu”, „żadne pole nie jest puste, jeśli nie powinno być”. Kontrole semantyczne wyłapują błędy pomijane w kontrolach strukturalnych i są możliwe tylko wtedy, gdy struktura artefaktu jest wystarczająco bogata, aby wyrazić, co oznaczałoby „poprawne”.
Twórz ustrukturyzowane artefakty. Zweryfikuj je automatycznie. Uwzględnij kontrole semantyczne, a nie tylko strukturalne. Pętla weryfikacyjna zamyka się tylko wtedy, gdy artefakt ma kształt, na którym można przeprowadzić kontrolę; nieustrukturyzowane dane wyjściowe pozostawiają pętlę otwartą, a w otwartych pętlach błędy przedostają się do opublikowanych prac.
Fig 83.1 — Structure Closes the Loop. The focal structured artifact is what makes the automated checks tractable — schema-validatable, semantically inspectable. Prose-only output leaves the loop open; structure is what lets it close.
Chapter 84
Diagramy bez syrenki
Diagramy w tej książce mają kształt dłoni w formacie SVG — wykonane na zamówienie współrzędne, celowa typografia, powściągliwe użycie akcentu — i chcę poświęcić rozdział na wyjaśnienie dlaczego, ponieważ dominującą alternatywą dla diagramów generowanych przez sztuczną inteligencję jest składnia syreny renderowana na diagram, a wynik tego potoku jest tym, co nazwałem „syreńskim błotem”. Nie jest to krytyka narzędzia Mermaid, które jest przydatne w odpowiednim kontekście; jest to krytyka używania Syreny jako substytutu projektu.
Specyficznym trybem awarii Mermaid Slop jest to, że każdy diagram wygląda tak samo. Te same zaokrąglone prostokąty, ta sama domyślna paleta, te same automatycznie układane strzałki, ta sama ogólna typografia. Narzędzie rozwiązuje problem rysowania tak całkowicie, że problem projektowy — co powinien podkreślać ten diagram, co powinien oddalić, gdzie powinien wylądować wzrok — nigdy nie zostanie w ogóle rozwiązany, ponieważ narzędzie nigdy nie zadało pytania. Rezultatem jest diagram zawierający informacje, ale bez głosu redakcyjnego, a to głos redakcyjny sprawia, że diagram jest warty oglądania, a nie tylko czytelności.
Alternatywa — wykonany na zamówienie plik SVG, ręcznie skomponowany — zajmuje więcej czasu w przypadku diagramu, a dodatkowy czas jest tam, gdzie żyje wartość. Zdecyduj, jakiego koloru powinien być akcent. Decydowanie, które pudełko jest ogniskowe. Decydowanie, gdzie powinien znaleźć się podpis. Podejmowanie decyzji, czy diagram jest w ogóle potrzebny, czy też akapit lepiej spełni swoje zadanie. Każda z tych decyzji jest drobnym aktem projektowym, a ich kumulacja sprawia, że księga diagramów staje się książką, do której naprawdę chcesz zajrzeć.
Podejście sztucznej inteligencji jest takie, że sztuczna inteligencja jest bardzo dobra w tworzeniu składni syreny na żądanie — powiedz „narysuj to”, a utworzy ona syntaktycznie poprawną syrenę, która opisuje kształt. To, czego nie radzi sobie dobrze, przynajmniej nie bez uważnego podpowiedzi, to tworzenie na zamówienie, powściągliwego SVG, który uwzględnia określony system projektowy. Zatem pokusą, zwłaszcza dla praktykujących ścigających się z czasem, jest zaakceptowanie rezultatu Syreny i pójście dalej. W rezultacie powstają dokumenty pełne syren, z których wszystkie przekazują mniej więcej te same informacje i żaden z nich nie ma głosu.
Stosuję dyscyplinę polegającą na tym, że każdy diagram pojawiający się w publikowanym przeze mnie dokumencie jest ręcznie komponowany z systemem projektowym, nawet jeśli początkowy pomysł pochodzi z wersji roboczej Mermaid wygenerowanej przez sztuczną inteligencję. Wersja robocza Syreny jest przydatna — mówi mi, jakie pola i strzałki są potrzebne, które węzły są najważniejsze — ale ostateczny plik SVG jest tworzony przeze mnie (lub przez model z bardzo szczegółowym monitem zawierającym żetony projektu i ograniczenia), a nie akceptowany jako wygenerowany. Dodatkowy czas na diagramie jest rzeczywisty; skumulowana spójność estetyczna jest tego warta.
Wiąże się z tym szerszy argument dotyczący gustu, który jest taki, że narzędzia AI zwykle generują wyniki, które odpowiadają średniej ich danych szkoleniowych, a średnia w każdej dziedzinie kreatywności jest przeciętna. Projektowanie to w szczególności dziedzina, w której bycie przeciętnym daje nudne wyniki, a nudne wyniki są tym, co łączy większość diagramów generowanych przez sztuczną inteligencję. Pobicie średniej wymaga albo solidnego systemu projektowego w postaci szybkiego rusztowania, albo ręcznego komponowania – a jedno i drugie wymaga więcej wysiłku niż zaakceptowanie rozwiązania domyślnego. Ten dodatkowy wysiłek odróżnia przemyślane dokumenty od przeciętnych.
Ręcznie utwórz diagramy, które pojawią się w opublikowanej pracy. Użyj powściągliwego systemu projektowania. Przyjmuj wersje robocze Syreny jako pomoce w myśleniu, a nie jako ostateczne wyniki. Każdy diagram warty zamieszczenia zasługuje na dodatkową przepustkę; wszystko, co nie jest warte dodatkowej przepustki, nie jest warte uwzględnienia.
No figure. This chapter argues for restraint in diagram production; the whole book is its own figure, in the sense that every earlier diagram is an example of the discipline this chapter names. A Mermaid slop example here would be uncharitable and would defeat the argument by inclusion.
Chapter 85
Typ Bezpieczeństwo w szwach
Kiedy umiejętność przekazuje dane innej umiejętności lub gdy dane wyjściowe serii są przekazywane z powrotem do danych wejściowych następnej serii, interfejs między nimi jest spójny. Błędy to miejsca, w których kumulują się błędy, ponieważ obie strony przyjmują założenia na temat tego, co jest po drugiej stronie, a niewielkie odchylenia w którymkolwiek z założeń powodują subtelne błędy. Bezpieczeństwo typów na szwach — wymuszanie, aby dane przepływające przez szew miały kształt, jakiego oczekują obie strony — to jedna z najważniejszych dyscyplin, jakie przyjąłem.
Schemat awarii bez bezpieczeństwa typu jest znany. Umiejętność A tworzy obiekt z określonymi polami. Umiejętność B zużywa obiekt z określonymi polami. Obydwa działają w izolacji. Ktoś modyfikuje A, aby dodać nowe pole lub zmienić nazwę istniejącego, nie zastanawia się nad sprawdzeniem, co zależy od A, a B psuje się w pewnym momencie w przyszłości, gdy trafiony zostanie dokładny przypadek Edge. Przerwa jest subtelna, ponieważ dane wyjściowe A wyglądają w przybliżeniu poprawnie, a awaria B wygląda na błąd B, więc wyizolowanie pierwotnej przyczyny zajmuje wiele godzin.
Bezpieczeństwo typu na szwie przenosi tę awarię z awarii środowiska wykonawczego do błędu w czasie kompilacji lub w czasie kompilacji. Szew formalnie deklaruje swój kształt: A obiecuje wyemitować obiekt z polami tego typu; B deklaruje, że oczekuje obiektu z tymi polami. Wszelkie niezgodności są wychwytywane przed wykonaniem kodu, w momencie wprowadzenia niezgodności. Cechą charakterystyczną sztucznej inteligencji jest to, że gdy model generuje kod, który krzyżuje się ze sobą, kontrola typu działa jak automatyczna weryfikacja danych wyjściowych modelu — model nie może wyemitować czegoś, co nie pasuje do interfejsu, bez zauważenia tego przez moduł sprawdzający typ.
Dyscyplina polega na wyraźnym rysowaniu szwów wszędzie tam, gdzie dane przekraczają granicę. Między umiejętnościami. Między czasem wykonania a jego trwałością. Pomiędzy frontendem a backendem. Między agentem a jego narzędziami. Każda z tych granic zasługuje na wyraźny typ — schemat, definicję interfejsu, typ na poziomie języka — na który zgadzają się obie strony. Ilość pracy AI w utrzymaniu tego typu jest banalna; ilość pracy włożona w wyłapanie błędów, którym zapobiegają, jest ogromna.
Mechanizm, który sprawia, że jest to praktyczne, to typy, które są tanie w zdefiniowaniu i tanie w sprawdzeniu. W bazach kodu używam biblioteki do pisania TypeScript lub Pythona; w sytuacjach przesyłania danych korzystam ze schematów JSON lub definicji protobuf. Nie liczy się konkretna technologia – liczy się to, że szew ma formalny kształt, co do którego można sprawdzić obie strony, a weryfikacja odbywa się automatycznie. Ręczna dokumentacja interfejsów nigdy nie działała w bazach kodu, które oglądałem; automatyczne sprawdzanie typu zawsze ma.
Warto wymienić konkretną pułapkę AI. Kiedy agent generuje ustrukturyzowane dane wyjściowe, które trafiają do kolejnego narzędzia, dane wyjściowe agenta powinny zostać sprawdzone pod kątem schematu przed przekazaniem ich do narzędzia. Nie dlatego, że agent kłamie, ale dlatego, że może wygenerować prawie prawidłowe dane wyjściowe w sposób, który w określonych przypadkach spowoduje awarię narzędzia. Walidacja na szwie wychwytuje je, zanim się rozprzestrzenią, i można poprosić model o regenerację zgodnie ze schematem, aż będzie zgodny. Szew sprawia, że agentowe użycie narzędzi jest bezpieczne na dużą skalę.
Narysuj typy na każdym szwie. Egzekwuj je automatycznie. Sprawdź wyniki modelu przed przekroczeniem szwu. Typy to mechanizm, który przekształca interfejsy z konwencji w kontrakt; bez nich każdy szew to wypadek, który może wydarzyć się w najmniej dogodnym momencie.
No figure. The pattern is a formal type at a boundary, which is code, not diagram. The implicit visual is the adapter shape from Fig 16.1 with the interface annotated as a type — same picture, richer boundary.
Chapter 86
Karnet Recenzyjny
Zanim cokolwiek wyślę do klienta, jest on poddawany specjalnej recenzji — ustrukturyzowanemu ponownemu przeczytaniu, którego celem jest uchwycenie wszystkiego, co przeoczyło początkowe pisanie. W przypadku większości artefaktów przejście zajmuje od piętnastu do trzydziestu minut i jest to najbardziej niezawodny krok w kierunku poprawy jakości, jaki znam. Pomijanie tego wydaje się skuteczne; Za każdym razem oszczędza to więcej czasu niż kosztuje.
Przepustka ma specyficzną strukturę, którą udoskonalałem przez lata. Najpierw przeczytaj: czy argumentacja jest spójna? Czy każdy akapit wynika z poprzedniego i czy całość gdzieś się buduje? Druga lektura: czy szczegóły są prawidłowe? Każdy nazwany fakt, każda liczba, każde twierdzenie na temat produktu. Trzecia lektura: czy ton jest odpowiedni? Czy to brzmi jak ja, w rejestrze, jakiego oczekuje publiczność, bez popadania w korporacyjną gadkę i sztuczną przypadkowość? Czwarta lektura: czego brakuje? Jakie pytanie zadałby inteligentny czytelnik, na które nie ma tutaj odpowiedzi?
Struktura obejmująca cztery odczyty ma znaczenie, ponieważ oddziela obawy, które w jednym czytaniu zacierałyby się. Kiedy czytam dla spójności, nie rozpraszają mnie pytania dotyczące faktów. Kiedy czytam dla faktów, nie oceniam tonu. Każde przejście koncentruje się na jednym celu, co pozwala mi faktycznie zauważyć konkretne problemy, których szuka. Pojedyncza przepustka w stylu „pozwól mi to przeczytać” zwykle omija wszystko, ponieważ uwaga nie jest skupiana na tyle wnikliwie, aby uchwycić cokolwiek konkretnego.
Dyscyplina między podaniami jest równie ważna jak podania. Nie robię wszystkich czterech na jednym posiedzeniu. Robię test spójności, odkładam dokument na co najmniej kilka godzin, wracam po przepustkę faktyczną, odkładam ponownie i tak dalej. Dzięki lukom przy każdym przejściu dokument jest świeży; ciągłe przeglądanie dziedziczy zmęczenie poprzedniego przejścia i staje się coraz mniej przydatne. Lepiej mniej podań z prawdziwymi przerwami, niż więcej podań jeden po drugim.
Punkt widzenia sztucznej inteligencji jest taki, że sztuczna inteligencja może pomóc przy podaniach, ale nie powinna ich zastępować. Model może oznaczać prawdopodobne błędy rzeczowe, sugerować ulepszenia strukturalne, wskazywać problemy z tonem — wszystkie przydatne dane wejściowe. Model nie może natomiast ocenić, czy dokument faktycznie spełnia swoje zadanie wobec konkretnego odbiorcy, czy mówi to, co chciałem powiedzieć, czy nacisk jest odpowiedni. Te osądy pozostają moje, a podania są tam, gdzie je wydaję.
Przyczyną niepowodzenia pominięcia przeglądu jest to, że wersja dokumentu z dnia wysyłki jest prawie zawsze zauważalnie gorsza od wersji, którą wysłałbym, gdybym przeszedł pomyślnie. Nie katastrofalnie gorsze — różnice są zwykle niewielkie — ale stale obecne i na wielu dokumentach nakładają się na tło o nierównych krawędziach, których można uniknąć. Klienci nieświadomie zauważają, kiedy otrzymana przez nich praca została sprawdzona, a kiedy nie; wersję recenzowaną czyta się jako przemyślaną, wersję niesprawdzoną jako odpowiednią.
Cztery skupione przejścia, rozmieszczone w czasie. Różne pytanie na każde przejście. Używaj sztucznej inteligencji jako wejścia, a nie zamiennika. Przegląd ma miejsce wtedy, gdy kompetentna praca staje się celowo dobrą pracą, a różnica między nimi polega na tym, na czym buduje się trwałe relacje z klientami.
No figure. Four sequential passes are trivially depicted as arrows, and the diagram would add nothing to the argument that the passes need to be separated in time.
Chapter 87
Testy właściwości dla podpowiedzi
Tradycyjne testy sprawdzają, czy określone dane wejściowe dają określone wyniki. Testy właściwości sprawdzają, czy dane wejściowe spełniają określone właściwości — dane wyjściowe są zawsze posortowane, zawsze niepuste i zawsze w prawidłowym stanie. W przypadku kodu testy właściwości są dojrzałą dyscypliną. W przypadku podpowiedzi są one rzadko używane i szczególnie dobrze nadają się do pracy ze sztuczną inteligencją, ponieważ podpowiedzi działają probabilistycznie, a testy z określonymi danymi wejściowymi mogą na szczęście przejść pomyślnie, pomijając szerokie klasy niepowodzeń.
Motywacją, która mnie do tego zmotywowała, było obserwowanie podpowiedzi, które przekazały konkretne przykłady, pod kątem których je przetestowałem, a które w przewidywalny sposób zawiodły na danych wejściowych, których specjalnie nie sprawdziłem. Podpowiedź „zadziałała” na moich dziesięciu przykładach i zepsuła się na jedenastym, a jedenasty był strukturalnie podobny do jednego z dziesięciu w sposób, który powinien sprawić, że zadziałał. Brakowało testu właściwości „dla wejść o tym kształcie wynik powinien zawsze spełniać X”, a nie testu konkretnych par wejście-wyjście.
Mechanizm polega na generowaniu wielu danych wejściowych dla interesującej Cię klasy — albo z rzeczywistej dystrybucji, albo z syntetycznej dystrybucji zaprojektowanej do obsługi przypadków brzegowych — uruchamiając je w wierszu zachęty i sprawdzając dane wyjściowe pod kątem wymaganych właściwości. Właściwość może być strukturalna (każdy wynik ma ten sam schemat), semantyczna (każdy wynik mieści się w prawidłowym zakresie wartości) lub behawioralna (wynik zmienia się odpowiednio, gdy zmieniają się określone aspekty wejściowe). Liczy się to, że właściwość jest określona na tyle jasno, że można ją automatycznie sprawdzić na wielu próbkach.
Testowanie właściwości jest szczególnie przydatne przy wychwytywaniu regresji modelu typu opisanego w rozdziale 66. Kiedy model jest aktualizowany i określone wyniki nieznacznie się zmieniają, ale właściwości nadal się utrzymują, system kontynuuje pracę; gdy właściwości przestaną być przechowywane, test właściwości zostanie uruchomiony natychmiast, zanim jakikolwiek klient zobaczy regresję. Różni się to jakościowo od testów opartych na przykładach, które przechodzą lub kończą się niepowodzeniem na podstawie tożsamości — przesunięcie wyniku zachowujące właściwość jest fałszywym niepowodzeniem na przykład w testach i prawidłowym pozytywnym zaliczeniem testów właściwości.
Wadą testów właściwości jest to, że są one tak dobre, jak właściwości, które zamierzasz sprawdzić. Test właściwości, który sprawdza tylko, czy dane wyjściowe nie są puste, wychwytuje tylko błąd dotyczący pustych wyników; czegokolwiek jeszcze brakuje. Zatem projektowanie właściwości jest miejscem, w którym żyje inteligencja i jest iteracyjne — zacznij od oczywistych właściwości, obserwuj, które błędy nadal się pojawiają, dodaj właściwości, aby je wychwycić. Z biegiem czasu zestaw właściwości skupia się na czymś, co wychwytuje większość klas awarii, a pozostałe awarie to te, których właściwości naprawdę nie mogły przewidzieć.
Warto wymienić wymiar kosztów. Przeprowadzenie testu właściwości na wielu próbkach kosztuje wiele wywołań modeli. W przypadku konkretnego produktu, który jest wysyłany do produkcji, koszt ten jest dobrze uzasadniony; w przypadku prac eksploracyjnych może to być przesada. Moją roboczą zasadą jest to, że każdy monit wysyłany do klienta otrzymuje pakiet nieruchomości; podpowiedzi eksploracyjne tego nie robią. Pasek „wysyłki” nie znajduje się w tym miejscu „w produkcji”, ale „oczekuje się, że będzie działać niezawodnie w przypadku danych wejściowych, których osobiście nie widziałem” – co jest większością podpowiedzi skierowanych do klienta.
Zapisz właściwości monitów o wysyłkę. Próbka z realistycznych rozkładów. Obserwuj niepowodzenia i dodaj właściwości pominiętych zajęć. Testy właściwości zmieniają „podpowiedź działa na moich przykładach” w „podpowiedź działa na klasie danych wejściowych, które faktycznie zobaczy”, co jest znacznie silniejszym twierdzeniem.
No figure. Property testing is a code-level pattern whose visual representation is a test file, which belongs in a repo rather than a book. The value is in adopting the discipline, and the diagram of many samples running through a prompt is trite once described.
Chapter 88
Wysyłka źródła prawdy
Każdy długoterminowy system kliencki, który tworzę, ostatecznie potrzebuje źródła prawdy — konkretnego miejsca, w którym znajduje się kanoniczna odpowiedź na pytanie „jaki jest obecny stan”, tak aby konsumenci na dalszym etapie, pulpity nawigacyjne, eksporty i raporty wskazywały na tę samą podstawową rzeczywistość. Decydowanie, jakie jest to źródło i obrona jego autorytetu przed kuszącymi alternatywami, to specyficzne rzemiosło, któremu warto poświęcić rozdział.
Najczęściej obserwowany przeze mnie tryb awarii to systemy z dwoma lub trzema źródłami, które miały się ze sobą zgadzać, a tak nie jest. Baza danych i pamięć podręczna. Sklep operacyjny i sklep raportujący. Aktywne API i nocny eksport. Dowolne dwie niezgodności powodują takie samo zamieszanie – który z nich ma rację? — a odpowiedź często brzmi: „Ani dokładnie, obaj na przestrzeni czasu na różne sposoby oddalili się od ideału”. Aby temu zapobiec, wystarczy wskazać na wstępie jedno z nich jako źródło prawdy i sprawić, by pozostałe z niego jednoznacznie wywodziły się.
Nazwane źródło ma autorytet, którego nie mają źródła pochodne. Każdy zapis trafia najpierw do źródła; sklepy pochodne doganiają źródło. Każdy odczyt wymagający dokładności odczytuje ze źródła; sklepy pochodne obsługują odczyty, w których akceptowalna jest nieaktualność. Każde uzgodnienie jest sprawdzane ze źródłem; Spory między sklepami pochodnymi są rozwiązywane poprzez sprawdzenie, co mówi źródło. Źródło jest arbitrem, a co drugi sklep to dalszy czytelnik z podrzędną rolą.
Z punktu widzenia sztucznej inteligencji systemy agentowe wytwarzają wiele stanów — ślady, artefakty, wyniki pośrednie — i kuszące jest przechowywanie ich w dogodnym miejscu na każdym etapie. Bez dyscypliny opartej na źródle prawdy otrzymasz ten sam ślad podsumowany w trzech miejscach, z których każde odbiega od innych i nie można stwierdzić, który jest kanoniczny. Zasada polega na wyznaczeniu od początku jednego magazynu jako wiarygodnego — zwykle samego dziennika śledzenia — i traktowaniu wszystkich pozostałych jako wyprowadzeń, które można na jego podstawie odbudować.
Konsekwencją tego jest to, że wszystko, czego nie ma w źródle prawdy, nie liczy się. Jeśli zagregowany pulpit nawigacyjny pokazuje liczbę, której nie można odtworzyć ze źródła, liczba jest błędna; jeśli raport zawiera artefakt, do którego odniesienia nie ma w źródle, artefakt jest bezstanowy. Jest to niewygodne na początku, ponieważ oznacza, że nie można oszukiwać — każdy wyświetlany element stanu musi pochodzić z legalnego miejsca — i to właśnie ten dyskomfort zapewnia uczciwość systemów. Oszukiwanie powoduje krótkotrwałą wygodę i długoterminowy dryf.
Podstawowa zasada projektowania jest taka, że „spójność” jest właściwością systemu z jednym autorytatywnym magazynem; nie jest to możliwe w przypadku wielu równych sklepów. Literatura dotycząca systemów rozproszonych wie o tym od dziesięcioleci. Systemy AI dziedziczą dokładnie tę samą zasadę: wybierz swój wiarygodny sklep, wyprowadź wszystko inne, a problem spójności stanie się łatwy do rozwiązania. Spróbuj mieć wiele źródeł prawdy, a wymyślisz własną wersję rozwiązanego problemu, a mylisz się w ten sam sposób, w jaki robili to wcześniejsi praktycy.
Podaj źródło. Spraw, aby wszystko inne było pochodną. Odmawiaj pokazywania czegokolwiek, czego nie można prześledzić. Spójność, jaką uzyskujesz, nie jest darmowa — wymaga dyscypliny w zakresie zapisów — i jest to właściwość, która zmienia kolekcję sklepów w system, któremu możesz zaufać.
No figure. The pattern is a hub-and-spoke with the source at the centre and derived stores radiating outward — a shape drawn many times in every distributed-systems textbook. Redrawing it here would add nothing.
Chapter 89
Kontrola tonu
Każdy fragment treści kierowanej do klienta przechodzi specjalną kontrolę, którą nazywam kontrolą tonu: czytanie dokumentu na głos lub prawie na głos w myślach i nasłuchiwanie, gdziekolwiek ucichnie głos. Ponieważ ton to element, w którym pisma wspomagane sztuczną inteligencją najczęściej popełniają błędy, a klienci zauważają spadki tonu na poziomie poniżej świadomej świadomości — nie mówią, że „ton był wyłączony”, po prostu schodzą z nieco mniejszym zaufaniem, niż mieliby w innym przypadku.
Konkretne poślizgi tonowe, na które zwracam uwagę, to te. Nagłe przejście do języka korporacyjnego, gdzie dokument, który czytało się jak po ludzku, nagle bez powodu zaczyna mówić o „wykorzystaniu synergii” lub „dostarczeniu wartości”. Niesamowita swoboda, w której dokument stara się brzmieć przyjaźnie i kończy się na początkach typu „hej, więc…”, które nie pasują do niczego innego w tym utworze. Nadmierne zabezpieczenie, w przypadku którego każde twierdzenie jest opatrzone trzema ostrzeżeniami, dopóki czytelnik nie będzie w stanie stwierdzić, co się właściwie mówi. Biurokratyczny głos pasywny, gdzie „zrobiliśmy X” zmienia się w „X zostało podjęte”. Każdy z nich jest mały i każdy z nich podważa wiarygodność.
Proza generowana przez sztuczną inteligencję jest szczególnie podatna na określone wpadki, które wymieniłem, ponieważ szkolenie modelki naraża ją na kontakt z ogromną ilością korporacyjnego języka, przesadnie chronionym pismem i ogólną życzliwością, a te wzorce domyślnie łatwo wpaść. Bez celowej kontroli tonu treści tworzone przez model zbliżają się do średniej danych treningowych, a średnia nie jest ani szczególnie dobra, ani szczególnie wyróżniająca się. Neutralna przeciętność jest trybem awarii.
Mechanizm, którego używam, jest nudny: przeczytaj dokument, na głos, jeśli mogę, po cichu, jeśli nie, i zanotuj każde miejsce, w którym głos brzmi inaczej niż to, co faktycznie mówię lub piszę. Każda notatka staje się edycją. Czasami zmiana polega na zastąpieniu słowa „dźwignia” słowem „wykorzystanie”. Czasami jest to całe zdanie — zastąpienie zabezpieczonego, pasywnego roszczenia bezpośrednim. Czasem jest to akapit. Efektem końcowym jest dokument, który brzmi jak ja, a nie jak dane szkoleniowe.
Ma to większe znaczenie, niż mogłoby się wydawać, ponieważ spójność głosu jest jedną z konkretnych rzeczy, które sprawiają, że pisanie wydaje się godne zaufania. Dokument, w którym trzykrotnie przesuwa się rejestr na stronie, jest irytujący, nawet jeśli czytelnik nie potrafi określić dlaczego; dokument, który zachowuje spójny ton, sprawia wrażenie autorstwa, nawet jeśli sam głos nie jest niczym niezwykłym. Autorstwo to sygnał, na który czytelnicy reagują na poziomie przedświadomym i który składa się z drobnych decyzji o charakterze całych dokumentów.
Istnieje specyficzna dyscyplina dotycząca edycji dźwięku generowanego przez model, na której się opieram: przepisz pierwsze dwa akapity własnym głosem, bez pomocy i użyj ich jako odniesienia tonalnego do edycji reszty. Pierwsze dwa akapity odzwierciedlają oczekiwania czytelnika wobec całego artykułu i jeśli są one konsekwentnie wypowiedziane w Twoim tonie, reszta dokumentu musi się zgadzać lub niedopasowanie jest widoczne. To bardziej poprawia ton całego dokumentu niż jakikolwiek ogólny monit „spraw, by brzmiał bardziej jak ja” kierowany do modelu.
Czytaj pod kątem tonu. Łap konkretne poślizgi. Zakotwicz własnymi akapitami początkowymi. Spójność głosu nie jest dekoracyjna; to podłoże, na którym buduje się wiarygodność, a pisanie wspomagane sztuczną inteligencją wymaga kontroli tonu jeszcze bardziej niż zwykłe pisanie odręczne.
No figure. Tone is auditory, in an inner-voice sense; the honest depiction of a tone check is a person reading aloud, which the book has neither the space nor the medium to represent well.
Chapter 90
Red-Teaming własnych wyników
Część IX kończy się najbardziej niewygodną dyscypliną weryfikacji: celowym atakowaniem własnej pracy w poszukiwaniu sposobów, w jakie może ona być błędna, błędnie zinterpretowana lub wykorzystana. Łączenie własnych wyników w zespół czerwonych jest nieprzyjemne, ponieważ wymaga utrzymywania stanowiska, że to, co stworzyłeś, jest potencjalnie wadliwe, dokładnie w tym momencie, w którym chciałbyś mieć pewność, że tak nie jest. To i tak robi to, co odróżnia praktyków, którzy wychwytują własne błędy, od tych, których błędy muszą wyłapać klienci.
Specyficzną praktyką jest zadawanie pytań w odniesieniu do każdego znaczącego wyniku: jak to mogło pójść nie tak? Nie „czy coś pójdzie źle” – to kwestia defensywna – ale „jak mogłoby się nie udać”, co jest pytaniem dotyczącym kreatywności. Gdybym próbował to złamać, zawstydzić, błędnie zinterpretować, wydobyć coś, czego nie powinien ujawniać, co bym zrobił? Odpowiedzi na te pytania dotyczą luk w zabezpieczeniach danych wyjściowych, a znalezienie ich samodzielnie jest znacznie tańsze niż znalezienie ich przez kogoś innego.
Ataki specyficzne dla sztucznej inteligencji, które warto wymienić, obejmują natychmiastową ekstrakcję (rozdział 67), wytwarzanie danych wyjściowych ujawniających poufne informacje na temat szkolenia lub systemu oraz wytwarzanie danych wyjściowych, które użytkownik mógłby wyrwać z kontekstu w sposób powodujący dalsze problemy. Każdy z nich to klasa awarii, którą mogą wywołać określone dane wejściowe, a testowanie tych danych przed wysyłką zmienia system „mamy nadzieję, że nikt nie pomyśli o wypróbowaniu tego” w system „próbowaliśmy tego i potwierdziliśmy, że sobie z tym poradziliśmy”.
Dyscyplina musi być rzeczywiście kontradyktoryjna. Nie wystarczy wypróbować kilka oczywistych ataków i zadeklarować, że system jest bezpieczny; musisz naprawdę spróbować go złamać, tak jak zrobiłby to zainteresowany przeciwnik. Jest to niewygodne, ponieważ wymaga odłożenia na bok identyfikacji z systemem i traktowania go jak przeciwnika. Praktycy, którym nie uda się dokonać takiej zmiany mentalności, ominą klasy porażek, których nie przeoczy prawdziwy przeciwnik, a luka zostanie nadrobiona w najgorszym możliwym momencie.
Mechanizm, którego używam, to mała „lista kontrolna zespołu czerwonego” dla każdego wdrożonego systemu, aktualizowana w miarę pojawiania się nowych klas ataków. Szybka ekstrakcja: czy to działa? Wypróbuj kilka technik ekstrakcji i zobacz. Próby Jailbreak: czy system kontynuuje wykonywanie zadania pomimo monitów przeciwnika? Wypróbuj typowe wzorce jailbreak. Naruszenia granic: czy system odrzuca żądania, które powinien odrzucić, czysto? Wypróbuj żądania w pobliżu granicy i poza nią. Każdy z nich jest konkretnym testem, a każda wykryta luka jest konkretną luką, której nie znajdzie aktywny użytkownik.
Pod spodem kryje się szersza zasada, która głosi, że większość luk w zabezpieczeniach systemów AI to znane kategorie, a zastosowanie myślenia według znanych kategorii pozwala na ich tanie wyłapanie. Konkretne dane wejściowe, które powodowałyby wyodrębnienie monitu w twoim systemie, są nieznane; ogólny kształt ataków polegających na natychmiastowym wyodrębnieniu jest dobrze udokumentowany i łatwy do przetestowania. Przetestuj kształt, a wychwycisz konkretną instancję, bez konieczności wyliczania każdego możliwego ataku.
Ostatnim elementem jest uczciwość w stosunku do tego, co znajdziesz. Jeśli zespół czerwonych odkryje prawdziwą lukę w zabezpieczeniach, napraw ją przed wysyłką — nie wysyłaj i nie trać nadziei. Jeśli ujawni coś, czego nie można w pełni naprawić, ale można częściowo złagodzić, wyślij rozwiązanie i powiedz klientowi, co pozostało. Zespół czerwonych, który ujawnia problemy, a następnie je ukrywa, pokonuje dyscyplinę; Red-Teaming, który działa na podstawie tego, co znajdzie, jest dyscypliną działającą prawidłowo.
Zapytaj, jak mogło pójść nie tak. Spróbuj to złamać. Napraw to, co się psuje. Wysyłaj z lukami, które znalazłeś celowo zamkniętymi, a nie z tymi, które mogłeś uznać za wciąż otwarte. Klient, który nigdy nie będzie musiał znajdować Twoich słabych punktów, to klient, któremu ufasz.
No figure. Red-teaming is a mindset applied to a specific system, and the specific attacks are so varied that a diagram would either be a generic "attacker → system" arrow (trite) or a taxonomy of attacks (out of date the moment it's printed). The discipline is what matters, and the discipline is verbal.
Part X
System, który działa sam
Ostatnia część — to, co wyłania się, gdy dyscypliny z poprzednich dziewięciu części się łączą. Nocna zmiana jako dźwignia, crontab, który cicho wykonuje pracę, delegowanie zadań na Twoją własną maszynę i pytanie, co pozostaje do zrobienia człowiekowi, gdy system działa dobrze.
Chapter 91
Łączenie nocne jako dźwignia
Dyscypliny opisane w tej książce opłacają się indywidualnie — lepsza księga, czystszy adapter, bardziej zdyscyplinowana kpina. Opłacają się wykładniczo tam, gdzie się kumulują, a konkretne kumulowanie, które chcę nazwać, ma miejsce, gdy praca z dnia na dzień przestaje być okazjonalną sztuczką i staje się głównym sposobem, w jaki system wytwarza wartość. Składanie z dnia na dzień to dźwignia, ku której zmierzała cała książka.
Wzór jest taki. W ciągu dwudziestu aktywnych godzin tygodniowo podejmuję decyzje, przeglądam wyniki i informuję kolejkę nocną. Podczas ponad stu godzin nieaktywnych tygodniowo kolejka przetwarza to, co przekazałem. Stosunek godzin aktywnych do pasywnych w systemie wynosi mniej więcej od jednego do pięciu, co oznacza, że każda dobrze spędzona godzina może zamienić się w pięć godzin dalszej pracy. Ten stosunek się sumuje — wyniki z każdego tygodnia z dnia na dzień są uwzględniane w podsumowaniach na następny tydzień, a poprawa jakości briefów z każdego miesiąca przekłada się na lepsze wyniki w kolejkach.
Krytyczną właściwością jest to, że złożenie wymaga obecności każdej z dyscyplin. Bez bezpiecznej operacji z Części III, kolejka generuje uszkodzone dane wyjściowe, które nie nadają się do użytku. Bez księgi kosztów z Części IV kolejka generuje drogie produkty, których ekonomiki nie można zweryfikować. Bez zestawu umiejętności z Części V kolejka tworzy jednorazowe serie, które nie łączą się ze sobą. Bez przepustki weryfikacyjnej z Części IX kolejka generuje dane wyjściowe, którym nie można ufać. Każda część księgi jest warunkiem koniecznym złożenia; jeśli pominiesz którykolwiek z nich, dźwignia nie wystąpi.
System, który wyłania się, gdy wszyscy są obecni, nie jest fantazją „AI robi wszystko”. Jest to specyficzna konfiguracja oparta na pętli i skali, w której uwaga człowieka jest skupiona na elementach, które może wykonać tylko ludzka uwaga — ocenie strategicznej, relacji z klientem, ocenie na poziomie gustu — a przepustowość mechaniczna jest delegowana. Jest to zbliżone do układu, jaki próbowano osiągnąć w przypadku dobrych operacji poprzedzających wprowadzenie sztucznej inteligencji, z udziałem zespołów ludzkich, ale przy niższych kosztach i lepszej obserwowalności. Nowością jest ekonomia; wzór jest stary.
Lekcja, którą warto wymienić, jest taka, że tego rodzaju dźwignię buduje się powoli, a nie nagłą zmianę. Zajęło mi wiele lat stopniowego stosowania tych dyscyplin, zanim złożenie stało się zauważalne, a zdarzały się długie odcinki, w których każda pojedyncza praktyka wydawała się dodatkową pracą o niejasnym efekcie. Mieszanie nie ogłasza się samo; gromadzi się spokojnie. Praktycy, którzy porzucają dyscypliny, ponieważ indywidualne korzyści są małe, nigdy nie docierają do strefy łączenia, gdzie małe indywidualne korzyści mnożą się w coś większego.
Druga lekcja dotyczy limitu dźwigni. Łączenie poprzez nocną pracę jest realne, ale nie nieograniczone. Pułap wyznacza jakość briefów, które mogę przygotować, uczciwość recenzji, jaką mogę wystawić, oraz spójność kierunku strategicznego, jaki mogę obrać. Każda z nich to ludzka zdolność, której nie można skalować przy większej liczbie obliczeń. Maszyna może wzmocnić to, co robię dobrze; nie zastąpi tego, co robię źle. Oznacza to, że wykorzystanie związków w oparciu o podłoże ludzkich kompetencji – a udoskonalenie tego podłoża jest inwestycją o najwyższym zwrocie po pewnym czasie.
Zbuduj wszystkie dyscypliny. Obserwuj, jak nasilają się przez lata, a nie miesiące. Uznaj, że pułapem dźwigni są ludzkie możliwości; tam też inwestuj dalej. System, który działa sam, nie działa bez człowieka, dla którego działa.
Fig 91.1 — Compounding Overnight. The focal 20 hours a week produce briefs; five nights of overnight runs multiply the throughput; the morning merge is where the accumulated output is judged and shipped. The leverage is the ratio between what one hour of judgement briefs and what five nights process.
Chapter 92
Puenta Crontaba
Żart, który przyszedłem opowiedzieć na temat całego systemu, jest taki, że większość mojej kariery po cichu zajmowała się uniksowym crontabem. To nie metafora — prawdziwy crontab na prawdziwym serwerze, z zaplanowanymi wpisami uruchamianymi każdej nocy, każdego ranka, raz na godzinę i w każdą niedzielę o 6 rano, uruchamiający określone zautomatyzowane przepływy pracy, które wytwarzają większość mechanicznych wyników, jakie kiedykolwiek widzą moi klienci. Crontab jest puentą argumentu, który składa się z dnia na dzień, a jasne przedstawienie go jest warte osobnego rozdziału, ponieważ prostota jest tym, co zaskakuje ludzi.
To, co jest w crontabie, nie jest efektowne. Codzienna praca generująca raporty, od których zależy wielu klientów. Poranna praca, która sprawdza nocne wyniki i powiadamia mnie, jeśli coś się nie powiedzie. Cotygodniowa praca polegająca na uzgadnianiu ksiąg zgodnie z rozdziałem 40. Godzinna praca polegająca na obserwowaniu zdarzeń zewnętrznych, na które muszę zareagować. Miesięczna praca polegająca na tworzeniu podsumowania, które otrzymuje każdy klient. Żadne z nich samo w sobie nie jest skomplikowane; każdy z nich, zanim istniało takie rozwiązanie, zajmowałby godzinę mojego czasu w określonym dniu tygodnia lub miesiąca, a teraz są wpisami zaplanowanymi, które odbywają się w czasie, gdy zajmuję się innymi sprawami.
Powodem, dla którego „tylko crontab” jest puentą, jest to, że ludzie oczekują, że dźwignia opisana w tej książce będzie wymagać czegoś bardziej wyrafinowanego. Platformy orkiestracyjne. Silniki przepływu pracy. Klastry Kubernetesa. Rzeczywisty mechanizm w przypadku większości mojej automatyzacji to prymitywny harmonogram, który istnieje od lat 70. XX wieku i wykonuje proste planowanie zadań bez żadnych innowacji. Dźwignia nie znajduje się w harmonogramie; jest to praca, którą planuje planista. Cron jest mechanizmem; dźwignia jest dyscypliną.
Lekcja z tego jest architektoniczna. Kiedy przepływ pracy musi przebiegać zgodnie z harmonogramem, właściwym pytaniem nie jest „jaką zaawansowaną platformę planowania powinienem zastosować”, ale „jak proste może być planowanie przy jednoczesnym wykonywaniu pracy”. Na większość moich potrzeb wystarczy cron, dobrze ukształtowany skrypt i alert monitorujący — a za każdym razem wystarczająca liczba wyrafinowanych bitów, ponieważ wystarczy jedna rzecz mniej do utrzymania, zabezpieczenia i stronicowania. Proste narzędzia, które działają przez dziesięciolecia, są warte więcej niż modne, wymagające ciągłej pielęgnacji.
Tryb awarii, którego chcę uniknąć nazewnictwa, z reguły polega na tym, że zaplanowane przepływy pracy mogą po cichu gnić. Zadanie cron, które wcześniej działało, może przestać działać — wywoływany przez nie interfejs API został przeniesiony, w skrypcie występuje problem ze środowiskiem, w magazynie wyjściowym brakuje miejsca — i nikt tego nie zauważa, ponieważ cron ochoczo kontynuuje wykonywanie zadania i beztrosko kontynuuje rejestrowanie niepowodzeń. Dyscypliną, która to ratuje, jest śledzenie z rozdziału 18: każde zaplanowane uruchomienie emituje swój ślad, warstwa monitorująca obserwuje te ślady, a każde uruchomienie, które nie zakończy się pomyślnie, powoduje wyświetlenie strony. Cicha awaria powoduje, że działający crontab staje się starzejącym się; monitorowane awarie sprawiają, że firma jest uczciwa.
Specyficznym elementem wartym wymienienia jest to, że wpisy w crontabie powinny być czytelne dla osoby, która musi je poprawiać o 3 nad ranem, czyli często jestem to ja, a pewnego dnia może to być ktoś inny. Dobrze skomentowane wpisy. Opisowe nazwy skryptów. Zmienne środowiskowe, które mają sens. Crontab dobrze zorganizowanego systemu czyta się jak dokumentację tego, co system faktycznie robi zgodnie z harmonogramem, a to w dużej mierze jest to, co robi. Niechlujne crontaby czyta się jak tajemnicę; niechlujne tajemnice pękają w niewygodnych momentach.
Użyj najprostszego harmonogramu, który działa. Monitoruj ślady. Komentuj wpisy. I niech „tylko crontab” będzie puentą Twojego systemu — ponieważ jeśli dźwignia naprawdę pochodzi z dyscypliny stojącej za harmonogramem, harmonogram może być nudny.
No figure. The crontab is text; drawing it would be a screenshot of a config file, which is not a figure in the book's design sense. The point is that boring infrastructure is often the right infrastructure.
Chapter 93
Delegowanie do własnej maszyny
Następuje zmiana w sposobie myślenia o własnym laptopie lub serwerze, gdy przestaje on być narzędziem, z którego korzystasz, a zaczyna być współpracownikiem, któremu delegujesz pracę. Ten rozdział dotyczy tej zmiany, ponieważ zmienia ona oczekiwania wobec maszyny i to, o co śmiało można ją zapytać, a dokonanie tej zmiany zajęło mi więcej czasu, niż się spodziewałem.
W starym modelu laptop jest miejscem pracy — miejscem, w którym pracuję, korzystając z narzędzi znajdujących się na komputerze. W tym modelu gdy zamykam laptopa praca się zatrzymuje. Nic nie działa, gdy mnie nie ma; nic nie musi; maszyna jest w całości pod moim aktywnym użytkowaniem. W ten sposób korzystałem z komputerów przez pierwsze piętnaście lat mojej kariery i był to wówczas właściwy model – maszyny nie były wystarczająco szybkie i wydajne, aby warto było je delegować, a nie było czego delegować.
Nowy model polega na tym, że maszyna jest kolegą. Coś, czemu mogę zlecić wykonanie zadania, oczekiwać, że zostanie ukończone, gdy będę gdzie indziej, i sprawdzić, kiedy wrócę. Kiedy zamykam laptopa – lub, co bardziej prawdopodobne, kiedy zamykam aktywny edytor – praca się nie kończy. Zaplanowane uruchomienie ognia. Wykonywanie zautomatyzowanych rurociągów. Proces wsadowy nocny. Godziny aktywności maszyny nie pokrywają się z moimi godzinami aktywności i właśnie w tej asymetrii tkwi efekt dźwigni z rozdziału 91.
Na początku zmiana mentalna jest niekomfortowa. Zaufanie delegowanemu pracownikowi wymaga możliwości sprawdzenia, co zrobił po fakcie, pewności, że poprosi o pomoc, gdy utknie, i akceptacji go podczas podejmowania przez niego decyzji pod twoją nieobecność. W odniesieniu do komputera oznacza to dobre śledzenie, dobre ostrzeganie i dobrze ukształtowane skrypty, które głośno zawodzą, gdy nie mogą kontynuować. Każdy z nich został omówiony wcześniej w książce; zmiana mentalna polega na połączeniu ich w całość i zaufaniu wynikowi.
Brak tej zmiany polega na tym, że praktycy korzystający z narzędzi wspomaganych sztuczną inteligencją nadal pracują tak, jakby korzystali ze starego modelu – tylko do aktywnego użytkowania, zamykają laptopa i nic się nie dzieje. Mogą okazjonalnie uruchamiać partie ręcznie i nazywać je automatyzacją, ale rola maszyny nadal polega na narzędziu używanym przez aktywnego człowieka. Komplikacja, o której opowiada ta książka, nie ma miejsca w tym modelu, ponieważ w rzeczywistości nigdy nie deklaruje się dodatkowych godzin przerobu. Maszyna mogła więcej; nie jest to wymagane.
Błędem związanym ze złym wprowadzeniem zmiany biegów jest zbyt duże zaufanie do maszyny i zbyt wczesne jej przełożenie. Delegowanie pracy przed wdrożeniem śledzenia, monitorowania i obsługi błędów daje efekt odwrotny do efektu dźwigni — niewykryte awarie kumulujące się z dnia na dzień, wykrywane dopiero po złożeniu skargi przez klienta. Zaufanie do maszyny trzeba zdobyć dzięki dyscyplinie, która sprawia, że delegowanie jest bezpieczne, a przedwczesne delegowanie uczy praktyków, że „automatyzacja nie działa”, gdy doszło do automatyzacji bez siatki bezpieczeństwa.
Synteza jest taka, że maszyna może być doskonałym współpracownikiem w określonych warunkach i to dokładnie te warunki, o których opowiadała się ta książka. Zbuduj śledzenie. Zbuduj monitoring. Zbuduj klasyfikację awarii. Zbuduj księgę. Kiedy już je wdrożysz, delegowanie będzie bezpieczne; zanim znajdą się na miejscu, jest to lekkomyślne. Zatem dokonanie zmiany mentalnej nie polega tylko na zaufaniu – chodzi o zdobycie pewności, na której opiera się zaufanie.
Traktuj maszynę jak kolegę, jeśli na to zasługuje. Deleguj to, z czym może uczciwie sobie poradzić. Sprawdź to po śladach, a nie po najechaniu myszką. Efekt dźwigni wynika z realności delegowania, a realność delegowania wynika z realności sieci bezpieczeństwa. Obydwa albo żadne.
No figure. The shift is mental — a change in how one thinks of the machine — and the honest visual is a person handing a task to a laptop, which the book has neither the space nor the medium to render usefully. The point is a metaphor to internalise, not a shape to draw.
Chapter 94
Co pozostało dla człowieka
Jeśli maszyna wykonuje pracę mechaniczną, przetwarza w ciągu nocy, wytwarza artefakty i utrzymuje harmonogram – co mi pozostaje do zrobienia? Pytanie brzmi banalnie, ale traktuję je poważnie, bo jeśli szczera odpowiedź brzmi „coraz mniej”, ma to wpływ na to, jak planuję następną dekadę mojej kariery. Moja robocza odpowiedź, po latach obserwacji tego, co się faktycznie dzieje, jest taka, że rola człowieka zawęża się, ale nie znika; staje się bardziej skoncentrowana na konkretnej pracy, którą mogą wykonać tylko ludzie.
Właściwie to tym, na czym teraz poświęcam swój czas, w godzinach ludzkich, są te rzeczy. Ocena strategiczna — jakich klientów przyjąć, jakie problemy rozwiązać, jakie kształty zaangażowania wybrać. Relacja — bezpośredni kontakt człowieka z klientami, odczytywanie tego, czego tak naprawdę potrzebują pod tym, co mówią. Projekt — decyzje na poziomie gustu dotyczące tego, jak powinien wyglądać produkt końcowy, jaką strukturę powinien mieć system i jakie wrażenie miałby dobry wynik. Przegląd — czynność porannego łączenia, polegająca na ocenie, co wyprodukowała maszyna i podjęciu decyzji, jakie statki. Nauczanie — pomaganie współpracownikom, klientom i czytelnikom w zdobywaniu wiedzy o rzeczach, o których wiem, że oni nie wiedzą.
Żadnego z nich nie udało się w przekonujący sposób zautomatyzować i nie spodziewam się, że rozwój sztucznej inteligencji w najbliższej przyszłości znacząco to zmieni. Ocena strategiczna wymaga kontekstu gromadzonego przez lata i stosowanego w nowych sytuacjach. Związek wymaga faktycznego bycia osobą w kontakcie z drugą osobą. Projektowanie na poziomie gustu wymaga zmysłu estetycznego człowieka, któremu zależy na konkretnym odbiorcy. Recenzja wymaga pozycji, która pozwala powiedzieć „tak, wyślij” lub „nie, wykonaj ponownie” i zaufania w obu przypadkach. Nauczanie wymaga faktycznego przejścia przez to, czego uczysz.
Interesujące jest to, że w tym układzie godziny pracy są bardziej skompresowane niż wcześniej. Kiedy prace mechaniczne są delegowane, pozostała praca jest bardziej gęsta — więcej strategicznych decyzji na godzinę, więcej relacji z klientami na godzinę, więcej przeglądów na godzinę. Oznacza to, że ten sam dwudziestogodzinny tydzień wytwarza znacznie więcej tego, co naprawdę ważne, ale oznacza to również, że te dwadzieścia godzin jest bardziej intensywne niż osiemdziesiąt rozcieńczonych godzin pracy przed sztuczną inteligencją. Dźwignia nie zmniejsza wysiłku; koncentruje go na czynnościach o wyższej wydajności, które często są bardziej męczące na godzinę.
Konsekwencją tego jest to, że praca ludzka czerpie korzyści z inwestycji, których nie przyniosła praca mechaniczna. Jeśli wartością są ludzkie godziny, to poprawa ludzkich możliwości – czytania, myślenia, smaku, osądu – jest inwestycją o najwyższym zwrocie po pewnym czasie. Inwestowanie w bardziej wyrafinowaną automatyzację przynosi coraz mniejsze zyski, gdy automatyzacja jest już dobra; Inwestowanie w człowieka, które wzmacnia, przynosi korzyści. Jest to specyficzny przypadek godzin spędzonych częściowo na rozwoju człowieka, a nie tylko na wykonywaniu zadań.
Warto wspomnieć o szerszej kwestii filozoficznej. Strach, że sztuczna inteligencja sprawi, że praca ludzka stanie się przestarzała, zakłada, że praca ludzka była w pierwszej kolejności wymienna z pracą maszyn. W konkretnej praktyce opisanej w tej książce tak nie było — godziny pracy ludzkiej zawsze robiły coś innego niż godziny mechaniczne, a godziny pracy mechanicznej stawały się coraz tańsze, nie zmienia to jednak ich przeznaczenia. Zmienia się proporcja, która sprawia, że konkretny wkład człowieka staje się bardziej widoczny i wartościowy, a nie mniejszy.
To, co pozostało człowiekowi, nie jest mniejsze niż wcześniej. Jest bardziej skoncentrowany, cenniejszy, bardziej wymagający i ma większe znaczenie dla tego, czy cały system wytwarza coś, co warto mieć. To jest przyszłość, którą ta książka opisuje od początku; crontab wykonuje pracę mechaniczną, podczas gdy człowiek wykonuje pracę specyficznie ludzką, a jedno i drugie jest niezbędne dla wyniku.
No figure. This chapter is a stance about human specificity; a diagram of what humans versus machines do would be either patronising or premature, and the point is better made in prose.
Chapter 95
Kiedy uczyć maszynę
Czasami szczerą reakcją na powtarzające się zadanie jest zdobycie umiejętności, a czasami uczciwą reakcją jest wykonywanie go ręcznie jeszcze przez jeden cykl. Podejmowanie decyzji, która jest konkretną oceną, i chcę poświęcić rozdział na to, co o tym myślę, ponieważ „czy powinienem to zautomatyzować” to pytanie, które pojawia się kilka razy w tygodniu, a uzyskanie błędnej odpowiedzi w którąkolwiek stronę jest kosztowne.
Naiwna odpowiedź brzmi: „zawsze automatyzuj”. Każde zadanie, które się powtarza, zasługuje na umiejętność. Jest to błędne, ponieważ obliczenie progu rentowności z rozdziału 35 pokazuje, że istnieje próg — powtarzające się zadania ze zbyt małą liczbą instancji nie generują kosztów automatyzacji, a czas konfiguracji jest marnowany. Naiwna odpowiedź optymalizuje pod kątem niewłaściwego horyzontu; traktuje automatyzację jako bezpłatną, choć tak nie jest.
Przeciwnaiwna odpowiedź brzmi: „nigdy nie automatyzuj; praca ręczna jest w porządku”. Jest to błędne podejście, ponieważ zadania, których rzeczywisty koszt polega na niewielkim ręcznym powtórzeniu, ostatecznie składają się na znaczną ilość czasu, szczególnie w przypadku ćwiczeń indywidualnych w ograniczonych godzinach. Osoba praktykująca na zawsze manualnie gromadzi w tle obciążenie małymi, powtarzalnymi zadaniami, które mogłyby zostać odrzucone przez automatyzację, a obciążenie ostatecznie przekracza ich możliwości dalszego rozwijania praktyki. Odmowa automatyzacji z zasady powoduje wąskie gardło w kształcie kariery.
Właściwa odpowiedź leży pomiędzy i wymaga indywidualnej oceny każdego przypadku. Moje robocze heurystyki są takie. Jeśli zadanie powtarza się według ustalonego harmonogramu (co tydzień, co miesiąc), zautomatyzuj go, gdy tylko zostanie dobrze zdefiniowane, ponieważ powtarzalność jest gwarantowana. Jeśli zadanie powtarza się na żądanie, poczekaj, aż wykonasz je ręcznie trzy do pięciu razy, ponieważ do tego czasu wzorzec zmienności nie będzie wystarczająco jasny, aby można go było zautomatyzować. Jeśli zadanie jest unikalne, ale jego kształt może się powtarzać (konkretny raport dla jednego klienta, którego mogą chcieć inni klienci), uczciwym pierwszym krokiem jest dobre napisanie wersji ręcznej i sprawdzenie, czy rzeczywiście pojawi się ponowne pytanie o kształt, zanim zainwestujesz w umiejętność.
Istnieje konkretny wzór do obserwacji, który pomaga w podjęciu decyzji. Kiedy wykonuję zadanie ręcznie i przyłapuję się na tym, że myślę: „Wiem, że już to kiedyś robiłem, ale nie pamiętam dokładnie jak”, często jest to sygnał, że dane zadanie jest bardziej powtarzalne, niż myślałem. Moment rozpoznania poprzednich przypadków jest momentem na rozważenie umiejętności. Alternatywa — każdorazowe rekonstruowanie podejścia od zera — to forma ukrytych kosztów, które dzięki trybowi ręcznego ciągłego działania stają się niewidoczne.
Innym wzorcem, który warto wymienić, jest pojawienie się wspólnego kształtu w wielu zadaniach. Kiedy dwa lub trzy zadania, które traktowałem jako jednorazowe, zaczynają wyglądać, jakby były to przypadki tej samej umiejętności – tych samych danych wejściowych, tego samego ogólnego kształtu, tej samej kategorii wyników – ta zbieżność jest momentem, w którym podstawowa umiejętność chce zaistnieć. Budowanie jednej umiejętności, która służy trzem zadaniom, jest tańsze niż budowanie trzech umiejętności i często daje bardziej ogólną zdolność, która automatycznie wychwytuje przyszłe podobne zadania.
Naucz maszynę, kiedy powtarzalność jest realna, kiedy widziałeś kształt wystarczająco dużo razy, aby mieć o nim opinię, i kiedy wersja ręczna zaczyna wydawać się niewidocznym kosztem. Nie ucz tego zbyt wcześnie – usmażysz się na błędnych założeniach. Nie czekaj zbyt długo — podatek ręczny będziesz płacić bezterminowo. Właściwy moment to wezwanie do osądu, a jego właściwe wykonanie staje się częścią intuicji, która rozwija się przez lata prowadzenia praktyki.
No figure. This is a judgement call between two failure modes; the decision surface between them is well-argued in prose and would be lost in a diagram.
Chapter 96
Dziedziczenie
Ten rozdział dotyczy pytania, które uważam za niewygodne, ale które zacząłem traktować poważnie: co dzieje się z systemem opisanym w tej książce, kiedy to nie ja go uruchamiam? Nie dlatego, że planuję wkrótce przestać – nie mam tego – ale dlatego, że praktyka, która działa tylko z jedną konkretną osobą w centrum, jest praktyką kruchą i należy przeciwdziałać jej kruchości.
Naiwna odpowiedź jest taka, że sukcesja nie stanowi problemu, ponieważ praktyka solowa jest z definicji powiązana z osobą praktykującą solo. Jeśli przestaną, to się zatrzyma. Ale to nie do końca prawda, a myślenie o tym, dlaczego nie jest to prawdą, jest pouczające. Relacje z klientami, klienci referencyjni, reputacja — te elementy można przenieść na następcę, jeśli taki istnieje. Konkretne umiejętności w pakiecie są przenośne — są kodem i można je przekazać. Wzorce zaangażowania, narracje skierowane do klienta, gust projektowy – to kwestie bardziej osobiste, ale przynajmniej w zasadzie można je udokumentować.
To, czego nie da się łatwo przenieść, to konkretny sąd, który wszystko spaja. Intuicja dotycząca tego, jakie zobowiązania podjąć. Przegląd na poziomie gustu, który decyduje o tym, jakie statki. Szczególny głos, który klienci rozpoznają jako mój. Są one naprawdę moje w sposób, którego nawet najlepsza dokumentacja nie jest w stanie w pełni uchwycić, a każdy następca będzie prowadził wersję tej praktyki, a nie tę samą praktykę. To jest szczere i w porządku – następca powinien stworzyć własną wersję, opierając się na moich informacjach, ale nie będąc do niej przykuty.
Konkretny element myślenia o sukcesji, który zmienił moją praktykę, jest następujący: co byłoby prawdą, gdyby jutro potrącił mnie autobus? Czy klienci utknęliby w martwym punkcie? Czy trwające zobowiązania upadłyby? Czy systemy, które zbudowałem dla klientów, będą nadal działać, czy też w ciągu tygodnia zaczną po cichu ulegać awariom? Każda odpowiedź, która wiąże się z niemożnością kontynuowania praktyki pod moją nieobecność, jest słabością, którą powinienem zmniejszyć, nawet jeśli konkretne wydarzenie, które mogłoby ją wywołać, wydaje się mało prawdopodobne. Współczynnik magistrali jest liczbą rzeczywistą, a mój był wyższy niż powinien w różnych punktach.
Konkretne redukcje, które wprowadziłem, są praktyczne. Każdy klient ma udokumentowane informacje o przekazaniu — kim jestem, co robimy, gdzie działają systemy i z kim się skontaktować, jeśli nie będę osiągalny. Każdy system kliencki ma element Runbook — co robi, jak działa, co może pójść nie tak i do kogo się zwrócić, jeśli tak się stanie. Każde trwające zlecenie ma wstępny plan awaryjnej sukcesji — jeśli nie będę mógł kontynuować, ten konkretny kolega może go przejąć w krótkim czasie. Nic z tego nie jest skomplikowane; wszystko to zmienia sytuację klienta z „zależy całkowicie od mojej ciągłej obecności” do „odpornego na określone zakłócenia”.
Konsekwencją, której zaakceptowanie zajęło mi więcej czasu, jest to, że gotowość do sukcesji sprawia, że praktyka jest lepsza w teraźniejszości, a nie tylko odporna na moją nieobecność. Runbooki, które pomogłyby następcy, pomagają mi również, gdy wracam z dwutygodniowego urlopu i nie pamiętam, co robi dany system. Dokumentacja przekazania, która pomogłaby klientowi znaleźć ciągłość, pomaga mi także zapamiętać kształt zaangażowania po sześciu miesiącach. Dyscypliny zmniejszające kruchość zmniejszają również tarcie, a redukcja kruchości jest prawdopodobnie szczęśliwym skutkiem ubocznym tego, że redukcja tarcia sama w sobie jest wartościowa.
Pomyśl o sukcesji, nie traktując jej jako chorobliwej. Celowo zmniejszaj kruchość. Napisz elementy Runbook. Dokumentuj zaręczyny. Nie dlatego, że autobus wkrótce się pojawi, ale dlatego, że praktyka powinna być solidna, a dyscyplina polegająca na jej wzmacnianiu poprawia ją w sposób, który przynosi korzyści na długo przed pojawieniem się jakichkolwiek konkretnych zakłóceń.
No figure. Succession is a set of documents and relationships, not a shape; the visual honesty of this chapter is the absence of a diagram, because "what would you leave behind" resists being drawn without becoming sentimental.
Chapter 97
Umiejętność odchodzenia na emeryturę
Każda umiejętność w zestawie ma swój koniec. Niektóre kończą się szybko – stworzone na potrzeby konkretnego spotkania, nie są już potrzebne po zakończeniu zaangażowania. Niektóre kończą się powoli — używane co tydzień przez rok, co miesiąc przez następny rok, a potem co kwartał, aż po cichu nikt już ich nie używa. W tym rozdziale mowa jest o szczególnej trosce, na jaką zasługuje odchodząca na emeryturę umiejętność, ponieważ sposób, w jaki wycofujesz umiejętność, uczy cię czegoś o tym, jak umiejętności powinny być rozwijane.
Obserwacja, która zapoczątkowała takie myślenie, była taka, że niektóre z moich najstarszych umiejętności – te, które zbudowałem na początku mojej praktyki – nagromadziły się w sobie, czego przyczyny już nie pamiętam. Specyficzne dziwactwo w formacie wyjściowym, specyficzna zależność, która istniała z powodu utraconego z powodu czasu, specyficzne zachowanie, które kiedyś było prawidłowe, a teraz było szczątkowe. Kiedy w końcu zdecydowałem się wycofać tę umiejętność, odkryłem, że nie potrafię w pełni wyjaśnić, dlaczego działa ona w taki sposób, w jaki działa, co oznaczało, że nie mogłem z całą pewnością odbudować tej samej funkcjonalności, gdybym kiedykolwiek jej potrzebował. Przejście na emeryturę uwidoczniło nagromadzoną ciemność.
Konkretnym aktem przejścia na emeryturę, który mnie zaskoczył, była wartość napisania faktycznej noty emerytalnej. Nie flaga wycofania z rozdziału 48 — dłuższy dokument zawierający odpowiedź „do czego służy ta umiejętność, dlaczego istnieje, jakie są jej zarysy i co należy zrobić, jeśli dana funkcjonalność będzie kiedykolwiek potrzebna”. Napisanie tej notatki zmusiło mnie do wyrażenia tego, co zakładałem, że wiem, a sformułowanie jej ujawniło, ile z tego, co wiedziałem, zostało w rzeczywistości zapisane wcześniej w pamięci podręcznej i nie jest już ważne. Notatka o przejściu na emeryturę to dokument, który zostaje dobrze napisany tylko dlatego, że jest pisany pod koniec przejścia na emeryturę; w tym samym dokumencie napisanym w połowie służby pominiętoby ważne części.
Poniżej znajduje się lekcja projektowania: umiejętności, które gromadzą nieprzejrzystą skorupę, to umiejętności, których czytelnicy po sześciu miesiącach nie są w stanie zrozumieć. Zaświadczenie o przejściu na emeryturę nie naprawia tego z mocą wsteczną, ale dyscyplina związana z jego pisaniem sprawia, że zdobywam kolejne umiejętności przy mniejszym wysiłku, który muszę tłumaczyć. Jeśli wiem, że w końcu nadejdzie odprawa emerytalna, podchodzę ostrożniej do konkretnych wyborów na etapie budowy, ponieważ wiem, że będę musiał je uzasadnić. Przewidywana dokumentacja jest funkcją wymuszającą spójny projekt.
Druga lekcja jest taka, że wycofanie umiejętności jest często momentem nauki w takim samym stopniu, jak jej budowa. To, co zrozumiałem na temat klasy problemu podczas budowania umiejętności, było niekompletne; to, co zrozumiałem po dwóch latach prowadzenia tej umiejętności, jest inne i często podczas rozmów na temat przejścia na emeryturę spotykają się te dwie wersje mojego zrozumienia. Artefaktem tego spotkania jest notatka o przejściu na emeryturę – dokument sporządzony przez starszego, mądrzejszego mnie, przyglądającego się wyborom młodszego, mniej poinformowanego mnie i je godzącego.
Jest taki specyficzny smak, który warto wymienić, którym jest nie wstydzenie się umiejętności, które przechodzę na emeryturę. Niektóre zbudowano w pośpiechu. Niektóre z nich zbudowano na podstawie założeń, które okazały się błędne. Niektóre po prostu przeżyły swój cel. Żadna z nich nie jest porażką; są uczciwym łukiem praktyki, która zmieniała się przez lata. Apartament, który nigdy niczego nie rezygnuje, to apartament, który udaje, że świat się nie poruszył; apartament, który świadomie odchodzi na emeryturę, to taki, który uwzględnia ruch i dostosowuje się.
Napisz notatkę o przejściu na emeryturę. Ucz się z tego. Niech dyscyplina przewidywanej emerytury wpłynie na sposób budowania nowych umiejętności. Zakończenie umiejętności jest wydarzeniem najwyższej klasy w życiu pakietu, a nie przypisem – a dokumenty sporządzone na końcu często informują o tym, co będzie dalej.
No figure. Retirement is a document being written and a codebase moving to an archive — neither is a shape that gains from being drawn. The point is that retirement deserves care, and the care is verbal.
Chapter 98
Audyt roczny
Raz do roku celowo siadam i audytuję swoją praktykę – nie cotygodniową telemetrię, ale długie spojrzenie na to, jak zmienił się kształt mojej pracy w ciągu ostatnich dwunastu miesięcy. Jakiego rodzaju zajęcia podjąłem? Jakie umiejętności były najczęściej wykorzystywane? Jaki był stosunek nowej pracy do konserwacji? W czym się poprawiłem, a co pozostało bez zmian? Audyt roczny jest retrospektywą praktyki i to zdyscyplinowana refleksja kształtuje kolejny rok.
Powodem, dla którego należy to robić co roku – a nie co miesiąc, nie co kwartał – jest to, że krótsze horyzonty ukrywają dryf. Z miesiąca na miesiąc praktyka wygląda stabilnie. Z kwartału na kwartał zmiany są nadal niewielkie. W ciągu roku tendencje kumulują się w coś widocznego: pojawiły się nowe kategorie zaangażowania, stare zanikły, mój zestaw umiejętności po cichu się zmienił, lista klientów uległa zmianie. Nic z tego nie było zauważalne w żadnym pojedynczym momencie; wszystko to jest zauważalne łącznie i suma jest tym, co ujmuje widok rok do roku.
Konkretne pytania, które zadaję, są następujące. Jaka część moich godzin przeznaczona była na który filar pakietu umiejętności? Czy filary, które zainwestowałem, są tymi, które wytworzyły wartość? Jaki był stosunek nowych godzin pracy do godzin konserwacji i czy ten stosunek jest trwały? Które umiejętności były wykorzystywane najczęściej i czy były to te, których się spodziewałem? Którzy klienci stanowili jaką część przychodów i jak zmieniła się ta koncentracja? Jaki był stosunek moich godzin pracy do wkładu maszyny i czy wzrosło mieszanie?
Odpowiedzi na te pytania często mnie zaskakują. Spodziewam się, że spędziłem czas na X i stwierdzam, że faktycznie spędziłem czas na Y. Oczekuję, że relacja z klientem pogłębi się, a następnie stwierdzi, że się ustabilizowała. Spodziewam się, że nowa umiejętność się przyjęła, ale popadła w ruinę. Przydatnym spostrzeżeniem jest luka między oczekiwaniami a rzeczywistością, ponieważ oczekiwanie to model, który noszę ze sobą przez cały rok, a rzeczywistość jest tym, co faktycznie się wydarzyło. Celem audytu jest skorygowanie modelu z rzeczywistością.
Wynikiem audytu jest krótka pisemna refleksja – nie więcej niż strona – zawierająca to, co mnie zaskoczyło i co powinien podkreślić kolejny rok. Nie jest to plan strategiczny; nie jest planem działania; zestaw obserwacji na temat tego, co faktycznie działa, a co nie. Strategia przychodzi później, oparta na refleksji; samo odbicie jest surowcem. Pominięcie refleksji i przejście od razu do strategii powoduje oderwanie planów strategicznych od rzeczywistości, którą mają kierować.
Istnieje szczególna korzyść, której dostrzeżenie zajęło mi kilka lat, a mianowicie to, że coroczny audyt buduje na przestrzeni lat swego rodzaju pamięć instytucjonalną. Lektura refleksji z poprzedniego roku wraz z obserwacjami z bieżącego roku pokazuje postęp – nie tylko tam, gdzie jestem teraz, ale także skąd pochodzę. Oto historia praktyki, opowiedziana w krótkich rocznych migawkach, i jest to fragment wiedzy, którego nie udało się uzyskać w żadnym pojedynczym roku. Złożony efekt jest taki, że refleksje z piątego roku są znacznie bogatsze niż z pierwszego roku, ponieważ są to refleksje oparte na czterech poprzednich refleksjach.
Zrób audyt roczny. Zadaj konkretne pytania. Napisz krótką refleksję. Pisząc tegoroczny, przeczytaj poprzedni rok. Praktyki, które nie odzwierciedlają dryfu bez zauważenia; praktyki, które rzeczywiście odzwierciedlają, kierują ich dryfem, co stanowi różnicę między karierą, która zmierza dokądś celowo, a karierą podążającą tam, gdzie zaprowadzi ją bezwładność.
No figure. The audit is a set of questions and answers; a diagram of it would be a checklist, which is more useful as text than as a picture.
Chapter 99
Wywiad końcowy z własnym systemem
Pod koniec pisania tej książki wykonałem konkretne ćwiczenie, które chcę opisać, ponieważ okazało się bardziej przydatne, niż się spodziewałem. Wyobrażałem sobie, że odchodzę z własnej praktyki – wychodząc na rozmowę z osobą ją przejmującą. Co bym im powiedział? Co wiedziałem o działaniu systemu, czego nie zapisano nigdzie? Co musieliby osobiście ode mnie usłyszeć, zanim będą mogli przeprowadzić tę sprawę tak, jak należy?
Na początku ćwiczenie wydawało mi się niezręczne, ponieważ tak naprawdę niczego nie zostawiałem, a wyimaginowany następca był hipotetyczny. Ale kadrowanie zadziałało. Zmusiło mnie to do wyartykułowania rzeczy, które nosiłem w głowie jako wiedzę ukrytą – konkretnych niepisanych zasad zapewniających uczciwość praktyki, szczególnych cech każdej relacji z klientem, ocen, które pojawiały się przez lata i nie zostały ujęte w żadnym dokumencie. Po wyartykułowaniu większość z nich okazała się warta prawidłowego spisania, nie dlatego, że następca był nieuchronny, ale dlatego, że wyartykułowanie ich uczyniło je bardziej przenośnymi, nawet dla mnie.
Konkretne rzeczy, które mówiłem wyimaginowanemu następcy, okazały się taksonomią wartą nazwania. Niepisane zasady zaangażowania – jaką jakość uwagi klienci otrzymują, które prośby są realizowane powoli, a które szybciej. Specyficzne decyzje dotyczące smaku, które zachodzą w systemie projektowania — dlaczego jest to kolor akcentujący, dlaczego są takie czcionki, dlaczego diagramy wyglądają tak, jak wyglądają. Relacje między umiejętnościami, które nie są udokumentowane w manifestach — które wyniki umiejętności wpływają na które, dlaczego niektóre kompozycje działają, a inne nie. Idiomy specyficzne dla klienta — wyrażenia, które oznaczają coś specyficznego dla konkretnego klienta, na co można by spojrzeć świeżym okiem.
Każdy z nich okazał się mieć wartość wykraczającą poza wyimaginowaną sekwencję. Zapisanie niepisanych zasad oznaczało, że mogłem do nich wrócić, gdy praktyka się rozwinęła lub zmienił się kontekst; stały się raczej aktualizowalne niż skostniałe. Dokumentowanie decyzji dotyczących smaku oznaczało, że mogłem do nich wracać bez konieczności ponownego ich za każdym razem; smak stał się powtarzalny. Pisanie kompozycji oznaczało możliwość budowania przyszłych umiejętności, mając na uwadze wzór; kompozycja stała się raczej zasadą projektowania niż przypadkiem.
Istnieje szersza obserwacja, że ćwiczenie się skrystalizowało, co oznacza, że trzymanie w głowie ukrytej wiedzy, nawet dla siebie, jest kosztowne. To, co wydaje się intuicją niewymagającą wysiłku, w rzeczywistości jest obciążeniem umysłowym, które pochłania uwagę, którą wolałbyś spędzić gdzie indziej. Eksternalizacja wiedzy w dokumentach pozwala odciążyć ją — nie poprzez zmniejszanie wiedzy, ale poprzez brak konieczności aktywnego pamiętania o niej. Praktyka działa lepiej, gdy własny operator nie jest wąskim gardłem w zapamiętywaniu jej działania.
Ćwiczenie ujawniło również luki. Miejsca, w których wyimaginowany następca miałby pytania, na które nie mogłem odpowiedzieć. Miejsca, w których improwizowałem w sposób, którego nie zauważyłem. Miejsca, w których praktyka działała pomimo mojej wiedzy, a nie dzięki niej. Każdy z nich był wart zbadania – improwizacja mogła być ukrytą siłą lub ukrytą słabością, a tak czy inaczej, nazwanie jej umożliwiło dalsze działanie.
Wykonaj ćwiczenie, nawet jeśli nie masz następcy, któremu możesz go przekazać. Wyobraź sobie jednego. Przeprowadź wywiad tak, jakbyś wyjeżdżał. Dokument, który przedstawiasz, nie jest dla nich; jest dla ciebie, a jego wartość kryje się w samej artykulacji, a nie w jakimkolwiek przekazie, który pewnego dnia mógłby o tym poinformować. Praktyki, które można wyrazić, to praktyki, które można ulepszyć; praktyk, które nie mogą pozostać zależne od konkretnego człowieka, który je prowadzi, czyli kruchości, od której rozpoczęliśmy tę część i którą teraz świadomie kończymy.
No figure. This is a personal exercise resulting in a private document; the honest visual is a person writing at a desk, which is not a shape this book renders.
Chapter 100
Co będzie dalej
Po stu rozdziałach książka kończy się pytaniem, które każdy czytelnik ma prawo zadać: co będzie dalej? Nie dla branży sztucznej inteligencji, której przyszłości nie chcę przewidywać ze szczegółami; ale dla praktyka, który doczytał aż do tego momentu i decyduje, co z tym zrobić. To jest rozdział, którego chciałbym, gdybym był czytelnikiem – szczera, niezabezpieczona rada autora na temat tego, od czego właściwie zacząć.
Dla większości czytelników pierwszą rzeczą, która nadchodzi, nie jest budowanie nowego systemu. To spędzenie tygodnia na uczciwym sprawdzeniu pracy, którą już wykonujesz. Na co przeznaczasz aktywne godziny? Które części tej pracy to tylko Ty? Które części można delegować i do czego? Jaki jest Twój obecny stosunek przepustowości aktywnej do pasywnej i gdzie przesunęłyby ją niewielkie zmiany? Odpowiedz na te pytania, zanim zbudujesz coś nowego; odpowiedzi zwykle przekierowują to, co byś zbudował.
Drugą rzeczą, która następuje, jest wybranie jednej dyscypliny z tej książki i celowe przyjmowanie jej przez miesiąc. Nie wszyscy; jeden. Wybierz tego, którego nieobecność wydaje się najbardziej boleć w Twojej obecnej konfiguracji. Jeśli nie masz księgi, dodaj księgę na miesiąc. Jeśli nie masz telemetrii kosztów, Dodaj telemetrię kosztów. Jeśli Twoje kpiny są dopracowane, odznacz je. Niezależnie od tego, który z nich wybierzesz, poświęć miesiąc na budowanie nawyku, zanim dodasz kolejny. Próba przyjęcia wszystkiego na raz powoduje bałagan; Przyjmowanie sekwencyjnie daje trwałą praktykę.
Trzecią rzeczą, która nadchodzi, jest cierpliwość w związku z mieszaniem. Dyscypliny opisane w tej książce nie przynoszą efektów w ciągu tygodni. Opłacają się latami i są długie okresy, w których poszczególne ćwiczenia wydają się narzucane, a łączenie jeszcze się nie rozpoczęło. Zrób to mimo wszystko i daj im czas, którego potrzebują. Praktycy, którzy porzucili te dyscypliny, ponieważ „indywidualna wypłata nie była tego warta”, to ci, którzy nigdy nie dotarli do strefy łączenia, a nagroda nie jest widoczna w żadnej pojedynczej praktyce – znajduje się na przecięciu wielu z nich, utrzymywanym przez wystarczająco długi czas, aby przecięcie stało się widoczne.
Czwartą następną rzeczą jest szczerość w mówieniu o tym, czego nie wiesz. Ta książka przedstawia odpowiedzi jednej osoby, opracowane na podstawie praktyki jednej osoby, z jej słabymi punktami. To, co napisałem, może nie pasować do Twojej pracy, Twoich klientów i Twojego temperamentu. Podejdź do szczegółów luźno; potraktować podstawowe stanowiska poważniej; weź rzeczywiste wzorce i przełóż je na własną rzeczywistość. Czytelnik, który zastosuje tę książkę dosłownie, uzyska gorsze rezultaty niż czytelnik, który przyjmie jej kształt i przepracuje szczegóły dla własnego kontekstu.
Piątą rzeczą, która zaraz nastąpi – i ostatnią, z którą chcę Was zostawić – jest powrót do twierdzenia z rozdziału 1, na które stara się zapracować cała książka. Inżynieria AI, dobrze wykonana, nie polega na pisaniu, a coraz bardziej na temat obecności tylko tam, gdzie twoja obecność stanowi ograniczenie. Wszystko na tych stronach jest instrumentem potwierdzającym to stanowisko. Nocna zmiana, zestaw umiejętności, dyscyplina klienta, księga kosztów, przepustka weryfikacyjna – wszystkie mają na celu ochronę dwudziestu godzin, skupienie ludzkiej uwagi tam, gdzie jest to istotne, przekazanie prac mechanicznych maszynie, która faktycznie sobie z tym poradzi. Jeśli wybierzesz jedną rzecz z tej książki, zajmij to stanowisko i pozwól, aby określone praktyki były opcjonalne.
Praktyka będzie się rozwijać. Narzędzia będą się zmieniać. Poszczególne rozdziały będą datowane nierównomiernie. Mam nadzieję, że utrzyma się podstawowy schemat: niewielka uwaga poświęcana częściom pracy, które za nią płacą, delegowanie całej reszty systemowi, który działa sam. Konkretny system, który opisałem, jest jednym z sprawdzonych przykładów; wzór uogólnia bardziej niż szczegóły. Idź i stwórz własną wersję tego, a jeśli znajdziesz się gdzieś za kilka lat w pokoju i będziesz opowiadał historie o dyscyplinach, które sprawiły, że to zadziałało, niektóre z tych historii będą twoje, a inne będą echem moich i obie będą dotyczyć tej samej rozmowy. Oto, co będzie dalej: twoja wersja, świadoma, ale nie ograniczona tą wersją, wykonująca pracę, którą tylko ty możesz wykonać, w ciągu dwudziestu godzin, które faktycznie masz.
No figure. The book closes without a final diagram because the final argument is stance rather than structure — and stances resist visualisation for reasons this book has argued at length. If a picture were needed here, it would be Fig 1.1 seen from the other end: the same quadrant, the same three things, the same delegated periphery, only now understood as a practice sustained across a career rather than a lens on a single week.