Машинный вывод: конверт со схемой, а не разбор текста
Агенты, MCP-серверы и скрипты CI обязаны читать JSON, а не парсить человеческий вывод. У каждого события есть имя схемы, метка времени и признак завершённости.
Любая команда принимает параметр вывода с тремя значениями. Текст — человекочитаемый, с цветом, машинно не разбираемый. JSON — один объект на стандартный вывод. JSONL — по объекту на строку, последняя строка содержит результат.
Правило простое: агенты, MCP-серверы и скрипты непрерывной интеграции обязаны использовать JSON или JSONL, а не разбирать свободный текст.
Почему это правило, а не пожелание
Человеческий вывод меняется. Мы добавляем поле, переформулируем сообщение, меняем порядок строк — и это нормально, потому что он для человека.
Скрипт, который разбирает такой вывод регулярным выражением, ломается от улучшения формулировки. Причём ломается не сразу и не громко: чаще он начинает извлекать пустую строку и считать, что всё в порядке.
Разделив два вывода, мы получаем свободу менять один и обязательство не менять другой без объявления версии.
Что внутри конверта
У каждого события есть имя схемы — строка вида «продукт, версия, путь команды через точки». Метка времени. Вид события. Полезная нагрузка, специфичная для команды. Идентификатор для связывания событий одного запуска. И признак того, является ли событие завершающим.
Имя схемы в каждом событии — не избыточность. Оно позволяет потребителю решить, понимает он это событие или нет, не угадывая по структуре полезной нагрузки.
Признак завершённости отвечает на вопрос, который иначе решается таймаутами: закончилась команда или ещё идёт.
Устаревший алиас
Был короткий флаг, который теперь означает построчный формат. Он объявлен устаревшим, печатает предупреждение в поток ошибок и будет удалён в следующей минорной версии.
Мы предпочитаем этот путь молчаливому сохранению совместимости навсегда. Предупреждение в поток ошибок не ломает разбор стандартного вывода, но его видит человек, который смотрит логи.
Зачем это агентам
Отдельно стоит сказать про сценарий, ради которого контракт вывода вообще выделен в документ: инструментом пользуется не только человек.
Языковой модели, которая вызывает команду через MCP-сервер, нужен предсказуемый ответ. Она не умеет надёжно отличить «сообщение об успехе, изменившее формулировку» от «сообщения об ошибке». Строгий конверт с именем схемы и признаком завершённости снимает этот класс проблем целиком.
Это же требование делает вывод пригодным для непрерывной интеграции — там ровно та же потребность и ровно те же грабли.
Что не попадает в стандартный вывод
Ничего, кроме конверта. Диагностика, предупреждения, прогресс — в поток ошибок.
Правило звучит очевидным и нарушается постоянно: одна отладочная печать в стандартный вывод делает JSON невалидным, и обнаруживается это у потребителя, а не у автора.