Неинтерактивный режим - это точка, где агент перестаёт быть собеседником и становится звеном конвейера. Запуск с флагом печати выполняет задачу без интерфейса и завершается. Ключевая деталь, которую надо усвоить до первого скрипта: без флага форсирования изменения предлагаются, но не применяются. Мутация рабочего дерева в автоматическом прогоне требует явного разрешения и подходящей политики - это операционный шлюз, а не побочный эффект режима.
Различение стоит подчеркнуть, потому что в разных местах документации формулировки звучат по-разному, а решает всё поведение. Прогон без форсирования безопасен по эффекту: он читает, рассуждает и отдаёт результат. Прогон с форсированием меняет файлы. Первый годится для обзора и анализа в непрерывной интеграции, второй - только там, где вы сознательно выстроили изоляцию и права.
Форматов вывода три, и выбирают их по тому, кто читает результат. Текст отдаёт только финальное сообщение - это для человека и для простого скрипта. Единый объект JSON приходит одним ответом и содержит результат вместе со служебными полями вроде длительности и идентификаторов - это для автоматизации, которой нужен машинный разбор. Потоковый формат отдаёт события по строкам и завершается финальным событием - это для интерфейсов, показывающих прогресс, и для аудита вызовов инструментов.
Полезно один раз увидеть все три вызова рядом. Ниже - объяснение изменений без правок, список рисков одним объектом и исправление теста с потоковым выводом и разрешением менять файлы. Обратите внимание, что флаг форсирования появляется только в третьей команде: в первых двух он не нужен и потому не написан.
Служебные поля машинного вывода стоят отдельного внимания. Идентификаторы прогона и сессии - это то, чем результат связывается с логом сборки, с задачей в трекере и с возможностью продолжить работу позже; длительность - то, по чему замечают, что задача стала стоить втрое дороже, чем неделю назад. Скрипт, который берёт из ответа только текст, выбрасывает ровно ту часть, которая делает автоматический прогон наблюдаемым.
| Формат | Что на выходе | Когда использовать |
|---|---|---|
| text |
| Только финальное сообщение |
| Человекочитаемый скрипт |
| json | Один объект результата при успехе | Нужны результат, длительность и идентификаторы |
|---|
| stream-json | События по строкам и финальное событие | Прогресс, аудит вызовов, отмена |
|---|
| stream-json с частями | Посимвольные приращения и повторные события | Интерфейс реального времени; фильтровать по документированным полям |
|---|
Потребитель потокового вывода должен быть написан с запасом на будущее. Неизвестные поля игнорируют, финального события дожидаются, а его отсутствие не считают успехом. Это не перестраховка: продукт развивается, и новые типы событий появляются раньше, чем обновляется ваш разбор. Жёсткий разбор ровно под сегодняшний набор ломается на первом же обновлении, причём молча.
Про обработку ошибок есть отдельное правило, которое экономит много времени. При сбое объект результата может вообще не прийти: ошибка окажется в потоке ошибок, а код возврата будет ненулевым. Значит, автоматизация проверяет и код возврата, и структуру вывода, а не полагается на одно из двух. Скрипт, который читает только стандартный вывод, однажды примет сбой за успех и пропустит его дальше по конвейеру.
Есть и граница применимости, о которой легко забыть в увлечении автоматизацией. Автоматическому прогону имеет смысл поручать только то, у чего есть машинно проверяемый признак успеха: тест, линтер, сборка, сравнение с эталоном. Задача, результат которой оценивается на глаз, в неинтерактивном режиме превращается в текст, который никто не читает. Формулируя задание для скрипта, вы одновременно формулируете, чем будет доказан результат.
Инженерный вывод простой: неинтерактивный режим силён предсказуемостью, и её нужно поддерживать явными решениями. Формат вывода выбран под потребителя, права заданы заранее, изменение файлов разрешено осознанно, ошибки обрабатываются по двум признакам. Тогда агент действительно становится инструментом конвейера, а не источником сюрпризов в нём.
Типичные провалы предсказуемы. Ждать изменений файлов без явного разрешения на мутацию. Разбирать текстовый вывод там, где нужен машинный формат. Считать отсутствие финального события успешным завершением. И проверять только код возврата, не глядя на структуру результата.
# Безопасно по эффекту: получить ответ
agent -p --output-format text "Объясни текущий diff"
# Один финальный объект для машинного разбора
agent -p --output-format json "Перечисли риски в тестах"
# Поток событий; изменение файлов разрешено явно
agent -p --force --output-format stream-json --stream-partial-output \
"Почини сфокусированный тест и приложи отчёт о проверке"