Команды, внедряющие AI-агентов в разработку, сталкиваются с одной и той же проблемой: первые два-три агента работают предсказуемо, но при масштабировании до пяти-семи начинается хаос. Результаты расходятся, агенты дублируют работу, аудит превращается в раскопки логов, а стоимость инференса растёт быстрее, чем польза. Harness engineering - это методология построения системы управления, которая решает эту проблему через двухэтажную архитектуру: сквозной control plane на верхнем уровне и локальные гейты на каждом конвейере.
В этой статье разбираем архитектуру, которая выросла из одной фабрики разработки в набор из почти десяти параллельных конвейеров. Три принципа - ratchet, sensor-first и измеримость - удерживают систему от деградации. Практический репозиторий-скелет даёт готовую структуру для старта, а анализ переносимости между Cursor, Claude Code, Codex и Gemini помогает выбрать инструмент без привязки к вендору.
Почему управление AI-агентами требует инженерного подхода
Рост числа AI-агентов в проектах - факт, подтверждённый цифрами. По данным опросов среди разработчиков середины 2026 года, более 60% команд используют минимум трёх AI-агентов в ежедневной работе, а 25% - семь и более. Проблема не в самих агентах, а в отсутствии системного слоя управления между ними и кодом.
Типичные симптомы: агент A генерирует код, который ломает изменения агента B; PR-ревью перегружено, потому что три агента предлагают конфликтующие правки; никто не может ответить, почему конкретная строка оказалась в проде. Это инженерная проблема, и решается она инженерными методами - архитектурой, метриками и автоматизацией, а не добавлением новых инструкций в промпт.
Harness engineering переносит фокус с «как заставить одного агента работать лучше» на «как сделать систему из десяти агентов управляемой». Ключевое отличие от ad-hoc подхода: harness проектируется как отдельный архитектурный слой, а не как набор скриптов, прикрученных к каждому агенту. Подробный разбор пяти архитектурных решений обвязки мы делали в материале про архитектурные ставки обвязки кодинг-агентов - там контролируемый эксперимент показал, что смена harness влияет на результат в 7.8 раза сильнее, чем смена модели.
Двухэтажная архитектура harness: control plane и локальные гейты
Архитектура разделена на два уровня. Верхний - control plane - отвечает на вопрос «что делается и почему». Нижний - локальные гейты на каждом конвейере - отвечает на вопрос «как именно и с каким качеством». Разделение принципиально: без него любая попытка централизованного контроля превращается в бутылочное горлышко, а полная автономия конвейеров - в неконтролируемый зоопарк.
Control plane: сквозной контроль через Work Items и audit trail
Control plane оперирует единицами работы - Work Items. Work Item - это структурированная запись, которая проходит через всю систему: от постановки задачи до верификации результата. Каждый Work Item содержит: идентификатор, тип задачи (генерация кода, рефакторинг, исследование), приоритет, назначенного агента или пул агентов, статус и ссылки на артефакты.
Жизненный цикл Work Item выглядит так: задача создаётся в control plane вручную или через API → назначается агенту с учётом текущей загрузки и компетенций → агент выполняет работу, проходя через локальные гейты конвейера → результат фиксируется в audit trail → Work Item переходит в статус completed или rejected. Отклонённый Work Item не исчезает - он попадает в очередь на анализ и запускает ratchet-цикл.
Audit trail - это неизменяемый журнал всех событий: кто создал задачу, какой агент её взял, какие инструменты использовал, какие гейты прошёл или провалил, кто подтвердил результат. Для compliance-сценариев audit trail даёт полную воспроизводимость: по любой строке в проде можно восстановить цепочку решений, которая к ней привела. Это закрывает один из главных страхов regulated-индустрий - невозможность объяснить, как AI-агент пришёл к конкретному решению. Смежная тема разбирается в статье про побочный продукт AI-агента, где архитектура контекстной инфраструктуры на tree-sitter позволила аналитикам отслеживать каждое действие агента.
Локальные гейты: автономия и безопасность на уровне конвейеров
Локальный гейт - это точка проверки, через которую обязан пройти каждый артефакт перед переходом на следующий этап конвейера. Гейты настраиваются под конкретную фабрику, но работают в рамках политик, заданных control plane. Типичный набор гейтов для кодинг-конвейера: валидация синтаксиса, прогон юнит-тестов, проверка стиля, сканирование секретов, оценка сложности диффа.
Гейт не блокирует работу агента - он блокирует продвижение артефакта дальше по пайплайну. Агент получает сигнал «гейт X провален, причина Y» и может повторить попытку. Количество повторных попыток ограничено настройками конвейера. Если лимит исчерпан, Work Item уходит на ручную обработку.
Важный архитектурный принцип: гейты не должны дублировать друг друга на разных конвейерах. Каждый конвейер определяет свой набор проверок, но форматы отчётов гейтов унифицированы - control plane собирает их в единую картину. Это позволяет сравнивать качество работы разных агентов на разных задачах по одним метрикам.
Принципы поддержания системы: ratchet, sensor-first, измеримость
Архитектура - это статика. Динамику определяют три принципа, которые предотвращают энтропию: система не деградирует со временем, а становится только жёстче и точнее.
Ratchet: превращение сбоев в постоянные улучшения
Ratchet-принцип: каждый сбой, допущенный агентом и пропущенный гейтами, превращается в постоянный фикс среды. Не в тикет «разобраться когда-нибудь», а в изменение, которое вступает в силу немедленно и действует для всех последующих запусков.
Цикл ratchet: обнаружение сбоя (через audit trail или ручной отлов) → анализ корневой причины → выбор точки фиксации → внедрение → верификация, что такой же сбой больше не воспроизводится. Точки фиксации: новый гейт в конвейере, обновление шаблона промпта, добавление правила в линтер, расширение тестовой базы.
Пример из практики: агент сгенерировал код с хардкодом API-ключа. Гейт сканирования секретов сработал, но только на уровне регулярного выражения - ключ был закодирован нестандартным образом и проскочил. Ratchet-фикс: в гейт добавлен детектор энтропии строк (высокая энтропия = вероятный ключ), а в промпт агента - явный запрет на хардкод любых строк длиннее 20 символов, похожих на токены. После фикса проблема не воспроизводилась ни на одном конвейере.
Sensor-first: детекторы до текстовых правил
Принцип sensor-first: сначала ставим датчик, который измеряет реальность, потом пишем правило, которое на эту реальность реагирует. Текстовые инструкции в промптах без датчиков - это гадание. Агенты работают в динамической среде: меняются версии библиотек, паттерны кода, требования безопасности. Правило, написанное в январе, в марте может быть нерелевантным, а в июле - вредным.
Датчики - это метрики и алерты, встроенные в конвейер: процент отклонённых PR, среднее время прохождения гейта, распределение типов ошибок, частота повторных попыток. Резкий скачок любой метрики - сигнал к анализу, а не к немедленному написанию нового правила. Правило появляется только после того, как датчик подтвердил устойчивую аномалию.
Пример: датчик зафиксировал рост процента PR, отклонённых на гейте проверки стиля, с 5% до 18% за неделю. Анализ показал, что агент начал использовать новый паттерн форматирования, не описанный в конфиге линтера. Вместо правила «форматируй код правильно» в промпт добавлена ссылка на конкретную секцию конфига линтера, а гейт обновлён до последней версии правил. Проблема решена за счёт данных, а не заклинаний.
Измеримость: правила, которые меняют поведение
Каждое правило в harness должно иметь метрику эффективности. Правило, которое нельзя измерить, не существует - оно просто занимает место в конфигурации и создаёт иллюзию контроля. Критерий: после включения правила метрика должна измениться в ожидаемую сторону в течение заданного периода. Если изменений нет - правило удаляется или пересматривается.
Процесс аудита правил: раз в две недели для каждого активного правила снимается его метрика. Правила с нулевым влиянием помечаются на удаление. Правила с отрицательным влиянием (ухудшили метрику) отключаются немедленно с разбором причины. Это жёсткий фильтр, который не даёт harness распухать от «полезных» инструкций, которые на самом деле ничего не меняют.
Пример: правило «агент должен комментировать каждое своё действие в логе» имело метрику «процент шагов с комментарием». До правила - 40%, после - 42%. Разница в пределах погрешности. Правило удалено, вместо него добавлен структурированный формат лога, который агент заполняет в любом случае. Процент осмысленного логирования вырос до 95% без единой текстовой инструкции.
От одной фабрики к десяти: масштабирование системы
Система начиналась с одной фабрики разработки: один конвейер, один агент, три гейта. Через полгода конвейеров стало почти десять: бэкенд, фронтенд, инфраструктура, аналитика, документация, безопасность, тестирование, ревью, исследовательский. Масштабирование вскрыло три проблемы.
Первая: управление зависимостями между конвейерами. Агент бэкенда генерирует контракт API, который нужен агенту фронтенда. Решение: Work Items с типом «контракт» создаются в control plane и блокируют зависимые задачи до своего завершения. Вторая: конфликты ресурсов. Два агента не могут одновременно править один файл. Решение: блокировки на уровне репозитория с таймаутом, управляемые через control plane. Третья: поддержка согласованности правил. Гейты на разных конвейерах начали расходиться в версиях линтеров и тестовых наборов. Решение: унификация конфигураций через общий реестр, где каждая версия гейта - это иммутабельный артефакт.
Шаблонизация гейтов стала ключевым архитектурным решением. Новый конвейер запускается не с пустого набора правил, а с шаблона, который содержит минимальный жизнеспособный набор гейтов: синтаксис, секреты, тесты. Дальше конвейер доращивает специфичные проверки, но база остаётся общей. Это сократило время запуска нового конвейера с трёх дней до четырёх часов.
Практический пример: репозиторий-скелет для быстрого старта
Репозиторий-скелет - это готовая структура директорий и конфигураций, с которой можно стартовать harness engineering за один день. Скелет не привязан к конкретному инструменту и работает с любым агентом, поддерживающим вызов внешних команд.
Структура репозитория:
harness-skeleton/
├── control-plane/
│ ├── work-items/
│ │ └── templates/ # JSON-шаблоны Work Items
│ ├── audit-trail/
│ │ └── schema.json # Схема событий audit trail
│ └── policies/
│ └── global.json # Глобальные политики
├── conveyors/
│ ├── backend/
│ │ ├── gates/ # Гейты бэкенд-конвейера
│ │ └── config.json
│ ├── frontend/
│ └── ...
├── sensors/
│ ├── definitions/ # Определения датчиков
│ └── alerts.json # Пороги алертов
└── ratchet/
└── fixes/ # Зафиксированные ratchet-фиксы
Work Item templates - это JSON-файлы с предзаполненными полями: тип задачи, приоритет по умолчанию, список обязательных гейтов, таймаут выполнения. Audit trail schema описывает структуру события: timestamp, work_item_id, agent_id, event_type, payload. Sensors definitions - конфигурации датчиков: что измеряем, с какой периодичностью, какой порог считается аномалией.
Для старта достаточно клонировать скелет, заполнить config.json под свой стек, определить первый конвейер и запустить агента с указанием эндпоинта control plane. Первый Work Item можно создать вручную через JSON-файл - API наращивается позже. Полный путь от клонирования до первого выполненного Work Item занимает около четырёх часов при условии, что агент уже настроен и имеет доступ к репозиторию.
Переносимость между инструментами: Cursor, Claude Code, Codex, Gemini
Harness engineering проектировался с прицелом на открытые стандарты, а не на API конкретного вендора. Это позволяет менять агента под задачей без перестройки всей системы. Четыре инструмента - Cursor, Claude Code, OpenAI Codex и Google Gemini - протестированы на совместимость по трём критериям: поддержка Work Items, интеграция с audit trail, настраиваемость гейтов.
Сравнительная таблица возможностей
| Инструмент | Поддержка Work Items | Интеграция audit trail | Настраиваемость гейтов | Зрелость API |
|---|---|---|---|---|
| Cursor | Через custom commands и .cursorrules | Частичная - логи агента доступны, но не структурированы | Высокая - можно встроить вызовы внешних скриптов на каждом шаге | Средняя - API расширяется, но документация отстаёт |
| Claude Code | Через custom slash commands и hooks | Полная - каждая операция логируется с возможностью экспорта | Средняя - hooks покрывают основные точки, но не все этапы конвейера | Высокая - документировано, стабильно |
| OpenAI Codex | Через Codex SDK и function calling | Частичная - зависит от самописной обвязки | Низкая - гейты нужно реализовывать как внешние инструменты | Высокая - зрелый SDK, богатая экосистема |
| Google Gemini | Через Gemini CLI и плагины | Полная - интеграция с Cloud Logging из коробки | Высокая - плагинная архитектура позволяет встроить гейты на любом этапе | Средняя - активно развивается, но версионирование ломается между релизами |
Claude Code показывает лучшую интеграцию audit trail из коробки - каждое действие агента логируется с полным контекстом, и эти логи можно направить в control plane напрямую. Gemini выигрывает по настраиваемости гейтов за счёт плагинной архитектуры: гейт оформляется как плагин и встраивается в любой этап конвейера без модификации кода агента. Codex требует больше всего самописной обвязки, но его SDK наиболее зрелый и предсказуемый. Cursor занимает промежуточную позицию: custom commands дают гибкость, но отсутствие структурированного логирования требует доработок.
Общая рекомендация: для команд, которым критичен audit trail и compliance, - Claude Code или Gemini. Для команд с сильной внутренней экспертизой, готовых писать обвязку, - Codex. Для быстрого старта с минимальными затратами на настройку - Cursor. Подробный разбор агентной IDE нового поколения с мультиагентной оркестровкой читайте в обзоре Google Antigravity - там архитектура Editor View и Manager View решает похожие задачи разделения контроля и исполнения.
Внедрение harness engineering: первые шаги и подводные камни
Дорожная карта внедрения рассчитана на команду из трёх-пяти разработчиков, уже использующих хотя бы одного AI-агента. Первый шаг - аудит текущих агентов: какие задачи они выполняют, какие артефакты производят, где оседают результаты. Без этого аудита нельзя определить критические конвейеры, с которых стоит начинать.
Второй шаг - выбор одного, максимум двух критических конвейеров для пилота. Критический конвейер - тот, где сбой агента причиняет наибольший ущерб: ломает сборку, пропускает уязвимость, генерирует некорректные данные. Пилот на критическом конвейере даёт максимально быструю обратную связь и обоснование для расширения.
Третий шаг - развёртывание control plane в минимальной конфигурации: Work Items, audit trail, два-три гейта. Не нужно проектировать идеальную схему на все случаи. Control plane должен заработать и начать накапливать данные. Четвёртый шаг - запуск ratchet-цикла: первый же сбой, пойманный гейтами или вручную, превращается в фикс среды. С этого момента система начинает самоусиливаться.
Типичные ошибки на старте: переусложнение (десять гейтов на первый конвейер, ни один не отлажен), игнорирование sensor-first (правила пишутся до того, как собраны метрики), отсутствие измеримости (правила добавляются, но их влияние не отслеживается). Для малых команд рекомендация: начинать с трёх гейтов (синтаксис, секреты, тесты) и одного датчика (процент отклонённых PR). Расширение - только после того, как эти три гейта работают без ручного вмешательства две недели.
Harness engineering не требует покупки нового инструмента. Control plane можно развернуть как набор скриптов в репозитории, audit trail - как JSON-лог, гейты - как хуки в CI. Система растёт органически вместе с количеством агентов и конвейеров. Главное - начать с архитектуры, а не с заплаток. О том, как построить агента с нуля и какие метрики закладывать в архитектуру сразу, - в материале про создание AI-агента на Python с разбором latency, cost и reliability.