- BrainTools - https://www.braintools.ru -

Как кодинг-агенты используют инструменты, память и контекст репозитория, чтобы писать код лучше

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

Сильного хардкора и больших откровений в ней нет, но это отличный материал для старта изучения архитектуры кодинг-ассистентов и лучшего понимания, как оно работает внутри.


В этой статье я хочу разобрать общую архитектуру кодинг-агентов и агентных харнессов: что это такое, как они работают и как разные части складываются в единую систему на практике. Мои читатели часто спрашивают об агентах — решил написать справочный материал, на который смогу ссылаться.

Агенты стали важной темой, потому что большая часть прогресса в практических LLM-системах связана не только с улучшением самих моделей, а тем, как мы их используем. Во многих реальных приложениях система вокруг LLM — инструменты, управление контекстом, память [1] — играет не меньшую роль, чем сама модель. Этим и объясняется, почему такие системы, как Claude Code или Codex, в консоли ощущаются значительно мощнее, чем те же модели в обычном чат-интерфейсе.

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

Claude Code, Codex CLI и другие кодинг-агенты

Скорее всего, вы знакомы с Claude Code или Codex CLI. Если коротко: это агентные инструменты для написания кода, которые оборачивают вокруг LLM в прикладной слой, называемый агентный харнесс (agentic harness) — чтобы работа с кодом была удобнее и эффективнее.

Рисунок 1: Claude Code CLI, Codex CLI и мой Mini Coding Agent.

Рисунок 1: Claude Code CLI, Codex CLI и мой Mini Coding Agent.

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

Это важно различать. Когда речь заходит о способностях LLM к написанию кода, люди нередко смешивают воедино и саму модель, и ее поведение [2] при рассуждениях, и готовый агентный продукт. Прежде чем углубляться в детали кодинг-агентов, кратко поясню разницу между более широкими понятиями: LLM, рассуждающими моделями (reasoning-моделями) и агентами.

О связи между LLM, reasoning-моделями и агентами

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

Агент — это слой поверх модели, а по сути — управляющий цикл вокруг нее. Получив цель, агентный слой (или харнесс) решает: что проверить следующим, какие инструменты вызвать, как обновить состояние и когда остановиться.

Грубо говоря, связь такова: LLM — это двигатель, reasoning-модель — прокачанный двигатель (мощнее, но дороже в эксплуатации), а агентный харнесс помогает нам этот двигатель использовать. Аналогия неточная, потому что обычные и reasoning-LLM можно применять и напрямую (в чат-интерфейсе или python-сессии), но суть идеи она передает.

Рисунок 2: Связь между обычной LLM, reasoning-LLM (или reasoning-моделью) и LLM, обернутой в агентный харнесс

Рисунок 2: Связь между обычной LLM, reasoning-LLM (или reasoning-моделью) и LLM, обернутой в агентный харнесс

Иными словами, агент — это система, которая многократно вызывает модель внутри некоторой среды.

Итого, коротко:

  • LLM: сырая модель

  • Reasoning-модель: LLM, оптимизированная для вывода промежуточных цепочек рассуждений и более частой самопроверки

  • Агент: цикл, использующий модель вместе с инструментами, памятью и обратной связью от среды

  • Агентный харнесс: программный каркас вокруг агента, который управляет контекстом, инструментами, промптами, состоянием и потоком управления

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

В этом же контексте встречаются еще два популярных термина: агентный харнесс и (агентный) кодинг-харнесс. Кодинг-харнесс — это программный каркас вокруг модели, помогающий ей эффективно писать и редактировать код. Агентный харнесс — понятие пошире, не привязанное к коду (например, OpenClaw). Codex и Claude Code можно считать кодинг-харнессами.

В общем, лучшая LLM дает лучшую основу для reasoning-модели (которая требует дополнительного обучения [3]), а харнесс позволяет выжать из этой reasoning-модели максимум.

Конечно, LLM и reasoning-модели способны решать задачи по написанию кода и без харнесса, но кодинг — это лишь отчасти про предсказание следующего токена. Значительная часть работы разработки — это навигация по репозиторию, поиск по коду, просмотр определений функций, применение диффов, запуск тестов, изучение ошибок и удержание всего нужного в контексте. (все разработчики знают, что это серьезная умственная работа — и именно поэтому нас так раздражают отвлечения во время кодинга :)).

Рисунок 3. Кодинг-харнесс объединяет три слоя: семейство моделей, агентный цикл и компоненты среды выполнения. Модель обеспечивает «двигатель», агентный цикл управляет итеративным решением задач, а компоненты среды — всю инфраструктуру. Внутри цикла: «observe» собирает информацию из среды, «inspect» анализирует ее, «choose» выбирает следующий шаг, «act» его выполняет

Рисунок 3. Кодинг-харнесс объединяет три слоя: семейство моделей, агентный цикл и компоненты среды выполнения. Модель обеспечивает «двигатель», агентный цикл управляет итеративным решением задач, а компоненты среды — всю инфраструктуру. Внутри цикла: «observe» собирает информацию из среды, «inspect» анализирует ее, «choose» выбирает следующий шаг, «act» его выполняет

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

Кодинг-харнесс

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

Сегодня именно этот слой во многом определяет пользовательский опыт [4] — значительно больше, чем прямое обращение к модели или веб-чат-интерфейс (который ближе к «чату с загруженными файлами»).

Поскольку базовые версии современных LLM имеют очень схожие возможности (например, базовые GPT-5.4, Opus 4.6, GLM-5 и им подобные), харнесс нередко становится тем фактором, который делает одну LLM лучше другой.

Это лишь мое предположение, но я подозреваю: если взять одну из самых мощных современных open-weight LLM — например GLM-5 — и запустить ее в аналогичном харнессе, она, скорее всего, покажет результаты на уровне GPT-5.4 в Codex или Claude Opus 4.6 в Claude Code. Правда, дообучение под конкретный харнесс всё равно полезно. Например, OpenAI исторически поддерживала отдельные варианты GPT-5.3 и GPT-5.3-Codex.

В следующем разделе я хочу подробнее рассмотреть основные компоненты кодинг-харнесса на примере моего Mini Coding Agent [5]:

Рисунок 4: Основные возможности харнесса кодинг-агента / кодинг-харнесса, которые обсудим в следующих разделах

Рисунок 4: Основные возможности харнесса кодинг-агента / кодинг-харнесса, которые обсудим в следующих разделах

Кстати, в этой статье я использую термины «кодинг-агент» и «кодинг-харнесс» как взаимозаменяемые — для простоты. (но строго говоря, агент — это управляемый моделью цикл принятия решений, а харнесс — окружающий программный каркас, предоставляющий контекст, инструменты и среду исполнения)

Рисунок 5: Минималистичный, но полностью рабочий Mini Coding Agent, написанный с нуля на чистом Python

Рисунок 5: Минималистичный, но полностью рабочий Mini Coding Agent, написанный с нуля на чистом Python

Ниже — шесть основных компонентов кодинг-агентов. Конкретные примеры кода можно посмотреть в исходниках моего минималистичного и написанного с нуля на питоне Mini Coding Agent [5]. В коде эти шесть компонентов отмечены комментариями:

```
##############################
#### Шесть компонентнов агента ####
##############################
# 1) Контекст репозитория -> WorkspaceContext
# 2) Prompt Shape And Cache Reuse -> build_prefix, memory_text, prompt
# 3) Structured Tools, Validation, And Permissions -> build_tools, run_tool, validate_tool, approve, parse, path, tool_*
# 4) Context Reduction And Output Management -> clip, history_text
# 5) Transcripts, Memory, And Resumption -> SessionStore, record, note_tool, ask, reset
# 6) Delegation And Bounded Subagents -> tool_delegate
```

1. Живой контекст репозитория

Пожалуй, это самый очевидный компонент — и одновременно один из важнейших.

Когда пользователь говорит «исправь тесты» или «реализуй xyz», модель должна знать: находится ли она внутри Git-репозитория, на какой ветке, есть ли в проекте документы с инструкциями — и так далее.

Все это важно, потому что подобные детали меняются и определяют, какое действие будет правильным. Например, «исправь тесты» — не самодостаточная инструкция. Если агент видит AGENTS.md или README проекта, он может узнать, какую команду запустить для тестов. Зная корневую папку и структуру репозитория, агент смотрит в нужных местах, а не гадает.

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

Рисунок 6: Агентный харнесс сначала строит краткое описание рабочего пространства, которое объединяется с запросом пользователя для дополнительного контекста проекта

Рисунок 6: Агентный харнесс сначала строит краткое описание рабочего пространства, которое объединяется с запросом пользователя для дополнительного контекста проекта

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

2. Структура промпта и повторное использование кэша

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

В кодинг-сессиях многое повторяется: правила для агента остаются теми же, описания инструментов — тоже. И даже сводка рабочего пространства по большей части не меняется. Что действительно меняется — это последний запрос пользователя, недавняя история диалога и, возможно, краткосрочная память.

«Умные» рантаймы не пересобирают все как один гигантский монолитный промпт при каждом обращении — как показано на рисунке ниже.

Рисунок 7: Агентный харнесс строит стабильный префикс промпта, добавляет изменяющееся состояние сессии и подает этот объединенный промпт модели

Рисунок 7: Агентный харнесс строит стабильный префикс промпта, добавляет изменяющееся состояние сессии и подает этот объединенный промпт модели

Главное отличие от раздела 1 в том, что там речь шла о сборе фактов о репозитории. Здесь же нас интересует эффективная упаковка и кэширование этих фактов для повторных вызовов модели.

«Стабильный префикс промпта» означает, что содержащаяся там информация почти не меняется. Как правило, это общие инструкции, описания инструментов и сводка рабочего пространства. Тратить вычисления на пересборку этого блока с нуля при каждом взаимодействии, если ничего существенного не изменилось, не нужно.

Остальные компоненты обновляются чаще — обычно при каждом обращении. Это краткосрочная память, недавняя история диалога и последний запрос пользователя.

Кэширование «стабильного префикса промпта» устроено просто: умный рантайм старается повторно использовать эту часть, не пересобирая ее заново.

3. Доступ к инструментам и их использование

Именно здесь система начинает ощущаться не как чат, а как настоящий агент.

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

Вместо того чтобы позволять модели импровизировать произвольный синтаксис, харнесс обычно предоставляет фиксированный список именованных инструментов — с понятными входами и чёткими ограничениями. (но, конечно, что-то вроде Python-функции subprocess.call может входить в этот список — и тогда агент сможет выполнять широкий набор произвольных shell-команд)

Процесс использования инструментов показан на рисунке ниже.

Рисунок 8: Модель генерирует структурированное действие, харнесс его валидирует, при необходимости запрашивает подтверждение, выполняет и возвращает ограниченный результат обратно в цикл

Рисунок 8: Модель генерирует структурированное действие, харнесс его валидирует, при необходимости запрашивает подтверждение, выполняет и возвращает ограниченный результат обратно в цикл

Для наглядности — пример того, как это выглядит для пользователя в моем Mini Coding Agent. (он выглядит скромнее, чем Claude Code или Codex: это очень минималистичная реализация на чистом Python без внешних зависимостей)

Рисунок 9: Пример запроса на подтверждение вызова инструмента в Mini Coding Agent

Рисунок 9: Пример запроса на подтверждение вызова инструмента в Mini Coding Agent

Модель должна выбрать действие, которое харнесс распознает: список файлов, чтение файла, поиск, выполнение shell-команды, запись файла и многие другие. Аргументы нужно передать в форме, которую харнесс может проверить.

Когда модель просит что-то сделать, рантайм может остановиться и выполнить программные проверки:

– «Это известный инструмент?»

– «Аргументы корректны?»

– «Нужно ли подтверждение пользователя?»

– «Запрашиваемый путь вообще находится внутри рабочего пространства?»

Только после успешного прохождения всех проверок что-либо реально выполняется.

Работа с кодинг-агентами, конечно, несет определённые риски, но проверки харнесса ещё и повышают надежность: модель не выполняет совершенно произвольные команды.

Харнесс не только отклоняет некорректные действия и запрашивает подтверждения — он еще и ограничивает доступ к файлам пределами репозитория, проверяя пути. В каком-то смысле харнесс дает модели меньше свободы — но одновременно и делает систему удобнее.

4. Борьба с раздуванием контекста

Раздувание контекста — не уникальная проблема кодинг-агентов, это вообще общая проблема всех LLM. Да, модели сегодня поддерживают все более длинные контекстные окна (я недавно писал [6] о вариантах внимания [7], которые снижают вычислительные затраты), но длинные контексты все равно дороги и могут вносить дополнительный шум (если там много нерелевантной информации).

Кодинг-агенты еще сильнее подвержены раздуванию контекста, чем обычные LLM в многошаговых диалогах — из-за повторных чтений файлов, объемных выводов инструментов, логов и прочего.

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

Концептуально сжатие контекста в кодинг-агентах можно представить так, как показано на рисунке ниже. По сути, мы смотрим подробнее на шаг clip (шаг 6) из рисунка 8 в предыдущем разделе.

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

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

Минималистичный харнесс использует хотя бы две стратегии сжатия. У процесса сжатия еще есть синоним — компактизация.

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

Вторая стратегия — сокращение или суммаризация истории: преобразование полной истории сессии (подробнее об этом в следующем разделе) в более компактное резюме для последующего промпта.

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

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

В целом, на мой взгляд, это один из недооцененных, «скучных» аспектов хорошего проектирования кодинг-агента. Многое из того, что воспринимается как «качество модели», на деле — качество контекста.

5. Структурированная память сессии

На практике все шесть концепций тесно переплетены, и разные разделы и рисунки освещают их с разных точек зрения [8] или с разным уровнем детализации. В предыдущем разделе мы говорили об использовании истории в момент формирования промпта и о том, как строить компактное представление взаимодействия. Там главный вопрос такой: сколько прошлого нужно возвращать в модель при следующем обращении? Акцент — на сжатии, обрезке, дедупликации и приоритете недавних событий.

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

Итого, кодинг-агент разделяет состояние на (как минимум) два уровня:

  • рабочая память: небольшое, дистиллированное состояние, которое агент явно поддерживает

  • полный транскрипт: охватывает все запросы пользователя, выводы инструментов и ответы LLM

Рисунок 11: Новые события добавляются в полный транскрипт и суммаризируются в рабочую память. Файлы сессии на диске обычно хранятся в формате JSON

Рисунок 11: Новые события добавляются в полный транскрипт и суммаризируются в рабочую память. Файлы сессии на диске обычно хранятся в формате JSON

На рисунке выше показаны два основных файла сессии: полный транскрипт и рабочая память, которые обычно хранятся как JSON-файлы на диске. Как уже говорилось, полный транскрипт хранит всю историю и позволяет возобновить работу после закрытия агента. Рабочая память — это более дистиллированная версия с наиболее важной на данный момент информацией; она несколько похожа на компактный транскрипт.

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

После шага 4 на рисунке выше последний запрос пользователя вместе с ответом LLM и выводом инструмента будет записан как «новое событие» и в полный транскрипт, и в рабочую память — в следующем раунде. Это не показано на рисунке, чтобы не загромождать его.

6. Делегирование и (ограниченные) субагенты

Как только у агента появляются инструменты и состояние, следующая полезная возможность — делегирование.

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

(в моем mini coding agent реализация проще, и дочерний агент всё ещё работает синхронно, но основная идея та же)

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

Поэтому настоящая задача проектирования — не только как запустить (spawn) субагента, но и как его обуздать (bind).

Рисунок 12: Субагент наследует достаточно контекста, чтобы быть полезным, но работает в более жестких границах, чем основной агент

Рисунок 12: Субагент наследует достаточно контекста, чтобы быть полезным, но работает в более жестких границах, чем основной агент

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

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

Как это соотносится с OpenClaw?

OpenClaw — интересный случай для сравнения, но это не совсем та же система.

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

Есть несколько точек пересечения с кодинг-харнессом:

  • он использует файлы промптов и инструкций в рабочем пространстве, такие как AGENTS.md, SOUL.md и TOOLS.md

  • он ведёт JSONL-файлы сессий, включает сжатие транскриптов и управление сессиями

  • он может порождать вспомогательные сессии и субагенты

Но, как уже говорилось, акцент другой. Кодинг-агенты оптимизированы для разработчика, который работает в репозитории и просит помощника просматривать файлы, редактировать код и эффективно использовать локальные инструменты. OpenClaw оптимизирован под запуск множества долгоживущих локальных агентов в чатах, каналах и рабочих пространствах — при этом кодинг — лишь одна из важных задач.

Итог по компонентам

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

Рисунок 13: Шесть основных возможностей кодинг-харнесса, рассмотренных в предыдущих разделах

Рисунок 13: Шесть основных возможностей кодинг-харнесса, рассмотренных в предыдущих разделах

Если вам интересно посмотреть на реализацию в чистом, минималистичном коде на Python — загляните в мой Mini Coding Agent [5].


Спасибо! Я делаю переводы хороших статей, потому что считаю, что уже готовый качественный контент про агентов и LLM должен быть и на русском языке, а автоперевод хоть и решает задачу прочтения, но не справляется так, как мне хотелось бы. Помимо этого я делюсь своими заметками на ту же тему в тг-канальчике Agentic World [9] и пишу свои крафтовые статейки:

Автор: antipov_dmitry

Источник [13]


Сайт-источник BrainTools: https://www.braintools.ru

Путь до страницы источника: https://www.braintools.ru/article/28505

URLs in this post:

[1] память: http://www.braintools.ru/article/4140

[2] поведение: http://www.braintools.ru/article/9372

[3] обучения: http://www.braintools.ru/article/5125

[4] опыт: http://www.braintools.ru/article/6952

[5] Mini Coding Agent: https://github.com/rasbt/mini-coding-agent

[6] недавно писал: https://magazine.sebastianraschka.com/p/visual-attention-variants

[7] внимания: http://www.braintools.ru/article/7595

[8] зрения: http://www.braintools.ru/article/6238

[9] Agentic World: https://t.me/anti_notes

[10] Русский культурный код как оценка генеративных моделей: https://habr.com/ru/articles/1011192/

[11] Разработка после разработчиков. Что оставит AI?: https://habr.com/ru/articles/1006912/

[12] Как я делаю своего голосового AI-ассистента: роботы пишут код и работают, когда я отдыхаю: https://habr.com/ru/articles/994454/

[13] Источник: https://habr.com/ru/articles/1021168/?utm_campaign=1021168&utm_source=habrahabr&utm_medium=rss

www.BrainTools.ru

Rambler's Top100