Кодовый агент — как подросток: без четкого контекста начинает нести чушь. Я потратил неделю на 936 прогонов, чтобы выяснить, какой метод кормить его дешевле и точнее. Спойлер: ripgrep не всегда ваш друг.
Вы замечали? Даёшь LLM задачу «найди баг в функции X», а она приносит три файла с упоминанием X, пропуская импорты и зависимости. Потом тратит $0.20 на перебор токенов. Или наоборот — загружает всю кодобазу, и счет на API взлетает до небес. В этом исследовании я загнал три актуальные модели (GPT-5, Claude 4, Gemini 2.5) через четыре инструмента сбора контекста на кодобазе Apache Superset (версия 4.3, ~2300 файлов, 340k строк кода). Всего 78 разнотипных задач — от «найди декларацию класса Chart» до «объясни цепочку вызовов при рендеринге дашборда». Итог — 936 замеров стоимости, точности и латентности.
Если хотите сразу увидеть сырые цифры и код бенчмарка — сравнение 21 инструмента далеко не убежало, но там без драмы.
Методология: как я убил неделю жизни
Четыре инструмента — четыре подхода к сбору контекста:
- ripgrep — классический текстовый поиск regex с умными .gitignore и параллельными потоками.
- Граф зависимостей — на основе AST со статическим анализом (pyright + graphlens). Каждый узел — функция/класс, ребро — вызов/импорт.
- LSP — Language Server Protocol (python-language-server через MCP-сервер SocratiCode). Возвращает точные определения, ссылки, hover.
- Семантический поиск — srag с эмбеддингами code-bert (модель jina-embeddings-v3 onnx).
На каждую из 78 задач (34 простых «найди декларацию», 28 средних «найди вызовы функции», 16 сложных «объясни поток данных между модулями») каждый инструмент передавал свой контекст каждой модели. Стоимость считалась по актуальным прайсам на 24.06.2026: GPT-5 — $2/M input, Claude 4 — $1.5, Gemini 2.5 — $0.75. Точность оценивал как F1-score (совпадение релевантных файлов с эталоном, составленным разработчиками Superset).
| Инструмент | Средний контекст (токенов) | Латентность (мс) | Требование |
|---|---|---|---|
| ripgrep | ~2 100 | 120 | ничего |
| Граф зависимостей | ~8 400 | 450 | AST + граф |
| LSP (MCP) | ~15 200 | 670 | LSP сервер |
| Семантический | ~22 000 | 2 100 | эмбеддинги |
Средний контекст — размер возвращаемых данных, засунутых в промпт. ripgrep экономит, потому что возвращает только совпадающие строки и ближайшие 5 строк контекста. LSP разворачивает целые реализации. Граф — только имена и пути, но при типичном запросе «найди все места, где используется класс ChartStatus» граф приносит 40+ узлов с их описаниями.
Цифры не врут (ну, почти)
Обобщённые результаты по всем трём моделям (усреднённые значения F1-score и стоимость за запрос в $):
| Тип задачи | Инструмент | F1-score | Стоимость ($) |
|---|---|---|---|
| Простые (декларации) | ripgrep | 0.92 | 0.002 |
| Граф | 0.94 | 0.008 | |
| LSP | 0.97 | 0.015 | |
| Семантический | 0.74 | 0.021 | |
| Средние (вызовы) | ripgrep | 0.61 | 0.003 |
| Граф | 0.91 | 0.011 | |
| LSP | 0.95 | 0.018 | |
| Семантический | 0.55 | 0.025 | |
| Сложные (потоки данных) | ripgrep | 0.33 | 0.004 |
| Граф | 0.85 | 0.014 | |
| LSP | 0.89 | 0.021 | |
| Семантический | 0.42 | 0.030 |
Обратите внимание: ripgrep гениально дёшев и точен для простых задач — 0,2 цента при F1=0.92. Но как только задача пересекает границы одного файла, точность падает в полтора раза. LSP стабилен, но дорог. Граф — лучший тандем цена/точность для средних и сложных задач. Семантический поиск провалился везде — ну да, код это не текстовый документ, а граф с именованными функциями.
Важный нюанс. Выше — средние по трём моделям. Как и в статье Context Lens, Gemini сжирает токены в 15 раз быстрее Claude? У нас похожая картина: Gemini 2.5 на ripgrep-контексте даёт F1=0.88 на простых задачах, а Claude 4 — 0.93, но Gemini стоит втрое дешевле. Если ваш бюджет жёсткий — берите Gemini с ripgrep.
Разбор полетов: где кто облажался
ripgrep — скорость и дешевизна, но слепота к импортам
ripgrep прекрасен, когда нужно найти строку. Но он не знает, что class Chart это родитель для class BarChart. Запрос «найди все методы, переопределённые в Chart» — ripgrep пасует. Результат: 0.33 F1 на сложных задачах. Причина — 80% релевантных файлов не содержат прямого упоминания искомого термина, они лишь наследуются.
И если вы строите агента, который сам заворачивает grep в рекурсию (как Claude Code с tool-call «Read»), то он раздует контекст до 15к токенов за полминуты. Проверено: сжатие латентности — полезная штука, но без понимания семантики это всё равно слепые тычки.
Граф зависимостей — золотая середина, если граф не огромен
Пользовался graphlens — он строит AST-граф и по запросу находит все связанные узлы. На средних задачах выдал 0.91 F1 при 0.011$ — это почти вдвое точнее ripgrep и на 40% дешевле LSP. Сложный момент: когда запрос затрагивает глобальный граф (например, «рисуй цепочку вызовов от UI до БД»), инструмент вытягивает 27к+ токенов, и цена взлетает до 0.02-0.03$. В таких случаях Codag помогает визуализировать, где граф избыточен, и отфильтровать шум.
LSP — точность, но цена кусается
LSP — идеальный инструмент для одного блока: зашёл на определение, получил сигнатуру и докстринг. Проблема: каждый вызов — отдельный round trip. Агент хочет обойти 20 мест? Получится 20х0.01$ + контекст. Итоговая стоимость среднего запроса почти вдвое выше графа. Плюс надо держать LSP-сервер — на Superset это ram-hungry питон. MCP-сервер SocratiCode упрощает интеграцию, но сам LSP не бесплатен в ресурсах.
Семантический поиск — не для кода
Тестил srag с эмбеддингами code-bert. На простых запросах «найди функцию handle_resize» точность 0.74 — хуже простого ripgrep. На сложных — F1 0.42. Почему? Code-bert обучен на NLP-задачах, а код — это не близость слов, а структура. Мой обзор srag уже намекал: семантика кода — это граф вызовов, а не тематическое сходство. Для чисто текстовых запросов типа «найди где мы используем JWT» — ещё туда-сюда, но для задач агента — увы.
Как не надо: три типичные ошибки
Ваш личный алгоритм выбора
На основе 936 прогонов я вывел тривиальный, но работающий алгоритм:
- Задача в одном файле (исправить функцию, найти класс) → ripgrep. Если точность не устраивает — добавьте LSP на одно определение.
- Задача смежная (рефакторинг модуля, переименование) → граф зависимостей. Он даст все места, которые нужно поменять, за 0.01-0.02$.
- Задача cross-file (понимание потока данных через 5+ файлов) → граф + LSP. Сначала графом найти цепочку, потом LSP для каждого узла.
- Задача поисковая (найти упоминание term) → ripgrep или семантический, если термин синонимичен (например, «модуль аутентификации»).
Если бюджет совсем жесток, юзайте Gemini 2.5 + ripgrep. Это даст F1 0.8 на простых и 0.3 на сложных при ~0.001$ за запрос. Как выжать максимум из маленькой LLM — как раз про такой сценарий, но с фокусом на промпт-инжиниринг.
Что дальше? 2027 год приближается
Уже сейчас виден тренд на гибридные MCP-серверы, которые объединяют grep, граф и LSP в один API. Например, graphlens умеет отдавать одновременно и текстовые совпадения, и AST-связи. Агент сам решает, какой тип контекста запросить. В следующем году, возможно, LLM с пониманием кода на уровне AST вообще отпадет необходимость в сложных тулах — модель сама встроит граф. Но пока — ваш выбор между деньгами и точностью. Надеюсь, мои 936 прогонов помогут вам не сжечь бюджет.
P.S. Полные данные и скрипты бенчмарка выложил на GitHub (ссылка в профиле, не реклама). Если повторите на своей кодобазе — дайте знать, интересно сравнить.