Зачем это нужно
К этому моменту курса у нас уже есть основные строительные блоки controlled AI development:
- specification и acceptance criteria;
- architecture constraints и ADR;
- task decomposition;
- context engineering;
- project instructions;
- skills;
- tools и MCP;
- permission boundaries.
Теперь нужно собрать их в один рабочий цикл.
Главная ошибка при работе с coding agent:
Попросить агента "сделай фичу" и позволить ему сразу писать код.
Иногда это срабатывает на маленьких задачах. Но на реальном проекте такой подход быстро приводит к типичным проблемам:
- агент меняет код до понимания requirements;
- не читает существующий pattern;
- берет слишком широкий scope;
- пишет код без теста;
- не запускает verification;
- объявляет "готово" без evidence;
- смешивает unrelated changes;
- не проверяет diff;
- не связывает результат с acceptance criteria.
Правильный development loop делает работу агента управляемой. Он не гарантирует идеальный результат, но снижает вероятность хаоса и дает человеку прозрачные контрольные точки.
Главная цель урока - научиться проводить одну development task через полный single-agent loop: от чтения spec до проверенного diff и commit-ready результата.
Основная идея
Правильный development loop:
READ SPEC
-> INSPECT CURRENT CODE
-> CREATE PLAN
-> SELECT ONE TASK
-> WRITE/UPDATE TEST
-> IMPLEMENT
-> RUN TESTS
-> REVIEW DIFF
-> CHECK ACCEPTANCE CRITERIA
-> COMMIT OR HANDOFF
Короткая формула:
Сначала понять.
Потом ограничить scope.
Потом изменить.
Потом доказать.
Потом зафиксировать.
Agentic development не должен быть потоком случайных edits. Это инженерный процесс, где каждый шаг оставляет evidence.
Ключевые термины
| Термин | Значение |
|---|---|
| Development Loop | Повторяемая последовательность выполнения одной coding task агентом. |
| Spec | Документ, описывающий требуемое поведение. |
| Acceptance Criteria | Проверяемые условия готовности feature или task. |
| Relevant Code | Существующий код, который влияет на текущую задачу. |
| Local Pattern | Ближайший существующий способ решать похожую задачу в проекте. |
| Plan | Краткая последовательность действий перед edits. |
| Scope | Граница изменений, необходимых для текущей task. |
| Test First | Подход, где агент пишет или обновляет test до implementation, когда это практично. |
| Verification | Команды и проверки, подтверждающие результат. |
| Diff Review | Просмотр итоговых изменений перед объявлением задачи завершенной. |
| Evidence | Проверяемые факты: commands, exit codes, test results, changed files, AC status. |
| Definition of Done | Минимальные условия, при которых task можно считать завершенной. |
| Commit-ready | Состояние, когда diff сфокусирован, проверен и готов к commit или PR. |
Схема полного loop
Обратите внимание: loop содержит возвраты. Это не линейная "магическая дорожка", где один prompt сразу приводит к success. Если tests падают или AC не выполнены, агент возвращается к implementation или уточнению.
Шаг 1. Read Spec
Первый шаг - понять, что нужно построить.
Агент должен прочитать:
- feature specification;
- task description;
- acceptance criteria;
- constraints;
- non-goals;
- linked ADR или architecture notes, если задача архитектурная;
- user constraints из текущего prompt.
Цель:
Сформулировать expected behavior до чтения implementation details.
Плохой старт:
Пользователь: "Добавь reset password".
Агент: сразу создает files и controllers.
Хороший старт:
Агент:
1. Прочитал spec.
2. Выписал AC:
- request email;
- token expires;
- consumed token cannot be reused;
- no user enumeration.
3. Отметил unclear points.
Если spec отсутствует, агент не должен притворяться, что requirements очевидны. Он может:
- запросить уточнение;
- сформулировать assumptions;
- предложить минимальный spec;
- двигаться только там, где behavior безопасно и ясно.
Что извлекать из spec
Полезный extraction формат:
Feature:
Primary behavior:
Acceptance criteria:
- AC1:
- AC2:
- AC3:
Non-goals:
Constraints:
Open questions:
Verification candidates:
Пример:
Feature:
Create project endpoint.
Primary behavior:
Authenticated user can create a project with a valid name.
Acceptance criteria:
- AC1: POST /api/projects accepts name.
- AC2: Invalid name returns validation error.
- AC3: Created project belongs to current user.
- AC4: Successful response returns 201 and project id.
Non-goals:
- No billing integration in this task.
Constraints:
- Do not change auth middleware.
Verification candidates:
- API integration test.
- Service unit test if existing pattern uses it.
Такой extraction помогает агенту не потерять цель после чтения кода.
Шаг 2. Inspect Current Code
После spec агент должен понять текущую систему.
Он ищет:
- ближайшую похожую реализацию;
- tests рядом с похожей feature;
- routing или module conventions;
- service boundaries;
- validation style;
- error handling pattern;
- naming conventions;
- generated files;
- existing commands.
Цель:
Не изобретать архитектуру заново.
Плохой подход:
Добавить новый abstraction layer, потому что так обычно делают в tutorials.
Хороший подход:
Найти existing endpoint, посмотреть controller/service/test pattern,
и добавить новую behavior тем же стилем.
Что считать relevant code
Relevant code - это не "весь репозиторий".
Для API task:
- route/controller files;
- service files;
- validation schema;
- model/repository layer;
- API tests;
- OpenAPI contract;
- auth middleware, если затронуто.
Для bug fix:
- failing path;
- code owner module;
- nearby tests;
- fixtures;
- logs/reproduction artifact.
Для frontend form:
- existing forms;
- design system components;
- validation library;
- state management pattern;
- component tests;
- accessibility patterns.
Агент должен читать достаточно, но не утонуть в unrelated context.
Шаг 3. Create Plan
Plan нужен, чтобы зафиксировать направление до edits.
Хороший plan:
- короткий;
- связан с AC;
- перечисляет files/layers;
- содержит test strategy;
- отмечает risks;
- выбирает одну task.
Пример:
Plan:
1. Add API test for POST /api/projects validation and success case.
2. Reuse existing project service pattern from `teams` endpoint.
3. Add request validation schema.
4. Implement route/controller and service call.
5. Update OpenAPI path if contract is maintained manually.
6. Run targeted API test and typecheck.
Плохой plan:
I will implement the feature.
Это не plan. Это намерение.
Plan должен быть проверяемым
Проверяемый plan отвечает:
| Вопрос | Ответ должен быть в plan |
|---|---|
| Что меняем? | Target behavior или files/layers. |
| Почему так? | Ссылка на spec/local pattern. |
| Как проверяем? | Tests/commands. |
| Что не трогаем? | Scope boundaries. |
| Где риск? | Auth, migration, public contract, external services. |
Если plan нельзя проверить, он не управляет агентом.
Шаг 4. Select One Task
AI пишет быстро. Именно поэтому нужно ограничивать scope.
Правило:
One task -> one focused diff -> one verification story.
Плохо:
Добавить endpoint, переписать auth, обновить UI, сделать migration,
почистить старый код, обновить docs и улучшить архитектуру.
Лучше разбить:
Task 1: add database migration.
Task 2: add backend endpoint.
Task 3: add frontend form.
Task 4: update docs/release notes.
Внутри одного loop агент должен выполнять одну task. Если по пути обнаружилась другая проблема, ее нужно:
- зафиксировать как follow-up;
- не исправлять без необходимости;
- исправить только если она блокирует текущую task.
Scope guardrails
Перед edits агент должен назвать:
In scope:
- route
- validation
- service method
- API tests
Out of scope:
- frontend form
- billing behavior
- auth middleware rewrite
- unrelated refactor
Это помогает человеку понять, что агент не расширил задачу сам.
Шаг 5. Write or Update Test
Test - это лучший способ превратить requirement в проверку.
Не всегда нужно строго TDD, но при AI development полезно стремиться:
Сначала test или хотя бы test plan.
Потом implementation.
Для new feature:
- добавить test для key acceptance criteria;
- обновить существующий test, если behavior меняется;
- добавить contract test, если меняется API contract;
- добавить migration test, если меняется schema.
Для bug fix:
- сначала reproduction;
- затем failing regression test;
- потом fix.
Если test невозможно написать сразу, агент должен объяснить почему:
No existing test harness for this module.
Closest verification: manual command + static inspection.
Residual risk: no automated regression coverage.
Failing test не всегда обязателен, но evidence обязателен
В идеале:
RED -> GREEN
Но бывают ситуации:
- legacy code без test framework;
- UI behavior без setup;
- docs-only change;
- refactor без behavior change;
- environment unavailable.
Тогда agent должен дать alternative evidence:
- static checks;
- typecheck;
- lint;
- targeted manual scenario;
- contract validation;
- screenshot;
- diff reasoning against AC;
- explicit residual risk.
Нельзя заменять evidence фразой:
Должно работать.
Шаг 6. Implement
Implementation должен быть минимальным scoped change.
Хорошие принципы:
- reuse existing patterns;
- не менять unrelated modules;
- не добавлять dependency без причины;
- не делать opportunistic refactor;
- не менять public contract без spec;
- не скрывать failing tests;
- не писать generated files вручную, если проект генерирует их command;
- сохранять architecture boundaries.
Implementation должен отвечать на plan и AC, а не на вдохновение агента.
Плохой implementation:
Task: add validation.
Diff: переписан весь controller layer.
Хороший implementation:
Task: add validation.
Diff: validation schema + one controller branch + tests.
Шаг 7. Run Tests
Verification начинается с targeted checks.
Порядок:
- Самый близкий test к изменению.
- Module-level tests, если изменен shared module.
- Typecheck/lint, если команды быстрые и релевантные.
- Broader suite, если change risky или shared.
- Manual check, если automated test недоступен.
Пример:
npm test -- tests/api/projects.test.ts
npm run typecheck
npm run lint
Для Python:
pytest tests/api/test_projects.py
ruff check .
mypy app
Для Go:
go test ./internal/projects
go test ./...
Команды зависят от проекта. Loop требует не конкретный command, а принцип:
Проверить ближайшее поведение и сообщить результат.
Как сообщать verification
Не так:
Tests pass.
А так:
Verification:
- `npm test -- tests/api/projects.test.ts`: passed, exit code 0
- `npm run typecheck`: passed, exit code 0
Если не удалось:
Verification:
- `npm test -- tests/api/projects.test.ts`: not run
Reason: dependencies are not installed in this environment.
Residual risk:
- Endpoint behavior was not executed by automated tests locally.
Evidence должно быть конкретным.
Шаг 8. Review Diff
Перед завершением task агент должен посмотреть diff.
Diff review отвечает:
- все изменения относятся к task?
- нет unrelated refactor?
- нет debug prints?
- нет secrets?
- нет временных files?
- tests добавлены там, где нужно?
- generated files изменены ожидаемо?
- public API не поменялся случайно?
- naming соответствует project style?
- documentation/contract обновлены, если behavior изменился?
Команды:
git diff --stat
git diff
git status --short
В этом курсе важно: агент не должен объявлять "готово" до просмотра diff.
Diff review checklist
[ ] Diff focused on one task
[ ] No unrelated files changed
[ ] No secrets or credentials
[ ] No debug prints
[ ] Tests added/updated
[ ] Generated files handled correctly
[ ] Public contracts updated when needed
[ ] Verification commands run or limitation reported
[ ] Acceptance criteria checked
Если diff содержит unrelated changes, агент должен:
- не удалять чужие изменения без разрешения;
- отделить свои изменения от existing dirty worktree;
- сообщить о несвязанных изменениях, если они мешают;
- продолжить только в safe scope.
Шаг 9. Check Acceptance Criteria
Tests могут быть зелеными, но AC все равно не выполнены.
Например:
AC: invalid name returns 422 with field-level error.
Test: only checks status code 400.
Поэтому после verification нужен AC checklist:
Acceptance criteria:
- AC1 POST /api/projects accepts valid name: satisfied
- AC2 invalid name returns validation error: satisfied by API test
- AC3 project belongs to current user: satisfied by service assertion
- AC4 returns 201 with project id: satisfied by API test
Если AC не покрыт:
- AC5 OpenAPI contract updated: not satisfied
Reason: project has no checked-in OpenAPI contract.
Follow-up: confirm whether external API catalog exists.
AC checklist связывает результат с requirements.
Шаг 10. Commit or Handoff
Commit - это фиксация завершенной единицы работы.
В agent workflow commit должен быть:
- после diff review;
- после verification;
- после AC check;
- с focused diff;
- с понятным message;
- без unrelated changes.
Но агент не всегда должен сам делать commit. Это зависит от пользовательского запроса и permission model.
В курсе полезно мыслить так:
Commit-ready result сначала.
Commit после явного разрешения или если workflow это предполагает.
Commit-ready output:
Summary:
- Added POST /api/projects endpoint with validation and service integration.
Changed files:
- src/api/projects.ts
- src/services/projects.ts
- tests/api/projects.test.ts
Verification:
- npm test -- tests/api/projects.test.ts: passed, exit code 0
- npm run typecheck: passed, exit code 0
Acceptance criteria:
- AC1 valid project creation: satisfied
- AC2 validation error: satisfied
- AC3 ownership: satisfied
Ready for commit:
- yes
Evidence-based completion
Нельзя считать task завершенной только потому, что агент уверен.
Completion требует evidence:
| Evidence | Пример |
|---|---|
| Changed files | src/api/projects.ts, tests/api/projects.test.ts |
| Commands | npm test -- tests/api/projects.test.ts |
| Results | passed, exit code 0 |
| AC status | AC1/AC2/AC3 satisfied |
| Diff review | no unrelated changes |
| Risk | full suite not run, external service unavailable |
Фраза:
Готово.
не является engineering completion.
Loop как state machine
State machine полезна, потому что показывает stop conditions:
- нет spec -> нельзя уверенно implement;
- нет relevant code context -> нельзя менять architecture;
- нет verification -> нельзя говорить "готово";
- diff не review -> нельзя commit-ready;
- AC не checked -> task не завершена.
Agent prompt для полного loop
Пример user prompt:
Выполни задачу через controlled development loop.
Spec:
specs/features/project-create.md
Task:
Добавить POST /api/projects.
Ограничения:
- Не менять auth middleware.
- Не добавлять новые dependencies.
- Работать только с backend endpoint и tests.
Ожидаемый loop:
1. Прочитай spec и выпиши AC.
2. Найди ближайший existing endpoint pattern.
3. Составь короткий plan.
4. Добавь или обнови targeted test.
5. Реализуй минимальный diff.
6. Запусти targeted verification.
7. Проверь diff.
8. Сопоставь результат с AC.
9. Верни summary, changed files, commands/results, AC status и risks.
Такой prompt не должен повторяться каждый раз вручную. Его можно превратить в project instruction или skill. Но для обучения полезно явно увидеть loop.
Пример transcript
Сценарий:
Task:
Добавить POST /api/projects.
1. Read spec
Spec summary:
- Authenticated user can create project.
- Request requires `name`.
- Empty name returns validation error.
- Success returns 201 and project id.
- Project owner is current user.
Non-goal:
- No billing.
2. Inspect code
Relevant patterns:
- Existing endpoint: POST /api/teams
- Validation style: zod schema in `src/api/validation`
- Service pattern: `teamService.createForUser`
- Tests: `tests/api/teams.test.ts`
3. Plan
Plan:
1. Add API tests for success and invalid name.
2. Add project validation schema.
3. Add route/controller using existing teams pattern.
4. Add service create method if missing.
5. Run targeted API test.
4. Test
Added:
- tests/api/projects.test.ts
Cases:
- POST /api/projects returns 201 for valid name.
- POST /api/projects returns validation error for empty name.
5. Implement
Changed:
- src/api/projects.ts
- src/api/validation/project.ts
- src/services/projects.ts
6. Verify
Verification:
- npm test -- tests/api/projects.test.ts: passed, exit code 0
- npm run typecheck: passed, exit code 0
7. Review diff
Diff review:
- Changes scoped to project endpoint.
- No auth middleware changes.
- No new dependencies.
- No unrelated files.
8. Check AC
Acceptance criteria:
- Valid create request returns 201: satisfied.
- Empty name rejected: satisfied.
- Owner is current user: satisfied.
- Billing untouched: satisfied.
9. Handoff
Result:
Commit-ready.
Это идеализированный transcript. В реальности tests могут падать, spec может быть неполной, environment может быть unavailable. Но структура ответа сохраняется.
Что делать, если test failed
Failed test - это не провал агента. Это normal feedback.
Правильный loop:
Run test
-> observe failure
-> understand failure
-> patch relevant code
-> rerun targeted test
Плохой loop:
Run test
-> failed
-> ignore
-> "готово"
или:
Run test
-> failed
-> delete failing assertion
-> "fixed"
Правило:
Нельзя ослаблять test только для зеленого результата.
Если test wrong, агент должен объяснить почему и изменить его в соответствии со spec, а не с желанием пройти suite.
Что делать, если command не запускается
Иногда verification невозможна:
- dependencies не установлены;
- database недоступна;
- Docker не работает;
- нет credentials;
- команда слишком дорогая;
- sandbox запрещает action;
- external service unavailable.
Правильный ответ:
Verification:
- `npm test -- tests/api/projects.test.ts`: not run
Reason: node_modules missing.
What I checked instead:
- Static diff review.
- Existing patterns matched.
- Type-level imports inspected.
Residual risk:
- Runtime behavior not verified locally.
Агент должен быть честным. Не запускалось - значит не запускалось.
Stop conditions
Иногда loop должен остановиться до implementation.
Остановиться и спросить, если:
- acceptance criteria отсутствуют для critical behavior;
- authorization policy unclear;
- destructive migration required;
- production credentials needed;
- spec conflicts with existing contract;
- task требует external write без approval;
- user asks to hide failures;
- implementation would require broad unrelated refactor.
Пример:
Я могу добавить endpoint skeleton, но authorization behavior для admin operation не задан. Это security-sensitive решение, поэтому нужно уточнение до code edits.
Stop condition - это не слабость агента. Это часть controlled development.
One task at a time
Почему это важно:
- проще проверить diff;
- проще откатить;
- проще понять failure;
- проще написать tests;
- проще сделать commit;
- меньше chance unrelated changes;
- человек может review быстрее.
Пример split:
Feature: Team invitations
Task 1: database migration for invitations
Task 2: backend endpoint POST /api/teams/:id/invitations
Task 3: email sending integration
Task 4: frontend invitation form
Task 5: release note
Каждая task проходит loop отдельно.
Definition of Done для agent task
Task считается завершенной, если:
[ ] Spec/AC прочитаны
[ ] Relevant code inspected
[ ] Plan составлен
[ ] Scope ограничен
[ ] Test added/updated или limitation explained
[ ] Implementation scoped
[ ] Targeted verification run или limitation explained
[ ] Diff reviewed
[ ] Acceptance criteria checked
[ ] Risks/follow-ups named
[ ] Commit-ready output provided
Если один пункт отсутствует, агент не должен говорить "полностью готово". Он может сказать:
Implementation done, but verification incomplete because...
Это честный и полезный результат.
Связь с предыдущими модулями
Development loop собирает весь курс:
| Модуль | Как используется в loop |
|---|---|
| LLM failure modes | Loop снижает hallucination и premature coding. |
| Specification | Read spec и AC check. |
| Architecture | Inspect constraints и ADR перед edits. |
| Task decomposition | One task at a time. |
| Context engineering | Читать relevant context, не весь проект. |
| Skills | Подключить workflow skill, например create-api-endpoint. |
| Tools/MCP | Выполнять search, tests, diff, external reads/writes. |
Loop - это не еще один документ. Это orchestration pattern для всех уже изученных механизмов.
Роль skills в loop
Skill может специализировать loop под тип задачи.
Например:
Generic loop:
Read -> Plan -> Test -> Implement -> Verify -> Review
create-api-endpoint skill:
Read spec -> Find endpoint pattern -> Add API test -> Implement route/service -> Contract check -> AC status
Skill не заменяет loop. Skill делает loop конкретнее.
Роль tools в loop
Tools дают действия:
search_repository()
read_file()
apply_patch()
run_tests()
get_git_diff()
MCP tools/resources могут добавить external context:
github://pull/123/diff
ci://runs/456/logs
comment_on_pr()
Но loop решает, когда их использовать и что делать с result.
Prompt template для агента
Можно использовать такой reusable prompt:
Work through this task using the controlled development loop.
Before editing:
- read the spec/task;
- inspect relevant existing code;
- identify local patterns;
- produce a short plan;
- name in-scope and out-of-scope changes.
During editing:
- work on one task only;
- add or update tests when practical;
- keep the diff focused.
Before completion:
- run targeted verification;
- review the diff;
- check acceptance criteria;
- report changed files, commands/results, AC status, and residual risks.
Task:
<task>
Этот prompt можно позже превратить в project rule или skill. Но не делайте его огромным. Основная ценность - последовательность и evidence.
Output template
Финальный ответ агента после task:
Summary:
- ...
Changed files:
- ...
Verification:
- `<command>`: passed/failed/not run, exit code ...
Acceptance criteria:
- AC1: satisfied/not satisfied
- AC2: satisfied/not satisfied
Diff review:
- Focused: yes/no
- Unrelated changes: none/list
Risks and follow-ups:
- ...
Такой output помогает человеку быстро принять решение:
- можно ли смотреть diff;
- нужно ли еще debugging;
- нужна ли ручная проверка;
- готово ли к commit.
Типичные ошибки
| Ошибка | Симптом | Исправление |
|---|---|---|
| Start with edits | Агент пишет код до понимания spec | Read spec и relevant code first. |
| No local pattern | Новый стиль в старом проекте | Найти ближайший аналог. |
| Big task | Огромный diff | Split one task at a time. |
| No tests | Нет regression evidence | Add/update targeted test или explain limitation. |
| No verification | "Должно работать" | Run command and report result. |
| No diff review | Unrelated files попали в change | git diff перед финалом. |
| No AC check | Tests pass, feature incomplete | AC checklist. |
| Hidden failures | Агент не сообщает падение | Report failed commands honestly. |
| Opportunistic refactor | Diff растет без необходимости | Keep scope. |
| Premature commit | Commit до checks | Commit-ready только после evidence. |
Практика: провести task через loop
Возьмите task:
Добавить endpoint POST /api/projects.
Заполните transcript:
1. Spec summary:
2. Acceptance criteria:
3. Relevant code inspected:
4. Local patterns:
5. Plan:
6. In scope:
7. Out of scope:
8. Test added/updated:
9. Implementation summary:
10. Verification commands/results:
11. Diff review:
12. AC status:
13. Risks/follow-ups:
14. Commit-ready:
Цель практики - не написать идеальный endpoint, а научиться видеть весь процесс.
Критерии готовности
После урока студент должен уметь:
- перечислить шаги development loop;
- объяснить, почему edits не должны быть первым шагом;
- извлекать AC из spec;
- искать relevant code и local patterns;
- составлять короткий plan;
- ограничивать task scope;
- писать или обновлять targeted test;
- запускать verification и сообщать evidence;
- делать diff review;
- сопоставлять результат с AC;
- формировать commit-ready handoff.
Краткое резюме
Правильный agent development loop превращает AI coding из "попросили и надеемся" в контролируемый engineering process.
Базовая последовательность:
read spec
inspect code
plan
select one task
test
implement
verify
review diff
check AC
commit-ready handoff
Главное правило:
Task не завершена без evidence.
Evidence - это changed files, commands, exit codes, test results, diff review и acceptance criteria status. Чем быстрее агент пишет код, тем важнее дисциплина verification.
Вопросы для самопроверки
- Почему agent не должен начинать с code edits?
- Чем relevant code отличается от "прочитать весь репозиторий"?
- Что делать, если automated test невозможно запустить?
- Почему diff review нужен даже после passing tests?
- Какие пункты входят в Definition of Done для agent task?
Что дальше
В следующем уроке мы разделим этот loop на Plan Mode и Act Mode. Это добавит еще одну важную границу: агент может сначала работать read-only, проектировать plan и согласовывать scope, а только потом получать разрешение на edits и tool calls с более высоким риском.