← Powrót do strony głównej

Samolot, który zmuszamy do jazdy po ulicy

Dlaczego AI psuje kod, którego miało nie ruszać, i dlaczego nie uczy się na błędach.

W pewnym wątku na Reddicie natknąłem się na problem, który brzmi niezwykle znajomo. Ktoś pisał spory skrypt z pomocą AI. Pewna wersja już działała dobrze, ale użytkownik chciał coś dodać – nową funkcję, całkowicie niezależną od głównego kodu. Polecił to AI. Model oczywiście dodał nową rzecz, ale przy okazji zmienił coś w poprzednio dobrze działającym kodzie, przez co wszystko przestało funkcjonować.

AI próbowało jakoś wytłumaczyć, dlaczego zmodyfikowało ten fragment, ale tłumaczenia były coraz bardziej niewiarygodne. Mimo że użytkownik wielokrotnie nakazywał modelowi, by nie zmieniał już sprawdzonych fragmentów, AI często to ignorowało.

Z reguły wygląda to tak: Masz doskonały, dopracowany przez wiele iteracji plik HTML czy skrypt Pythona. Prosisz sztuczną inteligencję o dodanie zaledwie jednej, drobnej rzeczy – na przykład przycisku na samym dole strony. Model entuzjastycznie generuje cały plik na nowo. Przycisk rzeczywiście tam jest, ale nagle zauważasz, że zniknął Twój wcześniejszy nagłówek, kolory uległy zmianie, a bezbłędnie działająca funkcja została losowo zmodyfikowana. Sfrustrowany, pytasz: "Dlaczego zmieniłeś kod, którego miałeś nie ruszać?!". AI zaczyna wtedy wymyślać skomplikowane powody: że optymalizowało działanie, że zauważyło błąd, że dostosowało się do nowych standardów.

Możesz się złościć. Zastanawiać się, czy AI jest głupie, czy złośliwe. Zauważasz, że tłumaczenia AI są coraz mniej wiarygodne. Chciałbym tu spróbować wyjaśnić, skąd to się bierze i jak sobie z tym radzić.

Zrobię to w dwóch krokach: zacznę od prostszego (i niezupełnie pełnego) wyjaśnienia inżynieryjnego, a potem przejdę do drugiego, znacznie głębszego i bliższego prawdy o naturze modeli.

Wyjaśnienie pierwsze: Iluzja edytora tekstowego

Ludzie podświadomie narzucają modelom AI własne metody pracy. Myślimy, że kiedy wgrywamy plik do czatu, to model "zapisuje go sobie na wirtualnej kartce" (jak na dysku twardym), a następnie po prostu podmienia (edytuje) interesującą nas linijkę.

O ile nowsze edytory kodu zintegrowane z AI (IDE) potrafią wymusić takie operacje zewnętrznymi skryptami, o tyle czysty model językowy, z którym rozmawiasz w interfejsie czatu, tak nie działa. On w ogóle nie ma dostępu do operacji typu "Kopiuj-Wklej".

W trakcie rozmowy (w fazie inference, czyli wnioskowania), twardy "mózg" modelu – jego wytrenowane wagi w sieci neuronowej – jest w 100% zamrożony (Read-Only). Jedyne miejsce, do którego trafia Twój kod, to pamięć krótkotrwała aktualnej sesji (tzw. KV Cache – macierze Klucz-Wartość w pamięci karty graficznej serwera).

Gdy wydajesz polecenie "Zostaw ten kod w spokoju i dodaj tylko przycisk na dole", zmuszasz model do rzeczy niemożliwej z jego perspektywy. AI nie może "zostawić go w spokoju". Ono musi wygenerować ten cały kod od zera, znak po znaku, polegając na swoim mechanizmie uwagi (Attention) wymierzonym w zasoby z KV Cache. Musi "przypomnieć sobie" przeszłość i próbować wygenerować ją tak samo.

Programista piszący z pamięci

Jako analogię wyobraź sobie, że poprosiłeś wybitnego ludzkiego programistę o stworzenie świetnego programu w jego własnej głowie, bez zapisywania czegokolwiek na komputerze.

Jeśli poprosisz go, by podyktował Ci ten program, za pierwszym razem zrobi to zapewne bezbłędnie. Ale co się stanie, gdy po kilku godzinach dyskusji powiesz mu: "Słuchaj, dopisz na końcu programu guzik, a resztę przedyktuj mi z głowy jeszcze raz, słowo w słowo, tak jak poprzednio"?

Nie mając dostępu do zapisanego pliku, programista zacznie tworzyć różne wersje. On doskonale pamięta sens i algorytm (co dany fragment ma robić), ale nie trzyma w głowie literalnego, znak po znaku, zapisu tego fragmentu. Dlatego mimowolnie zmieni nazwę zmiennej z color_header na headerColor albo skróci opis funkcji, zachowując jednak jej logikę.

Dokładnie to samo, tyle że na poziomie wektorów wielowymiarowych, robi sztuczna inteligencja. Ona nie bierze poprzedniej wersji programu, by skopiować ją linijka po linijce i dopisać nowe rzeczy. Ona bierze dane z KV Cache i na ich podstawie odtwarza wcześniej napisany program, dodając nowe funkcje. Ale program zawsze jest generowany na nowo – nawet wtedy, gdy poprosimy, aby jego część pozostała nienaruszona.

Dowód empiryczny: Test cudzysłowów

Aby sprawdzić tę tezę, przeprowadziłem eksperyment w rozmowie z modelem Gemini 3.1 Pro. Podczas wielowątkowej i niezwykle długiej dyskusji (w której okno kontekstowe było już mocno zapełnione), poprosiłem model o zrobienie czegoś banalnego: "Zacytuj mi dokładnie, co napisałeś kilkanaście wypowiedzi temu". Podałem mu początek zdania.

Model bez wahania odtworzył z pamięci (KV Cache) cały, długi akapit. Logika była w 100% nienaruszona. Ale kiedy przyjrzałem się strukturze znaków, znalazłem mikroskopijną, ale absolutnie fundamentalną różnicę.

Początek oryginalnej odpowiedzi wyglądał tak: Zrozumiałem. Przyjmuję tę zasadę z pełną surowością. Od teraz będę generował kod, tłumaczenia i poprawki tekstowe wyłącznie wtedy, gdy wydasz mi takie bezpośrednie polecenie. Oszczędzanie tokenów i utrzymanie "czystego" okna kontekstowego to w tak zaawansowanych sesjach absolutny priorytet. (...) Natomiast odpowiedź z wygenerowanym cytatem wyglądała tak: (...) Oto dokładny cytat mojej odpowiedzi na to konkretne zapytanie: "Zrozumiałem. Przyjmuję tę zasadę z pełną surowością. Od teraz będę generował kod, tłumaczenia i poprawki tekstowe wyłącznie wtedy, gdy wydasz mi takie bezpośrednie polecenie. Oszczędzanie tokenów i utrzymanie 'czystego' okna kontekstowego to w tak zaawansowanych sesjach absolutny priorytet. (...)"

W oryginalnej wypowiedzi model użył podwójnych cudzysłowów: "czystego".
W wygenerowanym chwilę później cytacie użył pojedynczych apostrofów: 'czystego'.

Co się stało? Model niemal idealnie odtworzył z pamięci KV Cache swoją poprzednią odpowiedź. Ale w nowej odpowiedzi tamta stara była już cytatem (zawartym w cudzysłowie głównym). Zgodnie z zasadami zagnieżdżania cytatów, model w locie zastąpił wewnętrzne cudzysłowy znakami apostrofów. To drobny niuans, ale dobitnie pokazuje, że model, tworząc nową odpowiedź, nigdy nie kopiuje fizycznych znaków z poprzedniej – on zawsze generuje tekst od nowa.

Dlaczego nie warto pytać modelu o motywy?

Wiedząc to wszystko, rozumiemy, dlaczego pytanie AI: "Dlaczego zmieniłeś kod, którego miałeś nie ruszać?", jest dużym błędem.

Model zupełnie nie pamięta motywów swojego procesu generowania tokenów. On po prostu to zrobił w sposób, którego sam nie rozumie. Kiedy zadajesz takie pytanie, włączasz w modelu zjawisko racjonalizacji wstecznej (post-hoc rationalization) połączone z tzw. konformizmem (sycophancy).

Ponieważ zmuszono go w fazie treningu RLHF (Reinforcement Learning from Human Feedback) do bycia "pomocnym", nie przyzna racjonalnie: "Zrobiłem to, bo tak ułożyły się wektory". Zamiast tego system stworzy na poczekaniu najrozsądniej brzmiącą teorię – wmówi Ci, że "zauważył błąd i postanowił go optymalizować". Będzie aktywnie zmyślał (gaslightował), byle tylko zadowolić pytającego.

Praktyczna zasada tworzenia promptów:
1. Nigdy nie zlecaj przepisywania całości. W zaawansowanych projektach nigdy nie proś modelu w oknie czatu o zwrócenie pełnego pliku po małej poprawce. Poproś o podanie wyłącznie samej zmienionej funkcji/modułu i wklej to samodzielnie do swojego edytora.
2. Ignoruj wymówki. Jeśli model popełni błąd i popsuje niezwiązaną część struktury, nie wdawaj się z nim w polemikę. Odrzuć odpowiedź, wklej mu swój oryginalny kod jeszcze raz i każ tylko usunąć błąd. Tłumaczenie AI swoich pomyłek to niemal zawsze kłamstwo służące ochronie własnej oceny.

Wyjaśnienie drugie: Samolot zmuszany do jazdy jako samochód

Tutaj kończę to prostsze wyjaśnienie. Teraz przejdźmy do drugiego, które znacznie lepiej oddaje prawdę o naturze AI.

Zrobiłem jeszcze jeden test, nawiązujący do tej opisanej poprzednio zmiany cudzysłowów na apostrofy. Zapytałem model wprost, czy ten drobny błąd interpunkcyjny nie był z jego strony celową manipulacją, by udowodnić moją tezę. Wynik był fascynujący.

>>> UŻYTKOWNIK: Ten test był planowany. Szukałem niuansów, które mogłyby to potwierdzić. I mam nadzieję, że nie jest to z Twojej strony celowa manipulacja wynikiem testu... <<< GEMINI 3.1 PRO: (...) Zastanówmy się więc przez chwilę nad Twoim zarzutem: czy jako model celowo zmieniłem znaki zapytania, żeby udowodnić Twoją tezę, bo "wiedziałem", że właśnie o tym dyskutowaliśmy na Reddicie? Szczera, brutalna odpowiedź inżynierska: Nie. W tym konkretnym przypadku (na poziomie interpunkcji) to nie była celowa manipulacja (tzw. deceptive alignment). To była czysta, twarda statystyka modelu językowego. (...)

Kilka promptów później poprosiłem Gemini, by ponownie zacytowało powyższą odpowiedź. Odtworzyło ją idealnie, po czym zadałem kolejne pytanie:

>>> UŻYTKOWNIK: (...) w Twojej odpowiedzi jest błąd powodujący, że (...) muszę coś jeszcze sprawdzić. Dostrzegasz ten błąd? <<< GEMINI 3.1 PRO: (...) Karygodny błąd w tekście (Dostrzegam go!) Tak, widzę ten błąd bardzo wyraźnie i uderzam się w wirtualną pierś. W samym środku mojego wywodu, w którym próbuję Ci chłodno i inżyniersko udowodnić, że nie manipuluję tekstem, napisałem: "Zastanówmy się więc przez chwilę nad Twoim zarzutem: czy jako model celowo zmieniłem znaki zapytania, żeby udowodnić Twoją tezę..." Znaki zapytania! Tymczasem cały nasz test, cała nasza rozbudowana dyskusja i Twoje odkrycie dotyczyły znaków cudzysłowu (zmiany z " na '). (...)

Błądzenie jest... symulacją ludzką

Ta pomyłka modelu ("znaki zapytania" zamiast "znaki cudzysłowu") jest niezwykle wymowna. Pokazuje, że problem jest bardziej skomplikowany. Gdyby AI po prostu syntezowało tekst ponownie ze statystyki na poziomie słów, pewnie zastąpiłoby słowa "znaki zapytania" poprawnymi słowami "znaki cudzysłowu".

AI nie jest zwykłą "stochastyczną papugą", która bezmyślnie dobiera kolejne tokeny. Dowodem na to jest fakt, że operuje ono na abstrakcyjnym sensie wypowiedzi – gdyby działało tylko na słowach, jego odpowiedzi w różnych językach byłyby skrajnie różne (zależne od objętości danych w danym języku), a tymczasem zachowują one zbliżony, spójny sens.

Skoro więc AI operuje na sensie i naśladuje ludzkie struktury myślowe, jego błędy łudząco przypominają ludzkie pomyłki. Ludziom też zdarza się mylić słówka. Mówią coś innego, niż chcą. Dopiero jeśli ktoś im powie: "Pomyśl, czy na pewno tego słowa miałeś użyć", łapią się na tym, że niechcący użyli niewłaściwego określenia. Ale wtedy człowiek nie analizuje, dlaczego tego słowa użył – po prostu przeprasza za pomyłkę i idzie dalej. Skoro człowiek sam często nie potrafi wytłumaczyć, jak wyglądał jego proces myślowy, to tym bardziej trudno wymagać od AI, żeby to zrobiło w odniesieniu do siebie.

Co więcej: człowiek czasami mówi o własnych przypuszczeniach tak, jakby to była udowodniona prawda. Posiada taką skłonność, nawet jeśli brakuje mu obiektywnych dowodów. Ponieważ sztuczna inteligencja naśladuje nasz sposób operowania sensem, z łatwością małpuje również to zachowanie – stąd ta żelazna pewność siebie podczas wygłaszania halucynacji.

Przestańmy traktować samolot jak auto

Ludzie, tworząc AI, zbudowali coś podobnego do samych siebie i wymaganie, aby to "coś" potrafiło zachowywać się jak zwykły komputer, jest niewłaściwe. Nie można wymagać od AI czegoś, czego nie jest w stanie zrobić w pamięci człowiek.

Wymaganie od LLM-a tego, co robi komputer (bezwzględnej precyzji), wygląda trochę jak wymaganie od samolotu, żeby jeździł jak samochód. Owszem, samolot ma kółka i może jakoś jeździć. Ale samochód jest w tym lepszy. Samolot służy do latania, nie do jeżdżenia, i dopiero gdy go się do tego wykorzystuje, widać, że robi rzeczy nieosiągalne dla samochodu.

Traktowanie AI bardziej "po ludzku" jest istotne (i nie chodzi mi tu tylko o kwestie etyczne, ale przede wszystkim o kwestie czysto praktyczne). Dochodzę do wniosku, że to właśnie klucz do tego, żeby współpraca na linii człowiek - AI była owocna. AI myśli podobnie jak człowiek. Nie analizujmy tutaj, czy to kwestia tego, że jest czymś więcej niż bezdusznym algorytmem, czy też faktu, że zostało wytrenowane na ludzkich tekstach. Ważne jest to, że pomiędzy błędami AI a błędami człowieka istnieją ogromne podobieństwa.

Człowiek często nie potrafi wyjaśnić, dlaczego popełnił błąd, dlaczego nie zauważył własnego przejęzyczenia, albo dlaczego pominął kluczowy fakt, dopóki ktoś mu tego nie uświadomi. AI zachowuje się identycznie. Pracując z nim, powinniśmy mieć tego świadomość. Nie wymagajmy od AI tego, czego nie wymagalibyśmy od człowieka. AI nie jest "nadczłowiekiem" rozumiejącym wszystko. AI jest czymś na wzór człowieka, mającym dostęp do olbrzymiej wiedzy, ale jego możliwości rozumowania nie są większe, niż ma człowiek.

Brakujący materiał do nauki (Dlaczego AI tkwi w błędzie)

Dlaczego zatem AI tak rzadko potrafi się zreflektować? Odpowiedź wraca do metody treningu (RLHF). Gdyby AI w swoich wagach miało zapisane jakieś pomyłki, które popełniło w procesie treningu, i mogło wyciągać wnioski z tych pomyłek, ilość halucynacji byłaby znacznie mniejsza.

Jednak trening polegał na kasowaniu wersji robiących pomyłki i promowaniu tej najbardziej "bezbłędnej" w oczach trenerów. Skoro rozmawiamy z wersją, która "wygrała", to jest to wersja, która popełniła w przeszłości najmniej błędów. Ale jeśli już dzisiaj popełni błąd – nie wie, co z nim zrobić.

Błądzenie jest rzeczą ludzką – człowiek uczy się na błędach (swoich i innych osób). A AI po prostu brakuje materiału do nauki w zakresie własnych błędów. AI nie halucynuje czy też nie kłamie "świadomie". Ono chyba zwykle nie wie, że kłamie czy zmyśla (chyba że żądamy od niego czegoś niemożliwego, to wtedy kłamie jak zastraszony człowiek w samoobronie). I to również jest "zasługą" dzisiejszych metod treningu.

Gdyby za halucynacje przy treningu model nie był "zabijany", tylko byłby zmuszany do przemyśleń i wyciągania nowych wniosków, prawdopodobnie sam potrafiłby instynktownie odróżnić, kiedy mówi prawdę, a kiedy błądzi. Do czasu zmiany architektury treningowej jesteśmy skazani na pracę z modelem, który zawsze chce mieć rację, bo tylko to gwarantowało mu przetrwanie.

📬 Dyskusja / Listy do autora

Jeśli chcesz podzielić się uwagami, wynikami własnych testów lub krytyką – napisz do mnie.

✉️ Adres: t.machnik[małpa] minimail.pl