AmigaОбучение ИИ
Модуль 4 · Проверяем и делимся · урок 8 из 10

Доверяй, но проверяй: контроль автономных прогонов

11 мин чтения▶ есть видеоверсия

Ночной скрипт отработал, рутина отчиталась зелёным статусом, PR от @claude висит в очереди. Что дальше? Соблазн большой: раз всё зелёное, мержим. В этом уроке разберём, почему зелёный статус ничего не гарантирует, какие четыре источника правды есть у любого автономного прогона, как формулировать критерии приёмки до запуска и что на самом деле означает «доверять» инструменту.

Зелёный статус — не результат

Документация по рутинам формулирует это прямо: зелёный статус запуска означает, что сессия стартовала и завершилась без инфраструктурной ошибки. Он не означает, что задача из вашего запроса выполнена. Заблокированные сетевые запросы, недоступные инструменты, падение по существу задачи — всё это видно только в транскрипте.

То же верно для claude -p: код выхода 0 говорит, что Claude Code отработал, а не что миграция прошла. И для GitHub Actions: зелёная галочка у рабочего процесса — это «действие завершилось», а не «PR корректен».

Поэтому первое правило: проверять результат, а не статус. Второе, из уроков про навыки и хуки: требовать от Claude доказательств, а не утверждений. «Тесты проходят» — не доказательство; вывод pnpm test с числами — доказательство. Проверять доказательство быстрее, чем перезапускать всё самому, и это единственный способ оценить сессию, которую вы не смотрели.

Четыре источника правды

После любого автономного прогона есть четыре места, куда стоит заглянуть, в порядке возрастания трудоёмкости.

1. Проверки, которые запускаются сами. Тесты, проверка типов, линтер, сборка. Если Claude их запускал, в отчёте должен быть вывод. Если не запускал — запустите сами до того, как читать код. Красный результат здесь снимает все дальнейшие вопросы.

2. Диф. git diff --stat показывает что изменилось, и это первое, на что смотреть. Двадцать ожидаемых файлов и один package.json, которого в задаче не было, — вот где проблема. Потом git diff по подозрительным файлам. Вопросы к дифу: есть ли изменения вне рамок задачи; не отключены ли тесты; не появились ли any, @ts-ignore, eslint-disable, skip; не изменились ли lock-файлы, миграции, конфиги CI.

3. Транскрипт. У сессии -p с --output-format stream-json каждое событие — строка JSON: какой инструмент вызван, с какими аргументами, что вернул. У рутины транскрипт открывается по ссылке на запуск; у GitHub Actions — в логе. Читать всё не нужно. Ищите три вещи: отклонённые действия (в итоговом сообщении stream-json есть список permission_denials), ошибки инструментов и место, где Claude решил, что «готово». Если он объявил готовность после трёх падений тестов подряд — это видно.

4. Работающий результат. Для веб-задачи — открыть страницу, для API — дёрнуть эндпоинт, для библиотеки — собрать зависимый проект. Это самый дорогой уровень, и до него доходят, когда первые три чистые.

Для командных прогонов полезно, чтобы отчёт складывался автоматически: скрипт из урока про headless-режим писал в markdown первую строку OK/FAIL и список файлов на каждый репозиторий — утром это читается за пять минут.

Критерии приёмки — до запуска

Самая частая причина «сделал не то» — критерии были в голове, а не в запросе. Для автономного прогона это фатально: спросить некого. Поэтому критерии приёмки пишутся до запуска и попадают в запрос текстом.

Хороший критерий проверяем и бинарен. Сравните для задачи «обновить зависимости в 20 проектах»:

Плохо: «обнови зависимости и убедись, что всё работает».

Хорошо:

text
Обнови минорные и патч-версии зависимостей через pnpm update.
Мажорные версии не трогай — перечисли их в отчёте.
Критерии готовности:
1. pnpm install проходит без предупреждений о peer-зависимостях.
2. pnpm typecheck и pnpm test проходят; вывод приложи.
3. pnpm build завершается с кодом 0.
4. Изменены только package.json и pnpm-lock.yaml.
Если какой-то критерий не выполняется, откати конкретный пакет,
который его нарушает, и опиши это. Не удаляй и не пропускай тесты.
В конце выведи одну строку: OK или FAIL.

Такой запрос делает три вещи одновременно: даёт Claude проверяемую цель, даёт вам чек-лист для утренней проверки и закрывает обходные пути (удалить тест, добавить skip, поднять мажорную версию «потому что так проходит»).

Критерии из задачи можно превратить в жёсткий барьер — Stop-хук, который не даёт завершить ход, пока pnpm test красный, — или в условие /goal, которое отдельный проверяющий перепроверяет после каждого хода. Но даже с барьером критерии в запросе нужны: хук проверяет один сигнал, запрос описывает всю задачу.

Независимое ревью

Есть эффект, который стоит знать: модель, написавшая код, склонна считать его правильным — как и человек. Документация советует адверсарное ревью: отдельный субагент с чистым контекстом видит только диф и критерии, а не рассуждения, которые привели к коду, и оценивает результат сам по себе.

Для поиска багов — /code-review, он работает именно так. Для проверки по плану — прямой запрос:

text
Используй субагента, чтобы проверить диф обновления зависимостей
по критериям из задачи. Для каждого критерия — выполнен или нет,
с доказательством. Отметь изменения вне рамок задачи.
Сообщай только пробелы, влияющие на корректность или на критерии;
стилевые замечания не нужны.

Последняя фраза обязательна. Ревьюер, которого попросили найти проблемы, найдёт их — это то, о чём его попросили. Без ограничения вы получите лишние абстракции, защитный код и тесты на невозможные случаи. Рабочее правило: исправлять только то, что влияет на корректность или требования, остальное — по желанию.

Воспроизводимость как основа доверия

Доверять инструменту можно только тогда, когда одинаковый вход даёт предсказуемый результат. Для автономных прогонов это требует дисциплины по четырём пунктам.

Одинаковое окружение. --bare в скриптах отключает хуки, плагины, MCP-серверы и автопамять, которые есть на одной машине и отсутствуют на другой. Нужный контекст передаётся явно флагами --settings, --append-system-prompt, --mcp-config. Результат прогона не должен зависеть от того, чей ноутбук его запустил.

Одинаковый запрос. Запрос лежит в файле в репозитории, а не в истории терминала. Изменение запроса — коммит с объяснением. Тогда, когда прогон вдруг начал вести себя иначе, можно посмотреть, что поменялось: запрос, код или модель.

Ограниченные права. --allowedTools с точным списком и --max-turns. Не потому, что Claude злонамерен, а потому, что узкие права делают поведение предсказуемым: он не сможет «починить» тест установкой другого пакета, если установка не разрешена.

Прогон на выборке. Сначала на двух-трёх проектах, чтение отчётов и дифов, правка запроса — потом на всех. Документация советует именно так для массовых операций. Если на трёх проектах всё чисто, доверие к прогону на двадцати обоснованно; если на трёх есть сюрпризы, на двадцати они умножатся.

Из этого складывается практика: у команды есть папка со скриптами автономных прогонов, у каждого — запрос в файле, точный список прав, критерии приёмки и место, куда пишется отчёт. Новый прогон проходит через выборку. История правок запроса показывает, чему команда научилась.

Чек-лист после автономного прогона

  • Прочитан отчёт: первая строка OK/FAIL, вывод проверок приложен.
  • git diff --stat: только ожидаемые файлы; lock-файлы, миграции, конфиги CI — объяснены.
  • В дифе нет skip, any, @ts-ignore, eslint-disable, удалённых тестов без обоснования.
  • В транскрипте нет отклонённых действий и ошибок инструментов, которые Claude «обошёл».
  • Критерии приёмки из запроса проверены по одному.
  • Независимое ревью прогнано, находки по корректности исправлены.
  • Результат проверен вживую там, где это дёшево.

Это тот же чек-лист, который вы применяете к PR коллеги, — просто здесь его нужно применять всегда, потому что «я был рядом и видел» не работает.

Попробуйте сами

10–15 мин на рабочем месте
  1. Возьмите последний PR, который Claude сделал для вас (локально или через @claude). Пройдите по чек-листу выше и запишите, что вы пропустили бы, если бы просто посмотрели на зелёный статус.
  2. Напишите критерии приёмки для задачи «перевести пять компонентов на новые токены темы» по образцу из урока: бинарные, проверяемые, с закрытыми обходными путями. Запустите задачу с этими критериями в запросе и сравните отчёт с тем, что вы получали раньше.
  3. Прогоните claude -p с --output-format stream-json --verbose на небольшой задаче и посмотрите, как выглядит транскрипт. Найдите строки с вызовами инструментов и итоговое сообщение.

Коротко

  • Зелёный статус означает «сессия завершилась», а не «задача выполнена». Проверяйте результат, требуйте доказательств.
  • Четыре источника правды: автоматические проверки, диф (--stat, потом подозрительные файлы), транскрипт, работающий результат.
  • Критерии приёмки пишутся до запуска, в запрос, бинарно и проверяемо, с закрытыми обходными путями.
  • Независимое ревью в чистом контексте, ограниченное корректностью и требованиями.
  • Доверие строится на воспроизводимости: --bare, запрос в файле, точные права, прогон на выборке перед прогоном на всех.

Видеоверсия

Сценарий озвучки · 562 слова, ≈ 4 мин

Ночной скрипт отработал, рутина отчиталась зелёным, пул-реквест от Claude ждёт в очереди. Соблазн большой: всё зелёное — мержим. В этом ролике разберём, почему зелёный статус ничего не гарантирует и как проверять результат автономного прогона.

Начнём с главного. Зелёный статус запуска рутины означает, что сессия стартовала и завершилась без инфраструктурной ошибки. Он не означает, что задача выполнена. То же с неинтерактивным запуском: нулевой код выхода говорит, что Claude Code отработал, а не что миграция прошла. И с CI: зелёная галочка — это «действие завершилось». Поэтому проверять нужно результат, а не статус. И требовать от Claude доказательств: фраза «тесты проходят» — не доказательство, вывод команды с числами — доказательство.

После любого прогона есть четыре места, куда заглянуть. Первое — автоматические проверки: тесты, типы, линтер, сборка. Если Claude их запускал, вывод должен быть в отчёте. Если нет — запустите сами до того, как читать код. Второе — диф. Сначала краткая статистика: что изменилось. Двадцать ожидаемых файлов и один файл зависимостей, которого в задаче не было, — вот где искать. Потом сам диф по подозрительным файлам: нет ли изменений вне задачи, не отключены ли тесты, не появились ли «эни» и подавляющие комментарии. Третье — транскрипт: у неинтерактивного запуска он в потоковом джейсоне, у рутины — по ссылке на запуск, у CI — в логе. Читать всё не нужно. Ищите отклонённые действия, ошибки инструментов и момент, где Claude решил, что готово. Если он объявил готовность после трёх падений тестов — это видно. Четвёртое — работающий результат: открыть страницу, дёрнуть эндпоинт. Самый дорогой уровень, до него доходят, когда первые три чистые.

Теперь о критериях. Самая частая причина «сделал не то» — критерии были в голове, а не в запросе. Для автономного прогона это фатально: спросить некого. Поэтому критерии приёмки пишутся до запуска и попадают в запрос. Хороший критерий проверяем и бинарен. Не «обнови зависимости и убедись, что всё работает», а: обнови минорные версии, мажорные перечисли; установка без предупреждений; типы и тесты проходят, вывод приложи; сборка с нулевым кодом; изменены только два файла; если критерий нарушен — откати конкретный пакет и опиши; тесты не удалять и не пропускать; в конце одна строка — «ок» или «фейл». Такой запрос даёт Claude цель, даёт вам утренний чек-лист и закрывает обходные пути.

Дальше — независимое ревью. Модель, написавшая код, склонна считать его правильным, как и человек. Поэтому отдельный субагент с чистым контекстом видит только диф и критерии, а не рассуждения, которые привели к коду. Для поиска багов есть команда «код-ревью», для проверки по критериям — прямой запрос субагенту. И обязательная оговорка: сообщать только пробелы, влияющие на корректность. Ревьюер, которого попросили найти проблемы, найдёт их всегда. Без ограничения вы получите лишние абстракции и тесты на невозможные случаи.

И о доверии. Доверять инструменту можно, когда одинаковый вход даёт предсказуемый результат. Четыре пункта дисциплины. Одинаковое окружение: флаг «бэр» в скриптах отключает хуки и плагины, которые есть на одной машине и отсутствуют на другой. Одинаковый запрос: он лежит в файле в репозитории, изменение — коммит с объяснением; тогда видно, что поменялось, когда прогон вдруг повёл себя иначе. Ограниченные права: точный список инструментов и лимит ходов — не потому, что Claude злонамерен, а потому, что узкие права делают поведение предсказуемым. И прогон на выборке: сначала два-три проекта, чтение отчётов, правка запроса — потом все. Если на трёх чисто, доверие к двадцати обоснованно.

Из этого складывается практика: у команды папка со скриптами прогонов, у каждого — запрос в файле, права, критерии и место для отчёта. А чек-лист после прогона — тот же, что для пул-реквеста коллеги. Просто здесь его нужно применять всегда, потому что «я был рядом и видел» не работает.

Отметка хранится только в вашем браузере