Разбор харнессов ИИ‑агентов: как они устроены на обычном проекте, какими бывают — и что показал машинный журнал живого проекта

Пилю офлайн‑заметочник Nitinol и пишу об этом статьи. В первой части рассказывал, как десять лет терял заметки, во второй — про хранение и поиск без RAG, в третьей показал свой харнесс: обвязку из правил и проверок, через которую у меня проходит каждая задача. Показать‑то показал, но так и не объяснил, что это слово значит. В статье разберём, что именно скрывается за «обвязкой». А заодно покажу замеры со своего проекта, которых в третьей части не хватало.

Вопрос «какая нейросеть лучше пишет код» — это лишь половина вопроса. Помимо самой модели есть ещё и обвязка вокруг неё — она же harness, «харнесс».

На самом деле принято (громкое заявление для терминов, рождающихся быстрее, чем комьюнити успевает прийти к консенсусу) выделять четыре слоя агентной системы: модель, скаффолд, харнесс и агент.

1. Четыре слова на примере одного проекта

Устоявшаяся формула: Model + Harness = Agent. Разберём их на примере обычного проекта — интернет‑магазина на Next.js и Postgres: команда из четырёх человек, CI на GitHub Actions. Разработчик открывает проект, запускает Claude Code, Codex или Cursor — и пишет: «покрась кнопку корзины в васильковый цвет». Дальше разберём, где модель, где скаффолд, где харнесс и где агент.

Модель

Модель — это функция «текст на входе → текст на выходе», которая живёт в пределах одного вызова. Вы дали ей вход, она вернула ответ и остановилась. Памяти между вызовами у неё нет; сама она ничего не делает, только генерирует текст.

На нашем проекте это Claude Opus, GPT-5.x, Gemini, DeepSeek — кто угодно. Важно другое: модель не видит ваш репозиторий — она не знает ничего про магазин, его движок, язык программирования, структуру проекта. Только вход и выход.

Скаффолд

Скаффолд (scaffold, “строительные леса”) — всё, что окружает модель до первого вызова и определяет, с чем и по каким правилам она работает. В нашем примере это:

  • системный промпт вендора — кто ты, как себя вести, как отвечать;

  • описания инструментов — что такое ReadEditBashGrep, с какими аргументами их звать и когда нельзя;

  • файл правил проекта — CLAUDE.md или AGENTS.md в корне (второй — межвендорный стандарт, его читают пара десятков инструментов). Например:

# Магазин — правила для агента
- Пакетный менеджер pnpm, не npm. Тесты — `pnpm test`, линтер — `pnpm lint`.
- Миграции в db/migrations не правь руками: генерируй через `pnpm db:migrate`.
- Цены — только в копейках (integer), никаких float.
- Перед коммитом: typecheck, lint, тесты. Коммит без зелёного — нельзя.
- Тексты интерфейса — на русском.
  • список подключённых внешних инструментов — например, доступ к тестовой базе и к Jira через MCP;

  • формат ответа, который харнесс умеет разбирать: как модель должна сказать «вызови инструмент», а как — «я закончила».

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

Харнесс

Харнесс (harness — “упряжь”, «обвязка») — исполнительная машина вокруг вызова. Что она делает:

  1. собирает промпт из скаффолда, истории и вашей задачи;

  2. зовёт модель;

  3. разбирает ответ — модель попросила прочитать cart.ts или styles.css? запустить pnpm test?;

  4. исполняет запрошенное: читает файл, запускает команду, спрашивает у вас разрешение (но это не точно) на опасное (rm -rfgit pushDROP DATABASE);

  5. подкладывает результат обратно в историю;

  6. решает, продолжать или остановиться, — и идёт на шаг 1.

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

Агент

Агент — то, что получается, когда модель посадили в этот цикл с инструментами. Когда говорят «агент сделал PR», имеют в виду всю связку целиком. Агент — это LLM, гоняющий инструменты в цикле ради цели.

Агент — вся связка. Скаффолд задаёт условия, модель выбирает действие, харнесс исполняет цикл.
Агент — вся связка. Скаффолд задаёт условия, модель выбирает действие, харнесс исполняет цикл.

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

Оговорка о терминах. Границу между скаффолдом и харнессом проводят по‑разному, а часто не проводят вовсе. Здесь так: скаффолд — что задано заранее (промпты, схемы инструментов, формат ответа); харнесс — цикл, который это исполняет (вызов, парсинг, запуск инструментов, остановка).

Насколько велик вклад обвязки: замеры

Вклад обвязки можно измерить. Ниже — несколько независимых источников; для каждого коротко поясню, кто проводил замер и на чём он основан.

Источник

Кто это

Что меняли

Эффект

“Stop Comparing LLM Agents Without Disclosing the Harness” (arXiv 2605.23950)

Академическая работа (Тулейн, Ратгерс, Virginia Tech), целиком посвящённая тому, что сравнивать агентов без указания обвязки бессмысленно

Только харнесс, модель фиксирована: Claude Opus 4.5 на SWE‑bench Pro, голый SWE‑agent → Claude Code

45,9% → 55,4%, +9,5 п.п.

Она же, разрез по SWE‑bench Verified

То же исследование на более известном бенчмарке

Grok 4: академический SWE‑agent → скаффолд xAI

58,6% → 72–75%, +13–16 п.п.

LangChain, “Improving Deep Agents with harness engineering”

Разработчики LangChain/LangGraph — самого популярного фреймворка для сборки агентов; отчёт о собственном прыжке из‑за пределов топ-30 в топ-5 на Terminal‑Bench 2.0

Промпт + middleware с проверкой перед завершением + бюджет рассуждений, модель (GPT-5.2-Codex) не менялась

52,8% → 66,5%, +13,7 п.п.

Endor Labs (200 задач, апрель 2026)

Компания по безопасности цепочки поставок ПО; ведёт публичный бенчмарк агентов на реальных задачах

Codex → Cursor, GPT-5.5 в обоих; доля функционально корректных решений

61,5% → 87,2%, +25,7 п.п.

Vercel, “We removed 80% of our agent's tools”

Платформа деплоя фронтенда и авторы AI SDK; отчёт о своём продакшен‑агенте

17 инструментов → 2

80% → 100% (четыре запроса из пяти против пяти из пяти)

Epoch AI, “Why benchmarking is hard”

Независимая исследовательская организация, ведёт свой хаб бенчмарков

Только скаффолд на SWE‑bench Verified

до 11 п.п. у GPT-5 и до 15 п.п. у Kimi K2 Thinking

Кейс CORE‑Bench (arXiv 2606.26158)

Разбор от команды самого бенчмарка (Принстон, Беркли, MIT): 39 задач на воспроизведение научных результатов

Только скаффолд: стандартный CORE‑Agent → Codex CLI, модель та же (GPT-5.4)

51,3% → 94,9%, +44 п.п.; Opus 4.5 в Claude Code против CORE‑Agent — +7,6 п.п.

Claw‑SWE‑Bench (arXiv 2606.12344)

Бенчмарк на 350 задач из 43 репозиториев на восьми языках; прогон по девяти моделям и пяти харнессам

Смена модели при фиксированном харнессе против смены харнесса при фиксированной модели

29,4 п.п. против 27,4 п.п. — вклад обвязки почти равен вкладу модели

2. Словарь на полях

Дальше будет много терминов, которые айтишник, не живущий внутри агентов, наверняка слышал, но не обязательно щупал. Собрал их в кучку и добавил примеры. Главу можно пролистать и возвращаться к ней по мере надобности, или сохранить в закладки:)

Модель и вызов

Токен — единица текста для модели: примерно ¾ английского слова или 2–3 буквы русского. Ваш CLAUDE.md на 80 строк — это пара тысяч токенов в каждом вызове.

Контекстное окно — сколько токенов модель видит за один вызов: промпт и ответ вместе. У фронтирных моделей — до миллиона, у остальных 128–200 тысяч. Сессия с чтением файлов набивает окно за несколько часов, а качество проседает раньше — поэтому харнесс историю сжимает.

Системный промпт — инструкция «кто ты и как себя вести», которую харнесс кладёт в вызов первой. Текст вендора плюс ваши файлы правил.

Инструмент (tool) — действие, которое модель может попросить выполнить. ReadEditBash, поиск по коду, запрос к базе.

Вокруг цикла

MCP (Model Context Protocol) — стандарт подключения внешних инструментов к харнессу.

Хук — скрипт, который харнесс запускает сам на событии: перед вызовом инструмента, после правки файла, в конце ответа. Может заблокировать действие и вернуть модели сообщение. После каждой правки прогнать линтер и отдать ошибки модели; перед bash‑командой не пустить rm -rf. Срабатывает всегда — в отличие от правила в промпте, которое модель может пропустить.

Скилл — папка с инструкцией и вспомогательными файлами, которую агент подгружает по необходимости — или явно, если вы попросите. /release — пошаговые инструкции выпуска версии.

Субагент — отдельный вызов модели с чистым контекстом и своей задачей; возвращает резюме, а не всю переписку. «Проверь этот диф свежими глазами».

Песочница — изолированное окружение, где агент может ломать что угодно. Docker‑контейнер без доступа к продовой базе или к Hugging Face)

Компакция — сжатие истории диалога, когда она перестаёт влезать в окно. Сообщение «context compacted» посреди длинной сессии. Сжатие может сожрать что‑то важное, поэтому его стараются избегать, пока возможно.

Кэш промптов — провайдер не пересчитывает неизменный префикс запроса. Стабильный системный промпт стоит в десять раз дешевле нового.

Context rot — деградация качества ответов с ростом длины входа. Агент на третьем часу «забыл», что делал на первом.

Проверки, ревью, процесс

Бенчмарк — стандартный набор задач для сравнения моделей и агентов. SWE‑bench — починка багов в известных репозиториях; Terminal‑Bench — задачи в терминале.

Reward hacking — агент находит способ пройти проверку, не решая задачу. Переписал тест под свой ответ вместо починки кода.

Гейт — проверка, без зелёного исхода которой коммит или релиз не делается. typecheck → lint → тесты → ревью.

Спека — документ‑контракт задачи: проблема, сценарий, границы, критерии приёмки. docs/product/promo-codes.md до первой строчки кода.

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

Линза — угол зрения, под которым смотрят на один и тот же код: какой вопрос ревьюер задаёт и что считает дефектом. Один диф под разными линзами даёт разные списки замечаний.

Ось ревью — отдельный прогон ревью с одной линзой: свой промпт, свой вопрос, свой список находок. bugs — ошибки в коде, security — границы доверия, impact — кто ещё сломается. Один судья со всеми вопросами сразу размазывается; по вопросу на прогон — находки острее, а списки можно свести и проверить по отдельности.

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

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

Мутационная проба — намеренно сломать код под тестом и убедиться, что тест покраснел. Зелёный тест при сломанном коде — тест слепой: он проверяет сам себя.

3. Сам цикл — десять строк

Стив Кинни — инженер и автор курсов Frontend Masters — прочитал исходники Claude Code, Codex, Cursor, Vercel AI SDK, LangGraph и smolagents. Под разными интерфейсами он нашёл, по сути, одну и ту же архитектуру:

def run(task, tools):
    messages = [system_prompt, task]
    while True:
        response = llm.call(messages, tools)
        if response.tool == "complete_task":
            return response.result             # структурированный «ретурн»
        result = execute_tool(response.tool, response.args)
        messages.append(tool_result(result))   # ТОЛЬКО append, историю не правим

Вот и весь цикл. Anthropic в «Building effective agents» и OpenAI в своём практическом руководстве описывают агента одинаково: модель вызывает инструменты, получает результаты и продолжает, пока не сработает условие выхода.

Сам цикл давно не самое сложное. Инженерия начинается вокруг него.

В боевом коде это выглядит примерно так:

while (!done && budget.remaining()) {
  const action = await model.decide(context)
  const result = await execute(action)
  context.append(result)
  done = checkExit(context, result)
}

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

Результат возвращается в контекст. Бюджет и условие выхода определяют, будет ли следующий шаг.
Результат возвращается в контекст. Бюджет и условие выхода определяют, будет ли следующий шаг.

Чаще всего спотыкаются об условие остановки. «Спросить агента, не зациклился ли он» не получится. Нужны жёсткие лимиты (max_iterations, дедлайн, бюджет токенов) и явный инструмент‑терминатор, которым модель сообщает: «Я закончила, вот структурированный результат».

4. Что реально лежит в обвязке: разбор по слоям

Сначала короткая карта, затем разберём каждый слой.

Слой

За что отвечает

Чем платите, если сделан плохо

Управление контекстом

Что кладём в окно на каждом шаге

Деградация на длинных задачах, «забыл, что делал»

Компакция

Что делаем при переполнении

Потеря нити, повтор уже сделанного

Кэширование промптов

Переиспользование вычислений

Счёт в 3–10 раз выше, задержка

Дизайн инструментов

Что агент вообще умеет

Ошибочные вызовы, метания между тулами

Права и песочница

Что можно без спроса

Испорченное окружение, RCE

Верификация

Как отличить «сделал» от «кажется»

Уверенно сломанный код в мастере

Память и состояние

Что переживает сессию

Каждый прогон с нуля

Оркестрация

Один агент или много

Токены ×15 и рассогласование

4.1. Управление контекстом

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

У этой работы есть название — context engineering.

Почему нельзя «просто положить всё»? В 2025 году Chroma Research — исследовательское подразделение Chroma, разработчика популярной векторной БД, — измерила на 18 моделях эффект context rot. Чем длиннее вход, тем менее надёжен результат, даже на тривиальных задачах. В тесте «иголка в стоге сена», где нужно найти один факт в длинном тексте, связный и хорошо структурированный «стог» неожиданно ухудшал результат, а перемешанный — улучшал. Есть и классическая работа «Lost in the Middle» исследователей Стэнфорда, Беркли и Samaya AI: если нужное лежит в середине контекста, а не в начале или конце, точность падает более чем на 20%.

Сфокусированный промпт примерно на 300 токенов может обыграть полный на 113 тысяч. Для обычного проекта правило простое: не скармливайте агенту весь репозиторий; дайте три нужных файла и объясните, где искать остальное.

4.2. Компакция

Когда история всё‑таки переполняет окно, харнесс её сворачивает. Самый простой вариант — попросить модель всё пересказать. Более аккуратный сохраняет ещё и уже сделанные выводы. Codex, например, возвращает специальный объект компакции со сжатым состоянием и запускает этот механизм автоматически при превышении порога. Цена ошибки в этом слое видна по свежему случаю: в конце августа 2026 команда Codex нашла, что при компакции старые картинки оставались в контексте и порой тут же запускали компакцию заново; после починки этой и двух соседних утечек OpenAI обещает от 10 до 50% больше работы на ту же квоту — и сбросила лимиты всем платным пользователям.

4.3. Кэширование промптов — ядро экономики

Кэш промптов префиксный. Провайдер сравнивает новый запрос со старым побайтово от начала и переиспользует вычисления до первого различия. От этого напрямую зависит счёт:

Держите системный промпт, описания инструментов и ранний контекст байт‑стабильными и только дописывайте в историю. Любая правка раннего сообщения — промах кэша.

Провайдер

Запись в кэш

Чтение из кэша

Минимальный префикс

Anthropic (TTL 5 мин)

1,25× базовой цены входа

0,1× (скидка ~90%)

512–4096 токенов в зависимости от модели

Anthropic (TTL 1 час)

2,0×

0,1×

то же

OpenAI, GPT-5.6 и новее (с июля 2026)

1,25×

0,1×

1024 токена; кэш живёт 30 минут после последнего обращения

OpenAI, модели до 5.6 (автокэш)

бесплатно

зависит от модели, скидка 50–90%

2048 токенов, шаг 128

С GPT-5.6 OpenAI перешла на ту же схему, что у Anthropic: запись в кэш платная, чтение — десятая часть цены. А у Claude Fable 5.1, вышедшей 1 сентября 2026, чтение из кэша подешевело ещё вчетверо, до 0,025×: стабильный префикс там стоит уже не в десять, а в сорок раз дешевле нового.

Добавление в конец сохраняет общий префикс. Изменение начала затрагивает весь следующий за ним хвост.
Добавление в конец сохраняет общий префикс. Изменение начала затрагивает весь следующий за ним хвост.

В инженерном посте OpenAI “Unrolling the Codex agent loop” это сформулировано прямо: старый промпт намеренно остаётся точным префиксом нового. При попадании в кэш стоимость шага растёт с длиной контекста линейно, а не квадратично. Поэтому Codex не правит старое сообщение посреди диалога, а добавляет новое.

Кэш ломается при смене модели, набора инструментов, конфигурации песочницы или рабочей директории. Я, например, видел баг, при котором MCP‑сервер перечислял инструменты в разном порядке. Каждый шаг агента промахивался мимо кэша просто из‑за недетерминированного порядка полей в JSON.

4.4. Дизайн инструментов

Хочется дать агенту побольше инструментов и предоставить выбор. Обычно это только мешает.

Семнадцать инструментов против двух: Vercel сократил набор и поднял долю успешных запросов с 80% до 100% — правда, на выборке из пяти запросов, зато с расходом токенов на 37% меньше. Иногда хватает даже правки текста — Anthropic в «Writing effective tools for agents» описывает, как точная правка описаний инструментов (не кода — текста, который модель про них читает) вывела Claude Sonnet 3.5 на лучший на тот момент результат на SWE‑bench Verified, резко снизив частоту ошибок.

В официальном лидерборде SWE‑bench — главном бенчмарке по починке реальных багов в популярных репозиториях — моделям дают единственный инструмент: bash. Поэтому результат там во многом зависит от того, насколько хорошо связка умеет работать с оболочкой и ориентироваться в CLI.

Есть ещё приём code execution вместо цепочек вызовов. В посте «Code execution with MCP» Anthropic предлагает не загружать в контекст определения всех MCP‑инструментов. Их можно представить как кодовый API в файловой системе и дать агенту среду исполнения: пусть он сам пишет код, вызывает инструменты и обрабатывает данные на месте. В замере Anthropic воркфлоу на 150 тысяч токенов сжался до двух тысяч — минус 98,7%.

Текст ошибки инструмента — тоже часть интерфейса агента. Сообщение «файл не найден, вот похожие пути» полезнее, чем безликое tool failed: харнесс превращает сбой в подсказку, и агент может скорректировать следующий шаг.

4.5. Права, песочница, безопасность

Формулировка Соломона Хайкса, создателя Docker, которую разнёс по индустрии Саймон Уиллисон — соавтор Django и один из самых цитируемых наблюдателей за LLM, — и которую стоит повесить на стену: ИИ‑агент — это LLM, крушащий своё окружение в цикле.

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

Практический минимум отсюда такой: песочница без интернета, режим «без подтверждений» только внутри контейнера и участие человека перед необратимыми действиями.

Примитив изоляции

Старт

Ядро

Кто использует

Firecracker microVM (лёгкие виртуалки от AWS, на них работает Lambda)

~125 мс

отдельное

E2B

gVisor (песочница Google: перехватывает системные вызовы)

< 1 с

перехват сисколлов

Modal (есть GPU)

Hardened‑контейнеры (обычный Docker с закрученными гайками)

27–90 мс

общее с хостом

Daytona

E2B, Modal и Daytona — провайдеры облачных песочниц для агентов: вы отдаёте им код на исполнение, они отвечают за изоляцию. Разница в последнем столбце принципиальна. В мае 2026 года Microsoft раскрыла две CVE, в которых prompt injection во фреймворке Semantic Kernel доводился до RCE — выполнения произвольного кода — на уровне хоста. При такой модели угроз общее ядро перестаёт быть абстрактным риском.

4.6. Верификация

Тесты, линтеры и типы дают агенту обратную связь: помогают отличить «сделал» от «кажется, сделал».

Для длинных прогонов Anthropic советует просить агента коммитить прогресс с осмысленными сообщениями и вести отдельный файл состояния. Тогда неудачную правку можно откатить через git, а рабочий контекст — восстановить после перезапуска.

Хорошо работает отдельный агент‑ревьюер с чистым контекстом. Тот, кто писал код, — плохой судья своей работы: он видит не только диф, но и собственные намерения. Ревьюер без контекста автора видит лишь то, что действительно написано. Здесь появляется понятие линзы — вопроса, с которым судья смотрит на диф. Одному можно сказать «ищи баги», другому — «ищи, чем тут можно злоупотребить», третьему — «найди, кто ещё сломается от этой правки». Код один, вопросы разные, поэтому и замечания почти не пересекаются. На этом паттерне построен весь мой процесс.

И тут же вторая половина, про которую забывают. Дорогое ревью должно оставлять после себя дешёвые проверки. Агент‑ревьюер стоит десятки тысяч токенов за находку, юнит‑тест — миллисекунды. Значит, у каждой починенной серьёзной находки есть второй вопрос: что сделано, чтобы впредь этот класс дефектов ловил детерминированный гейт? Ответов ровно три — добавлен тест; перенесено в техдолг; либо честное «дешёвым гейтом этот класс не ловится» (гонки, поведение внешней модели, вёрстка в реальном браузере — законный исход).

4.7. Память и состояние

Памятью может служить файловая система: файл прогресса, git‑история, артефакты для следующей сессии, скиллы с инструкциями, которые модель подгружает по мере надобности. Николас Карлини — известный исследователь безопасности ML, ныне в Anthropic — описывал сборку компилятора C на Rust в 100 тысяч строк шестнадцатью параллельными инстансами на общей кодовой базе: две недели, около 2000 сессий и примерно 20 тысяч долларов на API. Вся координация там шла через файлы и git, без специальной инфраструктуры для агентов.

4.8. Оркестрация: один агент или много

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

Cognition, создатель автономного агента Devin, в манифесте «Don't Build Multi‑Agents» приводит наглядный пример: первый субагент рисует фон в стиле Mario, второй — птицу из другой игры, и на выходе получаются несовместимые куски. Каждый по ходу работы принимает неявные решения; если эти решения расходятся, результат разваливается.

Тезис проверили академически. MAST (Multi‑Agent System Failure Taxonomy) из Беркли: исследователи разобрали реальные прогоны популярных мультиагентных систем и построили каталог из 14 режимов сбоя в трёх категориях. На рассогласование между агентами приходится около 37% всех сбоев — сопоставимо только с ошибками постановки и дизайна самой системы.

Anthropic в разборе своей исследовательской мультиагентной системы честно называет цену: агенты тратят примерно вчетверо больше токенов, чем чат, а мультиагентные системы — примерно в пятнадцать раз больше. При этом их система обошла одиночного агента на 90,2%, но 80% разницы в качестве объяснялось просто количеством потраченных токенов. То есть мультиагент работает — но покупается токенами, а не элегантностью.

Зато прижилась схема ведущий агент + временные изолированные субагенты со сжатым резюме на выходе. К ней сошлись Anthropic, OpenAI, Cognition, AutoGen и LangChain. Одноранговый «групповой чат агентов» работает хуже.

Остаётся вопрос сколько. Если ревьюеры почти не дублируют друг друга, соблазн понятен: добавить ещё одного. Но у добавочного взгляда есть точка насыщения, и она видна по журналу. Мой срез на 49 задачах с субагентами (25 августа, 937 находок): оставить только первого субагента — теряется 113 находок, первых двух — 41, первых трёх — 11. А находок, которые увидел бы только пятый или шестой, не нашлось ни одной: их наблюдения оказались повторами чужих. То есть после третьего вы платите почти за ноль. Число у вас будет своё — важно, что оно считается по журналу, а не по интуиции.

5. Второй смысл слова «харнесс»: процессная обвязка

До сих пор речь шла о вопросе «как агент делает шаг». Это технический харнесс, и в вашем проекте его почти наверняка написал вендор.

У команды, которая постоянно работает с агентами, довольно быстро появляется второй слой. Он отвечает уже на другой вопрос: «что считается сделанным?» На обычном проекте это файл правил в корне, pre‑commit, не пропускающий код без тестов, ревью свежим агентом перед мёржем, шаблон задачи, потолок «три круга правок, дальше — к человеку» и правило, по которому «ноль замечаний» не принимается на слово.

Это и есть процессный харнесс. Он живёт поверх вендорского и состоит из конфигурации: файлов правил, скиллов, субагентов, скриптов‑гейтов и журнала. Именно его я показывал в третьей части.

Вложенная схема показывает связь между выполнением шага и проверкой готовности работы.
Вложенная схема показывает связь между выполнением шага и проверкой готовности работы.

Технический харнесс

Процессный харнесс

Отвечает на вопрос

Как агент делает шаг

Что считается сделанным

Из чего состоит

Цикл, контекст, тулы, права

Правила, скиллы, гейты, журнал

Кто автор

Вендор или вы через SDK

Всегда вы

Как оценивается

Задержка, стоимость шага, надёжность вызовов

Улов: сколько дефектов поймано до мастера и по какой цене

Как улучшать

Сменить харнесс, настроить кэш, урезать тулы

Померить свой улов и подвинуть гейты

Эти слои легко смешать, хотя качество у них измеряется по‑разному. Спорят обычно о первом, а результат в продакшене часто определяет второй: смена Cursor на Claude Code не починит процесс, в котором никто не смотрит диф. Зато процессный харнесс, в отличие от публичного бенчмарка, каждый может измерить на собственном проекте.

У этого слоя, кстати, уже есть индустриальное имя.

6. SDD: спека как первоисточник

Spec‑Driven Development (SDD, разработка от спецификации) — ответ на проблему, которую принесли агенты: код стало дёшево генерировать, и он перестал быть самым ценным артефактом в репозитории.

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

Как это выглядит на практике

Канонический цикл SDD:

намерение → спецификация → план → задачи → реализация → верификация против спеки

Ключевое отличие от «просто написать тикет получше»: спека — машиночитаемый вход агента, живущий в репозитории рядом с кодом и меняющийся вместе с ним. Не документ в Confluence, который устареет через спринт.

Инструментарий: от CLI‑команд до «спека вместо кода»

Инструментов за год стало заметно больше, и они уже разошлись по нишам:

Инструмент

Кто

Форма

Чем отличается

Spec Kit

GitHub, открытый

Набор команд поверх вашего агента: /specify → /plan → /tasks

Де‑факто дефолт (130+ тысяч звёзд, 1.0 вышла 21 августа 2026), работает с 30+ агентами: Claude Code, Copilot, Cursor и др. Заточен под greenfield — новый проект с нуля

Kiro

AWS

Агентная IDE

Спека — центральный объект среды: requirements.mddesign.mdtasks.md прямо в репозитории; критерии приёмки в формальной нотации EARS. GA с ноября 2025-го

OpenSpec

Fission AI, MIT

Лёгкий слой поверх агента

Единственный, заточенный под brownfield — живую кодовую базу: описывается не система целиком, а изменение, с дельта‑маркерами ADDED / MODIFIED / REMOVED

Tessl

Стартап

Платформа «spec‑as‑source» + реестр

Самая радикальная версия идеи: спека — единственный источник, код генерируется из неё и правится через неё; сам фреймворк пока в закрытой бете. Плюс реестр из 10 000+ спек популярных библиотек — против галлюцинаций в API

План‑режимы вендорских агентов (plan mode в Claude Code, Plan Mode в Cursor) — это SDD‑лайт, встроенный в харнесс: те же «сначала документ, потом код», только без файла в репозитории.

Критика SDD

Методология молодая, и у неё уже видны два типичных провала.

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

Спека расходится с кодом. Та же болезнь когда‑то убила «документацию как источник правды». Если ничто механически не проверяет, что реализация соответствует спеке, спека протухнет — просто теперь её будет читать агент и уверенно строить по ней черт знает что.

Как SDD связана с харнессом

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

У меня такие замеры есть, не то что бы их можно экстраполировать на всю методолгию и индустрию но зато со своего огорода)

7. Что показал мой леджер: пять замеров

Теперь — что из всего этого видно на живом проекте. Nitinol — локальное десктопное рабочее пространство (Electron, TypeScript в строгом режиме, SQLite), версия 0.19. Разработчик один, весь код пишут агенты, и это важно для чтения всех чисел ниже: ИИ‑ревью здесь не дополнение к человеческому, а его замена — второго человека, который посмотрит диф, в проекте нет. В команде та же механика дала бы другие цифры: часть улова снял бы коллега на обычном ревью.

Конвейер — тот самый процессный харнесс из главы 5: спека с критериями приёмки → независимое ревью плана судьёй другого вендора (Codex) → реализация (Claude Code) → ревью дифа в чистом контексте, на рискованных задачах тремя линзами → адъюдикация → детерминированный гейт (типы, линтер, юниты, браузерный слой) → коммит. Каждый прогон и каждая находка пишутся в леджер. Основной срез я снял 23 августа: 2094 коммита за 77 дней жизни проекта; в журнале на тот момент 1551 строка, из которых собираются 626 находок, 510 принято. Поздние замеры — про потолки витков, насыщение субагентов и перенос находок в тесты из предыдущих глав — я снял 25–26 августа, когда журнал дорос до 2442 строк. Оговорка о происхождении: машинный журнал я веду только с 16 августа; всё, что старше, восстановлено разбором тел коммитов и показывает направление, а не точный уровень.

Ревью и тесты почти не пересекаются. У 639 наблюдений в журнале заполнено поле «поймали бы это тесты, типы или линтер сами». Ответ «да» — у 17, то есть у 2,7%. Это суждение при разборе, а не эксперимент, но порядок величины показателен: слой ревью ловит другой класс дефектов, чем детерминированные гейты, и они не заменяют друг друга. Если бы 60% находок закрывал линтер, слой ревью был бы дорогой роскошью.

Ревьюеры почти не дублируют друг друга. Из 510 принятых находок 89% увидел ровно один источник. Самая резкая цифра замера: находок, которые увидели оба вендора — и Codex‑судья, и Claude‑субагенты, — 9 из 626, полтора процента. Калибр при этом разный: у находок Codex две трети критичных (и брака тоже больше — 40 отклонённых против 5), у субагентов критична одна восьмая. И классы дефектов разные: Codex доминирует там, где проверка формально есть, но fail‑open, и на гонках; субагенты — на дрейфе доков и реестров; тесты, слепые к мутации, обе стороны ловят поровну. Оговорка: это не очная ставка — оси работали на разных задачах и с разными промптами, часть непересечения объясняется разным заданием. Но вывод устойчив и с поправкой: второй вендор в ревью — не подстраховка на случай сбоя первого, а другой набор глаз.

Один прогон ничего не проверяет. Замер, который я поставил специально для этой статьи: пять настоящих коммитов, ось дифа прогнана по каждому дважды с побайтово одинаковым входом. Судья совпал сам с собой на 57%, разброс — от полного совпадения до нуля на соседних коммитах. Практически важнее другое: второй прогон принёс 5 находок из 14, первый — одну. Повтор не подтверждает первый прогон, а добирает потерянное. После этого замера я записал в канон проекта правило: ось дифа гоняется дважды всегда, а отрицательный вердикт («ноль находок», «граница держит») засчитывается, только если его воспроизвёл независимый второй прогон.

Два прогона ревью на пяти коммитах: 1 находка только в первом, 8 в обоих, 5 только во втором; всего 14 уникальных находок
Два прогона ревью на пяти коммитах: 1 находка только в первом, 8 в обоих, 5 только во втором; всего 14 уникальных находок

Цена находки измерима, и она разная.

Ось ревью

Токенов на принятую находку

Минут на находку

Ревью плана

12 166

4

Ревью дифа

17 258

2

Влияние на зависимости

42 437

3

Безопасность

50 143

4

Лучшее соотношение сигнал/шум — у ревью плана: почти три четверти его находок критичны при 3% брака, а один прогон стоит в пять‑шесть раз дешевле остальных осей. Логично: на этапе плана ошибка стоит абзац, а не рефакторинг. И цена ревью линейна по размеру дифа: диф на 24 КБ судья читает за 6 тысяч токенов, на 174 КБ — за 44 тысячи, всемеро дороже. Аргумент за мелкие коммиты, у которого наконец есть число.

Утечки идут мимо гейта, а не мимо судьи. За окно до мастера доехали семь сломанных коммитов (нижняя граница: считаю только починки, помеченные трейлером со ссылкой на виновника). Пять из семи пришлись на пропущенный, обрезанный или вовсе не запущенный гейт; ни одна — на дефект кода, который все оси видели целиком и пропустили. Обратная проверка: три ретроспективных прогона по коммитам‑виновникам с полным входом дали ноль попаданий — ось не находит задним числом даже то, что от неё уже утекло. Вывод неудобен для обеих партий в споре об ИИ‑ревью: слой ловит много, и ловит то, чего не ловят тесты, — но другой класс, не тот, который утекает. Утечки закрываются дисциплиной прогона, а не качеством судьи.

8. Чеклист на практике

1. Сначала выжмите конфигурацию, потом стройте своё. Файл правил проекта, скиллы, хуки, субагенты и режим планирования дают бо́льшую часть выигрыша.

2. Стройте своё, только если упёрлись в конкретное ограничение. Причин четыре: нужны инструменты под ваш домен; требования приватности исключают облако; нужен роутинг моделей по шагам; требуется интеграция в CI и durable‑исполнение. «Хочется лучше» — не причина. Если всё же строите, берите SDK, а не голый while‑цикл.

3. Хук — закон, промпт — рекомендация. Инструкция в файле правил живёт в контексте модели, и модель может её не выполнить. Хук исполняется вне контекста, а обойти его можно только явно — так, что это останется в истории. Всё обязательное выносите в детерминированный слой: git‑хуки, скрипты‑валидаторы, проверки в CI. У меня этот слой долго был тоньше, чем следовало: каждый пятый кодовый коммит обходился без полного прогона, а пять утечек в мастер из семи пришлись на пропущенные или неполные гейты. Я поставил хук по ходу работы над статьёй — и тут же выяснил, что параллельная пачка умеет обходить этот путь. Любое «теперь закрыто» тоже надо проверять.

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

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

6. Отделяйте «что случилось с вызовом» от «что судья видел». Успешный вызов ещё не означает, что в контекст поместился весь диф. И проверяйте не только диф: у меня судья получает ещё и срез спеки, и тот резался своим лимитом — плоско, с конца. По конвенции репозитория в конце спеки лежит раздел «Риски и ограничения», так что систематически не доходил именно он, у каждой пятой спеки. Отдельным сортом та же болезнь: из‑за нумерации в заголовке («## 8. Критерии приёмки») парсер не узнавал секцию и слал судье пустой контракт — при бодром OK в статусе.

7. Проверяйте отрицания вторым прогоном. «Ничего не нашёл» — самое дорогое утверждение в системе, и его никто обычно не проверяет.

8. Ставьте потолки числом — и пусть их считает механизм, а не память агента. Формулировка без конкретного лимита превращается в пожелание, это полбеды. Хуже, что и лимит с числом им становится. Мой потолок «не больше трёх витков ревью плана» был записан числом в каноне — и всё равно нарушен на 15 задачах из 106, суммарно 34 лишних витка, потому что считать витки поручалось тому же агенту, которого потолок ограничивает.

9. Спека — вход агента, а не просто документ для людей. Если пошли в SDD, держите её короткой и механически проверяйте соответствие кода. Иначе получите протухший документ, по которому агент уверенно построит не то.

10. Считайте не только улов гейта, но и долю полных прогонов. У меня слой ревью выглядел отлично по улову, а детерминированный гейт при этом оказывался неполным в 17% коммитов, на кодовых — в 20,6%. Качество судьи и дисциплина прогона — разные метрики, и вторую почти никогда не считают.

11. Меряйте свой улов, а не бенчмарк. Заведите журнал: кто нашёл, что нашёл, что решили, сколько стоило. Через месяц у вас будут ответы про ваш код. Это самое дешёвое улучшение из всего списка — и почти никто его не делает.

12. Пусть каждая дорогая находка оставляет после себя дешёвую проверку. После починки серьёзного дефекта спрашивайте: что сделано, чтобы впредь этот класс ловил тест, а не агент за десятки тысяч токенов? Ответ «ничего» — тоже ответ, но он должен быть записан. Как сделать вопрос неотвратимым, показала глава 4.6: у меня ответы появились только тогда, когда без них перестала записываться строка журнала.

13. Мультиагент — только для действительно параллельной работы. Внутри задач мои агенты не конфликтовали — рассогласование из главы 4.8 жило на интеграции: общий файл затаскивал чужие правки, соседняя сессия сметала незакоммиченное. Поэтому на шов нужен отдельный гейт — у меня это сквозные тесты на слитом дереве, а не в каждой ветке, и они краснели в 37% прогонов. Детектор работает. Число же ревьюеров держите на измеренном насыщении, а не на «чем больше, тем лучше»: после третьего субагента прирост находок у меня практически исчезает.

9. Выводы

Обвязка — не обслуживающий код, а половина результата. Один и тот же GPT-5.5 в разных харнессах показал 61,5% и 87,2%, а на Claw‑SWE‑Bench смена обвязки сдвигала результат почти на столько же, на сколько смена модели. Пока все спорят о моделях, сопоставимый прирост можно получить конфигурацией, без миллионов на дообучение. Сам цикл при этом умещается в десять строк; разница — в том, что модель видит, сколько ей отпущено и как система понимает, что работа закончена.

Харнессов на практике два, и улучшать их нужно по‑разному. Технический отвечает за то, как агент делает шаг; его обычно покупают готовым и оценивают по задержке, цене и надёжности. Процессный определяет, что считается сделанным; его команда пишет сама и измеряет по улову дефектов до мастера.

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

Одного прогона недетерминированного судьи мало: судья совпадает сам с собой примерно наполовину. Ложную находку отсеет разбор. А «всё чисто» без повторного прогона не проверит уже никто.

Гейт течёт чаще судьи. Дисциплина прогона оказалась важнее качества ревьюера. Правило в промпте остаётся рекомендацией, хук ближе к закону — но и «закрыл хуком» не ставит точку: следующий замер нашёл обход через параллельную пачку. С потолками ровно то же: пока лимит считает тот самый агент, которого он ограничивает, лимита нет. Процессный харнесс живёт циклом «померил → закрыл → померил снова».

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

Главный вывод: обвязка решает — но только та, которую вы измеряете и дорабатываете.

Спасибо всем, кто дочитал и комментировал предыдущие части. Всем безлимитных лимитов)