AI-serie intervju 16: Hva kjennetegner en god spec-koding?
En god Spec Coding (spesifikasjonsdrevet programmering) handler om å gjøre «vage ideer» til «presise, verifiserbare og utførbare kontrakter». Det handler ikke bare om å skrive et dokument, men om å etablere et tvetydig kommunikasjonsspråk mellom menneske og AI (eller mellom mennesker). Nedenfor vil jeg gi et bilde av en god spesifikasjon ut fra fire dimensjoner: innholdsstruktur, skriveregler, samarbeidsflyt med AI og kvalitetsverifisering.
1. Standard struktur for spesifikasjonsdokument (med funksjonsmodul som eksempel)
| Kapittel | Obligatorisk innhold | Eksempel |
|---|---|---|
| 1. Mål og omfang | En setning som forklarer hva som gjøres og tydeliggjør hva som ikke gjøres | «Implementer API for brukerregistrering, inkluderer ikke e-postverifisering» |
| 2. Inngangs-/utgangskontrakt | Datastruktur, type, obligatoriske/valgfrie felt, eksempelverdier | POST /register request body {email: string, password: string}, response 201 eller 400 med feilkode |
| 3. Atferd og logikk | Forretningsregler, grensebetingelser, tilstandsoverganger | «Passordlengde 8-20 tegn, minst ett tall; hvis e-post finnes, returner 409» |
| 4. Feilhåndtering | Alle mulige unntaksscenarier med tilhørende feilkoder/meldinger | «Databaseforbindelse feiler → returner 503, ikke avslør stakken» |
| 5. Ikke-funksjonelle krav | Ytelse (responstid < 200ms), sikkerhet (parametriserte spørringer), logging, observerbarhet | «Alle SQL må bruke forhåndskompilerte spørringer; logg email men ikke password» |
| 6. Testtilfeller (kritisk) | Minst 3 typiske innganger + 2 grense-/unntaksinnganger, med forventet utgang | Se tabell under |
| 7. Avhengigheter og begrensninger | Hvilke biblioteker, versjoner, miljøvariabler som brukes | «Python 3.10+, FastAPI, miljøvariabel DB_URL» |
Eksempel på testtilfeller (innebygd i spesifikasjonen)
| Scenario | Inngang | Forventet utgang |
|---|---|---|
| Normal registrering | e-post: a@b.com, passord: Pass1234 |
201, returner user_id |
| Passord for kort | passord: Ab1 |
400, feilkode WEAK_PASSWORD |
| E-post finnes allerede | samme e-post | 409, feilkode EMAIL_EXISTS |
En god spesifikasjon bør først skrive testtilfeller, fordi AI kan generere enhetstester direkte basert på dem, og automatisk verifisere etter fullføring.
2. Kjerneprinsipper for å skrive spesifikasjoner (SMART-variant)
| Prinsipp | Forklaring | Moteksempel |
|---|---|---|
| Presis (Precise) | Bruk konkrete tall, typer, boolske betingelser; unngå «så mye som mulig», «vanligvis» | ❌ «Passordet må være sikkert nok» → ✅ «Passordet må være minst 8 tegn, inneholde stor bokstav, liten bokstav og tall» |
| Verifiserbar (Verifiable) | Hvert krav kan avgjøres som bestått/ikke bestått via automatisk testing eller manuell kontroll | ❌ «Koden skal være elegant» → ✅ «Syklomatisk kompleksitet ≤ 10, ingen dupliserte kodeblokker» |
| Tvetydig (Unambiguous) | Samme term har samme betydning gjennom hele teksten; gi ordliste om nødvendig | ❌ «Hvis brukeren ikke finnes, returner feil» → ✅ «Bruker finnes ikke → returner 404 med {code: 'USER_NOT_FOUND'}» |
| Fullstendig (Complete) | Dekker happy path, alle unntaksstier og ikke-funksjonelle krav | ❌ Skrev bare vellykket scenario → ✅ Inkluderer database-timeout, utilstrekkelige rettigheter, osv. |
| Atomær (Atomic) | Én spesifikasjon beskriver kun én uavhengig leverbar funksjon (slik at AI kan fullføre én gang) | ❌ Bruk én spesifikasjon for «hele betalingssystemet» → ✅ Del opp i «generer betalingsordre», «tilbakeringingsverifisering», «refusjon» |
3. Spesifikasjonsdrevet programmeringsflyt ved samarbeid med AI
- Mennesket skriver spesifikasjonen (struktur som ovenfor, spesielt testtilfeller og funksjonssignatur).
- Gi spesifikasjonen til AI på én gang (ikke legg til krav i dialog, unngå vibe-forurensning).
- AI produserer kode + enhetstester (AI må generere kjørbare tester basert på testtilfellene i spesifikasjonen).
- Kjør testene: Hvis alle består, gå til neste steg; hvis ikke, endre spesifikasjonen eller rett koden direkte (da kan man gå inn i en liten løkke, men endringer må dokumenteres).
- Menneskelig gjennomgang: Kontroller om det er introdusert funksjonalitet utenfor spesifikasjonen (scope creep), sjekk sikkerhet/ytelse.
- Fiksering: Legg spesifikasjonsdokumentet og den endelige koden sammen i depotet som permanent dokumentasjon.
Viktig praksis: Spesifikasjon som kode – bruk
spec.md+test_spec.py, der testfilen kommer direkte fra eksemplene i spesifikasjonen. Slik kan man senere kun kjøre testene for å verifisere om spesifikasjonen er brutt.
4. Effekter av en god spesifikasjon (kan brukes som akseptansekriterier)
- Forutsigbarhet: Samme spesifikasjon gitt til forskjellig AI (eller forskjellige personer) gir lignende implementering.
- Testbarhet: Etter at koden er skrevet, kan 90 % av korrektheten umiddelbart verifiseres automatisk.
- Vedlikeholdbarhet: Et halvt år senere kan hvem som helst forstå den opprinnelige designintensjonen ved å se på spesifikasjonen.
- Lav kommunikasjonskostnad: Teamet diskuterer kun spesifikasjonen, ikke spesifikke kodelinjer.
- Sikkerhet/kvalitet innebygd: Sikkerhetskrav (som parametriserte spørringer) og grensebetingelser er spesifisert i spesifikasjonen, AI må følge dem.
5. Eksempel på en god spesifikasjon (forenklet versjon)
# Spesifikasjon: API for brukerregistrering
## Omfang
- Mottar e-post, passord
- Sender ikke verifiserings-e-post, sjekker ikke e-postens ekthet
## 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" }
## Atferd
- E-post må oppfylle grunnleggende RFC 5322-format (a@b.c)
- Passord: lengde 8-20, minst ett tall og én stor bokstav
- Bruk bcrypt for kryptert lagring, saltkostnad 10
- Hvis e-post allerede finnes før lagring i database → 409
## Testtilfeller (inngang -> forventet statuskode+responsfelt)
| Inngang e-post | passord | Forventet |
|----------------|---------|-----------|
| test@x.com | Pass1234 | 201, user_id finnes |
| test@x.com | pass | 400, INVALID_PASSWORD |
| bad | Pass1234 | 400, INVALID_EMAIL |
| (allerede eksisterende e-post) | Pass1234 | 409, EMAIL_ALREADY_EXISTS |
## Ikke-funksjonelle
- SQL må bruke parametriserte spørringer (mot injeksjon)
- Logg registreringskilde-IP, ikke logg passord
- Responstid 95 % av forespørsler < 100 ms (uten bcrypt)
## Avhengigheter
- Python 3.10+, FastAPI, bcrypt, asyncpg
God Spec Coding = oversettelse av menneskets «designbeslutninger» til maskinens «testtilfeller + typesignaturer + atferdsbegrensninger», slik at AI kun fyller implementeringen, mens mennesket alltid kontrollerer kvalitet og retning.
评论
暂无已展示的评论。
发表评论(匿名)