Привет, дорогой читатель. Если тебя хоть раз тревожило то, почему так быстро улетают лимиты Claude Code или любого другого ИИ-тула для кодинга, ты пришел по адресу. Буквально пара правок, и хоба дневной лимит исчерпан, а баланс API показывает дно. Вся эта боль в статье про экономию токенов на инструментах сборки контекста.
Написано для комьюнити AI Enginees Guild https://t.me/ai_engineers_guild
Обычно мы не сильно задумываемся об оптимизации процесса: либо кодят с ИИ как есть (копипастя файлы вручную), либо пихают в контекст всю папку проекта целиком, либо на авось подрубают самые разные тулы в надежде, что «и так сойдет». А под капот умным агентам разработчики пихают всё подряд: вот тебе ripgrep, вот AST-парсер, вот чтение файлов целиком, развлекайся. Но я задался вопросом: какой конкретно поисковый тул реально помогает агенту решать задачи и экономить токены, а какой — только заставляет его блуждать по репозиторию и беспощадно жрать контекст?
Чтобы это выяснить, я собрал подобие бенчмарка (исходники выложил в letya999/tools-token-economy) и прогнал 21 конфигурацию тулов на реальных задачах разной сложности. Думал, что навороченный семантический поиск раскатает дедовский grep в сухую, но результаты оказались куда интереснее. А по пути я еще и словил критический баг в LLM-судье.
Ниже — честный технический разбор без воды, реальные данные и мысли вслух за кружкой сидра.
1. Проблема: как агенту ходить по файлам?
Когда разработчик пытается затащить ИИ в свой рабочий процесс, обычно всё сводится к трем сценариям:
-
Кодят с ИИ как есть — копипастят файлы в окно чата вручную и надеются, что модель угадает контекст.
-
Пихают всю папку проекта целиком — скармливают LLM весь репозиторий со всеми конфигами и доками, сжигая тонны токенов за один запрос.
-
На авось подрубают все доступные тулы — дают агенту карт-бланш на использование
ripgrep, AST-парсеров, LSP и векторного поиска одновременно, надеясь, что «и так сойдет».
Знакомая картина? Агент начинает судорожно вычитывать файлы один за другим, надеясь наткнуться на нужный кусок:
Но когда агент пытается починить реальный баг в незнакомой кодовой базе, его работа делится на две фазы:
-
Навигация (поиск): найти нужные файлы, понять зависимости, структуры и вызовы.
-
Исполнение (редактирование): применить патч и запустить тесты.
С редактированием всё понятно, а вот с навигацией беда. Я выдвинул простую гипотезу: избыток инструментов навигации вредит агенту не меньше, чем их недостаток.
Когда у модели разбегаются глаза от обилия возможностей, она либо бесконечно переключается между стратегиями поиска (context waste), либо затягивает в контекст столько мусора, что забывает изначальную задачу (эффект context explosion).
Мне было интересно нащупать, какой конкретно тул дает самый чистый контекст. В качестве метрики я взял SPT (Success Per Token) — количество успешных решений на каждую тысячу потраченных токенов.
2. Дизайн песочницы
Для экспериментов я поднял изолированную среду на Python 3.13 и WSL2 Ubuntu. Я виндов-вод, а хотелось чуть более чистый эксперимент. В целом в проекте есть скрипты под linux/macos/windows, на любой вкус. В роли агента выступал фреймворк Agno https://github.com/agno-agi/agno с gpt-4.1-mini. Почему Агно? Причины 3: я устал настраивать opencode, задолбался настраивать opencode и я хотел померить без костылей тулов, который скрыто для пользователя оптимизируют работу.
Все параметры (температура, промпты) зафиксированы, менял только доступные агенту инструменты поиска.
Получился 21 конфиг, которые я разбил на 6 категорий:
1. Семейство Grep-инструментов (Ablation-тесты)
Оставляем только классический текстовый поиск:
-
07_grep: дефолтный POSIX
grep. -
08_git_grep: поиск по индексу git.
-
09_rg: реактивный
ripgrep. -
10_ugrep: расширенный поиск с нечеткими совпадениями.
-
11_ast_grep: поиск по синтаксическому дереву.
2. Чтение контекста (Read-стратегии)
-
05_read_only: агент ищет только по glob-паттернам и читает файлы.
-
06_read_all: насильно закидываем в контекст вообще все файлы проекта со старта.
3. Семантическая навигация (Semantic)
Инструменты, строящие граф кода:
-
16_serena_only: доступ к MCP-серверу Serena, который дает символьный граф (кто кого вызывает, где лежат типы).
-
17_semble_only: поиск по локальным векторным эмбеддингам.
-
20_serena_semble: гибрид графа Serena и векторов Semble (⭐ спойлер: пушка-гонка).
4. Структурный поиск
-
12_tree_sitter: разбор файлов через AST.
-
13_lsp: плоский список символов по протоколу LSP.
5. Интегрированные архетипы
-
01_cursor_like: смесь
repo_mapи RAG (как под капотом Cursor). -
02_claude_code_like: гибрид
glob,ripgrepи чтения файлов. -
03_gemini_like: экстремальная солянка (
read_all+repo_map+rg). -
18_rg_repo_map:
ripgrepплюс карта репозитория.
6. Минимализм
-
21_bash_only: голый терминал. Выживай как хочешь.
Чтобы эта банда конфигураций не оставалась просто набором букв в коде, я завёл реестр в дашборде. Вот как выглядит этот зоопарк под капотом (разбил на две части, чтобы не ломать вам глаза мелким шрифтом):
Сценарии
Взял две задачи из реальной кодовой базы:
-
Medium: поправить регистрозависимость Bearer-токена в middleware. Найти функцию, поправить строку.
-
Hard: фича
aging_staleв пайплайне Polars. Надо прокинуть новое поле, обновить логику в 3 файлах и дописать тесты.
Оценка качества
Просто прогнать pytest недостаточно. Я натравил на результаты LLM-судью (gpt-5.4-nano), который ревьюил код по 7 критериям (качество, лаконичность, следование паттернам). Ну и считал токены и процент context waste (когда файл прочитан, но не использован).
3. Анатомия LLM-судьи: веса, эвалы и фильтр Неймана
В нашем бенчмарке LLM-судья не просто ставит лайк/дизлайк. Он оценивает код по 7 независимым метрикам ивалам: task_solved, correctness, tool_correctness, context_quality, minimality, pattern_adherence, tool_sequence. Каждому критерию назначен свой вес, а итоговая оценка (Eval Score) считается как взвешенное среднее.

Но и этого мало. Возникла проблема: если агент ломает бизнес-логику (0 за correctness), но при этом пишет красивый минималистичный код (1 за minimality), линейное среднее даст ему завышенный балл. Поэтому я использую геометрический показатель качества, где критические метрики выступают множителями: если correctness равна нулю, обнуляется весь скор.
А чтобы убрать шум от случайных галлюцинаций судьи на гигантских контекстах, я применил пару научных приколов:

-
Фильтр Неймана: статистический механизм, который отсекает выбросы (outliers) в оценках судьи, опираясь на дисперсию соседних прогонов. Если судья внезапно ставит 1.0 за решение, где ломается синтаксис, фильтр сглаживает эту галлюцинацию.
-
Поправка Демискар (Demiscar 2006): математический штраф за избыточное чтение. Этот алгоритм нелинейно понижает итоговый Eval Score, если параметр Waste% (прочитанные, но неиспользованные токены) превышает здоровый порог для данной задачи.
Именно этот строгий аппарат позволил отсеять хитрецов, которые ломали тесты, чтобы пройти их на шару.
4. Средняя задача: триумф дедовских методов
Для начала размялись на простой задаче — исправлении регистрозависимости Bearer-токена. Вот как выглядят параметры запуска и описание таски в интерфейсе дашборда:
На простой задаче (Bearer-токен) я прогнал 20 конфигов. 14 из них справились (70% pass rate).
И вот тут случилось первое открытие. Посмотрите на топ самых экономных:
|
Конфиг |
Инструменты |
Токены |
Тесты |
Примечание |
|---|---|---|---|---|
|
10_ugrep |
ugrep + edit |
2,697 |
✅ PASS |
⭐ Абсолютный чемпион |
|
18_rg_repo_map |
rg + repo_map |
3,003 |
✅ PASS |
Очень близко |
|
05_read_only |
glob + read |
3,276 |
✅ PASS |
|
|
07_grep |
grep + edit |
3,439 |
✅ PASS |
|
|
02_claude_code_like |
glob + rg + edit |
3,559 |
✅ PASS |
|
|
13_lsp |
lsp + edit |
9,994 |
✅ PASS |
Начало усложнения |
|
20_serena_semble |
serena + semble |
32,747 |
✅ PASS |
Тяжелая артиллерия |
|
03_gemini_like |
read_all + repo_map |
175,208 |
❌ FAIL |
Context explosion |
⭐ Главный вывод фазы Medium: на простых, точечных задачах легковесные утилиты типа grep, ugrep или ripgrep рвут всех. Агенту нужен ровно один шаг: найти строку Bearer, прочитать этот кусок, заменить. Копеечный расход (меньше 3 тысяч токенов) и моментальный патч.
А вот стратегия gemini_like (закинь в контекст всё) предсказуемо свалилась. Агент наглотался кода, запутался, слил 175 тысяч токенов в унитаз и выдал нерабочий мусор.
5. Сложная задача: когда Grep заводит в тупик
Для сложной задачи (добавление поля в Polars-пайплайн) я прогнал каждый конфиг по 6 раз для надежности. И тут картина перевернулась с ног на голову.
Лидерборд (отсортирован по оценке судьи p75):
|
Конфиг |
Инструменты |
Успех (pytest) |
Оценка судьи (p75) |
Средние токены |
|---|---|---|---|---|
|
04_codex_like |
grep + read + edit |
6/6 (100%) |
0.85 |
861,000 |
|
20_serena_semble |
serena + semble |
5/6 (83%) |
0.79 |
120,000 |
|
14_repo_map |
repo_map + edit |
4/6 (67%) |
0.76 |
97,000 |
|
16_serena_only |
serena |
6/6 (100%) |
0.68 |
79,000 |
|
17_semble_only |
semble |
5/6 (83%) |
0.58 |
84,000 |
|
10_ugrep |
ugrep + edit |
4/6 (67%) |
0.62 |
1,224,000 |
|
19_rg_lsp |
rg + lsp |
4/6 (67%) |
0.37 |
425,000 |
|
18_rg_repo_map |
rg + repo_map |
0/6 (0%) |
0.49 |
79,000 |
|
03_gemini_like |
read_all + repo_map |
0/6 (0%) |
0.00 |
419,000 |
|
21_bash_only |
bash |
0/6 (0%) |
0.10 |
85,000 |
А вот как эти результаты выглядят в интерфейсе нашего дашборда со всеми деталями (включая Net SPT и стоимость в центах):
И для любителей сырого терминального вывода — ловите скриншот финального отчёта прямо из консоли после завершения всех 126 раундов:
⚠️ Что мы тут видим:
-
Serena Only (16_serena_only) творит чудеса: 100% успех при средних затратах всего 79,000 токенов на раунд!
-
Codex-like (04_codex_like) тоже выдал 100% успех, но ценой чудовищного обжорства — 861,000 токенов. В 11 раз прожорливее Серены!
6. Инсайт: почему так происходит
Всё упирается в когнитивную глубину задачи.
На средней сложности нужно просто найти и заменить. Грепы тут идеальны. Сложные графы (Serena) для этого как микроскоп для забивания гвоздей.
На высокой сложности агенту нужно распутать клубок: понять, откуда вызывается функция в aging.py, посмотреть маппинг в commitment_resolver.py, чекнуть схему валидации.
С одним только grep агент начинает слепо блуждать. Ищет age, получает 150 совпадений по всему проекту и читает их все, раздувая контекст до 1.2 млн токенов (привет, ugrep).
А вот тулы вроде Serena дают семантику. Агент дергает find_symbol("calculate_work_item_aging_facts") и мгновенно получает граф вызовов. Он скачет по цепочке, читая только то, что нужно.
Вывод: Не пихайте в агента один универсальный тулсет. Для малых проектов вам ничего не надо, край давайте
ripgrep. Для сложного рефакторинга забирайтеgrepи давайте LSP/MCP тулы (а лучше просто ставьте Serena MCP https://github.com/oraios/serena, иначе агент сожрет весь лимит токенов на чтение мусора.
7. Эпик фейл с LLM-судьей (и как я спас данные)
Ну и вишенка на торте. Запустил я пачку ранов, открываю логи, а там… у всех запусков оценка судьи 0.0. При этом pytest зеленый.
Полез дебажить и нашел баг в моем llm_judge.py:
# Старый код, который всё сломал:try: itok = int(getattr(resp.metrics, "input_tokens", 0) or 0)except (TypeError, ValueError): itok = 0
Оказалось, в свежей версии Agno у ModelResponse пропал атрибут .metrics (всё переехало в resp.response_usage). Падал AttributeError, который я не ловил. Ошибка летела выше и ломала весь скоринг.
# Фикс здорового человека:try: usage = getattr(resp, "response_usage", None) if usage is not None: itok = int(getattr(usage, "input_tokens", 0) or 0) else: itok = int(getattr(resp, "input_tokens", 0) or 0)except (TypeError, ValueError, AttributeError): # Добавил AttributeError! itok = 0
Перезапускать все раны с нуля было бы больно. Но меня спасло простое правило: я всегда логирую сырые транзакции (agent_messages.json)..
9. Итоги

Если вы собираете свой Agent Harness, вот выжимка:
-
Grep для простых задач, семантика для сложных.
ripgrepидеален для локальных фиксов. Для рефакторинга нужны LSP-серверы и графы, иначе агент захлебнется в поиске. Serena MCP!; -
Прочитай всё (read_all) зло. Заливать все файлы репо в контекст со старта — верный путь к context explosion;
А какие тулы вы даете своим агентам под капот? Оставляете им свободу терминала или жестко ограничиваете MCP-серверами? Пишите в комменты, буду рад обсудить!
P.S. Исходный код харнесса и все сырые метрики лежат в репозитории letya999/tools-token-economy. Забирайте, ковыряйте, снижайте энтропию в своих агентах!
ссылка на оригинал статьи https://habr.com/ru/articles/1042880/