Анатомия agent harness: что на самом деле делает LLM-агента агентом
Глубокий разбор agent harness: оркестрация, инструменты, память, управление контекстом, проверка, безопасность и архитектурные решения вокруг LLM-агентов.
Оригинал: пост Akshay 🚀 в X.
Глубокий разбор того, что на самом деле строят Anthropic, OpenAI, Perplexity и LangChain: цикл оркестрации, инструменты, память, управление контекстом — всё, что превращает статeless-LLM в способного агента.
Вы построили чат-бота. Возможно, прикрутили ReAct-цикл с несколькими инструментами. Для демо всё работает. Потом вы пытаетесь сделать production-grade систему — и колёса отваливаются: модель забывает, что делала три шага назад, вызовы инструментов молча падают, а контекстное окно забивается мусором.
Проблема не в модели. Проблема во всём, что находится вокруг модели.
LangChain показал это на практике: они изменили только инфраструктуру вокруг LLM — модель и веса остались теми же — и поднялись с позиции вне топ-30 до 5-го места в TerminalBench 2.0. Отдельный исследовательский проект достиг 76,4% pass rate, позволив LLM самой оптимизировать инфраструктуру, и обошёл системы, спроектированные вручную.
У этой инфраструктуры теперь есть имя: agent harness — «обвязка агента».
Что такое agent harness?
Термин формализовали в начале 2026 года, но сама концепция существовала задолго до этого. Harness — это полная программная инфраструктура вокруг LLM: цикл оркестрации, инструменты, память, управление контекстом, сохранение состояния, обработка ошибок и guardrails. В документации Claude Code от Anthropic это сформулировано просто: SDK — это «agent harness, на котором работает Claude Code». Команда OpenAI Codex использует ту же рамку, прямо приравнивая термины «agent» и «harness» к немодельной инфраструктуре, которая делает LLM полезной.
Мне очень нравится каноничная формула Вивека Триведи из LangChain: «Если это не модель — это harness».
Именно здесь многие путаются. «Агент» — это возникающее поведение: целеориентированная, использующая инструменты, самокорректирующаяся сущность, с которой взаимодействует пользователь. Harness — это механизм, который производит такое поведение. Когда кто-то говорит «я построил агента», на практике он имеет в виду: «я построил harness и подключил к нему модель».
Берэн Миллидж точно сформулировал эту аналогию в эссе 2023 года «Scaffolded LLMs as Natural Language Computers». Сырая LLM — это CPU без RAM, диска и I/O. Контекстное окно выступает как RAM: быстрое, но ограниченное. Внешние базы данных работают как диск: большие, но медленные. Интеграции с инструментами — это драйверы устройств. Harness — это операционная система. Как писал Миллидж: «Мы заново изобрели архитектуру фон Неймана», потому что это естественная абстракция для любой вычислительной системы.
Три уровня инженерии
Вокруг модели есть три концентрических уровня инженерии:
- Prompt engineering — формирует инструкции, которые получает модель.
- Context engineering — управляет тем, что модель видит и когда.
- Harness engineering — включает оба предыдущих уровня плюс всю прикладную инфраструктуру: оркестрацию инструментов, сохранение состояния, восстановление после ошибок, циклы проверки, enforcement безопасности и управление жизненным циклом.
Harness — это не обёртка вокруг промпта. Это полная система, которая делает возможным автономное агентское поведение.
12 компонентов production-harness
Если обобщить подходы Anthropic, OpenAI, LangChain и broader practitioner community, production agent harness состоит из двенадцати отдельных компонентов. Пройдёмся по каждому.
1. Цикл оркестрации
Это сердцебиение системы. Он реализует цикл Thought-Action-Observation (TAO), также известный как ReAct loop. Цикл работает так: собрать промпт, вызвать LLM, разобрать выход, выполнить вызовы инструментов, вернуть результаты обратно, повторять до завершения.
Механически это часто просто while loop. Сложность находится не в самом цикле, а во всём, чем он управляет. Anthropic описывает свой runtime как «тупой цикл», где весь интеллект находится в модели. Harness лишь управляет ходами.
2. Инструменты
Инструменты — это руки агента. Они описываются схемами: имя, описание, типы параметров. Эти схемы добавляются в контекст LLM, чтобы модель знала, что доступно. Слой инструментов отвечает за регистрацию, валидацию схем, извлечение аргументов, sandboxed execution, захват результата и форматирование результата обратно в наблюдения, понятные LLM.
Claude Code даёт инструменты в шести категориях: файловые операции, поиск, выполнение команд, веб-доступ, code intelligence и запуск subagent. OpenAI Agents SDK поддерживает function tools через @function_tool, hosted tools вроде WebSearch, CodeInterpreter и FileSearch, а также MCP-серверы.
3. Память
Память работает на нескольких временных масштабах. Краткосрочная память — это история диалога внутри одной сессии. Долгосрочная память сохраняется между сессиями: Anthropic использует проектные файлы CLAUDE.md и автоматически создаваемые MEMORY.md; LangGraph использует namespace-organized JSON Stores; OpenAI поддерживает Sessions на SQLite или Redis.
Claude Code реализует трёхуровневую иерархию: лёгкий индекс примерно по 150 символов на запись, который всегда загружается; подробные тематические файлы, подтягиваемые по требованию; и сырые транскрипты, доступные только через поиск. Важный принцип: агент считает собственную память «подсказкой» и проверяет её по реальному состоянию перед действием.
4. Управление контекстом
Именно здесь многие агенты тихо ломаются. Главная проблема — context rot: качество модели падает на 30% и более, когда важная информация оказывается в середине окна. Это показали исследования Chroma и подтвердил Stanford в работе «Lost in the Middle». Даже миллионнотокенные окна страдают от ухудшения следования инструкциям по мере роста контекста.
Production-стратегии включают:
- Compaction: суммаризация истории при приближении к лимитам. Claude Code сохраняет архитектурные решения и нерешённые баги, отбрасывая повторяющиеся tool outputs.
- Observation masking: JetBrains Junie скрывает старые результаты инструментов, оставляя сами tool calls видимыми.
- Just-in-time retrieval: хранение лёгких идентификаторов и динамическая загрузка данных. Claude Code использует grep, glob, head и tail вместо загрузки целых файлов.
- Sub-agent delegation: каждый subagent исследует подробно, но возвращает только 1 000–2 000 токенов плотного резюме.
Гайд Anthropic по context engineering формулирует цель так: найти минимальный набор высокосигнальных токенов, который максимизирует вероятность нужного результата.
5. Конструирование промпта
Этот слой собирает то, что модель фактически видит на каждом шаге. Структура иерархическая: system prompt, определения инструментов, файлы памяти, история диалога и текущее сообщение пользователя.
OpenAI Codex использует строгий стек приоритетов: server-controlled system message с высшим приоритетом, definitions инструментов, developer instructions, user instructions — включая каскадные AGENTS.md с лимитом 32 KiB — и затем историю диалога.
6. Парсинг выхода
Современные harness полагаются на native tool calling: модель возвращает структурированные объекты tool_calls, а не свободный текст, который нужно парсить. Harness проверяет: есть ли вызовы инструментов? Если да — выполнить и продолжить цикл. Если нет — это финальный ответ.
Для структурированных выходов OpenAI и LangChain поддерживают schema-constrained responses через Pydantic models. Старые подходы вроде RetryWithErrorOutputParser, который возвращает модели исходный промпт, неудачный completion и ошибку парсинга, всё ещё полезны в edge cases.
7. Управление состоянием
LangGraph моделирует состояние как typed dictionaries, проходящие через узлы графа, а reducers сливают обновления. Checkpointing происходит на границах super-step, что позволяет продолжать после прерываний и делать time-travel debugging. OpenAI предлагает четыре взаимоисключающие стратегии: application memory, SDK sessions, server-side Conversations API или лёгкое связывание через previous_response_id. Claude Code идёт другим путём: git commits как checkpoints и progress files как структурированные scratchpads.
8. Обработка ошибок
Вот почему это важно: процесс из 10 шагов с 99% успешностью на каждом шаге всё равно имеет только около 90,4% end-to-end success. Ошибки быстро накапливаются.
LangGraph различает четыре типа ошибок: transient — retry with backoff; LLM-recoverable — вернуть ошибку как ToolMessage, чтобы модель адаптировалась; user-fixable — interrupt для человеческого ввода; unexpected — поднять наверх для debugging. Anthropic ловит сбои внутри tool handlers и возвращает их как error results, чтобы цикл продолжал работать. Production-harness Stripe ограничивает retry двумя попытками.
9. Guardrails и безопасность
OpenAI SDK реализует три уровня: input guardrails — запускаются на первом агенте; output guardrails — на финальном выходе; tool guardrails — на каждом вызове инструмента. Механизм tripwire немедленно останавливает агента при срабатывании.
Anthropic архитектурно отделяет enforcement разрешений от reasoning модели. Модель решает, что попытаться сделать; система инструментов решает, что разрешено. Claude Code независимо ограничивает около 40 дискретных возможностей инструментов в три этапа: установление доверия при загрузке проекта, permission check перед каждым tool call и явное подтверждение пользователя для рискованных операций.
10. Циклы проверки
Именно это отличает игрушечные демо от production agents. Anthropic рекомендует три подхода: rules-based feedback — тесты, линтеры, type checkers; visual feedback — screenshots через Playwright для UI-задач; LLM-as-judge — отдельный subagent оценивает результат.
Борис Черный, создатель Claude Code, отмечал: если дать модели способ проверять свою работу, качество повышается в 2–3 раза.
11. Оркестрация subagent
Claude Code поддерживает три модели исполнения: Fork — byte-identical copy родительского контекста; Teammate — отдельная terminal pane с file-based mailbox communication; Worktree — собственный git worktree и изолированная branch на агента. OpenAI SDK поддерживает agents-as-tools, где специалист решает ограниченную подзадачу, и handoffs, где специалист полностью принимает управление. LangGraph реализует subagents как вложенные state graphs.
Цикл в движении: пошаговый разбор
Теперь, когда компоненты понятны, посмотрим, как они работают вместе в одном цикле.
Шаг 1 — сборка промпта. Harness строит полный input: system prompt + tool schemas + memory files + conversation history + текущий user message. Важный контекст размещается в начале и конце промпта — с учётом эффекта «Lost in the Middle».
Шаг 2 — LLM inference. Собранный промпт отправляется в model API. Модель генерирует tokens: текст, запросы вызова инструментов или и то и другое.
Шаг 3 — классификация выхода. Если модель дала текст без tool calls, цикл заканчивается. Если запросила tools, переходим к исполнению. Если запросила handoff, обновляем текущего агента и перезапускаем.
Шаг 4 — исполнение tools. Для каждого tool call harness валидирует аргументы, проверяет permissions, исполняет в sandboxed environment и захватывает результаты. Read-only операции можно запускать параллельно; mutating operations выполняются последовательно.
Шаг 5 — упаковка результата. Tool results форматируются как сообщения, понятные LLM. Ошибки ловятся и возвращаются как error results, чтобы модель могла самокорректироваться.
Шаг 6 — обновление контекста. Результаты добавляются в историю диалога. Если контекст приближается к лимиту, harness запускает compaction.
Шаг 7 — loop. Возврат к шагу 1. Повторять до завершения.
Условия завершения многослойные: модель выдаёт ответ без tool calls, превышен лимит ходов, исчерпан token budget, сработал guardrail tripwire, пользователь прервал выполнение или вернулся safety refusal. Простой вопрос может занять 1–2 хода. Сложная refactoring-задача может связать десятки tool calls через множество ходов.
Для долгих задач, проходящих через несколько контекстных окон, Anthropic разработала двухфазный паттерн «Ralph Loop»: Initializer Agent настраивает окружение — init script, progress file, feature list, initial git commit; затем Coding Agent в каждой последующей сессии читает git logs и progress files, чтобы сориентироваться, выбирает самую приоритетную незавершённую feature, работает над ней, делает commit и пишет summaries. Файловая система обеспечивает continuity между контекстными окнами.
Как реальные фреймворки реализуют этот паттерн
Anthropic Claude Agent SDK exposes harness через единственную функцию query(), которая создаёт agentic loop и возвращает async iterator со streaming messages. Runtime — «dumb loop». Весь интеллект находится в модели. Claude Code использует цикл Gather-Act-Verify: собрать контекст — search files, read code; выполнить действие — edit files, run commands; проверить результат — run tests, check output; повторить.
OpenAI Agents SDK реализует harness через класс Runner в трёх режимах: async, sync и streamed. SDK «code-first»: workflow logic выражается на нативном Python, а не через graph DSL. Codex harness расширяет это трёхслойной архитектурой: Codex Core — agent code + runtime; App Server — bidirectional JSON-RPC API; client surfaces — CLI, VS Code и web app. Все surfaces используют один harness, поэтому «Codex models feel better on Codex surfaces than a generic chat window».
LangGraph моделирует harness как явный state graph. Два узла — llm_call и tool_node — соединены conditional edge: если есть tool calls, route to tool_node; если нет, route to END. LangGraph вырос из LangChain AgentExecutor, который был deprecated в v0.2, потому что его было сложно расширять и он плохо поддерживал multi-agent flows. LangChain Deep Agents явно использует термин «agent harness»: built-in tools, planning через write_todos, file systems для context management, subagent spawning и persistent memory.
CrewAI реализует role-based multi-agent architecture: Agent — harness вокруг LLM, заданный role, goal, backstory и tools; Task — единица работы; Crew — коллекция агентов. Слой CrewAI Flows добавляет «deterministic backbone with intelligence where it matters», управляя routing и validation, пока Crews отвечают за autonomous collaboration.
AutoGen, эволюционирующий в Microsoft Agent Framework, первым популяризировал conversation-driven orchestration. Его трёхслойная архитектура — Core, AgentChat, Extensions — поддерживает пять patterns: sequential, concurrent fan-out/fan-in, group chat, handoff и magentic, где manager agent ведёт dynamic task ledger и координирует specialists.
Метафора scaffolding
Метафора строительных лесов не декоративна. Она точна. В строительстве scaffolding — это временная инфраструктура, которая позволяет рабочим построить структуру, до которой иначе не добраться. Она не строит здание сама. Но без неё рабочие не reach upper floors.
Ключевой инсайт: scaffolding убирают, когда здание готово. По мере улучшения моделей сложность harness должна уменьшаться. Manus перестраивали пять раз за шесть месяцев, и каждый rewrite убирал complexity. Сложные tool definitions превращались в general shell execution. «Management agents» превращались в simple structured handoffs.
Это указывает на принцип co-evolution: модели теперь post-train вместе с конкретными harness. Claude Code model научилась использовать именно тот harness, с которым её тренировали. Изменение implementation инструментов может ухудшить performance из-за этой tight coupling.
«Future-proofing test» для harness design: если performance растёт с более сильными моделями без добавления сложности harness — дизайн здоровый.
Семь решений, которые определяют каждый harness
Каждый архитектор harness сталкивается с семью choices:
- Single-agent vs multi-agent. Anthropic и OpenAI советуют: сначала максимально прокачайте single agent. Multi-agent systems добавляют overhead — дополнительные LLM calls для routing, потерю контекста при handoffs. Разделять стоит только когда tool overload превышает примерно 10 пересекающихся инструментов или когда есть явно разные task domains.
- ReAct vs plan-and-execute. ReAct чередует reasoning и action на каждом шаге: гибко, но дороже на каждом шаге. Plan-and-execute отделяет planning от execution. LLMCompiler сообщает о 3,6x ускорении по сравнению с последовательным ReAct.
- Стратегия управления контекстным окном. Пять production-подходов: time-based clearing, conversation summarization, observation masking, structured note-taking и sub-agent delegation. Исследование ACON показало сокращение токенов на 26–54% при сохранении 95%+ accuracy за счёт приоритизации reasoning traces вместо сырых tool outputs.
- Дизайн verification loop. Computational verification — tests, linters — даёт deterministic ground truth. Inferential verification — LLM-as-judge — ловит semantic issues, но добавляет latency. Команда Martin Fowler в Thoughtworks описывает это как guides — feedforward, steer before action — и sensors — feedback, observe after action.
- Архитектура permissions и safety. Permissive — быстро, но рискованно, auto-approve большинства действий. Restrictive — безопасно, но медленно, требует approval на каждый action. Выбор зависит от deployment context.
- Стратегия tool scoping. Больше tools часто означает хуже performance. Vercel убрала 80% инструментов из v0 и получила лучший результат. Claude Code достигает 95% сокращения контекста через lazy loading. Принцип: expose минимальный tool set, нужный для текущего шага.
- Толщина harness. Сколько логики живёт в harness, а сколько оставлено модели. Anthropic ставит на thin harnesses и улучшение моделей. Graph-based frameworks ставят на explicit control. Anthropic регулярно удаляет planning steps из Claude Code harness по мере того, как новые версии модели internalize эту способность.
Harness — это продукт
Два продукта на одинаковых моделях могут показывать радикально разную performance только из-за harness design. Данные TerminalBench ясны: изменение одного лишь harness подвинуло агентов более чем на 20 позиций в рейтинге.
Harness — это не решённая проблема и не commodity layer. Именно здесь находится сложная инженерия: управление контекстом как scarce resource, проектирование verification loops, которые ловят ошибки до того, как они накапливаются, построение систем памяти, дающих continuity без hallucination, и архитектурные ставки на то, сколько scaffolding строить, а сколько оставлять модели.
Поле движется к более thin harnesses по мере улучшения моделей. Но сам harness никуда не исчезнет. Даже самой способной модели нужно что-то, что управляет её context window, исполняет tool calls, сохраняет state и проверяет work.
В следующий раз, когда ваш агент провалится, не вините модель. Посмотрите на harness.
На этом всё.
Если вам понравилось читать:
Найдите меня → @akshay_pachaar ✔️
Каждый день я делюсь tutorials и insights по AI, Machine Learning и vibe coding best practices.