Blog · 15 września 2026 · 9 min czytania
Ten sam agent, odwrotne wyniki: o rezultacie decyduje kryterium wyjścia
agenci AI · Codex CLI · LLM evals · workflow
TL;DR: W ciągu jednego tygodnia oddałem dwa zadania temu samemu agentowi kodującemu. Zadanie z jasnymi granicami (napisz sześć testów jednostkowych z listy przypadków) skończyło się w 70 sekund przy około 29,7K tokenów, z 6 na 6 przechodzącymi testami. Otwarte zadanie badawcze wróciło jako notatka o postępach, bez danych i z jednym błędnym faktem podanym z pełnym przekonaniem. Zadanie, które się nie udało, wykonywał mocniejszy model, więc to nie model tłumaczy różnicę. Tłumaczy ją kryterium wyjścia: pierwsze zadanie miało warunek, który mogła sprawdzić maszyna, drugie nie miało żadnego. Od tamtej pory stosuję zasadę: każde oddane zadanie kończy się liczbą albo sprawdzeniem typu zaliczone/niezaliczone, a deklarowana weryfikacja bez zapisanego wyniku liczy się jako brak weryfikacji.
Dwa zadania, jeden agent, jeden tydzień
Obok Claude Code używam Codex CLI od OpenAI i oddaję mu zadania z jasnymi granicami we własnym git worktree (setup opisałem w tekście Codex CLI obok Claude Code). Na początku września przeprowadziłem dwa testy w terenie w odstępie dwóch dni. Oba trafiły do tego samego CLI, z tymi samymi regułami, zabezpieczeniami i launcherem. Spodziewałem się, że różnica sprowadzi się do poziomu modelu. Sprowadziła się do tego, jak kończyło się każde zadanie.
Test pierwszy: sześć przypadków testowych, siedemdziesiąt sekund
Pierwsze zadanie było celowo małe: napisać testy jednostkowe dla funkcji pomocniczej czyszczącej tekst w jednym z moich produktów. Spec wymieniał sześć przypadków wziętych z komentarzy w samej funkcji, wskazywał plik, na którym należy wzorować styl, podawał dokładną komendę do uruchomienia testów i zabraniał ruszania jakiegokolwiek innego pliku. Zadanie szło w trybie nieinteraktywnym na GPT-5.6 Luna, szybkim poziomie, przy średnim effort.
- Utworzenie worktree i instalacja zależności: 14 sekund.
- Praca agenta od startu do końcowego raportu: 70 sekund.
- Tokeny: około 29,7K.
- Wynik: sześć testów, sześć przechodzących, co sprawdziłem, uruchamiając je ponownie ręcznie. Żadnych zmian poza zakresem specyfikacji, styl zgodny z plikiem wzorcowym.
Nie wszystko zadziałało. Commit nigdy nie powstał, bo piaskownica nie miała prawa zapisu do katalogu git głównego repozytorium, w którym worktree trzyma swoje metadane. Agent napisał o tym w raporcie i nie próbował obchodzić piaskownicy. Commit zrobiłem przy przeglądzie, a launcher teraz jawnie daje dostęp do tego jednego katalogu. Pierwsza próba utknęła też na minutę, czekając na stdin. Był to problem z narzędziami, który rozwiązało przekazanie specyfikacji jako pliku.
Test drugi: otwarty brief badawczy, który wrócił jako notatka o postępach
Drugie zadanie było badawcze. Zmapuj kanały wideo, które zajmują się niszowym tematem blisko jednego z moich produktów, w podziale na trzy grupy językowe, jedenaście pól na kanał, liczby podsumowujące, wnioski dla mnie i strona HTML obok danych. Zadanie szło na GPT-5.6 Sol, poziomie roboczym, we własnym worktree. Praca została podzielona na trzy równoległe podzadania i każde dostało Sol oraz pełny kontekst rozmowy.
Wrócił jeden plik o długości 48 linii, w całości o samej pracy: "Zrobione", "Pozostało", "Następny krok". Bez tabel, bez liczb, dwie nazwy kanałów wspomniane w tekście. Strona HTML nie istniała. Z jedenastu pól z briefu nie wypełniono ani jednego dla żadnego kanału. Limit użycia skończył się, zanim powstała jakakolwiek tabela.
Wynik nie był bezwartościowy i ważne jest to, w czym był dobry. Zaproponowany próg włączenia był ostry (materiał musi dotyczyć mierzenia, audytowania albo poprawiania tego, jak marka pojawia się w odpowiedziach AI; ogólne treści o AI odpadają) i trafił do końcowego raportu bez zmian. Podział rynku na segmenty też się obronił, kiedy pojawiły się prawdziwe dane.
Teraz fakty. Agent podał dwa kanały jako "potwierdzone dwujęzyczne". Jeden się zgadzał. Drugi należał do agencji marketingowej, której kanał jest w całości w jednym języku, a nazwa konta, którą agent sprawdził, należała do niezwiązanego z nią muzyka; agencja używa innej nazwy. Podmiot więc istnieje, ale został zweryfikowany pod złym adresem i doprowadził do złego wniosku. To ten rodzaj halucynacji, który prześlizguje się przez szybki przegląd, bo każdy jej element z osobna brzmi wiarygodnie.
Agent napisał też, że zweryfikował liczbę subskrybentów i filmów na stronach kanałów oraz daty publikacji w feedach kanałów. Nie zapisał żadnej z tych liczb. Z tej linii wzięła się moja zasada: deklarowana weryfikacja bez zapisanej liczby to żadna weryfikacja. Nie mogę jej użyć i nie mogę jej sprawdzić, więc nie da się jej odróżnić od weryfikacji, która nigdy się nie odbyła.
Resztę mówi koszt naprawy. Dojście od tej notatki do prawdziwego raportu (58 kanałów, liczby wzięte prosto ze źródła, pięć kanałów sprawdzonych ręcznie, wnioski, opublikowana strona) zajęło jedną pełną sesję Claude Code. To była cała merytoryczna praca. Z pierwszego przebiegu nie przetrwało prawie nic poza regułą włączenia.
Dlaczego agent poradził sobie z jednym zadaniem dobrze, a z drugim źle?
Kuszące jest wyjaśnienie, że chodzi o model, ale nie wytrzymuje ono zderzenia z faktami: zadanie, które się nie udało, wykonywał mocniejszy poziom. Różnica tkwi w kształcie zadania. Pisanie testów miało listę sześciu przypadków i jeden warunek zaliczenia: "testy są zielone". Agent wiedział, kiedy skończył, i ja też. Zadanie badawcze nie miało żadnego warunku. Agent bez warunku zamyka turę w miejscu, które wydaje się naturalnym punktem zatrzymania, a przy otwartym zadaniu jest nim podsumowanie własnych postępów. Notatka o stanie pracy to rozsądny wynik zadania, którego koniec nigdy nie został określony.
Skala pogorszyła sprawę. Trzy równoległe podzadania, wszystkie na najmocniejszym poziomie, wszystkie z pełną rozmową w kontekście, wydały budżet na kontekst i rozumowanie, zanim powstał choćby jeden wiersz danych. Szeroki zakres nie jest powodem, żeby na każdym etapie uruchamiać najmocniejszy model.
Czym jest kryterium wyjścia dla agenta AI?
Kryterium wyjścia to zapisany w zadaniu warunek, który mówi agentowi, że skończył, a osobie sprawdzającej, czy mu się udało. W klasycznej inżynierii plasuje się między kryteriami akceptacji a definition of done, z jednym dodatkowym wymaganiem dla agentów: musi dać się je sprawdzić bez polegania na relacji samego agenta o tym, co zrobił.
Porównaj dwie wersje tego samego briefu badawczego:
// illustrative shape: descriptive exit (fails)
Map the market of channels covering topic X and summarize findings.
// illustrative shape: numeric exit (works)
Produce a table with at least 20 rows per language group.
Every row has columns: name, handle, url, language, subscribers,
videos, last_upload, checked_on.
Every number has the source URL and the date it was read.
Write rows in batches of 5 to the data file; do not wait for the end.
Done = the table exists with all columns filled, or a report of which
rows could not be filled and why.Druga wersja daje agentowi linię mety, a mnie trzy rzeczy, które sprawdzę w minutę: liczbę wierszy, puste komórki i próbkę linków źródłowych. Ujawnia też sposób, w jaki zadanie zawodzi. Jeśli budżet skończy się w połowie, dostanę czterdzieści zweryfikowanych wierszy zamiast notatki o zamiarach.
Kilka nawyków w formułowaniu zadań, które z tego wyniknęły:
- Nazwij artefakt, który ma wrócić. "Tabela z N wierszami i tymi kolumnami" jest lepsza niż "zbadaj rynek".
- Wymagaj dowodu obok twierdzenia. Każda liczba ze źródłem i datą sprawdzenia. Twierdzenie bez dowodu traktuję tak, jakby go nie było.
- Daj agentowi uprawniony sposób na zatrzymanie się. "Jeśli spec jest niejasny, zatrzymaj się i zgłoś to" daje użyteczny raport. Bez tego agent zgaduje.
- Proś o częściowe wyniki wcześnie. Partie zapisane na dysku przetrwają obcięcie budżetu. Jeden zapis na końcu nie przetrwa.
Jak rozdzielać pracę badawczą między poziomy modeli?
Dzień po nieudanym przebiegu spisałem zasadę podziału dla szerokiego researchu. Dotyczy zarówno Claude Code, jak i Codexa. Określa, jak główna sesja dzieli i deleguje podzadania; nie zmienia modelu samej głównej sesji.
| Warstwa | Przykłady | Domyślny poziom |
|---|---|---|
| Zbieranie i mechanika | Wyszukiwanie, listy URL-i, liczby, daty, deduplikacja, sprawdzanie linków | Szybki poziom (Luna albo Sonnet 5), średni effort |
| Porządkowanie i niejednoznaczności | Łączenie źródeł, klasyfikacja właścicieli, wyłapywanie luk | Środkowy poziom (Terra) albo domyślny model Claude |
| Trudne decyzje | Kryteria włączenia, sporne przypadki, rekomendacje, końcowy audyt | Najmocniejszy model, jaki da się uzasadnić |
Nazwy modeli według stanu na wrzesień 2026. Zasady wykonania wokół tabeli są równie ważne jak sama tabela. Mocny model projektuje schema i rozstrzyga wyjątki, ale nigdy nie zbiera rekordów wiersz po wierszu. Agenci zbierający dane dostają samowystarczalny spec i minimalny kontekst, nigdy fork całej rozmowy. Najpierw idzie pilotaż na trzech do pięciu rekordach w każdej grupie, żeby sprawdzić kolumny i źródła przed pełnym przebiegiem. Każde podzadanie ma liczbowe kryterium wyjścia. Główna sesja przegląda każdy niejednoznaczny przypadek i próbkę mechanicznych, ale nie powtarza zbierania na mocnym modelu. Przed delegowaniem wybrany model zostaje zapisany obok każdego podzadania, więc "domyślnie najmocniejszy" musi być decyzją, a nie przypadkiem.
Kryterium sukcesu szerokiego researchu to użyteczny, sprawdzalny zbiór danych, zanim skończy się budżet. Dopracowana synteza przychodzi później, na podstawie tego zbioru.
Niedeterminizm, ograniczenia i co zrobiłbym jutro
Dwa przebiegi to mała próbka, a oba zadania różniły się zarówno poziomem modelu, jak i kształtem, więc traktuj to jako obserwację z terenu. Kontrolowany eksperyment wymagałby wielu przebiegów każdego z nich. Nie powtarzałem żadnego z zadań wiele razy, więc nie potrafię podać liczby opisującej rozrzut wyników. Właśnie ta niepewność jest argumentem za kryteriami wyjścia. Modele językowe są niedeterministyczne: ten sam prompt może dziś dać wyczerpującą odpowiedź, a jutro płytką. Nie kontroluję, który przebieg dostanę, ale mogę kontrolować, czy zły przebieg będzie oczywisty. Liczbowe kryterium wyjścia zamienia zły przebieg w niezaliczone sprawdzenie, które widać w minutę, zamiast w wiarygodnie wyglądający dokument, którego obalenie zajmuje godzinę.
Drugie ograniczenie: kryteria wyjścia nie sprawiają, że agent ma rację. Zła nazwa kanału przeszłaby sprawdzenie liczby wierszy. Dobre kryterium wymusza za to umieszczenie dowodu (URL-a, liczby, daty) na stronie, gdzie może go wyłapać sprawdzenie próbki. Weryfikacja nadal wymaga osoby sprawdzającej albo drugiego przejścia innym modelem.
Jeśli jutro oddajesz zadanie agentowi kodującemu:
- Zapisz linię mety przed zadaniem. Jeśli nie potrafisz opisać, jak wygląda "zrobione", w formie sprawdzenia, zadanie nie jest gotowe do delegowania.
- Wybieraj warunki, które oceni maszyna: przechodzące testy, udany build, liczba wierszy, brak pustych komórek.
- Traktuj "zweryfikowałem X" bez wartości X jako brak.
- Mechaniczne zbieranie wysyłaj do szybkiego poziomu, a mocny model zostaw do decyzji.
- Otwarte myślenie trzymaj w głównej sesji, gdzie możesz sterować nim tura po turze. Delegowanie działa przy zadaniach, które mają koniec.
Szerszą wersję tej myśli, że o jakości decyduje bardziej spec niż model, opisuję w tekście o wyborze modelu i effort w Claude Code.
Pytania, na które odpowiada ten wpis
- Czym jest kryterium wyjścia dla agenta kodującego AI?
- Kryterium wyjścia to zapisany w zadaniu warunek, który mówi agentowi, że skończył, a osobie sprawdzającej, czy mu się udało. W przypadku agentów musi dać się je sprawdzić bez polegania na relacji samego agenta, na przykład przechodzące testy albo tabela z ustaloną liczbą wierszy i wypełnionymi kolumnami.
- Dlaczego agent kodujący zwraca notatkę o postępach zamiast gotowego wyniku?
- Gdy zadanie nie ma sprawdzalnego końca, agent zamyka turę w naturalnym punkcie zatrzymania, a przy otwartej pracy często jest nim podsumowanie własnych postępów. Liczbowe kryterium wyjścia i prośba o częściowe wyniki zapisywane partiami dają mu linię mety i chronią wykonaną pracę, jeśli skończy się budżet.
- Jak powstrzymać agenta AI przed deklarowaniem weryfikacji, której nie wykonał?
- Wymagaj dowodu obok każdego twierdzenia: każda liczba ze źródłowym URL-em i datą sprawdzenia. Deklarowanej weryfikacji bez zapisanej wartości nie da się odróżnić od braku weryfikacji, więc traktuj ją jak brakującą.