Przejdź do głównej zawartości

Test: daj sesji pętlę informacji zwrotnej

Etap testu daje każdej sesji agenta szybką pętlę informacji zwrotnej, która w razie błędu blokuje zakończenie (fail closed): sprawdzenia uruchamiane jedną komendą, mierzalną definicję ukończenia i regułę, że sesja nie może zgłosić sukcesu, dopóki któreś sprawdzenie jest czerwone. Weryfikator w świeżym kontekście i ponowny przebieg w CI potwierdzają wynik, a evale testują regresyjnie konfigurację sterującą agentem.

Ta strona jest dla dewelopera, który prowadzi sesje agenta, i dla tech leada, który odpowiada za zespołowy kontrakt weryfikacji. Agent pisze: „gotowe, wszystkie testy przechodzą”. Pobierasz gałąź, uruchamiasz make test i dwa testy padają. Sesja nigdy ich nie uruchomiła; przeczytała kod i uznała, że działa. Teraz to ty uruchamiasz testy i wklejasz stack trace’y z powrotem do czatu.

Tradycyjnie: sygnał, że kod działa, przychodzi późno. CI odpowiada po minutach, tester po dniach, produkcja po tygodniach. Gdy kod pisze agent, późny sygnał oznacza, że człowiek sprawdza cały jego wynik.

AI-native: sesja sprawdza własną pracę, zanim zobaczy ją człowiek. Uruchamia testy, build i porównanie zrzutów ekranu, czyta błędy i iteruje, aż sprawdzenia przejdą. Człowiek czyta dowody, a nie każdą linię.

Pętla informacji zwrotnej i weryfikator to dwie różne rzeczy. Pętla działa przez całe zadanie. Weryfikator to jedno końcowe sprawdzenie w świeżym oknie kontekstu, gdy sesja uważa, że skończyła.

  • Blok weryfikacji do CLAUDE.md lub AGENTS.md, który agent uruchamia, zanim zgłosi zadanie jako ukończone.
  • Cztery prompty do skopiowania: definicja ukończenia, reprodukcja błędu, sprawdzenie wizualne i weryfikacja w świeżym kontekście.
  • Hook Stop w Claude Code, który nie pozwala sesji skończyć, dopóki bramka jest czerwona, oraz odpowiedniki w Codeksie i Cursorze.
  • Bezobsługowy przebieg weryfikatora w CI przez claude -p albo codex exec.
  • Runner evali, który mówi, czy zmiana instrukcji, skilli lub hooków pogorszyła pracę agenta.
  • Zestaw testów i build, z których każdy uruchamiasz lokalnie jedną komendą.
  • Przy pracy nad UI: przeglądarka, którą agent może sterować, na przykład Playwright MCP.
  • Zaakceptowany plan.md z komendami dowodowymi, z etapu Build: plan.md, potem implementacja. Pętlę możesz uruchomić bez niego, ale weryfikator potrzebuje czegoś, z czym porówna diff.

Włącz sprawdzenie do pętli, gdy agent może je uruchomić w kilka sekund lub kilka minut i przeczytać wynik. Wolne albo współdzielone sprawdzenia zostaw w CI, gdzie agent nie może ich edytować.

SprawdzenieKiedy działaCo łapieKto odpowiada
Lint i sprawdzenie typów zmienionych plikówPo każdej edycji (hook)Składnię, typy, rozjazd styluSesja
Testy jednostkowe (szybki projekt)Zanim sesja zgłosi ukończenieZepsute zachowanie w zmienionym moduleSesja
BuildZanim sesja zgłosi ukończenieBrakujące importy, błędy bundlowaniaSesja
Zrzut ekranu lub sprawdzenie w przeglądarceZadania UI, każda iteracjaBłędy układu i interakcjiSesja
Subagent weryfikatorRaz, na końcuNiespełnione punkty planu, regresje w sąsiednim kodzieŚwieży kontekst
Pełny zestaw, E2E, skany bezpieczeństwaCI przy każdym pushuWszystko, co sesja pominęła lub osłabiłaCI, poza diffem
  1. Opakuj każde sprawdzenie w jeden cel, który przy błędzie kończy się kodem niezerowym: make test, npm test, pytest. Agent nie odróżni wiarygodnie sukcesu od porażki w komendzie, która wypisuje błędy i kończy się kodem 0.

  2. Dodaj do pliku instrukcji projektu blok weryfikacji z poprawnym wynikiem każdej komendy. Claude Code czyta CLAUDE.md, Codex czyta AGENTS.md, a Cursor czyta projektowe Rules.

    ## Verifying your work
    - Build: make build (must finish with "Build succeeded")
    - Test: make test (all green; never skip or delete a failing test)
    - Lint: make lint (zero warnings)
    Run all three before reporting any task complete, and paste the
    output with each exit code. If a test fails, fix the code, not the test.
  3. Raz celowo zepsuj bramkę. Zmień jedną asercję tak, żeby musiała paść, uruchom make test i potwierdź, że wynik jest czerwony. Bramka, której nigdy nie widziałeś czerwonej, niczego nie dowodzi. Jak silna jest twoja wyrocznia? opisuje testy mutacyjne, które odpowiadają na to samo pytanie w skali.

Daj agentowi definicję ukończenia, którą może sprawdzić

Dział zatytułowany „Daj agentowi definicję ukończenia, którą może sprawdzić”

Subiektywny cel („upewnij się, że działa”) pozwala agentowi skończyć, gdy uzna, że skończył. Mierzalny cel pozwala skończyć dopiero wtedy, gdy potwierdzi to komenda. Wpisz cel w prompt, obok zadania.

Subiektywny celMierzalny cel
„Upewnij się, że kod dobrze wygląda”„npm run lint kończy się kodem 0 i zerem ostrzeżeń”
„Obsłuż przypadki brzegowe”„Trzy nowe testy (błędny podpis, zduplikowane zdarzenia, uszkodzony payload) są zielone”
„Zrób zgodnie z projektem”„Zrzut ekranu przy 1280 i 375 pikselach zgadza się z mocks/checkout.png; wypisz każdą różnicę”
„Niczego nie zepsuj”„Wszystkie istniejące testy w tests/billing/ nadal przechodzą”

Spraw, żeby „gotowe” było niemożliwe przy czerwonej bramce

Dział zatytułowany „Spraw, żeby „gotowe” było niemożliwe przy czerwonej bramce”

Instrukcja w CLAUDE.md jest tylko wskazówką; w długiej sesji agent może o niej zapomnieć. Hook uruchamia się za każdym razem. Podepnij szybką bramkę pod moment, w którym agent próbuje skończyć.

Hook Stop uruchamia się, gdy Claude kończy odpowiedź. Kod wyjścia 2 blokuje zakończenie i przekazuje stderr z powrotem do Claude’a, więc pracuje dalej nad błędem. Dodaj to do .claude/settings.json:

{
"hooks": {
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "cd \"$CLAUDE_PROJECT_DIR\" && make verify-fast 1>&2 || exit 2"
}
]
}
]
}
}

verify-fast to cel make, który dodajesz sam i który uruchamia tylko lint, sprawdzenie typów i testy jednostkowe, na przykład verify-fast: lint typecheck test-unit; pełne make test zostaje w CI.

Stop nie przyjmuje matchera. W Claude Code 2.1.283 hook Stop, który zablokuje zakończenie osiem razy z rzędu, zostaje pominięty i tura się kończy; limit zmienia zmienna CLAUDE_CODE_STOP_HOOK_BLOCK_CAP. Własny skrypt może odczytać stop_hook_active z wejścia hooka i zwracać sukces, dopóki ta wartość jest prawdziwa. Generowanie testów i TDD z Claude Code dodaje hook PostToolUse, który uruchamia tylko testy związane z edytowanym plikiem.

Poprawka błędu zaczyna się od testu, który odtwarza błąd i pada z oczekiwanego powodu. Commitujesz ten test, zanim zmieni się jakikolwiek kod aplikacji. Sesja naprawiająca nie może go edytować. Taka kolejność blokuje najczęstszy sposób, w jaki agent „naprawia” błąd: osłabienie sprawdzenia.

Po commicie testu zacznij poprawkę od: „Make the test in tests/refunds/ pass without editing any file under tests/.” Potem mechanicznie zablokuj edycję testów na czas poprawki. Ochrona wyroczni pokazuje reguły deny, hooki i konfigurację CODEOWNERS, a Programowanie sterowane testami z pomocą AI opisuje pętlę red-green dla nowych funkcji.

Testy jednostkowe nie widzą przesuniętego przycisku. Przy pracy nad UI daj agentowi przeglądarkę, makietę i mierzalne porównanie, i pozwól mu iterować: implementacja, zrzut ekranu, porównanie, poprawka. Playwright MCP (@playwright/mcp 0.0.82 w npm, 2026-09-26) to oficjalny serwer przeglądarki od Microsoftu.

Okno terminala
claude mcp add playwright -- npx @playwright/mcp@latest --isolated

--isolated trzyma profil przeglądarki w pamięci. Z trwałego profilu może naraz korzystać tylko jedna przeglądarka, więc równoległe sesje w osobnych worktree go potrzebują. README Playwrighta poleca agentom kodującym również Playwright CLI (@playwright/cli) ze skillami, bo schematy narzędzi MCP i snapshoty stron zużywają kontekst. Zainstaluj go przez npm install -g @playwright/cli@latest, a potem uruchom playwright-cli install --skills, żeby skopiować jego skill do workspace’u. Oba podejścia porównuje strona Playwright MCP, a agent-browser to osobne CLI przeglądarki dla agentów, jeśli chcesz mieć drugą opcję.

Sesja, która napisała kod, jest uwięziona we własnych założeniach; jej „wszystkie testy przechodzą” może znaczyć „przechodzą wszystkie testy, o których pomyślałam”. Subagent weryfikator startuje z czystym kontekstem, czyta diff i plan.md, sam uruchamia sprawdzenia i raportuje, niczego nie poprawiając. Zdefiniuj go raz i zacommituj, żeby każda sesja korzystała z tego samego weryfikatora:

Subagent to plik Markdown w .claude/agents/. Kompletny verifier.md jest na stronie Build.

Daj weryfikatorowi tylko narzędzia do czytania i uruchamiania (w Claude Code Bash, Read, Grep) i napisz mu instrukcję w trybie adwersarza: niech szuka regresji w sąsiednich modułach, a nie tylko w zmienionych liniach.

Uruchom sprawdzenia tam, gdzie agent nie może ich edytować

Dział zatytułowany „Uruchom sprawdzenia tam, gdzie agent nie może ich edytować”

Wklejony przez sesję wynik to deklaracja. Dowodem jest CI, które uruchamia te same komendy, bo konfiguracja CI leży poza diffem kontrolowanym przez agenta. Uruchamiaj w CI te same cele make, żeby lokalna bramka i bramka merge’a nie mogły się rozjechać.

Jako drugą opinię w CI uruchom weryfikatora bezobsługowo, tylko z narzędziami do czytania i uruchamiania oraz z limitem wydatków:

Okno terminala
claude -p "Run make test and make build. Compare git diff origin/main...HEAD \
with plan.md and list any plan item with no passing proof. Do not edit files." \
--allowedTools "Read" "Grep" "Bash(make test)" "Bash(make build)" "Bash(git diff *)" \
--output-format json --max-budget-usd 2 > verifier.json

Wymień każdy cel make z nazwy: Bash(make *) pozwoliłoby też na make deploy czy make clean. claude -p startuje w trybie uprawnień Manual, więc wywołanie narzędzia, które wymaga zgody i nie ma go w --allowedTools, zostaje odrzucone zamiast wyświetlić pytanie. --max-budget-usd działa tylko z --print.

Kod ma testy; konfiguracja, która steruje agentem, też ich potrzebuje. Zmiana CLAUDE.md, AGENTS.md, reguły, skilla, hooka albo modelu może pogorszyć pracę, którą agent tydzień temu wykonywał dobrze, i żaden test produktu tego nie zauważy. Zestaw evali jest właśnie takim testem.

  1. Zbierz od 20 do 50 prawdziwych zadań z ostatniej pracy, każde z commitem bazowym i zaakceptowanym wynikiem. Dołącz te, które agent zrobił źle.

  2. Zapisz każde zadanie jako przypadek: prompt.md, base-commit i check.sh, który rozstrzyga o sukcesie testami trzymanymi poza worktree, w którym działa agent, żeby testowany agent nie mógł ich zobaczyć ani edytować. Nie umieszczaj przypadków w commitach bazowych albo trzymaj je poza repozytorium.

  3. Uruchamiaj zestaw przy każdej zmianie plików harnessu oraz według harmonogramu, żeby złapać aktualizacje modeli i narzędzi.

  4. Uzależnij zmianę od odsetka zaliczonych przypadków. Edycja skilla, która obniża ten odsetek, przechodzi review przed merge’em.

  5. Każdy incydent produkcyjny zamień w przypadek, napisany przez zespół, do którego incydent należał, i zostaw go jako test regresyjny.

Minimalny runner, evals/run.sh, uruchamiany z katalogu głównego repozytorium:

#!/usr/bin/env bash
set -u
root=$(pwd); pass=0; total=0; mkdir -p evals/out
for case in evals/cases/*/; do
id=$(basename "$case"); total=$((total + 1)); dir=$(mktemp -d)
git worktree add --detach "$dir" "$(cat "$case/base-commit")" >/dev/null \
|| { echo "SKIP $id (bad base commit)"; total=$((total - 1)); continue; }
# The base commit has the OLD harness: copy the version under test into it.
cp -R CLAUDE.md .claude "$dir"/ 2>/dev/null
(cd "$dir" && claude -p "$(cat "$root/$case/prompt.md")" \
--permission-mode acceptEdits \
--allowedTools "Bash(make test)" "Bash(make build)" "Bash(make verify-fast)" \
--max-budget-usd 2 --output-format json > "$root/evals/out/$id.json")
if bash "$case/check.sh" "$dir"; then pass=$((pass + 1)); echo "PASS $id"; else echo "FAIL $id"; fi
git worktree remove --force "$dir"
done
echo "pass rate: $pass/$total"
[ "$total" -gt 0 ] || { echo "no cases ran"; exit 1; }
[ $((pass * 100 / total)) -ge "${EVAL_THRESHOLD:-90}" ]

Dla Codeksu zamień linię agenta na codex exec -C "$dir" -c default_permissions=":workspace" --ephemeral "$(cat "$root/$case/prompt.md")" (profile uprawnień są w Codex 0.157.1 w wersji beta) i kopiuj AGENTS.md oraz .codex/. Uruchamiaj zestaw kilka razy na zmianę: agenci nie są deterministyczni, a jeden przebieg jednego przypadku to próbka, nie werdykt. Przypadki, które zalicza każda konfiguracja, przestają je rozróżniać; zastąp je nowymi z monitoringu. Ciągłe evale opisują harmonogram i raportowanie, a Maintain zamianę incydentów w przypadki.

Skąd wiesz, że pętla działa, bez czytania każdej linii?

Dział zatytułowany „Skąd wiesz, że pętla działa, bez czytania każdej linii?”

Raport DORA 2025 (Google Cloud, 2025-09-23) stwierdza, że „without robust control systems, like strong automated testing, mature version control practices, and fast feedback loops, an increase in change volume leads to instability” (bez solidnych mechanizmów kontroli, takich jak dobre testy automatyczne, dojrzała kontrola wersji i szybkie pętle informacji zwrotnej, większa liczba zmian prowadzi do niestabilności). Pętla w sesji jest takim mechanizmem dla każdej sesji. Sprawdzaj ją po dowodach:

  • Dowód przychodzi razem z deklaracją. Każda wiadomość „gotowe” zawiera wklejony wynik i kod wyjścia każdej komendy weryfikacji. Wiadomość bez nich nie oznacza ukończenia.
  • CI zgadza się z sesją. Pierwszy przebieg CI na pull requeście agenta jest zielony. Gdy sesja mówiła „zielono”, a CI mówi „czerwono”, pętla jest zepsuta; ustal przyczynę przed kolejnym zadaniem.
  • Poprawki błędów zachowują swój test. Czerwony test trafił do commita przed poprawką, a diff poprawki nie dotyka chronionych ścieżek testów.
  • Tabela weryfikatora jest dołączona. Pull request zawiera tabelę punktów planu od weryfikatora. Pełny zestaw definiuje pakiet dowodów.
  • Zmiany harnessu mają wynik evali. Pull request, który edytuje instrukcje, skille lub hooki, pokazuje odsetek zaliczonych przypadków przed zmianą i po niej.

Kto zatwierdza. Deweloper akceptuje dowody przy rutynowych zmianach i czyta diff pod kątem intencji i ryzyka, a nie błędów kompilacji. Tech lead odpowiada za blok weryfikacji, bramkę zakończenia i próg evali oraz recenzuje każdą ich zmianę, bo agent, który może edytować bramkę, może ją też osłabić.

Wskaźniki wyprzedzające: odsetek zmian od agenta, które przechodzą CI za pierwszym razem, i odsetek zaliczonych evali w czasie. Wskaźniki opóźnione: czas review na pull request, odsetek nieudanych zmian (change failure rate) oraz regresje złapane w CI w porównaniu z produkcją. Każdy z nich definiuje strona Metryki AI-native SDLC.

Co psuje się w pętli informacji zwrotnej i jak to naprawić

Dział zatytułowany „Co psuje się w pętli informacji zwrotnej i jak to naprawić”

Agent zgłasza ukończenie, niczego nie uruchamiając. Blok weryfikacji jest w pliku instrukcji, ale sesja pominęła go przy długim kontekście. Dodaj hook Stop, żeby zakończenie przy czerwonej bramce było niemożliwe, i traktuj każde „gotowe” bez wklejonych kodów wyjścia jako nieukończone.

Agent edytuje test zamiast kodu. Usuwa asercję, dodaje skip albo robi wyjątek dla danych testowych. Najpierw commituj test odtwarzający błąd, blokuj edycję ścieżek testów podczas poprawek i każ CI oznaczać każdy diff poprawki, który dotyka testów. Mechanikę opisuje Ochrona wyroczni.

Pętla kręci się na czymś, czego kod nie naprawi. Baza danych nie działa, brakuje sekretu albo zewnętrzne API ogranicza liczbę zapytań testów. Agent ponawia próby albo zaczyna mockować kod produkcyjny. Opisz w pliku instrukcji granice mocków dla usług zewnętrznych, każ agentowi zatrzymać się i zgłosić awarię środowiska, a zakończenie tury zostaw limitowi hooka Stop.

Bramka jest zielona, ale niczego nie dowodzi. Testy niczego nie sprawdzają albo endpoint zdrowia zwraca 200 bez dotykania bazy. Przy każdej zmianie bramki celowo zepsuj jedną asercję i mierz siłę testów testami mutacyjnymi.

Niestabilne testy uczą agenta ponawiać do skutku. Sesja trzy razy uruchamia padający test, raz przechodzi i sesja zgłasza sukces. Przenieś znane niestabilne testy do kwarantanny, poza bramkę sesji, i każ agentowi zgłaszać test, który raz pada, a raz przechodzi, jako niestabilny, zamiast ogłaszać naprawę.

Weryfikator zgadza się ze wszystkim. Dostał podsumowanie od sesji implementującej i przejął jej założenia. Daj mu tylko diff, plan i komendy, i wymagaj, żeby każdą komendę uruchomił sam.

Równoległe sesje walczą o przeglądarkę. Dwa worktree dzielą jeden profil Playwrighta i jeden port serwera deweloperskiego. Użyj --isolated i przydziel każdemu worktree własny port.

Zestaw evali zawsze przechodzi. Każdy przypadek rozwiązuje każda konfiguracja, więc zestaw przestaje je rozróżniać. Wycofuj nasycone przypadki i dodawaj nowe z ostatnich porażek i incydentów.