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

Попросили OpenCode прочитать файл. К третьему шагу запрос вырос до 139 КБ

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

Марина, редакция TokenTool8 минут
Тележка с маленькой задачей проходит через двери и постепенно обрастает тяжёлыми рулонами контекста

Задача занимала одну строку: открыть файл и назвать текст кнопки. Сам файл — три строки. До него OpenCode принёс модели почти 30 КБ инструкций и описаний инструментов.

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

01

Вместо модели — картонный актёр с одной репликой

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

OpenCode 2.0.3

Обычный build-агент и его штатные инструменты.

Два файла

Кнопка из трёх строк и искусственный каталог на 802 строки.

Ноль внешних вызовов

Локальная заглушка вместо платной модели и API-ключа.

Сервер записывал размер JSON-тела, роли сообщений и названия инструментов. Заголовки авторизации не сохранялись. Настоящих ключей в стенде нет вообще.

02

Три строки почти ничего не изменили. Каталог — очень даже

С маленьким Button.tsx основной запрос занимал 29 963 байта. После чтения файла следующий вырос до 30 339 байт. Нормально: сам результат инструмента добавил всего 140 символов.

Затем мы повторили сценарий с искусственным каталогом размером 181 628 байт. Инструмент чтения не стал заталкивать его целиком: вернул первые 225 строк и сообщил, откуда продолжать. Заглушка запросила следующий кусок. Получилась такая тележка:

OpenCode 2.0.3 · локальный стенд

Размер несжатого JSON-тела перед отправкой модели

Служебный запрос
тело2 537 Б
инструменты0

Файл ещё не открывался

Первый шаг агента
тело29 964 Б
инструменты12

В запросе правила и схемы инструментов

После первого чтения
тело84 423 Б
инструменты12

Добавлены первые 225 строк файла

После второго чтения
тело138 976 Б
инструменты12

В истории уже два куска файла

Файл весил 181,6 КБ. После двух чтений очередной запрос агента — 139,0 КБ. Ответ по-прежнему должен был уместиться в одну строку.

Байты нельзя превращать в рубли делением на четыре и серьёзным выражением лица. Провайдер считает токены после своей токенизации, а конкретный агент и модель могут отправлять данные иначе. Здесь измерен объём JSON до сетевого сжатия — только он.

03

Двенадцать инструментов едут в каждом рабочем запросе

В нашем запуске OpenCode объявил модели двенадцать инструментов: чтение и запись файлов, поиск, shell, вопросы пользователю, web-поиск, подагенты и другие действия. Модель получает не только названия. У каждого инструмента есть описание и схема аргументов — иначе она не поймёт, как вызвать read и что положить в поле path.

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

правила агента + описание инструментов + ваша задача
+ вызов read + первые 225 строк
+ вызов read с offset + следующие строки
= следующий запрос к модели

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

04

Большое окно — это вместительный стол, а не память о проекте

В контекст модели должны одновременно поместиться системные правила, схемы инструментов, сообщения, результаты чтения и место для ответа. Когда активная история приближается к пределу, OpenCode включает compaction: старую часть заменяет сгенерированным checkpoint и оставляет рядом недавний хвост.

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

Поэтому «модель поддерживает 200 тысяч токенов» не означает «она навсегда запомнила двести тысяч токенов». Это размер рабочего стола. Старые бумаги всё равно складывают в папку, а на стол возвращают записку с пересказом.

05

Как попросить про кнопку и не привезти весь склад

Назовите файл

Путь и конкретный символ дешевле просьбы «найди, где у нас кнопка».

Дайте границу

Напишите, какие файлы можно читать и менять. Агенту не обидно.

Не вставляйте весь лог

Оставьте ошибку, несколько строк вокруг неё и команду, которая воспроизводит сбой.

Новая задача — новая сессия

Чужая история не обязана ехать в следующий маленький фикс.

Отдельный ключ и лимит

Агентный цикл делает несколько вызовов на одно сообщение. Ограничение ставится до эксперимента.

Попробовать на своём проекте

Для агента нужен отдельный счётчик, а не вера в маленький промпт

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

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

Границы опыта

Прогон сделан 15 сентября 2026 года на OpenCode 2.0.3. Локальный сервер повторял заранее заданные tool calls и записывал только безопасные тестовые сообщения. Результат описывает эту версию, build-агента и два наших файла; это не универсальный замер всех кодовых агентов и не расчёт оплачиваемых токенов.