Capstone: a three-agent team
Building the spec → code → review pipeline: the architect writes the spec, the coder implements, the reviewer sends back fixes — looping to green tests with an iteration limit and cost tracking.
Lesson content is currently available in Russian.
What you will learn
- →Проектировать контракты состояния между агентами до написания промптов.
- →Реализовывать цикл «код → ревью → правки» с лимитом итераций и механическим verify-gate.
- →Измерять прогон: итерации, токены, стоимость — и защищать архитектуру цифрами.
Архитектура: три роли и контракт состояния
Капстоун собирает весь курс в одну работающую систему: команда из трёх агентов доводит фичу от текстовой постановки до кода с зелёными тестами. Архитектор превращает постановку в спецификацию; кодер реализует по спеке; ревьюер проверяет и либо принимает, либо возвращает на доработку. Это pipeline с циклом обратной связи — топология из первого урока, обоснованная, а не модная: этапы фиксированы, а несовместимость ролей реальна (кодер-автор не должен сам себе быть ревьюером).
Проектирование начинается не с промптов, а с контракта состояния:
from typing import Literal, TypedDict
class TeamState(TypedDict):
task: str # исходная постановка
spec: str # markdown: цель, API, кейсы, критерии
code: str # unified diff относительно базы
test_report: str # вывод прогона тестов (механический)
review: str # замечания ревьюера по пунктам
verdict: Literal["approve", "revise", ""]
iterations: int # счётчик циклов код-ревью
tokens_spent: int # бюджетный счётчик
Каждое поле — контракт с форматом: спека — markdown с обязательными разделами (цель, API, тест-кейсы, критерии приёмки), код — unified diff, а не «файлы в вольном пересказе», ревью — нумерованные замечания с severity. Жёсткие форматы — это то, что делает hand-off проверяемым: узел может валидировать вход до вызова LLM и отклонить мусор дёшево. Именно контракты, а не промпты, — половина успеха капстоуна.
Реализация графа
Граф капстоуна — четыре содержательных узла и один маршрутизатор. Обратите внимание: прогон тестов — отдельный МЕХАНИЧЕСКИЙ узел без LLM; вердикт «тесты зелёные» выносит pytest, а не мнение модели.
from langgraph.graph import StateGraph, START, END
def route_after_review(state: TeamState) -> str:
if state["verdict"] == "approve":
return "done"
if state["iterations"] >= 3:
return "escalate" # к человеку, с полным контекстом
return "coder"
builder = StateGraph(TeamState)
builder.add_node("architect", architect)
builder.add_node("coder", coder)
builder.add_node("run_tests", run_tests) # subprocess, не LLM
builder.add_node("reviewer", reviewer)
builder.add_node("escalate", escalate)
builder.add_edge(START, "architect")
builder.add_edge("architect", "coder")
builder.add_edge("coder", "run_tests")
builder.add_edge("run_tests", "reviewer")
builder.add_conditional_edges(
"reviewer", route_after_review,
{"coder": "coder", "done": END, "escalate": "escalate"},
)
graph = builder.compile(checkpointer=checkpointer)
Три решения, на которых чаще всего срезаются. Первое: ревьюер получает спеку, дифф и отчёт тестов — но НЕ историю рассуждений кодера, иначе он заражается чужими обоснованиями и пропускает то, что видно свежим взглядом. Второе: кодер на втором круге получает только спеку, свой прошлый дифф и замечания — не весь лог. Третье: лимит итераций — три; после третьего «revise» система эскалирует человеку с полным контекстом вместо бесконечной полировки за ваши деньги.
Прогон, метрики и приёмка
Критерий приёмки капстоуна двухслойный, и оба слоя обязательны. Слой первый — функциональный: на трёх задачах разной сложности (функция с краевыми случаями, правка с рефакторингом, мелкая фича на два модуля) система доводит код до зелёных тестов без ручных правок. Тесты — реальный pytest в subprocess, не симуляция; если у задачи нет тестов, архитектор обязан включить тест-кейсы в спеку, а кодер — написать их первым коммитом.
Слой второй — экономический, и он отличает инженера от энтузиаста. По каждому прогону логируются: число итераций цикла код-ревью, токены по агентам, стоимость прогона, wall-clock время, вердикт. Ориентиры здорового прогона: одна-две итерации на простой задаче (три — сигнал, что спека размыта или ревьюер придирается к вкусовщине), стоимость от десятков центов до пары долларов в зависимости от моделей, и нулевая доля прогонов, ушедших в escalate по лимиту.
Диагностика по метрикам — главный навык этого урока. Хронические третьи итерации лечатся не «промптом построже», а разбором: ЧТО ревьюер возвращает? Если замечания к несоответствию спеке — слаба спека, чините архитектора (обязательные разделы, примеры). Если вкусовщина — чините ревьюера: явный список severity, запрет замечаний вне критериев приёмки. Если кодер игнорирует замечания — чините hand-off: замечания должны приходить нумерованным списком, и кодер обязан ответить на каждый пункт «исправлено: как» или «не согласен: почему». Система из агентов отлаживается как система, по узлу за раз.
Расширения: worktree, параллельные кодеры, человеческие ворота
Базовый капстоун работает со строкой-диффом в состоянии. Первое боевое расширение — реальная файловая система: кодер работает в git worktree на своей ветке (урок 5), узел run_tests запускает pytest в каталоге worktree, а после approve отдельный узел вливает ветку в dev и убирает worktree. Состояние графа при этом ссылается на артефакты — имя ветки, путь worktree, SHA коммита — а не таскает содержимое файлов: дешевле по токенам и честнее по архитектуре.
Второе расширение — человеческие ворота через interrupt (урок 2) между approve ревьюера и мёржем: граф останавливается, человек смотрит финальный дифф и отчёт тестов, resume — и только тогда мёрж. Автономность внутри песочницы, подпись человека на выходе — правильный дефолт для систем, пишущих в общий репозиторий.
Третье — параллельные кодеры через Send (урок 4) для задач, которые архитектор разложил на независимые модули: каждому кодеру — свой worktree, свои тесты, свой цикл с ревьюером; мёрж последовательный с повторным прогоном после каждого вливания (урок 5). Здесь же включается вся экономика урока 6: бюджет на прогон, RetryPolicy на узлах, cost per successful task как метрика сравнения с одиночным агентом.
И финальный тест зрелости: соберите тот же конвейер на CrewAI (три Agent, три Task, Process.sequential — цикл ревью придётся выразить через Flows) и сравните с LangGraph-версией по управляемости и цене. Умение обосновать выбор фреймворка измерениями, а не привычкой, — это и есть выпускной экзамен курса.
Practice
Капстоун: спека → код → ревью до зелёных тестов
Реализуйте команду из трёх агентов на LangGraph по архитектуре урока: контракт TeamState, механический узел тестов, цикл код-ревью с лимитом 3 итерации, эскалация человеку, бюджетный счётчик токенов. Прогоните на трёх задачах разной сложности в учебном репозитории с pytest.
Deliverable
Репозиторий с графом и промптами агентов, логи трёх прогонов с зелёными тестами и таблица метрик: итерации, токены по агентам, стоимость, время, вердикт — плюс три вывода о том, что вы изменили бы в промптах или контрактах.
Checkpoint
Защитите архитектуру своего капстоуна: почему pipeline с циклом, почему тесты — отдельный узел без LLM, почему лимит итераций именно нужен?
- ✓ Топология обоснована фиксированными этапами и несовместимостью ролей автора и ревьюера.
- ✓ Объяснено, что вердикт о тестах выносит механический прогон, а не мнение модели.
- ✓ Лимит итераций связан с экономикой: эскалация человеку дешевле бесконечной полировки.
Check yourself
Sources