Блог • AI / Agent
Гонка AI Coding Agent 2026: за что на самом деле соревнуются Claude Code, Codex, OpenCode и DeepSeek Agent? Архитектура Agent Harness через JSON Tool Calling
Таблица лидеров всё ещё спрашивает, у кого балл выше. Откройте терминал: файлы правит, тесты гоняет и MCP вызывает не этот ответ на естественном языке.
Claude Code, Codex, OpenCode и DeepSeek Agent снаружи продают Coding Agent, который умеет работать. Настоящий разрыв — Agent Harness: кто владеет прыжком JSON Tool Calling от arguments к побочным эффектам.
В этой статье:
- Какой слой Coding Agent добавляет сверх автодополнения
- Что держит Agent Harness и чего не держит модель
- Почему JSON Tool Calling — общая шина у всех четверых
- Семь прыжков одного tool call: где каждый ставит ворота
- Как локально в JSONNote разобрать arguments и schema
Запомните это: Гонка 2026 — не «кто точнее дополнит следующую строку». Модель выдаёт tool call, параметры — JSON. harness решает, получится ли parse, спрашивать ли, в какой песочнице гонять и как записать результат. Claude Code ставит хуки вокруг каждого вызова. Codex делает песочницу и одобрение границей по умолчанию. OpenCode делает модели и права сменной конфигурацией. DeepSeek Agent разбирает весь конвейер на плагины.
Настоящая гонка — не автодополнение
Автодополнение отвечает на «какая следующая строка». Coding Agent отвечает на «как довести цель в живом репозитории»: прочитать контекст, выбрать инструмент, поправить код, запустить команду, посмотреть результат, решить снова.
Интерфейс у всех четверых как чат. Цикл снизу почти один:
User goal
→ Agent loop
→ LLM emits tool_call (JSON arguments)
→ Harness parses / validates / gates / executes
→ Tool result returns to context
→ Agent decides again
Модель рассуждает и выбирает «кого звать дальше». harness решает, какие инструменты модель видит, законны ли arguments, нужно ли спросить человека, что инструмент реально делает, как пишется сессия и что значит «готово».
Списки функций будут всё больше сходиться. Skills, MCP, субагенты и тумблеры прав есть у всех. Разница — на каком слое лежит контроль. Как продукты позиционируются, см. AI Coding Agent — это уже не только автодополнение: за что соревнуются Codex, Claude Code, OpenCode и DeepSeek Harness?. Как крутится цикл, см. Как работает AI Coding Agent?. Здесь разбираем только одно: после того как JSON Tool Calling покинул модель, как harness берёт управление.
Что такое Agent Harness
К 2026 у слоя уже есть имя. Разбор исходников одиннадцати промышленных Coding Agent называет это Harness Engineering: Agent равен модели плюс harness — runtime, который стыкует LLM с миром через цикл, инструменты, контекст, контроль безопасности, оркестрацию и поверхности расширения.
Другой парный эксперимент спрашивает прямо: даст ли смена harness той же модели больше решённых задач? Средний балл часто рядом; репозиторные и конкурсные задачи могут разойтись в разные стороны; стоимость и доля отмен меняются. Вывод не «родной harness всегда сильнее». А «вы покупаете путь завершения, не точку в таблице».
Поэтому четверо спорят не о лишней кнопке. Они спорят, кто яснее соберёт контракт инструмента, границу исполнения и человеческое вето.
| Слой | За что отвечает | За что не отвечает |
|---|---|---|
| Модель | Выбрать инструмент, заполнить JSON arguments, прочитать результат, решить снова | Писать на диск, гонять shell, выходить в сеть, авторизовать |
| JSON-контракт | Как выглядят параметры и результаты | Должен ли этот вызов случиться |
| Agent Harness | Видимые инструменты, проверка, одобрение, песочница, обратная запись, сессия | Придумать за вас бизнес-цель |
Как стек делится по слоям, см. Стек AI Agent 2026: как сочетать LLM, MCP, Function Calling и JSON Schema?.
Общая шина: JSON Tool Calling
Tool Calling (он же Function Calling) — не синоним «модель умеет писать код». Это структурированный вызов: модель выбирает имя из объявленных вами инструментов и генерирует JSON, который должен лечь в контракт параметров.
В OpenAI-совместимом API поле parameters в определении инструмента само по себе JSON Schema:
{
"type": "function",
"function": {
"name": "run_tests",
"description": "Run the project test suite and return a structured summary.",
"parameters": {
"type": "object",
"additionalProperties": false,
"properties": {
"suite": { "type": "string", "enum": ["unit", "integration", "e2e"] },
"path": { "type": "string", "minLength": 1 }
},
"required": ["suite"]
}
}
}
Когда модель отвечает, arguments часто строка, а не уже распарсенный объект:
{
"id": "call_7f21",
"type": "function",
"function": {
"name": "run_tests",
"arguments": "{\"suite\":\"e2e\",\"path\":\"tests/checkout.spec.ts\"}"
}
}
Поэтому harness делает минимум два дела: сначала распарсить строку в валидный JSON, затем проверить поля, типы и перечисления по объявленной schema. Пропавшие кавычки, лишние запятые и необъявленные ключи случаются на этом прыжке.
MCP подключает ту же шину к внешнему Server: inputSchema / outputSchema по-прежнему JSON Schema, tools/call по-прежнему один структурированный вызов. Чем больше Server, тем больше description и schema в контексте модели и тем больше ворот у harness. Как делят ответственность за безопасность, см. Уязвимости безопасности MCP.
Поле боя: семь прыжков одного tool call
Разложите четверых: имена функций разные, форма трубы одна. Спор — кто решает на каждом прыжке:
-
1
Показ
Какие инструменты и какой кусок schema попадают в этот запрос. Невидимый инструмент модель не вызовет.
-
2
Выдача
Модель выбирает имя и генерирует строку arguments. Этот прыжок значит только «хочу вызвать».
-
3
Разбор
Строка становится объектом. Невалидный JSON обязан упасть до слоя исполнения.
-
4
Проверка
По JSON Schema смотрят обязательные поля, типы, перечисления и additionalProperties.
-
5
Ворота
allow / deny / ask. Законная форма — ещё не разрешение.
-
6
Исполнение
Реально гоняют в песочнице, рабочей области или с полными правами хоста. Побочные эффекты начинаются здесь.
-
7
Обратная запись
Результат становится текстом или JSON, пишется в сессию и кормится следующему кругу. У сбоя тоже должна быть структура, не одно «что-то сломалось».
Все четверо идут этими семью прыжками. Разница — куда вставлены хуки, насколько тугая песочница по умолчанию, можно ли сменить модель и заменяется ли сама труба.
Claude Code: хуки до и после вызова
Claude Code усиливает главного Agent: Skills, MCP, субагенты и CLAUDE.md крутятся вокруг одного Claude Agent. С JSON Tool Calling реально смыкаются детерминированные хуки до и после каждого вызова.
В официальном жизненном цикле каждый вызов инструмента в loop проходит через PreToolUse и PostToolUse. Можно перехватить появление запроса прав (PermissionRequest) или после сбоя решить, можно ли повторить (PermissionDenied / PostToolUseFailure).
Хук читает event JSON, не прозу. Он может переписать вход, отказать в вызове, потребовать подтверждения или после успеха дописать логи, прогнать форматтер и вернуть новый контекст. Уже случившийся побочный эффект он не откатит — PostToolUse приходит слишком поздно.
Правила прав сопоставляются deny → ask → allow, deny побеждает. Хук, вернувший allow, только пропускает интерактивный запрос; корпоративный deny-список он не перебьёт. Даже при bypassPermissions хук PreToolUse, вернувший deny, всё равно блокирует вызов.
Инженерный смысл ясный: вероятностный Agent плюс детерминированные ворота. Прогнать тесты после правок, закрыть опасные команды, требовать одобрение на защищённых путях — модель не должна «каждый раз вспоминать».
Подходит, когда workflow стабилен и нужно на главном цикле закрепить Skills, субагентов и хуки, упаковав опыт в переиспользуемые пакеты.
Codex: песочница и одобрение раньше исполнения
Codex (включая Codex CLI) сдвигает вопрос на слой исполнения. Как только Agent правит файлы, гоняет shell, ставит зависимости, трогает сеть и учётные данные, он должен ответить сразу на две разные вещи: граница возможностей и можно ли это действие сейчас.
| Механизм | На какой вопрос отвечает | Типичные регуляторы |
|---|---|---|
| Sandbox | До чего технически можно дотянуться или что изменить? | read-only / workspace-write / danger-full-access |
| Approval | Это действие сейчас разрешено? | untrusted / on-request / never |
По умолчанию — наименьшие права: сначала зажать среду, открывать по нужде. Недоверенный каталог стартует read-only. Когда рабочей области доверяют, обычный пресет — workspace-write плюс on-request: чтение, запись и обычные команды внутри рабочей области идут сами; выход из рабочей области или сеть требуют одобрения. Сеть по умолчанию выключена, её нужно явно открыть.
Новые версии описывают файловую систему и сеть через permission profile. Не смешивайте это со старым sandbox_mode. Имена меняются. Разделение не меняется: один регулятор — «до чего можно дотянуться», другой — «можно ли это сейчас».
Подходит, когда побочные эффекты большие, след исполнения должен быть аудируемым, а изоляция и одобрение — первого класса. Репозиторий: openai/codex.
OpenCode: модели меняются, права — конфигурация
Отличие OpenCode не в «ещё одном синтаксисе Skills». Позиция по умолчанию: модели меняются. Лицензия MIT, сначала терминал, много поставщиков и локальные модели. Гибкость в основном в конфигурации — provider, model, permission, agent, — а не в разборке ядра harness в шину плагинов.
Права ушли из раннего булева tools в permission: каждое действие — allow, ask или deny. Правила можно писать по имени инструмента, шаблону команды, выходу из рабочей области (external_directory). Срабатывает последнее совпадение. Субагент может быть строже главного — например роль review сразу deny на edit.
{
"$schema": "https://opencode.ai/config.json",
"permission": {
"bash": {
"*": "ask",
"git *": "allow",
"git push *": "deny"
},
"edit": "allow",
"external_directory": "deny"
}
}
Обычно выигрывает тем, что мультимодели — способность по умолчанию, не подарок вендора; открытая лицензия и сообщество; «сменить модель» — операция первого класса. Цена тоже ясная: граница исполнения и глубина плагинов не обязаны быть первым пунктом продажи. Вы покупаете harness со сменными моделями, не самый тяжёлый продукт песочницы и не ядро платформы «Everything is a plugin».
Подходит, когда не доверяете одному поставщику или нужно в том же цикле менять модели, включая локальные веса.
DeepSeek Agent: сам конвейер — плагин
DeepSeek опускает вопрос ещё на слой ниже. Публичный превью — DeepSeek Harness (dsh). Внешний контракт — интерфейс Agent; реализация по умолчанию — заменяемый agent-loop. Лозунг Everything is a plugin — модель, инструменты, Skills, сессия, песочница, хранилище, loop, планирование и UI можно менять.
С Tool Calling стыкуется конвейер инструментов, не ещё одно окно чата. ToolDefinition в реестре несёт типизированные параметры и выход. Модели показывают только name, description, parameters. execute, таймауты, флаги параллелизма и UI нельзя выпускать в запрос.
Каждый вызов идёт фиксированным водопадом:
tools/pre-execute → allow / deny / ask
monotonic guards → 只收紧,不能再放行
tools/execute → 真正派发(可包超时 / 重试)
tools/post-execute → 检查或替换结果
finalizeContent → 定义自己的收尾
tools/result → 冻结后的权威结果
Можно идти через нативный Function Calling или через PTC (зарезервированный транспорт run_code; вложенные вызовы всё равно входят в тот же конвейер). Параллелизм классифицируют по вызову: эксклюзивные — барьер, безопасные для параллели — в ограниченный пул; события всё равно пишут в сессию в порядке модели.
Подходит, когда нужен сам runtime как платформа, а не просто более сильный помощник. Слой модели — см. DeepSeek V4-Pro: полный разбор.
Один JSON, четыре ворот
Один и тот же JSON tool call у четверых упирается в разные ворота:
| Этот прыжок | Claude Code | Codex | OpenCode | DeepSeek Agent |
|---|---|---|---|---|
| Поверхность инструментов, которую видит модель | Встроенные инструменты + Skills + MCP; schema можно грузить лениво | Ящик инструментов сессии + заметки проекта (AGENTS.md) | Встроенные + MCP + обрезка по agent | Реестр с областью проецирует ToolSchema через allowlist |
| До входа arguments в слой исполнения | Хуки читают полный JSON события tool | Сначала способность песочницы, потом политика одобрения | Правила permission сверяют имя инструмента и вход | После parse — водопад pre-execute и монотонные стражи |
| Как человек ставит вето | PermissionRequest; deny сильнее hook allow | on-request / untrusted; можно отдать reviewer | ask; субагент может быть строже | Решение ask — результат первого класса в конвейере |
| Где случаются побочные эффекты | Локальные инструменты + постобработка хуками | Песочница на уровне ОС; сети нет по умолчанию, рабочая область на запись | Локальное исполнение, git-снимки, undo | Заменяемый sandbox-плагин |
| Как результат пишут обратно | PostToolUse / хуки сбоя дописывают контекст | События JSONL, удобно аудировать в CI | Диагностика LSP может вернуться в цикл | tools/result замораживается, затем лог сессии |
Последняя строка — не рейтинг. Вы покупаете «более удобного главного Agent», «более контролируемую среду исполнения», «слой конфигурации со сменными моделями» или «собираемый runtime».
Продуктовый взгляд на карту контроля, см. четыре архитектурных центра. Кто отвечает за безопасность, когда MCP раздувает поверхность инструментов, см. Когда AI Agent начинает «сам атаковать интернет»: как JSON становится границей безопасности.
Зачем всё ещё смотреть JSON Schema
Каким бы сильным ни был harness у четверых, грязные parameters на слое исполнения становятся инцидентом. Заполнение моделью — мягкое ограничение: arguments могут быть сломанным JSON, без полей или с необъявленными ключами.
Валидная schema — ещё не разрешение. Оба фрагмента ниже проходят широкую schema, где есть только поле sql. Только узкая сторона сводит операцию к перечислению и пишет идентификатор как pattern:
{
"loose": {
"type": "object",
"properties": { "sql": { "type": "string" } },
"required": ["sql"]
},
"tight": {
"type": "object",
"additionalProperties": false,
"properties": {
"op": { "type": "string", "enum": ["get_user_by_id"] },
"user_id": { "type": "string", "pattern": "^[a-z0-9-]{8,36}$" }
},
"required": ["op", "user_id"]
}
}
Как писать контракт и чем JSON Mode отличается от Strict Schema, см. Зачем ИИ нужен JSON Schema? Structured Output, Function Calling и JSON Schema и Зачем AI Agent нужен JSON Schema? От Tool Calling до Structured Output.
Разобрать tool call в JSONNote
Самый полезный материал отладки harness — часто кусок JSON: определение инструмента, arguments модели, события хуков, причина отказа. Всё это можно разобрать локально в браузере. Репозиторий загружать не нужно.
-
1
Сначала проверить, что arguments — законный JSON
Снимите экранирование со строки и бросьте в форматтер JSON. Пропавшие запятые, висячие запятые и одинарные кавычки взорвутся здесь.
-
2
Проверить по объявленной schema
Положите parameters / inputSchema инструмента и разобранный объект в JSON Schema. Смотрите: дыра в поле, неверный тип или лишний необъявленный ключ.
-
3
Сравнить «что одобрили» и «что сейчас»
Положите список инструментов прошлой недели и сегодняшний в JSON Diff и ищите тихие правки description и schema.
-
4
Нужно показать коллеге — через Hash
Данные остаются во fragment URL и не попадают на сервер. См. Поделиться JSON через URL Hash.
FAQ
За что на самом деле соревнуются Claude Code, Codex, OpenCode и DeepSeek Agent?
Не чеклист функций и не то, кто точнее дополнит следующую строку. Спор — Agent Harness: кто владеет прыжком JSON Tool Calling от разбора и проверки контракта через одобрение, исполнение в песочнице и обратную запись результата.
Что важнее — Agent Harness или модель?
Модель рассуждает и выбирает следующий шаг. harness решает, какие инструменты видны, законны ли arguments, нужно ли спросить человека на рискованном действии и где случаются побочные эффекты. Смена harness не гарантирует более высокий средний балл, но путь завершения, стоимость и доля отмен меняются. Вы выбираете контроль, не балл.
Кого из четырёх выбрать?
Единого чемпиона нет. Детерминированные хуки и права на главном Agent — Claude Code. Песочницу и одобрения как границу исполнения по умолчанию — Codex. Смена моделей и антилок-ин — OpenCode. loop, конвейер инструментов и песочницу как заменяемые плагины — DeepSeek Agent (DeepSeek Harness).
Есть ли у самого JSON Tool Calling контроль прав?
Нет. Модель выбирает имя инструмента и заполняет arguments. Этот прыжок значит только «хочу вызвать». Блокировать ли, в какой песочнице гонять, возвращать ли результат модели — дело harness. Нет инструмента, отказали в правах или JSON не прошёл проверку — на диске ничего не случится.
Зачем самому проверять JSON Schema?
Заполнение параметров моделью — мягкое ограничение. arguments часто строка: поля могут пропасть, тип съехать, появиться необъявленные ключи. Валидная schema — ещё не разрешение. В проде всё равно нужен parse плюс проверка, потом права и песочница. Каким бы сильным ни был harness у четверых, грязные parameters на слое исполнения становятся инцидентом.
Итог
Гонка Coding Agent 2026 снаружи как война моделей. В репозитории это война harness.
Модель выдаёт JSON. Harness решает, станет ли этот JSON побочным эффектом. Четверо спорят за контроль одной трубы: Claude Code ставит хуки, Codex сжимает границу исполнения, OpenCode снимает замок с модели, DeepSeek Agent делает сам runtime плагинами.
Функции будут сходиться дальше. Смотреть нужно на то, кто решает после того, как tool call покинул модель.
Дальше: вставить arguments одного tool call в JSONNote