Przejdź do treści
Vibe engineering

Vibe engineering · · 7 min czytania

Spec-driven development z AI: najpierw specyfikacja, potem kod

Najpierw piszesz spec, potem agent go realizuje. Dlaczego specyfikacja bije promptowanie z pamięci.

Większość zespołów używa AI tak, jakby promptowała z pamięci. Otwierasz agenta, opisujesz zadanie w trzech zdaniach, dostajesz kod, poprawiasz, dostajesz kolejny kod. Działa — do momentu, w którym zadanie przestaje mieścić się w jednym zdaniu. Wtedy agent zgaduje, a ty łapiesz się na poprawianiu konsekwencji własnej niedoprecyzowanej intencji. Spec-driven development odwraca tę kolejność: najpierw piszesz specyfikację, potem agent ją realizuje. Kod jest wynikiem, nie punktem wyjścia.

Dlaczego pisana specyfikacja bije promptowanie z pamięci

Prompt z pamięci ma trzy wady, które skalują się razem z prędkością agenta. Po pierwsze jest ulotny — znika z kontekstu po kilku turach, więc agent zaczyna pracować na własnej interpretacji sprzed dziesięciu wiadomości. Po drugie jest niekompletny — w głowie masz ograniczenia (limit czasu, format danych, ścieżka rollback), których nie wypowiadasz, bo „to oczywiste”. Dla agenta nic nie jest oczywiste. Po trzecie jest nieweryfikowalny — skoro nigdzie nie zapisałeś, co miało powstać, nie masz jak sprawdzić, czy powstało.

Pisana specyfikacja usuwa wszystkie trzy. Jest trwała, więc agent wraca do niej w każdej turze zamiast zgadywać. Jest kompletna, bo akt pisania zmusza cię do nazwania ograniczeń, które inaczej zostałyby w głowie. Jest weryfikowalna, bo zawiera kryteria akceptacji, do których można przyłożyć gotowy kod. To nie jest biurokracja — to przeniesienie myślenia z fazy poprawek do fazy projektu, gdzie kosztuje dziesięć razy mniej.

Anatomia dobrego SPEC.md

Dobry spec ma stałą strukturę, dzięki której zarówno człowiek, jak i agent wiedzą, gdzie czego szukać. Pięć sekcji wystarcza w 95% przypadków.

Cel. Jedno, najwyżej dwa zdania: co i dla kogo. Nie „jak”, tylko „po co”. Jeśli nie potrafisz streścić celu w dwóch zdaniach, prawdopodobnie masz dwa zadania udające jedno.

Wymagania funkcjonalne. Lista obserwowalnych zachowań. Każdy punkt opisuje coś, co system robi, najlepiej w formie „gdy X, to Y”. To jest mięso specu i tu spędzasz najwięcej czasu.

Wymagania niefunkcjonalne. Ograniczenia, które łatwo przeoczyć: latencja, koszt wywołania LLM, limity pamięci, kompatybilność wsteczna, ścieżka rollback, bezpieczeństwo danych. To one najczęściej decydują o tym, czy implementacja nadaje się na produkcję.

Out of scope. Jawna lista tego, czego nie robimy w tej iteracji. Bez tej sekcji agent — pomocny do przesady — dorzuca funkcje, których nikt nie zamawiał, a ty review'ujesz kod, który nigdy nie powinien powstać.

Kryteria akceptacji. Sprawdzalna lista warunków „gotowe”. Najlepiej w formie, którą da się zamienić na testy. Jeśli kryterium nie da się zweryfikować, to nie jest kryterium — to życzenie.

Jak agent używa specu jako kontraktu

Kiedy spec jest gotowy, przestaje być notatką, a staje się kontraktem. Agent dostaje go jako stały kontekst i pracuje wewnątrz jego granic: wymagania funkcjonalne mówią mu, co zbudować, niefunkcjonalne — w jakich ramach, out of scope — gdzie się zatrzymać, kryteria akceptacji — kiedy uznać zadanie za skończone.

Ta zmiana ma praktyczne konsekwencje. Po pierwsze, możesz poprosić agenta, by sam sprawdził swoją pracę względem kryteriów akceptacji, zanim zgłosi gotowość — i odeśle sobie pracę do poprawki bez twojego udziału. Po drugie, gdy agent chce zrobić coś spoza specu, jest to natychmiast widoczne: albo łamie kontrakt, albo spec był niekompletny. W obu przypadkach dostajesz sygnał wcześnie, a nie na review po dwóch godzinach generowania.

Kontrakt zmienia też charakter twojego review. Bez specu czytasz kod i pytasz „czy to robi to, co chciałem?” — opierając się na pamięci tego, czego chciałeś. Ze specem pytasz „czy to spełnia kryteria akceptacji?”, a odpowiedź jest binarna i niezależna od twojego nastroju. Review przestaje być negocjacją, a staje się sprawdzeniem względem ustalonego wcześniej standardu. To samo dotyczy agenta-recenzenta: ma jawny punkt odniesienia, więc jego uwagi są konkretne zamiast ogólnikowych.

Iterowanie spec-first zamiast code-first

Najważniejsza zmiana mentalna: gdy implementacja idzie nie tak, nie poprawiasz kodu — poprawiasz spec. Kod jest tani i odtwarzalny; agent wygeneruje go ponownie w minutę. Spec jest źródłem prawdy, więc to w nim naprawiasz przyczynę, nie objaw.

W praktyce wygląda to tak: agent dostarcza implementację, ty czytasz ją przez pryzmat kryteriów akceptacji, znajdujesz rozjazd. Zamiast pisać „zmień to i tamto” w czacie, wracasz do specu, dopisujesz brakujące wymaganie albo doprecyzowujesz dwuznaczne, i prosisz o ponowną implementację dotkniętego fragmentu. Po kilku iteracjach spec jest precyzyjny, a kod — jego wiernym odbiciem. Poprawki w czacie dają odwrotny efekt: kod się zgadza, ale spec zostaje w tyle i nikt już nie wie, co jest prawdą.

To podejście chroni cię też przed najczęstszą pułapką pracy z AI: szybkim dostarczeniem czegoś, co wygląda na działające, lecz rozwiązuje połowę problemu. Kryteria akceptacji są bezlitosne — albo wszystkie są spełnione, albo zadanie nie jest skończone, niezależnie od tego, jak ładnie wygląda kod.

Krótki spec to dobry spec

Spec ma mieścić się w 400–800 słowach. To nie jest arbitralny limit — to granica, poniżej której spec jest czytelny w całości na jeden rzut oka, zarówno dla człowieka, jak i dla okna kontekstu agenta. Dłuższy spec to zwykle objaw jednego z dwóch problemów: albo zadanie jest za duże i trzeba je rozbić na kilka mniejszych speców, albo opisujesz implementację zamiast intencji.

Ta druga pułapka jest podstępna. Im więcej „jak” wkładasz w spec, tym mniej miejsca zostaje agentowi na rozwiązanie, które mogłoby być lepsze od twojego pierwszego pomysłu, i tym szybciej spec się dezaktualizuje przy każdej zmianie kodu. Spec opisuje co i dlaczego; jak zostaw agentowi, o ile „jak” nie jest twardym wymaganiem niefunkcjonalnym.

Przykładowy szkielet specu, który mieści się w limicie:

  • Cel: endpoint do eksportu faktur klienta w PDF, używany przez panel rozliczeń.
  • Funkcjonalne: gdy klient żąda eksportu, system zwraca PDF ze wszystkimi fakturami z wybranego okresu; gdy okres jest pusty, zwraca jasny komunikat; gdy klient nie ma uprawnień, zwraca 403.
  • Niefunkcjonalne: odpowiedź poniżej 2 s dla 100 faktur; brak przechowywania PDF na dysku; logowanie bez danych osobowych.
  • Out of scope: wysyłka mailem, eksport do innych formatów, fakturowanie cykliczne.
  • Akceptacja: test dla okresu z fakturami zwraca poprawny PDF; test pustego okresu zwraca komunikat, nie błąd; test braku uprawnień zwraca 403; p95 czasu odpowiedzi poniżej 2 s.

Jak to skaluje się w zespole

Spec-first przestaje być osobistą dyscypliną, a staje się protokołem zespołu. Spec to wspólny artefakt, który możesz wrzucić do PR'a obok kodu, podlinkować w issue i przejrzeć tak samo jak diff. Review specu jest tańsze niż review implementacji, bo czyta się go w minutę, a wyłapuje błędne założenia, zanim ktokolwiek napisze linijkę kodu.

Dla zespołu daje to trzy rzeczy. Onboarding: nowa osoba czyta spec i rozumie intencję bez archeologii w kodzie. Spójność: dwie osoby z tym samym specem dostaną od agenta porównywalne rozwiązania, bo kontrakt jest ten sam. Audyt: po fakcie wiesz, co miało powstać i dlaczego, więc decyzje są odtwarzalne, a nie zamknięte w czyjejś pamięci.

W praktyce warto przyjąć prostą regułę: każda zmiana powyżej kilku plików dostaje spec, który człowiek akceptuje przed implementacją. Agent może napisać pierwszy draft — jest w tym dobry — ale podpis jest ludzki. Bez tej decyzji spec przestaje być kontraktem, a staje się kolejnym wygenerowanym tekstem, któremu nikt nie ufa.

TL;DR

Spec-driven development z AI odwraca kolejność: najpierw piszesz krótki (400–800 słów) SPEC.md z celem, wymaganiami funkcjonalnymi i niefunkcjonalnymi, sekcją out of scope i kryteriami akceptacji, a dopiero potem agent go realizuje. Spec jest kontraktem — agent pracuje w jego granicach, a gdy coś idzie nie tak, poprawiasz spec, nie kod. Krótki spec pozostaje czytelny i aktualny; jako artefakt zespołu skaluje onboarding, spójność i audyt. Pisana specyfikacja bije promptowanie z pamięci, bo jest trwała, kompletna i weryfikowalna — a podpis pod nią zawsze należy do człowieka.

Spec-driven development z AI: najpierw specyfikacja, potem kod | vibecoding.pl