Proces rozwoju napędzany przez specyfikacje: od wymagań do kodu
Pięć etapów od intencji do zweryfikowanego kodu.
Rozwój napędzany specyfikacją (Spec-Driven Development, SDD) działa, gdy specyfikacja jest przepływem pracy, a nie dokumentem archiwalnym, który odkłada się po fazie wstępnej. Chodzi nie o wytworzenie obszernego dokumentu wymagań produktu.
Chodzi o przejście przez sekwencję artefaktów podlegających weryfikacji, z których każdy redukuje niejednoznaczność, zanim ktokolwiek – człowiek czy agent AI – zmieni kod produkcyjny.
Jeśli nie znasz koncepcji SDD, zacznij od artykułu Czym jest rozwój napędzany specyfikacją?, który zawiera definicje, porównania z TDD i BDD oraz uzasadnienie traktowania specyfikacji jako źródła prawdy. Niniejszy artykuł w klasterze dokumentacji Architektura aplikacji jest przewodnikiem operacyjnym. Przechodzi przez pięć faz, pokazuje, co powinien zawierać każdy artefakt, wyjaśnia, gdzie mieszczą się agenty AI, oraz dostarcza gotowe szablony, które możesz skopiować do swojego repozytorium już dziś.

SDD to przepływ pracy, nie dokument
Najczęstszym błędnym podejściem w rozwoju napędzanym specyfikacją jest traktowanie specyfikacji jako biurokracji. Zespół pisze długi dokument wymagań, przechowuje go w wiki, a następnie koduje pamięciowo i na podstawie wątków czatowych. Specyfikacja istnieje, ale nie napędza żadnych działań. To teatralna dokumentacja, która jest gorsza niż brak specyfikacji, ponieważ tworzy fałszywe poczucie bezpieczeństwa.
Działający przepływ SDD generuje łańcuch artefaktów, z których każdy jest weryfikowany przed rozpoczęciem kolejnej fazy. Wymagania redukują niejednoznaczność produktu. Projekt redukuje niejednoznaczność techniczną. Zadania redukują niejednoznaczność wykonania. Implementacja produkuję kod względem znanego celu. Walidacja udowadnia, że łańcuch utrzymał się. Gdy któraś z faz ujawnia błąd, poprawiasz artefakt i uruchamiasz proces ponownie od tego punktu – a nie po tym, jak trzy tysiące linii odejścia od celu trafią do gałęzi głównej.
Przepływ pracy jest niezależny od narzędzi. Możesz go realizować za pomocą plików markdown w Git, GitHub Spec Kit, planów w Cursorze lub z prostym edytorem tekstu i dyscyplinowanym recenzentem. Istotne jest sekwencjonowanie i bramki weryfikacyjne, a nie marka narzędzi.
Faza 1 – Zdefiniuj wymagania
Faza definiowania odpowiada na pytanie, jaki problem rozwiązujesz i jak wygląda stan „gotowe”. Celowo omija ona pytanie, jak to zbudować. W momencie, gdy specyfikacja wymagań mówi „użyj posortowanych zbiorów Redis”, przestajesz definiować i zaczynasz projektować w niewłaściwym dokumencie. Trzymaj implementację z dala od wymagań. Umieść ją w planie.
Sformułowanie problemu i użytkownicy
Zacznij od jednego akapitu, który opisuje problem językiem potocznym. Nazwij użytkowników, których to dotyczy, oraz sytuację, która sprawia, że problem jest bolesny. Dobrze sformułowane zagadnienie pozwala recenzentowi, który nie brał udziału w spotkaniu planistycznym, ocenić, czy proponowane rozwiązanie faktycznie adresuje ten problem.
Przykład dla funkcji limitowania częstotliwości zapytań (rate-limiting) API:
Konsumenty API w warstwie bezpłatnej mogą wysyłać nieograniczoną liczbę żądań, co powoduje gwałtowne wzrosty kosztów i efekt „hałaśliwego sąsiada” wpływający na płatne najemników. Operatorzy platformy potrzebują wymazywalnego limitu na klucz bez interwencji manualnej.
Cele, rzeczy niezaliczane do celu (non-goals) i kryteria akceptacji
Cele opisują rezultaty, które dostarczysz. Rzeczy niezaliczane do celu (non-goals) opisują kuszącą, sąsiadującą pracę, której wyraźnie nie wykonasz. Wspólnie ograniczają one kreatywność agenta, co jest niezbędne, gdy narzędzia AI w przeciwnym razie „pomocnie” rozszerzają zakres.
| Sekcja | Dobry przykład | Słaby przykład |
|---|---|---|
| Cel | Odrzucaj żądania przekraczające limit na klucz z kodem HTTP 429 | Zrób API szybsze |
| Non-goal | Dashbilty rozliczeń na najemnika | Popraw wszystkie wydajności API |
| Kryterium akceptacji | Nieautoryzowane żądania otrzymują 401 przed uruchomieniem sprawdzania limitu | Endpoint jest bezpieczny |
Kryteria akceptacji powinny być na tyle precyzyjne, że każde z nich mapuje się co najmniej na jeden test. „Endpoint jest bezpieczny” nie jest kryterium akceptacji. „Nieautoryzowane żądania otrzymują HTTP 401” jest. Jeśli nie możesz zapisać konkretnego kryterium, wymagania są wciąż zbyt niejasne do implementacji.
Otwarte pytania
Wypisz każdą decyzję, która jeszcze nie została podjęta. Niejasne pytania nie są oznaką porażki. Są dowodem na to, że faza definiowania wykonuje swoją robotę. Rozwiąż je przed napisaniem planu projektowego, w przeciwnym razie zapłacisz za tę niejednoznaczność w formacie przeróbek implementacyjnych.
Minimalny szablon wymagań:
## Problem
[Jeden akapit: kto cierpi, dlaczego i co wywołuje problem.]
## Użytkownicy
- [Rola głównego użytkownika]
- [Rola drugoplanowego użytkownika]
## Cele
1. [Mierzalny rezultat]
2. [Mierzalny rezultat]
## Rzeczy niezaliczane do celu (Non-goals)
- [Wyraźnie poza zakresem]
- [Wyraźnie poza zakresem]
## Kryteria akceptacji
- [ ] [Weryfikowalne zachowanie]
- [ ] [Weryfikowalne zachowanie]
## Otwarte pytania
- [ ] [Pytanie blokujące planowanie]
Faza 2 – Zaplanuj projekt
Faza planowania tłumaczy intencje na decyzje techniczne. Tutaj mieszczą się posortowane zbiory Redis, granice modułów, zmiany schematów, kontrakty API, kroki migracji, ograniczenia bezpieczeństwa oraz strategia testowa. Plan wypływa ze specyfikacji wymagań oraz istniejących ograniczeń projektu – wyborów stacka, rejestru decyzji i konwencji przechowywanych w plikach takich jak AGENTS.md lub konstytucja projektu.
Architektura i dotknięte moduły
Nazwij moduły, usługi lub pakiety, które ulegną zmianie, i streszcz wzorzec integracji. Jeśli funkcja przekracza granicę usługi, udokumentuj kontrakt po obu stronach. Agenty halucynują API, gdy kontrakty są implikowane. Zrobienie ich jawnym w planie zapobiega wynalezieniu nieistniejących endpointów i błędnym kształtom odpowiedzi.
Model danych, kontrakty API i migracje
Udokumentuj zmiany schematów, nowe tabele lub pola, wymagania dotyczące indeksów oraz zasady kompatybilności wstecznej. Dla API HTTP napisz metodę, ścieżkę, kształt żądania, kształt odpowiedzi i kody błędów. Dla zdarzeń (events) napisz nazwy tematów (topic names), schematy ładunku (payload schemas) i semantykę dostawy. Uwzględnij kroki migracji i uwagi dotyczące cofania (rollback), gdy model danych ulega zmianie.
Bezpieczeństwo, obserwowalność i strategia testowa
Ograniczenia bezpieczeństwa należą do planu, nie do przemyśleń po fakcie w przeglądzie kodu. Zauważ wymagania uwierzytelniania, reguły autoryzacji, granice walidacji wejścia oraz dane, które nie powinny pojawiać się w logach. Obserwowalność powinna obejmować metryki, logi lub ślady (traces) potrzebne do potwierdzenia, że funkcja działa w środowisku produkcyjnym.
Strategia testowa odwołuje się do kryteriów akceptacji. Zidentyfikuj, które kryteria wymagają testów jednostkowych, które testów integracyjnych, a które weryfikacji manualnej. Jeśli używasz testowania jednostkowego w Go lub testowania jednostkowego w Pythonie, nazwij pakiety i pliki testowe, które spodziewasz się dodać. Plan bez strategii testowej to plan, który trafi do produkcji z lukami, które odkryjesz na miejscu.
Faza 3 – Rozłóż zadania implementacyjne
Faza zadań dekomponuje plan na fragmenty wystarczająco małe, aby można je było zaimplementować, zweryfikować i zatwierdzić niezależnie. To właśnie to sprawia, że rozwój wspomagany przez agenta jest podlegający weryfikacji. Zamiast jednego ogromnego diffu, otrzymujesz sekwencję skupionych zmian, z których każda odnosi się do nazwanej wymagania.
Wielkość zadań i zależności
Dobre zadanie dotyka ograniczonego zestawu plików, kończy się w jednej sesji agenta i kończy się krokiem weryfikacyjnym. Zadania powinny wyraźnie deklarować zależności. Zadania migracyjne wykonują się przed kodem odczytującym nowy schemat. Zmiany w bibliotekach współdzielonych wykonują się przed konsumentami. Zmiany w middleware’u uwierzytelniającym wykonują się przed endpointami zależnymi od nowego zachowania.
Pliki, walidacja i punkty kontrolne weryfikacji
Każde zadanie powinno zawierać listę plików, które prawdopodobnie ulegną zmianie, kryteria akceptacji, które spełnia, oraz sposób walidacji ukończenia. Walidacja może być komendą testową, przykładem z curla lub kontrolą manualną opisaną w krokach do skopiowania. Każde zadanie kończy się punktem kontrolnym weryfikacji przez człowieka. Recenzent potwierdza, że diff odpowiada opisu zadania przed rozpoczęciem kolejnego zadania.
Minimalny wpis zadania:
### Zadanie 3 -- Dodaj middleware limitu częstotliwości
**Zależy od:** Zadanie 1 (schemat), Zadanie 2 (repozytorium)
**Pliki:** middleware/ratelimit.go, middleware/ratelimit_test.go, server.go
**Spełnia:** AC-2 (429 przy przekroczeniu limitu), AC-3 (nagłówki limitu w odpowiedzi)
**Waliduj:** `go test ./middleware/...` przechodzi; curl przekraczający limit zwraca 429 z Retry-After
**Punkt kontrolny weryfikacji:** Potwierdź, że middleware działa po uwierzytelnieniu, przed handlerem
Uważaj na eksplozję wygenerowanych zadań. Agenty AI mogą wyprodukować plany pięćdziesięciu zadań w kilka sekund. Większość z tych zadań będzie redundantna lub zbyt granulowana, aby można ją było efektywnie zweryfikować. Przydatna lista zadań dla funkcji średniej wielkości często ma od pięciu do piętnastu pozycji, a nie pięćdziesiąt.
Faza 4 – Implementuj jedno zadanie na raz
Implementacja jest celowo wąska. Wybierz jedno zadanie, daj agentowi tylko kontekst potrzebny do tego zadania i zatrzymaj się, gdy walidacja przejdzie. Resetowanie kontekstu między zadaniami to cecha, a nie błąd. Zapobiega to zanieczyszczeniu późniejszej pracy wcześniejszymi założeniami i utrzymuje diffy w stanie podlegającym weryfikacji.
Zastosuj ograniczenia ze stosu specyfikacji
Agent implementujący powinien odczytać specyfikację wymagań, plan projektowy, opis bieżącego zadania oraz ograniczenia na poziomie projektu. Ograniczenia to sekcja o najwyższej ROI, którą większość zespołów pomija. Powiadzinają agenta, czego nie robić – nie refaktoryzuj niezwiązanych modułów, nie zmieniaj podpisów publicznych API poza tą funkcją, nie wprowadzaj nowych zależności bez aktualizacji planu.
Aktualizuj plan, gdy rzeczywistość się różni
Implementacja ujawni niespodzianki. Biblioteka nie obsługuje zakładanego zachowania. Migracja zajmuje dłużej niż oczekiwano. Przypadek brzegowy został pominięty w kryteriach akceptacji. Gdy tak się stanie, zaktualizuj specyfikację przed kontynuowaniem. Popraw wymagania lub plan, uzyskaj szybką weryfikację, a następnie wznowij implementację względem skorygowanego artefaktu. Kod, który cicho odbiega od specyfikacji, to sposób, w jaki odejście (drift) staje się trwałe.
Faza 5 – Waliduj względem specyfikacji
Walidacja to miejsce, w którym SDD zyskuje swoją wartość. Bez niej specyfikacja jest ćwiczeniem planistycznym. Z nią, specyfikacja jest kontraktem, który możesz sprawdzić względem dostarczonego kodu.
Automatyczne kontrole
Uruchom pełny zestaw testów, lint i kontrole typów w CI. Podłącz je do swojego potoku, używając wzorców z skrótu GitHub Actions, jeśli potrzebujesz praktycznego punktu startowego. Automatyczne kontrole łapią regresje. Nie łapią jednak błędnych funkcji zbudowanych poprawnie, dlatego przegląd kryteriów akceptacji nadal ma znaczenie.
Kryteria akceptacji i weryfikacja manualna
Przejdź przez każde kryterium akceptacji ze specyfikacji wymagań. Oznacz każde jako spełnione, nieudane lub odroczone z uzasadnieniem. Weryfikacja manualna łapie problemy UX, luki w bezpieczeństwie i błędne zachowanie, którego testy przeoczyły, ponieważ testy były pisane pod dopasowanie do błędnej specyfikacji.
Diff specyfikacji do kodu
Ostateczny krok walidacji porównuje implementację z planem projektowym. Czy zmienione pliki pasowały do plików przewidzianych w planie? Czy decyzje architektoniczne w kodzie pasowały do zarejestrowanych decyzji? Nieoczekiwane pliki w diffie są sygnałem – albo plan był niekompletny, albo agent zbiegł z toru. Oboje zasługują na uwagę przed scaleniem (merge). Utrzymywanie specyfikacji, testów i kodu w synchronizacji w rozwoju AI zamienia tę jednorazową weryfikację diffu w powtarzalną tabelę śledzenia i zestaw kontroli CI, dzięki czemu odejście jest łapane przy każdym PR, a nie tylko wtedy, gdy ktoś pamięta, aby spojrzeć.
| Warstwa walidacji | Łapie |
|---|---|
| Testy jednostkowe i integracyjne | Regresje i błędną logikę w ramach zakresu |
| Lint i kontrole typów | Problemy ze stylem i błędy typów |
| Przejście przez kryteria akceptacji | Błędne zachowanie zbudowane zgodnie ze specyfikacją |
| Diff specyfikacji do kodu | Odejście architektoniczne i przepełnienie zakresu |
Gdzie mieszczą się agenty AI w przepływie pracy
Agenty AI to akceleratory w każdej fazie, a nie zastępcy weryfikacji. Produktowy wzorzec to: szkic, weryfikacja, doszlifowanie, a następnie kontynuacja. Poproś agenta o przygotowanie szkicu specyfikacji wymagań na podstawie opisu problemu, a następnie edytuj intencję, dopóki cele, rzeczy niezaliczane do celu i kryteria akceptacji nie będą poprawne. Poproś agenta o przygotowanie szkicu planu projektowego na podstawie zatwierdzonych wymagań, a następnie zweryfikuj decyzje architektoniczne, zanim istnieją jakieś kod. Poproś agenta o implementację jednego fragmentu zadania na raz, zatwierdzając każdy diff przed rozpoczęciem kolejnego zadania.
Agenty są szczególnie przydatne przy tworzeniu pierwszych szkiców i testów boilerplate’owych. Ludzie są szczególnie przydatni przy łapaniu błędnych celów, niebezpiecznej architektury i subtelnej ekspansji zakresu. Przepływ pracy zawodzi, gdy pomija się którąkolwiek ze stron – gdy agenty implementują bez specyfikacji, lub gdy ludzie piszą specyfikacje, nigdy ich nie walidując względem kodu.
Niniejszy artykuł o przepływie pracy celowo pozostaje niezależny od narzędzi. Przewodniki wykonawcze specyficzne dla narzędzi – konfiguracja edytora, komendy slashowe, konfiguracja agenta – znajdują się w klastrze Narzędzia dla deweloperów AI. Filar procesowy żyje tutaj w praktykach dokumentacyjnych, ponieważ artefakty są ważniejsze niż dostawca.
Częste błędy, które zabijają rozwój napędzany specyfikacją
Ogromne specyfikacje przed jakąkolwiek walidacją. Trzydziestostronicowy dokument wymagań napisany przed prototypem czy zwiadem (spike) to biurokracja wodospotu, a nie SDD. Napisz minimalną specyfikację, która usuwa niejednoznaczność dla kolejnej fazy, a następnie weryfikuj założenia wczesnie. Nie każda funkcja wymaga pełnego pięciopuławowego pętli – Rozwój napędzany specyfikacją vs Vibe Coding wyjaśnia, kiedy lżejsza struktura jest wystarczająca.
Niejasne kryteria akceptacji. Przymiotniki takie jak „szybki”, „czysty” i „przyjazny dla użytkownika” nie są kryteriami akceptacji. Zamień je na mierzalne zachowanie. Jeśli nie możesz tego przetestować, nie możesz tego niezawodnie zaimplementować – zwłaszcza z agentem AI.
Brak „rzeczy niezaliczanych do celu” (non-goals). Bez nich agenty domyślnie rozszerzają zakres. Dodają warstwy cache’u, refaktoryzują sąsiadujące moduły i wprowadzają zależności, o które nie prosiłeś. Non-goals to sposób, w jaki mówisz „nie” z wyprzedzeniem.
Brak planu testów w fazie projektowej. Testy pisane dopiero po implementacji tendują do potwierdzania tego, co zostało zbudowane, a nie tego, co było zamierzone. Plan powinien nazwać, które kryteria akceptacji mapują się na które typy testów, zanim zmieni się pierwszy plik produkcyjny.
Pomijanie weryfikacji na granicach faz. Specyfikacja zweryfikowana przed planem. Plan zweryfikowany przed zadaniami. Zadania zweryfikowane przed implementacją. Każda brama jest tania. Naprawianie odejścia po dużym scaleniu jest drogie.
Pozwalanie na eksplozję wygenerowanych zadań. Traktuj listę zadań wygenerowaną przez AI z pięćdziesięciu pozycji jako szkic, nie harmonogram. Scal redundanckie pozycje, podziel zbyt duże i usuń zadania, które nie mapują się na wymagania.
SDD działa, gdy każda faza redukuje niejednoznaczność. Zawodzi, gdy tworzy biurokrację.
Ponowne wykorzystanie szablonów
Skopiuj je do swojego repozytorium i dostosuj. Przechowuj specyfikacje obok gałęzi funkcjonalnej, weryfikuj je w pull requestach i trzymaj pod kontrolą wersji, aby agenty i ludzie czytali to samo źródło.
Szablon wymagań
# Funkcja -- [nazwa]
## Problem
## Użytkownicy
## Cele
## Rzeczy niezaliczane do celu (Non-goals)
## Kryteria akceptacji
## Otwarte pytania
Szablon projektu
# Projekt -- [nazwa funkcji]
## Streszczenie
## Dotknięte moduły
## Zmiany modelu danych
## Kontrakty API
## Migracje
## Bezpieczeństwo
## Obserwowalność
## Strategia testowa
## Ryzyko i środki łagodzące
Szablon listy zadań
# Zadania -- [nazwa funkcji]
## Zadanie 1 -- [tytuł]
Zależy od:
Pliki:
Spełnia:
Waliduj:
Punkt kontrolny weryfikacji:
## Zadanie 2 -- [tytuł]
...
Lista kontrolna walidacji
# Walidacja -- [nazwa funkcji]
## Automatyczne
- [ ] Wszystkie testy przechodzą
- [ ] Lint czysty
- [ ] Kontrola typów czysta
## Kryteria akceptacji
- [ ] AC-1 --
- [ ] AC-2 --
## Specyfikacja do kodu
- [ ] Zmienione pliki pasują do planu
- [ ] Brak nieudokumentowanych zmian architektonicznych
- [ ] Specyfikacja zaktualizowana, jeśli implementacja się różniła
Wniosek
Rozwój napędzany specyfikacją nie polega na pisaniu więcej dokumentów. Polega na przechodzeniu przez fazy: zdefiniuj, zaplanuj, zadania, implementuj i waliduj, z bramką weryfikacyjną przy każdym kroku. Każda faza powinna pozostawić kolejnego wykonawcę – człowieka lub agenta – z mniejszą ilością zgadywania niż faza poprzednia.
Zacznij od małych. Uruchom pełny przepływ na jednej funkcji średniej wielkości. Trzymaj artefakty w markdownie w repozytorium. Aktualizuj specyfikację, gdy rzeczywistość odbiega. Waliduj przed scaleniem. Gdy łańcuch działa, otrzymujesz mniej odejścia, mniejsze diffy podlegające weryfikacji i trwały rejestr intencji, który przetrwa resety sesji i przekazania między zespołami.
Gdy łańcuch staje się biurokracją, skróć zakres – nie weryfikację. Dwustronicowa specyfikacja, która została zweryfikowana, jest lepsza niż trzydziestostronicowa specyfikacja, której nikt nie czytał.
Przydatne linki
- Dokumentacja GitHub Spec Kit – toolkit open-source implementujący podobną pętlę zdefiniuj-zaplanuj-zadania-implementuj
- Martin Fowler o narzędziach do rozwoju napędzanego specyfikacją – analiza Kiro, Spec Kit i Tessl