Blog · 19 września 2026 · 10 min czytania
Spec-driven development z agentami kodującymi: specyfikacje, które agent skończy beze mnie
agenci AI · spec-driven development · Claude Code · Codex CLI · workflow
TL;DR: Kiedy oddaję pracę agentowi kodującemu, który będzie działał beze mnie, specyfikacja jest całym interfejsem. Specyfikacja, którą agent jest w stanie skończyć, ma siedem części: gdzie agent pracuje, model produktu, którego musi przestrzegać, problem, cel opisany tym, co widzi użytkownik, twarde ograniczenia (żadnych zastosowanych migracji, żadnego merge, żadnego deployu, wyłącznie design system), ponumerowaną listę testów oraz blok zakończenia z dokładnymi sprawdzeniami do uruchomienia i raportem do napisania. Agent planujący pisze spec, drugi agent wykonuje go we własnym git worktree, a ja przeglądam wynik w około dwie minuty. Specyfikacje zawodzą, gdy nie mają warunku zakończenia, gdy opierają się na regułach, które agent przeczytał raz i zapomniał, albo gdy po cichu każą agentowi odkryć problem, zamiast go rozwiązać.
Czym jest spec-driven development z agentami kodującymi?
Spec-driven development to praktyka spisywania, co zmiana ma robić, czego nie może ruszać i jak zostanie sprawdzona, zanim powstanie jakikolwiek kod, a potem przekazania tego dokumentu temu, kto ją implementuje. Przy agentach kodujących implementuje model działający w piaskownicy, a spec staje się jedynym kanałem między moim zamiarem a jego pracą. Nikt nie odpowiada na pytania.
Mój konkretny problem: sam prowadzę produkt do dopasowywania ofert pracy i produkt do mierzenia widoczności w AI, z Claude Code jako głównym agentem i Codex CLI od OpenAI jako drugim (setup opisałem w tekście Codex CLI obok Claude Code). Chciałem oddawać całe funkcje i wracać do pull requestu, który mogę zmergować. Wypróbowałem trzy sposoby przekazywania pracy:
- Prompt w jednej linii. Szybko się go pisze. Sprawdza się przy zmianie nazwy. Przy czymkolwiek większym agent wypełnia luki domysłami, a ja płacę za te domysły przy przeglądzie.
- Praca w parze na żywo. Zostaję w sesji i odpowiadam na pytania. Wyniki są dobre, ale to ja jestem wąskim gardłem, a cały sens delegowania polegał na tym, żeby być gdzie indziej.
- Spisana specyfikacja w pliku. Wolniej powstaje i zmusza mnie do podjęcia decyzji, które wolałbym odłożyć. W zamian agent może dojść do końca sam, a spec służy jednocześnie jako lista kontrolna do przeglądu.
Trzeciego sposobu używam przy wszystkim, co zajmuje agentowi więcej niż kilka minut. Dalsza część artykułu pokazuje, jak wygląda spec w tym formacie. Wnioski pochodzą z prawdziwych specyfikacji.
Budowa specyfikacji, którą agent jest w stanie skończyć
Trzy moje ostatnie specyfikacje dotyczyły zupełnie różnych rzeczy: panelu administracyjnego, który miał być czytelny na pierwszy rzut oka, zmiany miejsca, do którego przycisk wychodzący kieruje użytkownika dla części rekordów, oraz błędu w imporcie danych, przez który rekord przychodzący jako kilka częściowych kopii zachowywał tylko jedną z nich. Miały wspólny szkielet.
# illustrative shape only
# Task: <one line, the outcome>
Where you are: worktree on branch <x>, created from <base>.
Work only here; other sessions use the main checkout.
## Product model how this part works, where X happens
## The problem symptoms, a real case, a read-only repro
## Goal what the user sees when it is done
## Hard constraints what must not change or be done
## Tests numbered cases
## Finish checks, commit rules, PR, reportGdzie jesteś. Pierwsze linie mówią, w którym worktree i na którym branchu jest agent oraz że inne sesje korzystają z głównego checkoutu. Inaczej agenci działający równolegle zabłądzą do tych samych plików.
Model produktu. Na początku pomijałem tę sekcję, a dziś uważam ją za najważniejszą. Wyjaśnia, jak działa odpowiednia część produktu, i wskazuje jedno miejsce, w którym żyje zagadnienie przekrojowe. Przy zmianie linku wychodzącego spec mówił, że parametry śledzące są dodawane w dokładnie jednej funkcji i że nigdy nie może powstać druga ścieżka. Bez tego zdania zdolny agent doda śledzenie w nowym miejscu wywołania, bo lokalnie to rozsądne.
Problem. Objawy w takiej formie, w jakiej je zgłoszono, jeden prawdziwy przypadek z konkretnymi wartościami i, jeśli istnieje, komenda tylko do odczytu, która go odtwarza. Prawdziwy przypadek zakotwicza agenta. Przy poprawce błędu spec pokazywał źródło, w którym garść prawdziwych rekordów zamieniała się w kilka razy więcej wpisów, przez co usterki nie dało się z niczym pomylić.
Cel. Opisany od strony ekranu, którą widzi użytkownik. Spec panelu administracyjnego nie wymieniał komponentów do zmiany. Wymieniał pytania, na które musi odpowiadać każdy wiersz: czy działa, jak daleko doszedł, ile nowych pozycji czeka na mój przegląd, ile odrzucono, czy coś się nie udało.
Testy. Ponumerowana lista przypadków. Przy błędzie pierwsza instrukcja brzmi: napisz test, który go odtwarza i nie przechodzi, a dopiero potem napraw. Ta lista jest też moją listą kontrolną do przeglądu.
Zakończenie. Dokładne komendy do instalacji, uruchomienia testów, typecheck i lintu zmienionych plików. Zasady commitów. Push i otwarcie pull requestu. Potem krótki raport w moim języku: co się zmieniło, które pliki, które testy i czego agent nie mógł zweryfikować. Ostatni punkt ma znaczenie. Agent, który nie może zalogować się do panelu administracyjnego, powinien to powiedzieć, zamiast sugerować, że sprawdził ekran.
Twarde ograniczenia: linie, które czynią delegowanie bezpiecznym
Twarde ograniczenia to część specyfikacji, dzięki której mogę odejść od komputera. Dzielą się na kilka rodzin.
- Nieodwracalne działania zostają przy mnie. Wypchnij branch i otwórz pull request; nie merguj, nie deployuj. Zmiana schema to nowy plik migracji w zwykłym folderze, a agent nigdy nie stosuje go na żadnej bazie danych.
- Niezmienniki, od których zależą inne systemy. Zapisana wartość, po której dopasowują się inne zadania, nie może się zmienić, a spec mówi, które moduły ją czytają, żeby agent mógł to sprawdzić. Jeśli wybór projektowy jest otwarty, agent musi wyjaśnić w opisie pull requestu, gdzie zastosował zmianę.
- Wyłącznie design system. Żadnych własnych przycisków, pól, kart, kolorów ani odstępów; wszystko działa w trybie ciemnym i jasnym. Jeśli brakuje komponentu, agent pisze o tym w raporcie, zamiast budować lokalną kopię.
- Nic wewnętrznego nie wycieka. Gdy zmiana dotyka czegokolwiek, co trafia do publicznego wyjścia (dane strukturalne, metadane, feedy, odpowiedzi API), spec mówi, że może się tam pojawić wyłącznie końcowa wartość przeznaczona dla użytkownika.
- Dokumentacja dla konkretnej wersji. Moja wersja frameworka ma zmiany łamiące zgodność, których model może nie znać, więc spec wskazuje dokumentację dostarczaną z zainstalowaną wersją i każe ją najpierw przeczytać.
- Wzorzec do skopiowania. Gdy ta sama poprawka istnieje już gdzie indziej, spec wskazuje ją razem z jej testem i mówi: "tutaj potrzebna ta sama logika". Zadanie projektowe zamienia się wtedy w przeniesienie gotowego rozwiązania.
Jedna reguła wygląda na zbędną, a wcale taka nie jest. Konwencje commitów (wiadomości po angielsku, jeden autor, bez trailera co-author, bez długich myślników, dodawanie plików po ścieżce) są już w pliku z instrukcjami, który czyta każdy agent. Mimo to powtarzam je w każdej specyfikacji. Agent czyta instrukcje raz na starcie i gubi je w trakcie długiej tury, a zabłąkany trailer co-author to najczęstsza wpadka, jaką widzę u obu CLI.
Kto pisze specyfikację, a kto ją wykonuje?
Pisze ją agent planujący. W praktyce to sesja Claude Code na najmocniejszym modelu, ta, która ma pamięć produktu, przeczytała kod i omówiła ze mną problem. Kiedy ta sesja dochodzi do pracy w pełni opisanej, jej instrukcje każą jej zapisać spec do pliku i wypisać gotową komendę dla drugiego terminala. Czytam spec, poprawiam go i wklejam jedną linię.
Wykonawcą jest inny agent z czystszym kontekstem. Przy pracy mechanicznej (testy z listy przypadków, szkielety, fixtures) to szybki poziom Codexa przy średnim effort. Przy implementacji gotowego planu to poziom roboczy przy wysokim effort. We wrześniu 2026 oznacza to GPT-5.6 Luna i GPT-5.6 Sol. Moja zasada dla poziomu roboczego: dostaje pełny spec, nigdy zadanie ustalenia, na czym polega problem. Launcher dokleja do każdego zadania instrukcję końcową: nikt nie odpowie na pytania, niejasny spec oznacza zatrzymanie się i raport, a ostatnia wiadomość wymienia pliki, wyniki testów i commit.
Ten podział działa, bo planowanie i wykonanie potrzebują czego innego. Planowanie potrzebuje długiego wątku, pamięci i osądu. Wykonanie potrzebuje precyzyjnego dokumentu i okna kontekstu, które nie jest już zapchane rozmową planistyczną. Ta sama idea na poziomie wyboru modelu pojawia się w tekście o wyborze modelu i effort w Claude Code: o jakości decyduje spec, a model głównie ustala tempo.
Ile kosztuje przegląd oddanego zadania?
Około dwóch minut na zadanie, a ta liczba prawie nie zależy od wielkości zmiany. Mój przegląd to stała procedura: diff stat brancha względem bazy; przejście code review, na oko albo przez głównego agenta; zielone testy w głównym checkoucie po lokalnym zmergowaniu brancha; sprawdzenie wiadomości commita pod kątem trailera co-author; sprawdzenie zmienionych plików pod kątem długich myślników; zakres zgodny ze specyfikacją. Dla drugiej opinii uruchamiam też przegląd tylko do odczytu w drugim agencie względem brancha bazowego, bo inny model łapie inne błędy.
Stały koszt przeglądu ma bezpośrednią konsekwencję: delegowanie opłaca się tylko przy zadaniach wartych co najmniej kilku minut pracy agenta. Przy dwuminutowej zmianie spędzam na przeglądzie tyle samo czasu, ile agent na pracy, i zysk znika. W moim pierwszym zmierzonym przebiegu zadanie z sześcioma przypadkami testowymi zajęło agentowi 70 sekund i około 29,7K tokenów, a wszystkie sześć testów przeszło za pierwszym razem. Zyskiem była równoległość i czysta główna sesja. Tokenów zaoszczędziło to bardzo niewiele.
Dlaczego specyfikacja zawodzi?
Brak warunku zakończenia. Najgorszy wynik z oddanego zadania dostałem przy otwartym briefie badawczym: zmapuj rynek, wypełnij jedenaście pól dla każdej pozycji, wyciągnij wnioski. Wróciła notatka o stanie własnej pracy, bez danych i z jednym błędnym faktem. Zadanie z pisaniem testów dwa dni wcześniej miało jeden warunek zaliczenia, zielone testy, i skończyło się za pierwszym podejściem. Bez sprawdzalnego końca agent zatrzymuje się tam, gdzie jego tura naturalnie się zamyka. O tej parze przebiegów napisałem w tekście o kryteriach wyjścia dla agentów kodujących.
Reguły, które agent przeczytał raz. Wszystko, co musi obowiązywać na końcu długiej tury, należy do samej specyfikacji, nawet jeśli jest też w instrukcjach globalnych. Właśnie dlatego istnieje blok zakończenia.
Ukryte odkrywanie. Spec, który mówi "napraw panel" bez objawów i docelowych pytań, każe agentowi wykonać myślenie produktowe. Agent zrobi jego część, z dużą pewnością siebie, a ja przy przeglądzie nie zgodzę się z połową.
Brak uprawnionego sposobu na zatrzymanie się. Jeśli spec nie mówi, co robić, gdy coś jest niejasne albo czegoś brakuje, agent zgaduje. Linie "napisz o tym w raporcie" zamieniają domysł w pytanie, na które mogę odpowiedzieć w następnej specyfikacji.
Problemy z harnessem. Niektóre porażki nie miały nic wspólnego z treścią specyfikacji. Mój pierwszy nieinteraktywny przebieg wisiał przez minutę, czekając na stdin, a pierwszy commit się nie udał, bo piaskownica nie mogła zapisywać do katalogu git głównego repozytorium, w którym worktree trzyma swoje metadane. Ten drugi problem agent zgłosił, zamiast go obchodzić. Oba wymagały poprawek w launcherze. Specyfikacja nie naprawi zepsutego harnessu.
Jest też ograniczenie, którego nie rozwiązałem. Napisanie dobrej specyfikacji zajmuje sporo czasu, często osobną sesję planowania, a przy niektórych zmianach ten czas to większość pracy. Spec-driven development się opłaca, gdy myślenie jest już zrobione i zostało tylko pisanie.
Co powiedziałbym komuś, kto jutro pisze swoją pierwszą specyfikację
- Zacznij od modelu produktu. Wskaż jedno miejsce, w którym żyje dane zagadnienie, i zabroń tworzenia drugiego.
- Opisz cel jako pytania, na które użytkownik odpowie, patrząc na wynik.
- Ponumeruj testy. Przy błędzie pierwszy test go odtwarza.
- Nieodwracalne kroki zostaw sobie: bez merge, bez deployu, migracje napisane, ale nie zastosowane.
- Zakończ blokiem zakończenia z dokładnymi komendami i raportem, który obejmuje to, czego nie dało się zweryfikować.
- Powtarzaj zasady commitów w każdej specyfikacji, nawet jeśli są w instrukcjach globalnych.
- Deleguj tylko zadania warte więcej niż czas przeglądu.
Pytania, na które odpowiada ten wpis
- Co powinna zawierać specyfikacja dla agenta kodującego?
- Specyfikacja, którą agent skończy sam, ma siedem części: gdzie agent pracuje, model produktu, którego musi przestrzegać, problem z prawdziwym przypadkiem, cel opisany tym, co widzi użytkownik, twarde ograniczenia, ponumerowaną listę testów oraz blok zakończenia z dokładnymi sprawdzeniami, zasadami commitów i raportem o tym, czego nie dało się zweryfikować.
- Kto powinien pisać specyfikację dla agenta kodującego AI?
- Pisze ją do pliku agent planujący, który ma kontekst produktu i omówił z Tobą problem. Drugi agent z czystym kontekstem wykonuje ją we własnym git worktree, a człowiek przegląda powstały pull request.
- Dlaczego specyfikacje dla agentów kodujących zawodzą?
- Najczęstsze przyczyny to brak warunku zakończenia, reguły, które agent przeczytał raz na początku i zgubił w trakcie długiej tury, oraz specyfikacje, które po cichu każą agentowi samemu odkryć problem. Pomaga też danie agentowi uprawnionego sposobu na zatrzymanie się i zgłoszenie problemu, bo wtedy nie zgaduje.