Seria wywiadów AI 16: Jak powinien wyglądać dobry spec coding?
Dobry Spec Coding (programowanie sterowane specyfikacją) polega na przekształceniu „niejasnych pomysłów” w „precyzyjne, weryfikowalne i wykonywalne kontrakty”. To nie tylko pisanie dokumentu, ale stworzenie jednoznacznego języka komunikacji między człowiekiem a AI (lub między ludźmi). Poniżej przedstawię, jak wygląda dobry spec z czterech perspektyw: struktury treści specyfikacji, zasad pisania, procesu współpracy z AI i walidacji jakości.
I. Standardowa struktura dokumentu specyfikacji (na przykładzie modułu funkcji)
| Rozdział | Wymagana treść | Przykład |
|---|---|---|
| 1. Cel i zakres | Opis jednym zdaniem, co robimy, wyraźnie określając czego nie robimy | „Implementacja API rejestracji użytkownika, bez weryfikacji e-mail” |
| 2. Kontrakt wejścia/wyjścia | Struktura danych, typy, pola wymagane/opcjonalne, przykładowe wartości | POST /register body żądania {email: string, password: string}, odpowiedź 201 lub 400 z kodem błędu |
| 3. Zachowanie i logika | Reguły biznesowe, warunki brzegowe, przejścia stanów | „Hasło długość 8-20 znaków, co najmniej jedna cyfra; jeśli e-mail już istnieje, zwróć 409” |
| 4. Obsługa błędów | Wszystkie możliwe scenariusze wyjątków i odpowiadające im kody/komunikaty błędów | „Błąd połączenia z bazą danych → zwróć 503, nie ujawniaj stosu” |
| 5. Wymagania niefunkcjonalne | Wydajność (czas odpowiedzi < 200ms), bezpieczeństwo (zapytania parametryczne), logowanie, obserwowalność | „Wszystkie SQL muszą być prekompilowane; rejestruj email, ale nie password” |
| 6. Przypadki testowe (kluczowe) | Co najmniej 3 typowe wejścia + 2 brzegowe/wyjątkowe, z oczekiwanymi wyjściami | Patrz tabela poniżej |
| 7. Zależności i ograniczenia | Jakie biblioteki, wersje, zmienne środowiskowe | „Python 3.10+, FastAPI, zmienna środowiskowa DB_URL” |
Przykładowe przypadki testowe (osadzone w specyfikacji)
| Scenariusz | Wejście | Oczekiwane wyjście |
|---|---|---|
| Normalna rejestracja | email: a@b.com, hasło: Pass1234 |
201, zwraca user_id |
| Hasło zbyt krótkie | hasło: Ab1 |
400, kod błędu WEAK_PASSWORD |
| E-mail już istnieje | ten sam e-mail co wyżej | 409, kod błędu EMAIL_EXISTS |
Dobry spec musi najpierw zawierać przypadki testowe, ponieważ AI może na ich podstawie bezpośrednio wygenerować testy jednostkowe, a po ich wykonaniu automatycznie zweryfikować poprawność.
II. Główne zasady pisania specyfikacji (wariant SMART)
| Zasada | Wyjaśnienie | Kontrprzykład |
|---|---|---|
| Precyzyjność (Precise) | Używaj konkretnych liczb, typów, warunków logicznych; unikaj „jak naj”, „zwykle” | ❌ „Hasło musi być wystarczająco bezpieczne” → ✅ „Hasło co najmniej 8 znaków, zawiera dużą literę, małą literę i cyfrę” |
| Weryfikowalność (Verifiable) | Każde wymaganie można sprawdzić za pomocą automatycznego testu lub ręcznej kontroli (zaliczone/niezaliczone) | ❌ „Kod musi być elegancki” → ✅ „Złożoność cyklomatyczna funkcji ≤ 10, brak zduplikowanych bloków kodu” |
| Jednoznaczność (Unambiguous) | Ten sam termin ma spójne znaczenie w całym dokumencie; w razie potrzeby podaj słownik | ❌ „Jeśli użytkownik nie istnieje, zwróć błąd” → ✅ „Użytkownik nie istnieje → zwróć 404 oraz {code: 'USER_NOT_FOUND'}” |
| Kompletność (Complete) | Obejmuje ścieżkę szczęśliwą, wszystkie ścieżki wyjątków i wymagania niefunkcjonalne | ❌ Napisano tylko scenariusz sukcesu → ✅ Obejmuje timeout bazy danych, brak uprawnień itp. |
| Atomowość (Atomic) | Jeden spec opisuje jedną, samodzielnie dostarczaną funkcję (ułatwia AI wykonanie jednym razem) | ❌ Jeden spec na „cały system płatności” → ✅ Podzielono na „generowanie zamówienia płatności”, „weryfikację podpisu zwrotnego”, „zwrot” |
III. Proces Spec Coding podczas współpracy z AI
- Człowiek pisze spec (według powyższej struktury, szczególnie przypadki testowe i sygnatury funkcji).
- Podaj spec AI za jednym razem (nie dodawaj wymagań w dialogu, aby uniknąć szumu).
- AI generuje kod i testy jednostkowe (AI musi utworzyć wykonywalne testy zgodne z przypadkami testowymi w specyfikacji).
- Uruchom testy: jeśli wszystkie przejdą, przejdź do następnego kroku; jeśli nie, popraw spec lub bezpośrednio skoryguj kod (wtedy możliwa jest mała pętla, ale należy rejestrować zmiany).
- Przegląd ręczny: sprawdź, czy nie wprowadzono funkcji spoza specyfikacji (scope creep), sprawdź bezpieczeństwo i wydajność.
- Utrwalenie: zatwierdź dokument specyfikacji wraz z końcowym kodem w repozytorium jako stały dokument.
Kluczowa praktyka: Specyfikacja jako kod – użyj
spec.md+test_spec.py, gdzie plik testowy pochodzi bezpośrednio z przykładów w specyfikacji. Dzięki temu późniejsza modyfikacja kodu wymaga jedynie uruchomienia testów, aby sprawdzić, czy specyfikacja nie została naruszona.
IV. Efekty dobrego speca (mogą służyć jako kryteria akceptacji)
- Deterministyczność: Ten sam spec podany różnym AI (lub różnym osobom) prowadzi do podobnych implementacji.
- Testowalność: Kod po napisaniu można natychmiast automatycznie zweryfikować w 90% pod kątem poprawności.
- Utrzymywalność: Po pół roku każdy, kto przeczyta spec, zrozumie pierwotne zamysły projektowe.
- Niskie koszty komunikacji: Zespół dyskutuje tylko o specyfikacji, a nie o konkretnych liniach kodu.
- Bezpieczeństwo/jakość wbudowane: Wymagania bezpieczeństwa (np. zapytania parametryczne) i warunki brzegowe są zapisane w specyfikacji, a AI musi ich przestrzegać.
V. Przykład dobrego speca (wersja bardzo uproszczona)
# Spec: API rejestracji użytkownika
## Zakres
- Przyjmuje email i hasło
- Nie wysyła e-maila weryfikacyjnego, nie sprawdza autentyczności e-maila
## Kontrakt
POST /register
Content-Type: application/json
Request: { "email": string, "password": string }
Response 201: { "user_id": string }
Response 400: { "code": "INVALID_PASSWORD" | "INVALID_EMAIL" }
Response 409: { "code": "EMAIL_ALREADY_EXISTS" }
## Zachowanie
- E-mail musi spełniać podstawowy format RFC 5322 (a@b.c)
- Hasło: długość 8-20, co najmniej jedna cyfra i jedna wielka litera
- Szyfrowane bcrypt, koszt soli 10
- Jeśli przed zapisem do bazy okaże się, że e-mail już istnieje → 409
## Przypadki testowe (wejście -> oczekiwany kod stanu + pole odpowiedzi)
| Wejście email | hasło | Oczekiwane |
|---------------|-------|------------|
| test@x.com | Pass1234 | 201, user_id istnieje |
| test@x.com | pass | 400, INVALID_PASSWORD |
| bad | Pass1234 | 400, INVALID_EMAIL |
| (istniejący e-mail) | Pass1234 | 409, EMAIL_ALREADY_EXISTS |
## Niefunkcjonalne
- SQL musi używać zapytań parametrycznych (ochrona przed injection)
- Logowanie IP źródła rejestracji, bez zapisywania hasła
- Czas odpowiedzi dla 95% zapytań < 100ms (bez bcrypt)
## Zależności
- Python 3.10+, FastAPI, bcrypt, asyncpg
Dobry Spec Coding = zapisanie „decyzji projektowych” człowieka jako „przypadków testowych + sygnatur typów + ograniczeń behawioralnych” dla maszyny, pozwalając AI jedynie na wypełnienie implementacji, podczas gdy człowiek zawsze kontroluje jakość i kierunek.
评论
暂无已展示的评论。
发表评论(匿名)