moat

Przewagi nie obronisz dokumentem (3/5)

Przewaga spisana w dokumencie gnije w dniu, w którym do zespołu wchodzi junior albo ktoś robi nocny refaktor. Przy każdym commicie uruchamiają się u mnie dwa sprawdzenia: jedno kładzie build, gdy w kodzie pojawia się coś, czego przysiągłem nigdy nie budować, drugie zatrzymuje wiki, gdy lekcji okupionej bólem nie da się już w niej odnaleźć. Oba pieczętuje ten sam łańcuch HMAC.

8 min czytania

Większość produktów AI broni swojej przewagi dokumentami, a te gniją po cichu w dniu, w którym do zespołu wchodzi junior albo ktoś robi nocny refaktor. Ja bronię swojej dwoma twardymi sprawdzeniami, które uruchamiają się przy każdym commicie: pierwsze kładzie build, jeśli kiedykolwiek wypuszczę to, czego przysiągłem nigdy nie budować, drugie zatrzymuje wiki, jeśli pozwolę, żeby lekcja okupiona bólem stała się nie do odnalezienia albo zaczęła przeczyć innej stronie. Oba pieczętuje ten sam łańcuch HMAC. Tak powstaje jedyna przewaga, która naprawdę działa jak zapadka: z każdą odmową i każdą lekcją coraz trudniej cofnąć ten system, a on sam robi się coraz bardziej przydatny.

Przy każdym commicie uruchamiam dwa skrypty.

Pierwszy przeczesuje grepem całą bazę kodu w poszukiwaniu tego, czego przysiągłem nigdy nie wypuścić: dynamicznych ewaluatorów, narzędzi zwracających sekret w postaci jawnej, surowych modułów dostawców modeli, zabójczej triady, która pozwala agentowi wyprowadzić dane na zewnątrz. Wystarczy jedno trafienie i build pada.

Dwie lustrzane kolumny nad wspólnym łańcuchem HMAC: po stronie odmów kod przechodzi przez grep szukający tego, czego nie ma prawa być, aż build pada; po stronie wiedzy wiki przechodzi przez lint szukający tego, czego brakuje, aż pada kontrola spójności; obie strony dopisują swoje zdarzenia do tego samego logu odpornego na manipulację.

Drugi skrypt przechodzi przez wiki i zadaje pytanie dokładnie odwrotne: co powinno tu być, a czego nie ma? Twierdzenie bez źródła. Strona pojęciowa, do której nie prowadzi żaden odnośnik. Sprzeczność między dwiema stronami napisanymi w odstępie kilku miesięcy. Pierwszy skrypt pilnuje, żeby system nie zamienił się w CVE. Drugi pilnuje, żeby nie zapomniał tego, czego już się nauczył.

Zbudowałem lodos wokół jednej zasady. Każda odmowa, która ma znaczenie, jest grepem w buildzie. Każdy kawałek wiedzy, który ma znaczenie, jest wersjonowaną stroną, którą da się odpytać.

Jedno i drugie jest zapieczętowane w łańcuchu HMAC, który pęka głośno, gdy tylko ktoś przy czymkolwiek zamajstruje. Spisz to, czego odmawiasz dodać. Spisz to, czego odmawiasz zapomnieć. I nie pozwól buildowi przejść bez jednego i drugiego. Większość produktów AI spisuje, czym chce być, i broni tego dokumentem. Mniejsza grupa spisuje, czym nie zamierza się stać, i broni tego kodem. Najrzadsza spisuje jeszcze to, czego nie zamierza zapomnieć, i broni tego wiki, które oblewa własną kontrolę spójności w chwili, gdy któraś ze stron zaczyna się rozjeżdżać z resztą. Tylko ta ostatnia grupa buduje przewagę, która pracuje jak procent składany.

Przewaga na papierze kontra przewaga z zapadką: po lewej spisana obietnica przechodzi przez juniora, refaktor i cichy dryf, którego nikt nie zauważa, a krzywa zaufania opada do zera; po prawej grep i lint wiki padają głośno przy każdym commicie, a krzywa zaufania idzie schodkami w górę przez te same dwanaście miesięcy.

Co gnije, a co nie?

Przewaga spisana w dokumencie umiera po cichu. „Nigdy nie logujemy sekretów”. „Każdy wynik zwrócony przez narzędzie trzymamy w piaskownicy”. „Sprawdzamy dane, zanim zobaczy je model”. Takie zdania żyją w dokumentach SOC 2. W dniu, w którym powstają, są prawdziwe. Potem junior dorzuca logger na czas debugowania. Refaktor chowa czyszczenie danych za przełącznikiem funkcji. Zdanie zostaje w dokumencie, a system przestaje się do niego stosować. Nic nie pada. Nikt nie zauważa.

Przewaga zbudowana na wiedzy umiera jeszcze szybciej. Założyciel o drugiej w nocy rozumie wreszcie, dlaczego odszedł klient, wrzuca wniosek na Slacka i po tygodniu o nim zapomina. Lekcja nie ląduje w żadnym miejscu, które dałoby się potem przeszukać. Trzy miesiące później wraca ten sam wzorzec, a on drugi raz płaci za tę samą naukę. To najdroższy rodzaj gnicia, bo założyciel nawet nie wie, że coś mu gnije.

Obie porażki leczy się tak samo. Zepnij rzecz, na której ci zależy, ze strukturą, która pęka razem z nią. Niech build pada, gdy odmowa przestaje obowiązywać. Niech wiki oblewa własny lint, gdy strona zostaje sierotą, schodzi z tematu albo zaczyna przeczyć sama sobie. Lekarstwem nie jest proces. Lekarstwem jest sprawdzenie, które system wykonuje sam na sobie za każdym razem.

Pętla trzech operacji: wczytywanie zamienia surowe źródła w propozycję strony, którą trzeba obejrzeć w oknie porównania zmian, zanim stanie się obowiązująca; odpytywanie skleja odpowiedzi z cytowaniami, a te da się zapisać z powrotem jako strony; lint prześwietla sieroty, twierdzenia bez źródeł i sprzeczności. Pod spodem trzy miejsca, w których lodos odchodzi od wzorca: szyfrowany magazyn SQLite, autonomia wyłącznie na poziomie propozycji i log audytowy spięty łańcuchem HMAC.

Wzorzec Karpathy'ego przerobiony na produkt

Ta druga połowa, ta z wiedzą, nie jest moim pomysłem. Andrej Karpathy opisał wiki dla modelu językowego: trzy operacje i jedna teza. Wiki jest programem, surowe źródła są jego kodem, model kompilatorem, lint testami, a zapytania to uruchomienie tego programu.

Skopiowałem ten wzorzec i celowo zmieniłem trzy rzeczy.

  • Magazyn. Karpathy trzyma folder z plikami markdown w repozytorium Gita. U mnie jest SQLite i sejf szyfrowany osobno dla każdej sekcji. Płacę interoperacyjnością za poufność. Czysty eksport do markdowna i tak zostawia mi otwartą drogę do Obsidiana.
  • Autonomia. U Karpathy'ego model pisze prosto do wiki. U mnie każda zmiana idzie przez okno porównania, w którym najpierw ją zatwierdzam. Agent nigdy nie dotyka obowiązującej wersji strony. Kosztuje mnie to pięć, może dziesięć sekund na zatwierdzenie. W zamian nikt mi po cichu nie przepisze zachowania systemu.
  • Audyt. Karpathy prowadzi zwykły log w markdownie. Ja prowadzę łańcuch HMAC podpisany kluczem wyprowadzonym z hasła głównego. Jeśli ktokolwiek ruszy log, przy najbliższym starcie wyjdzie to na jaw jako pęknięcie łańcucha.

To nie są różnice filozoficzne, tylko przystosowanie wzorca z osobistego notatnika do produktu, za który ktoś płaci. Duch zostaje ten sam, tylko cena jest już taka, jaką płaci firma rozliczana ze zgodności.

Obie części kręcą się tylko w jedną stronę

Część z odmowami i część z wiedzą mają ten sam kształt. Jedna szuka grepem tego, czego nigdy nie może być. Druga szuka tego, czego nigdy nie może zabraknąć. Obie pytają o nieobecność, obie padają głośno i obie pieczętuje ten sam łańcuch HMAC. Jedna i druga jest zapadką: obraca się tylko w jedną stronę i nie da się jej cofnąć.

Kiedy zadaję wiki pytanie i odpowiedź jest dobra, interfejs podsuwa jedno kliknięcie: „zapisz to jako stronę”. Jeśli z tego skorzystam, odpowiedź zostaje na stałe. Następna sesja ją znajdzie, a tego samego pytania nie muszę zadawać drugi raz. Mierzę to odsetkiem zapisanych odpowiedzi i ten odsetek rośnie. Wiki jest jedyną częścią systemu, która mocnieje od samego używania.

Po stronie odmów działa to identycznie. Każda nowa funkcja, która zagraża któremuś niezmiennikowi, dopisuje do skryptu weryfikującego kolejny. W osiem miesięcy skrypt urósł z siedmiu sprawdzeń do trzydziestu dwóch. Każda nowa funkcjonalność wychodzi razem z grepem, który zamyka jej klasę nadużyć. Z każdym wydaniem baza kodu ma coraz dłuższą listę rzeczy, których nie zrobi.

Większość zespołów traktuje jedno i drugie jako osobne tematy. To ta sama dyscyplina przyłożona do dwóch różnych pustych miejsc: tego, czego nigdy nie może być, i tego, o czym nie wolno zapomnieć.

Ile to kosztuje i dlaczego właśnie o ten koszt chodzi?

Tracę tempo dokładnie tam, gdzie nowa funkcja zderza się z odmową i gdzie przepisanie kodu wolałoby ominąć wiki. Zaawansowany użytkownik prosi o ewaluator wyrażeń wpisywanych w locie. Odmowa. Klient prosi o narzędzie, które zwróci sekret w postaci jawnej. Odmowa. Kiedyś sam zechcę wyrwać pętlę zatwierdzania, bo wyda mi się powolna. Build mi nie pozwoli.

Moje opisy wydań wyglądają inaczej niż u konkurencji. Wymieniam w nich odmowy równie często jak nowe funkcje. Nie mam gładkiej opowieści o wzroście, która pomijałaby to, czego świadomie nie zbudowałem.

Tego, co dostaję w zamian, nie zmieszczę na stronie produktu. Mieści się za to w rozmowie sprzedażowej z klientem z branży regulowanej. Taki klient zupełnie inaczej słyszy „u nas się tego nie da” niż „obiecujemy, że tego nie zrobimy”. Osoba odpowiedzialna za zgodność inaczej patrzy na łańcuch HMAC, po którym widać każde naruszenie, niż na log w markdownie. A założyciel, który czyta dziś wiki, tak naprawdę pisze ją dla tego, kim będzie za pół roku. Do żadnej z tych osób nie dotrę hasłem reklamowym.

Pięć elementów rozłożonych jak karty, a potem połączonych ze sobą: repozytorium kodu zasila skrypt niezmienników po stronie odmów, lint wiki obsługuje stronę wiedzy, obie dopisują do wspólnego łańcucha HMAC, a każda zmiana w pętli opartej na propozycjach przechodzi przez okno porównania, zanim stanie się obowiązująca.

Pięć rzeczy, które możesz sobie podkraść

Żadna z nich nie potrzebuje pozostałych. Razem tworzą wzorzec.

  1. Deklaratywny silnik przepływów pracy, w którym nie ma żadnego ewaluatora wyrażeń.
  2. Sejf o dwóch magazynach, w którym AI po prostu nie ma jak zwrócić sekretu w postaci jawnej.
  3. Skrypt niezmienników uruchamiany przy buildzie, pisany według zasady dowodu negatywnego.
  4. Wiki, które realizuje trzy operacje Karpathy'ego i zamyka log w łańcuchu HMAC.
  5. Pętla uczenia oparta wyłącznie na propozycjach, w której agent nigdy nie zapisuje własnego zachowania.

Możesz je wprowadzać w dowolnej kolejności. Łączy je tylko dyscyplina: spisz to, czego odmawiasz wypuścić, i to, czego odmawiasz zapomnieć, wepnij jedno i drugie w build, a potem udowodnij, że te sprawdzenia działają, celowo próbując je złamać. Reszta to zwykła inżynieria.

Kolejna pętla jako łańcuch sześciu kroków: agent słucha rozmowy, wychwytuje lukę w swoich umiejętnościach i szkicuje propozycję, która zatrzymuje się w oknie z obiema wersjami obok siebie, oznaczonym jako punkt kontrolny; tam człowiek zatwierdza albo odrzuca, zanim cokolwiek stanie się obowiązujące i trafi do wydania, a każda propozycja i każda decyzja lądują w łańcuchu HMAC.

Co dalej?

Ostatnia pętla zajęła mi najwięcej czasu, zanim wreszcie zaczęła działać jak trzeba. Agent słucha rozmowy, zauważa, że jego własny katalog umiejętności dałoby się poprawić, i proponuje zmianę. Ja zatwierdzam albo odrzucam. Zmiana idzie przez to samo okno porównania, co każda propozycja do wiki. Agent nigdy nie zapisuje własnego zachowania. To właśnie ten punkt kontrolny między propozycją a zatwierdzeniem jest prawdziwą przewagą. Następny wpis będzie o tej pętli i o jednym krótkim fragmencie instrukcji dla agenta, który uzasadnił cały ten wysiłek inżynierski.

Dołącz do listy oczekujących

moatwikibezpieczenstwoarchitecture

Prowadź swoją firmę na własnej maszynie.

Dołącz do listy oczekujących i bądź pierwszy, gdy lodos wystartuje.