Skip to content

Spec-driven delivery loops

Read Spec → Implement → Run Checks → Review → toista, kunnes hyväksytty tai max-iteraatiot täynnä. Spec-fields: goal, checks (deterministiset komennot), max_iterations, allowed_tools. Hands-on: aja 04_spec_loop_factory.py.

SW Builders
Advanced
60 min

Tähän mennessä olet käyttänyt yksittäisiä rooleja yksittäisiin tehtäviin. Spec-loop yhdistää ne autonomiseksi silmukaksi, joka ajaa, kunnes valmis tai pysähtymisehto täyttyy.

Loop-malli

   ┌─────────────────────────────────────────────────┐
   │                                                  │
   │   Read Spec                                      │
   │       ↓                                          │
   │   Implement (Builder agent)                      │
   │       ↓                                          │
   │   Run Checks (deterministic local commands)      │
   │       ↓                                          │
   │   Review (Reviewer agent)                        │
   │       ↓                                          │
   │   Approved? ──No──→ Adjust + iterate ──┐         │
   │       │                                 │         │
   │       Yes                              ↑         │
   │       ↓                                 │         │
   │   Ship + log decision trace ←──────────┘         │
   │                                                  │
   │   max_iterations exceeded? ──→ Halt + escalate   │
   │                                                  │
   └─────────────────────────────────────────────────┘

Spec-driven loop

Spec-driven loop on factory-pattern, jossa agentti(t) ajavat saman silmukan toistuvasti — implement → check → review — kunnes spec on täytetty tai max-iteraatiot ylittyy. Avain: spec on ainoa source of truth, eivät arvaukset siitä, mitä halutaan. Loop pysähtyy itsestään hallitusti.

Spec-rakenne

Spec-loopin spec on JSON tai YAML, jolla on tarkat kentät:

spec.example.jsonjson
{
"goal": "Add 120-second timeout to all outbound HTTP calls in src/api/",
"max_iterations": 5,
"checks": [
  {
    "name": "syntax",
    "command": "python -m py_compile src/api/*.py",
    "must_pass": true
  },
  {
    "name": "tests",
    "command": "pytest tests/api/ -x",
    "must_pass": true
  },
  {
    "name": "timeout-exists",
    "command": "grep -q 'timeout=120' src/api/*.py",
    "must_pass": true
  }
],
"implement_instructions": "Use the requests library timeout parameter. Don't change behaviour for non-HTTP calls.",
"review_instructions": "Verify timeout is exactly 120s, not approximated. Verify no test was disabled.",
"allowed_tools": ["Read", "Glob", "Grep", "Edit", "Bash"]
}
KenttäMitä se tekee
goalMitä halutaan saada aikaan — yhdellä lauseella
max_iterationsPysähtymisehto — älä koskaan loop ikuisesti
checksDeterministiset lokaalit komennot, jotka ajetaan jokaisen iteraation jälkeen
implement_instructions(Optional) miten rakennetaan
review_instructions(Optional) miten arvioidaan
allowed_toolsTool-whitelist — turvallisuus

Pro tip

Avain: checks ovat deterministisiä komentoja, ei LLM:n arvauksia. pytest, grep, npm test, eslint — nämä antavat oikean vastauksen joka kerta. LLM-reviewer voi sanoa "näyttää hyvältä", mutta vain test-suite tietää, toimiiko se.

Hands-on: Aja 04_spec_loop_factory.py

Pro tip

Hands-on -tiedostot (04_spec_loop_factory.py, spec.example.json, backend-runner) jaetaan Sessio 4:n live-koulutuksessa Wed Jun 17 — facilitator antaa zip-paketin tai jakaa repo-linkin sessiossa. Itseopiskelussa lue tämä lesson ohjeena spec-loopin rakenteesta, mutta odota tiedostot live-sessiosta tai pyydä niitä tuki@modernpath.ai.

Valmistautuminen:

Setupbash
cd content/basematerials/session-4-agentic/claude-factory-rehearsal/

# Valitse joku CLI-backend, jolla on aktiivinen subscription
# (claude / codex / opencode)
uv run python -V

Aja perus-spec:

Runbash
uv run python 04_spec_loop_factory.py \
  --backend claude \
  --spec spec.example.json

Tee oma spec:

spec.add-timeout.jsonjson
{
"goal": "Add 120s timeout",
"max_iterations": 3,
"checks": [
  {
    "name": "syntax",
    "command": "{python} -m py_compile {target_file}"
  },
  {
    "name": "timeout-exists",
    "command": "grep -q 'wait_for' {target_file}"
  }
]
}
Run own specbash
uv run python 04_spec_loop_factory.py \
  --backend claude \
  --spec spec.add-timeout.json

Pohdittavaa harjoituksen aikana

Quiz

Miten loop päättää milloin pysähtyä?

Quiz

Mitä tapahtuu, kun yksi checks epäonnistuu?

Quiz

Mihin ihmisen review sopii spec-loopissa?

Spec quality = output quality

Huono spec = huono output, riippumatta agentin älykkyydestä.

Anti-patternEsimerkkiKorjaus
Vague goal"Make it better""Reduce p95 latency from 300ms to under 100ms for /api/users"
Ei checksejä(puuttuu)Vähintään: syntax, tests, custom check
Korkea max_iterations50Aloita 3–5; nosta vain jos perusteltu
Whitelist puuttuu(puuttuu)Lisää allowed_tools — esim. älä anna bash jos ei tarvita
Liian iso scope"Refactor entire auth module"Pilko: "Add timeout to auth.py", "Split auth.py into oauth + session"

Harjoitus: Kirjoita spec omasta tehtävästäsi

Ota oma to-do (tiimisi backlogista) ja kirjoita siitä spec spec.example.json -muodossa. Mitä on goal? Mitkä ovat 3 determinististä checkiä? Mikä on järkevä max_iterations?

Mitä loop NÄYTTÄÄ ajossa?

Tyypillinen onnistunut ajo:

Loop output (lyhennetty)text
[iteration 1/5] Builder
→ Reading src/api/users.py
→ Reading specs/add-timeout.json
→ Edit: Added timeout=120 to 3 fetch() calls
→ Tokens: 1842 in / 421 out / $0.012

[iteration 1/5] Checks
✓ syntax — passed (0.4s)
✗ tests — FAILED (test_long_response timed out)
✓ timeout-exists — passed

[iteration 1/5] Reviewer
→ Verdict: REQUEST_CHANGES
→ Reason: test_long_response uses 180s mock — needs adjustment

[iteration 2/5] Builder
→ Edit: Updated test mock from 180s to 100s
→ Tokens: 612 in / 89 out / $0.004

[iteration 2/5] Checks
✓ syntax — passed
✓ tests — passed (12s)
✓ timeout-exists — passed

[iteration 2/5] Reviewer
→ Verdict: APPROVED
→ Total cost: $0.016, total time: 47s

[FINAL] Status: SUCCESS  iterations: 2/5  cost: $0.016

Mitä tämä kertoo:

  • Iteraatio 1 epäonnistui deterministisesti (test failure), ei LLM:n arvauksena
  • Builder näki virheen ja korjasi sekä koodin että testin
  • Reviewer hyväksyi vasta kun checks olivat vihreät
  • Lokitettu hinta + aika → seuraava run on vertailukohta

Yhteenveto

  • 🔁 Spec-loop = Read Spec → Implement → Run Checks → Review → iterate
  • 🎯 Spec on single source of truth — ei arvauksia
  • ✅ Checks ovat deterministisiä komentoja, eivät LLM-arvauksia
  • 🛑 Pysähdys: kaikki checks läpi TAI max_iterations ylittyy
  • 👤 Ihmisen rooli: kirjoita hyvä spec + hyväksy valmis tuotos

Seuraavassa oppitunnissa: Antipatternit — mitä menee pieleen ja miten suojautua siltä, että factorysta tulee vastuuvelka.

Sign in to track your progress

Sign in

Questions and answers

Sign in to participate in the discussion