LLM Harnesses: Почему обёртка важнее модели
На успех агента влияют не только модели, но и LLM-harness. Оркестрация, инструменты, контекст и проверка.
Harness — это весь код, конфигурация и логика выполнения, которые не являются самой моделью: цикл оркестрации, инструменты, память, управление контекстом, состояние, обработка ошибок, защитные ограничения и проверочные механизмы, которые в совокупности определяют, справится ли агент со своей задачей или нет. Если вы когда-либо выпускали LLM-функциональность с помощью SDK от OpenAI или Anthropic и наблюдали, как она зацикливается, галлюцинирует вызовы инструментов или забывает, что пользователь сказал три реплики назад, — вы уже столкнулись с ограничениями тонкого harness’а. И в большинстве случаев проблема была не в модели.
В этой статье вы найдёте точную ментальную модель harness’а, доказательства того, что именно он определяет вариативность результатов в большей степени, чем выбор модели, работающий JS/TS-harness, который можно прочитать от начала до конца, а также четыре решения, которые frontend-команда реально контролирует при выпуске встроенной AI-функциональности.
Ключевые выводы
- Harness — это весь код, конфигурация и логика выполнения, которые не являются самой моделью. Вивек Триведи из LangChain формулирует это так: «если ты не модель, ты — harness».
- Команда v0 из Vercel удалила 80% инструментов своего агента и увидела, как успешность выполнения задач выросла с 80% до 100%, среднее потребление токенов снизилось на 37%, а время обработки одного из худших запросов сократилось с 724 до 141 секунды — без каких-либо изменений в модели.
- В таблице лидеров Princeton HAL CORE-Bench Hard Claude Opus 4.5 набирает 42,22% с CORE-Agent и 77,78% с Claude Code — разрыв в 35,56 процентных пункта на одной и той же модели, обусловленный исключительно scaffold’ом.
- Дискуссия «harness против модели» не закрыта: SWE-Atlas от Scale AI показывает, что эффект scaffold’а варьируется в зависимости от модели, тогда как METR обнаружила, что Claude Code и Codex статистически значимо не превосходят её собственные стандартные scaffold’ы в оценке временного горизонта.
- Каждый harness должен содержать хотя бы одну детерминированную проверку — тест, валидатор схемы, регулярное выражение — прежде чем возвращать результат пользователю.
Что такое agent harness?
Agent harness — это полная программная система, обёртывающая вызов LLM: цикл оркестрации, определяющий, когда обращаться к модели; инструменты, которые модель может вызывать; память и контекст, которые она видит; состояние, переносимое между репликами; а также защитные ограничения и проверочные механизмы, фильтрующие её вывод. Каноническая формулировка принадлежит Вивеку Триведи из LangChain: «если ты не модель, ты — harness». Модель генерирует токены; harness — это всё то, что превращает эти токены в надёжную функциональность.
Наиболее ясная ментальная модель для понимания этих отношений предложена в эссе Берена Миллиджа 2023 года, где LLM-системы с scaffold’ом рассматриваются как компьютеры на естественном языке: LLM соответствует процессору, промпт и контекстное окно — оперативной памяти (быстрой, но ограниченной), а внешняя память вроде векторной базы данных — дисковому хранилищу. Инструменты выступают в роли драйверов устройств, взаимодействующих с внешним миром, а harness — это операционная система, координирующая всё это. Процессор без ОС не вычисляет ничего полезного. Модель необходима, но недостаточна.
Терминология в этой области весьма разнообразна, поэтому зафиксируем её раз и навсегда. Модель — это LLM: веса и API. Harness (иногда называемый scaffold) — это окружающий код. Агент — это результирующее поведение: целенаправленная, использующая инструменты, самокорректирующаяся сущность, с которой взаимодействует пользователь. Курс Hugging Face по агентам определяет агента как систему, использующую AI-модель для взаимодействия с окружающей средой и достижения цели, заданной пользователем. Когда кто-то говорит «я создал агента», он создал harness и направил его на модель. В собственном анонсе Claude Agent SDK компания Anthropic описывает Claude Code SDK как «agent harness, на котором работает Claude Code».
Почему обёртка важнее модели?
Discover how at OpenReplay.com.
Обёртка важнее модели потому, что одна и та же модель за разными harness’ами даёт кардинально разные результаты — и эти различия значительны, воспроизводимы и зафиксированы на публичных бенчмарках. Наиболее весомый аргумент: команда v0 из Vercel удалила 80% инструментов своего агента и увидела, как успешность выполнения задач выросла с 80% до 100%, среднее потребление токенов снизилось на 37%, а время обработки одного из худших запросов сократилось с 724 до 141 секунды — без каких-либо изменений в модели. Исправление было полностью в harness’е: меньше инструментов с более чётко очерченной областью применения.
Ещё два результата указывают в том же направлении. LangChain сообщила о переходе своего агента для написания кода с позиции ниже топ-30 в топ-5 на Terminal-Bench 2.0 исключительно за счёт изменения harness’а вокруг неизменной модели, согласно собственному описанию. А в таблице лидеров Princeton HAL CORE-Bench Hard Claude Opus 4.5 набирает 42,22% со scaffold’ом CORE-Agent и 77,78% с Claude Code — разрыв в 35,56 процентных пункта на одной и той же модели; при этом в таблице лидеров также фигурирует результат 95,5% при ручной валидации запуска Claude Code.
| Исследование | Модель изменена? | Harness изменён? | До | После |
|---|---|---|---|---|
| Vercel v0 | Нет | Да (−80% инструментов) | 80% успех | 100% успех, −37% токенов |
| LangChain / Terminal-Bench 2.0 | Нет | Да | Ниже топ-30 | Топ-5 |
| Princeton CORE-Bench Hard | Нет (Opus 4.5) | Да (scaffold) | 42,22% | 77,78% |
Дискуссия не закрыта, и чрезмерное упрощение здесь вредит репутации. SWE-Atlas от Scale AI сравнивает фирменные scaffold’ы агентов для написания кода с минималистичным mini-SWE-agent и показывает, что эффект scaffold’а варьируется в зависимости от модели, причём нативные scaffold’ы дают заметное улучшение по сравнению с минимальным базовым вариантом. Тем временем METR обнаружила, что Claude Code и Codex статистически значимо не превосходят её собственные стандартные scaffold’ы в оценке временного горизонта. Оба эффекта реальны; какой из них доминирует, зависит от режима задачи. Честная интерпретация, как формулирует MongoDB, такова: «LLM — наименьшая часть» — но выигрыш от harness’а не безграничен, и сильная модель на слабой задаче всё равно ограничивает то, что может компенсировать scaffold.
Из каких компонентов состоит LLM harness?
Производственный harness распадается на восемь компонентов, каждый из которых является точкой возможного отказа тонкой обёртки: цикл оркестрации, инструменты, память, управление контекстом, конструирование промптов, состояние, обработка ошибок и защитные ограничения с верификационными циклами.
Цикл оркестрации. Цикл реализует паттерн «Мысль–Действие–Наблюдение» (паттерн ReAct): вызвать модель, проверить, запросила ли она инструмент, запустить инструмент, передать результат обратно, повторять до тех пор, пока модель не ответит или не сработает защитный механизм. Как формулирует Викаш Рунгта в своём анализе архитектуры Claude Code, среда выполнения — это «тупой цикл», где весь интеллект живёт в модели, а harness лишь управляет репликами. Механически это цикл while с ограничением на количество итераций.
Инструменты. Инструменты — это руки агента: функции, предоставляемые модели в виде схем (имя, описание, типы параметров). Слой инструментов отвечает за регистрацию, валидацию аргументов, выполнение и форматирование результатов в наблюдения, читаемые моделью. Инструмент search_docs в виджете помощи — это инструмент; get_order_status — тоже.
Память. Краткосрочная память — это текущий разговор; долгосрочная память сохраняется между сессиями. В чат-виджете краткосрочная память — это массив сообщений, который вы воспроизводите на каждом ходу; долгосрочная память может представлять собой сводку по конкретному пользователю, загружаемую в начале сессии.
Управление контекстом. Дефицитный ресурс — контекстное окно, а режим отказа — деградация контекста: качество снижается, когда окно заполняется малоинформативными токенами. Согласно руководству Anthropic по контекстной инженерии, цель — минимальный набор высокоинформативных токенов. Стратегии: компакция (суммаризация старых реплик) и извлечение по требованию (получение данных по запросу, а не предварительная загрузка).
Конструирование промптов. Harness собирает входные данные иерархически: системный промпт, определения инструментов, память, история разговора, текущее сообщение. Порядок имеет значение; важный контекст должен располагаться в начале и конце окна.
Состояние. Состояние — это то, что сохраняется между репликами и сбоями: позиция агента в многошаговой задаче, промежуточные результаты, контрольные точки. Чат-виджет, «забывающий» ограничение, которое пользователь задал ранее, имеет проблему состояния, а не проблему модели.
Обработка ошибок. Задача из 10 шагов при 99%-ной успешности каждого шага имеет лишь ~90% сквозной успешности, поскольку ошибки накапливаются. Ключевой паттерн: возвращать ошибку инструмента модели в виде наблюдения, чтобы она могла самокорректироваться, а не выбрасывать исключение и прерывать выполнение.
Защитные ограничения и верификационные циклы. Защитные ограничения определяют, что агенту разрешено делать; верификационные циклы проверяют то, что он произвёл. В описании harness-инженерии от Мартина Фаулера и Биргитты Бёклер верификация разделена на guides (упреждающие — направляют до совершения действия) и sensors (обратная связь — наблюдают и инициируют самокоррекцию), а также на вычислительные (детерминированные: тесты, линтеры) и инференциальные (LLM в роли судьи) механизмы контроля.
Как создать agent harness на JavaScript?
Минимальный, но полноценный harness — это ReAct-цикл с ограничением на количество итераций, одним чётко ограниченным инструментом, обработчиком ошибок-как-наблюдений и одной детерминированной проверкой. Пример ниже использует Anthropic SDK и Zod для валидации схемы. Проверка верификации — это именно та часть, которую большинство тонких обёрток пропускает: без неё агент не имеет возможности узнать, что он ошибается.
import Anthropic from "@anthropic-ai/sdk";
import { z } from "zod";
const client = new Anthropic();
// Один инструмент с чётко ограниченной областью применения. Меньше инструментов = меньше ложных вызовов.
const tools: Anthropic.Tool[] = [
{
name: "get_order_status",
description: "Look up the status of an order by its numeric ID.",
input_schema: {
type: "object",
properties: { orderId: { type: "number" } },
required: ["orderId"],
},
},
];
// Детерминированная верификация: входные данные инструмента от модели должны соответствовать этой схеме.
const OrderArgs = z.object({ orderId: z.number().int().positive() });
async function runOrder(orderId: number) {
// Заглушка вместо реального запроса.
return { orderId, status: "shipped", eta: "2026-03-04" };
}
export async function harness(userMessage: string) {
const messages: Anthropic.MessageParam[] = [
{ role: "user", content: userMessage },
];
// Ограничение на количество итераций: важнейший защитный механизм против зацикливания.
for (let turn = 0; turn < 6; turn++) {
const res = await client.messages.create({
model: "claude-sonnet-4-6",
max_tokens: 1024,
system: "You are an order-status assistant. Use tools when asked about orders.",
tools,
messages,
});
const toolUse = res.content.find(
(b): b is Anthropic.ToolUseBlock => b.type === "tool_use"
);
if (!toolUse) return res.content; // Нет вызова инструмента → модель ответила.
messages.push({ role: "assistant", content: res.content });
let observation: string;
const parsed = OrderArgs.safeParse(toolUse.input);
if (!parsed.success) {
// Верификация не прошла: возвращаем ошибку КАК наблюдение, не выбрасываем исключение.
observation = `Invalid arguments: ${parsed.error.message}`;
} else {
try {
observation = JSON.stringify(await runOrder(parsed.data.orderId));
} catch (e) {
observation = `Tool error: ${(e as Error).message}`; // тоже наблюдение
}
}
messages.push({
role: "user",
content: [{ type: "tool_result", tool_use_id: toolUse.id, content: observation }],
});
}
return [{ type: "text", text: "Could not complete the request." }];
}
Четыре проектных решения в этих ~50 строках обеспечивают большую часть надёжности. Цикл for с ограничением на количество итераций — это и цикл оркестрации, и защита от зацикливания. Единственный инструмент сохраняет схему инструментов компактной. safeParse от Zod — это детерминированная проверка верификации, перехватывающая галлюцинированные аргументы до того, как они достигнут вашего бэкенда. И ошибки валидации, и ошибки времени выполнения возвращаются как наблюдения, а не выбрасываются как исключения — благодаря чему модель может скорректировать себя, а не прерывать выполнение. Механика работы с инструментами в Anthropic задокументирована в руководстве по использованию инструментов; эквивалентный цикл с OpenAI SDK использует tool_calls и сообщения с role: "tool".
Почему frontend-разработчики контролируют больше harness’а, чем думают?
Frontend-разработчики уже владеют harness’ом всякий раз, когда выпускают AI-чат-виджет, встроенного поискового ассистента или интерфейс copilot’а — просто это более тонкие harness’ы, чем агентные. Большинство проблем, на которые жалуются пользователи (зацикливание, галлюцинированные вызовы инструментов, потеря контекста, игнорирование ограничений), — это сбои harness’а, а не модели. Когда frontend-команда выпускает AI-функциональность, выбор модели — лишь одно решение из многих, а решения по harness’у — область применения инструментов, переносимый контекст, что верифицировать — как правило, получают меньше проектного внимания, чем заслуживают.
Соответствие прямое. Пользователь, наблюдающий, как ассистент «регенерирует» один и тот же неверный ответ, видит цикл оркестрации без верификации. Пользователь, чьё заявленное ограничение исчезает через две реплики, сталкивается с пробелом в управлении состоянием и контекстом. Вызов инструмента с мусорным аргументом, возвращающий непонятный ответ, — это отсутствующая проверка схемы, именно тот шаг safeParse из примера выше. Ни одна из этих проблем не решается заменой модели. Они решаются ужесточением обёртки, которой вы уже владеете.
Насколько толстым должен быть мой harness? Четыре решения, которые контролируют frontend-команды
Frontend-команда, выпускающая встроенную AI-функциональность, реально контролирует четыре решения по harness’у: область применения инструментов, стратегию контекста, верификационные циклы и толщину harness’а. Более широкий общеотраслевой список — одиночный или мультиагентный подход, ReAct против plan-and-execute, разрешения, надёжное выполнение, управление парком агентов — относится к инфраструктурным уровням, которых большинство чат-виджетов никогда не достигает.
-
Область применения инструментов — начинайте с менее чем 10 инструментов и расширяйте неохотно. Предоставление агенту большего числа инструментов, чем необходимо, надёжно снижает производительность, поскольку каждая дополнительная схема инструмента потребляет контекст и повышает вероятность ложного вызова. Результат Vercel — ключевое доказательство: удаление 80% инструментов улучшило всё.
-
Стратегия контекста — компакция и извлечение по требованию вместо заполнения окна. Не загружайте всю базу знаний в промпт заранее. Суммаризируйте старые реплики при приближении к лимиту окна и получайте документы по запросу. Руководство Anthropic по контекстной инженерии формулирует цель как минимальный набор высокоинформативных токенов.
-
Верификационные циклы — каждый harness должен содержать хотя бы одну детерминированную проверку перед возвратом результата пользователю. Валидатор схемы, регулярное выражение, юнит-тест — что-то, что harness может запустить независимо от суждения самой модели. Без этого агент не имеет возможности узнать, что он ошибается. Согласно разделению на вычислительные и инференциальные механизмы по Бёклер, начинайте с дешёвой вычислительной проверки; добавляйте LLM в роли судьи только тогда, когда требуется оценка семантической корректности.
-
Толщина harness’а — начинайте тонко, добавляйте структуру только при повторении паттерна сбоя. Не стройте оркестрацию заранее для сбоев, которых вы ещё не видели. Добавляйте повтор, защитное ограничение или шаг верификации, когда конкретный сбой проявляется более одного раза.
Просмотр записей сессий AI-функциональности в продакшне — один из самых быстрых способов оценить качество harness’а по поведению пользователей, поскольку диагностические признаки видны без какой-либо телеметрии на уровне модели. Повторное перефразирование одного и того же запроса сигнализирует о потере контекста или верификационном цикле, который никогда не срабатывает. Отказ от многошаговой задачи в середине разговора нередко объясняется проглоченной ошибкой инструмента, всплывающей в виде расплывчатого ответа. Поведение «скопировать и отредактировать» сигнализирует о пробеле в верификации: вывод прошёл проверки harness’а, но не удовлетворил пользователя. Повторные нажатия «Regenerate» или «Try again» — это признак зацикленного harness’а, неспособного обнаружить собственное состояние отказа.
Куда движется проектирование harness’ов?
Модели теперь дообучаются с учётом harness’а в петле обратной связи — как отмечает LangChain в своём обсуждении архитектуры agent harness, такие продукты, как Claude Code и Codex, объединяют обучение модели и проектирование harness’а в едином цикле — а это означает, что harness больше не является заменяемой обёрткой, а становится совместно эволюционирующей частью продуктовой поверхности. Для разработчиков это означает, что harness превращается в часть продукта, который вы проектируете, а не в универсальный адаптер, который можно перенести с одной модели на другую без изменений.
Это даёт вам чёткий тест на перспективность, основанный на метафоре строительных лесов: если ваш дизайн масштабируется без проблем с более сильной моделью — тот же harness, лучшие результаты — он надёжен. Если для компенсации по мере улучшения модели требуется больше scaffold’а, harness маскирует проблему модели или задачи, которую следует решать в другом месте. Строительные леса, как и настоящие, предназначены для того, чтобы быть убранными, когда конструкция встанет на собственные ноги.
В следующий раз, когда ваша AI-функциональность зациклится, забудет контекст или вернёт что-то уверенно неверное, проведите аудит harness’а прежде, чем аудировать модель. Начните с четырёх решений выше — область применения инструментов, стратегия контекста, одна детерминированная проверка и толщина — и добавляйте минимальное количество структуры, достаточное для того, чтобы сбой перестал повторяться.
Часто задаваемые вопросы
В чём разница между harness и scaffold?
На практике эти термины используются взаимозаменяемо; оба обозначают весь код, конфигурацию и логику выполнения, окружающие модель, которые не являются самой моделью. «Scaffold» чаще встречается в литературе по бенчмаркам — например, в сравнении CORE-Agent и scaffold'а Claude Code от Princeton, — тогда как «harness» предпочтителен в производственных и SDK-контекстах. Вивек Триведи из LangChain устраняет это различие правилом: если ты не модель, ты — harness.
Следует ли возвращать ошибку инструмента модели или выбрасывать исключение в harness'е?
Возвращайте ошибку модели в виде наблюдения, а не выбрасывайте исключение. Выброс исключения прерывает выполнение; возврат ошибки в виде результата инструмента позволяет модели увидеть, что пошло не так, и самокорректироваться на следующем ходу. Это важно, поскольку ошибки накапливаются в многошаговых задачах: задача из 10 шагов при 99%-ной успешности каждого шага имеет лишь около 90% сквозной успешности. Как ошибки валидации схемы, так и исключения времени выполнения должны перехватываться и передаваться обратно в виде наблюдений — никогда как необработанные исключения.
Улучшает ли добавление большего числа инструментов производительность агента?
Нет, добавление большего числа инструментов надёжно снижает производительность после определённого порога. Каждая схема инструмента потребляет токены контекстного окна и увеличивает вероятность ложного или неверного вызова инструмента. Команда v0 из Vercel удалила 80% инструментов своего агента и увидела, как успешность выполнения задач выросла с 80% до 100%, а среднее потребление токенов снизилось на 37% — на той же модели. Практическое правило: начинайте с менее чем 10 инструментов и расширяйте только при обнаружении реального пробела.
Могу ли я менять модели в одном и том же harness'е без изменений?
Всё в меньшей степени. Как отмечает LangChain в своём обсуждении архитектуры agent harness, такие продукты, как Claude Code и Codex, объединяют обучение модели и проектирование harness'а в едином цикле. Это делает harness совместно эволюционирующей частью продуктовой поверхности, а не универсальным адаптером. Полезный тест на перспективность: масштабируется ли ваш дизайн без проблем с более сильной моделью на том же harness'е; если для компенсации по мере улучшения модели требуется больше scaffold'а, harness маскирует более глубокую проблему.