Harness engineering (харнесс-инжиниринг) — настройка среды вокруг ИИ-агента: инструкций, инструментов, прав и проверок. Harness-Driven Development (HDD) — рабочий метод на его основе: каждая ошибка агента становится правилом этой среды.
Петля HDD
Петля работает так. Агент получает задачу и делает результат. Датчики (тест, линтер, ревью) проверяют результат. Если всё прошло, задача закрыта. Если датчик нашёл ошибку, человек не просто исправляет результат, а меняет окружение агента, то есть харнесс: дописывает строку в инструкцию, добавляет тест или хук. Следующая задача идёт уже с этим правилом, и такая ошибка не повторяется.
Принцип Митчелла Хашимото: если агент ошибся, харнесс меняют так, чтобы эта ошибка не повторилась Faros
Промпт исправляет один запрос, контекст — знания модели, харнесс — каждый следующий запуск агента. Пример: агент правит код и не запускает тесты.
Таблица показывает одну и ту же ошибку (агент правит код и не запускает тесты) и три способа её исправить. Промпт: дописать «запусти тесты после правки». Это действует только для одного запроса, следующий начнётся заново. Контекст: записать то же в файл инструкций проекта. Модель это читает, но может пропустить. Харнесс: поставить хук, который сам запускает тесты после каждой правки. Он выполняется без участия модели, поэтому исправление держится во всех следующих запусках.
Устройство харнесса: 3 × 3
Три домена контура и три контекста в каждом — девять канонов. У каждого канона ровно один домен и один контекст.
Матрицу удобно читать как три вопроса. Ожидание: каким должен быть результат (например, «после правки тесты проходят»). Наблюдение: каким он получился на самом деле, это записывает датчик. Луп: сравнивает одно с другим и решает, что делать. В каждой из трёх строк есть три вида опоры: спека (что должно быть верно), скилл (как действовать) и память (на что опереться). Слова «домен» и «канон» здесь только названия: домен — строка матрицы, канон — одна клетка, например спека Ожидания. Нижняя схема показывает направление связей: Ожидание и Наблюдение подаются на вход Лупа, а он выдаёт либо патч (поправить действие), либо пересмотр правил. Обратной ссылки на Луп нет, поэтому домены не запутываются друг в друге. Режимы памяти: snapshot — таблица, которая обновляется при новом измерении; live — данные берут из живой системы (например, через MCP) каждый раз заново и не хранят.
Двойная петля
Двойная петля отвечает на вопрос, что именно менять после ошибки. Возьмём ту же ошибку: агент не запустил тесты. В одинарной петле вы напоминаете агенту, он запускает тесты, а правила остаются прежними. В двойной вы спрашиваете, какое правило допустило ошибку, и меняете его: теперь тесты запускает хук после каждой правки. Идея пришла из теории обучения организаций (Крис Аргирис и Дональд Шён): одинарная петля исправляет действие, двойная пересматривает правила, из которых действие вытекало. Википедия: Double-loop learning.
Луп применяется и к себе: каждый прогон заканчивается остаточным риском, статус «готово» он не ставит.
Менять правила после каждой жалобы опасно: харнесс начнёт расползаться от случайных правок. Поэтому Луп применяет четыре проверки. Если поправки лишь затыкают дыры и ничего нового не предсказывают, их заменяют одним правилом. Если жалоб несколько, сначала проверяют тестом, есть ли у них общая причина. Новое правило принимают, только если с ним старые случаи по-прежнему объясняются. Правило без внешней проверки отбрасывают, но записывают, что и почему отброшено. Подпись под карточками значит, что Луп применяется и к самому себе: прогон не ставит «готово», а заканчивается указанием остаточного риска.
Направляющие и датчики
Проверки в харнессе делятся по двум признакам. Первый: когда они срабатывают. Направляющие работают до действия агента и задают курс: типы, шаблоны кода, инструкции, спеки. Датчики работают после действия и ловят отклонения: тесты, линтер, ИИ-ревью. Второй признак: как проверка устроена. Вычислимые проверки (типы, тесты, линтер) срабатывают за секунды и не ошибаются в рамках своего правила. Проверки через ИИ (ИИ-ревью, модель-судья) гибче и дороже, их оставляют для смысла: стиль, понятность, соответствие замыслу.
Деление по Martin Fowler: Harness engineering
Три слоя проверок
Проверки раскладывают по трём слоям. Качество кода: стиль, форматирование, типы, простые ошибки. Архитектура: границы модулей и зависимости между ними, требования к скорости. Поведение: делает ли продукт то, что нужно пользователю. Полоски на схеме показывают, насколько хорошо этот слой научились проверять автоматически: у первого полоска почти полная, у поведения самая короткая.
Зрелость слоёв по Martin Fowler
Раньше — дешевле
Любая проверка срабатывает в какой-то момент, и чем раньше, тем дешевле исправить ошибку. На схеме четыре момента: до работы агента (инструкции и спеки), при записи файла (хуки и линтер), в CI (автоматическая сборка и тесты при отправке кода в репозиторий) и на ревью человеком. Значки $ показывают растущую цену ошибки.
Тесты запускают движки вроде QUnit, Jest и Vitest. Чем они отличаются и когда какой брать, разобрано в статье Vitest или Jest: что выбрать для JavaScript-проекта и когда хватит QUnit. Правила поведения, которые обычными тестами не проверить, ищет модель на Quint.
Где нужен человек
Харнесс берёт на себя рутинные проверки: стиль, типы, тесты, границы модулей. Человек решает то, что формальной проверкой не закрыть: архитектуру, продуктовые вопросы и новые правила. Цифры на схеме показывают пример соотношения: 36 проверок у харнесса и 6 у человека.
«Хороший харнесс оставляет человека в контуре и направляет его внимание туда, где оно важнее всего» — пересказ Martin Fowler
HDD и спеки
Спека и харнесс дополняют друг друга. Спека отвечает на вопрос «что должно получиться», харнесс проверяет, что получилось именно это. На схеме спека задаёт нужный результат, харнесс проверяет его, и код принимают по результатам проверок, а не чтением каждой строки.
«Спеки задают целевое состояние, харнесс — систему контроля» — Loiane Groner. Про спеки — доклад Spec-Driven Development на практике
С чего начать
Харнесс не нужно проектировать целиком. Начните с пяти шагов: два первых настраивают окружение сразу, три остальных запускают петлю «ошибка → правило». Файл прогресса нужен, когда задача длиннее одной сессии: в нём список фич со статусом, и новая сессия агента продолжает с того же места.
- 1
- 2Линтер и тесты после каждой правкихук, который агент запускает сам, до того как отдать результат
- 3Журнал ошибок агентакаждая исправленная вручную ошибка — строка с причиной
- 4Ошибка → правилораз в неделю перенести записи журнала в инструкции, тесты или хуки
- 5Файл прогресса для долгих задачсписок фич со статусом и история коммитов, чтобы новая сессия продолжила с того же места Anthropic