Продолжение статьи про graphlens. Там я описал, что инструмент делает и как устроен, и по дороге уверенно заявил, что «агент жжёт токены, бегая grep'ом по репозиторию». Заявил — но ни одной цифры не привёл. Эта статья закрывает дыру: вот замеры, вот данные, вот воспроизводимый стенд. Спойлер: вывод оказался не таким, каким я его себе рисовал, и это самое интересное.
Коротко
Я взял одного и того же агента (Claude Code), менял у него ровно одну вещь — какой MCP-сервер отдаёт контекст по коду, — и гонял по 26 задачам на apache/superset. Четыре «руки»: filesystem (grep + read), graphlens (структурный граф), serena (LSP) и codegraph. Три модели (haiku / sonnet / opus), три сида — 936 прогонов.
Главный результат: вывод переворачивается в зависимости от типа задачи.
На простых «где определён X / от чего наследуется» — все четыре инструмента равны по точности, разница только в цене (~3×). graphlens тут ничем не выделяется.
На задачах «оцени радиус поражения / найди все переопределения / разреши неоднозначное имя» инструменты резко расходятся: grep разваливается (точность 0.71, до финиша доходит 83% прогонов, а те, что доходят, стоят в 10–23 раза дороже), а структурные инструменты остаются дешёвыми и точными.
Если бы я мерил только простые задачи, я бы написал «граф не нужен, grep справляется». Если бы только сложные — «grep не нужен, берите граф». Правда — посередине, и она про то, какую работу вы поручаете агенту.
Бизнес-кейс, который мы на самом деле измеряем
Представьте типичную ситуацию. Есть большой проект: сотни тысяч строк, бэкенд на Python, фронт на TypeScript, легаси, в которое страшно лезть. Вы подключаете к нему кодового агента — для ревью, для рефакторинга, для ответов на вопросы вроде «что сломается, если я поменяю сигнатуру вот этого метода».
Агент не видит весь репозиторий разом. Кто-то должен подавать ему контекст: какие функции где определены, кто кого вызывает, что от чего наследуется. И вот тут возникает архитектурное решение, у которого есть цена: чем именно кормить агента?
Вариантов, по сути, четыре класса:
Дать ему grep и read — пусть ищет текстом и читает файлы. Ноль инфраструктуры, работает везде.
Построить структурный граф кода (graphlens) — узлы-сущности, типизированные рёбра, точные ответы на «кто вызывает».
Поднять LSP (serena поверх language server) — то, чем питается ваша IDE.
Взять готовый code-graph продукт (codegraph).
Каждый вариант — это деньги (токены), время (латентность) и риск (агент не справится и упрётся в лимит ходов). apache/superset — почти идеальный стенд под этот кейс: ~400k строк, Python + TypeScript, граница /api/v1/... между фронтом и бэком. Большой полиглотный проект — ровно то, ради чего этот вопрос вообще стоит задавать.
Так сколько стоит каждое из решений? Давайте мерить.
Дизайн эксперимента: меняем одну переменную
Вся методология держится на одном принципе: зафиксировать всё, кроме одного. Модель, системный промпт, настройки, набор задач — константы. Меняется только MCP-сервер, отдающий контекст. Тогда любая разница в цифрах — это вклад именно инструмента, а не случайности конфигурации.
Никакой инструмент не назначен «бейзлайном, который надо побить». Все четыре меряются на равных, и пусть числа их ранжируют.
Четыре «руки»
Рука |
Провайдер контекста (MCP-сервер) |
Шаг индексации |
|---|---|---|
|
|
нет |
|
граф graphlens поверх MCP |
|
|
Serena (LSP) |
прогрев LSP-воркспейса |
|
конкурент на графах |
|
Важная деталь честности стенда: встроенные инструменты Claude Code (Read / Grep / Bash и прочие) выключены. Если их не отнять, агент проигнорирует MCP и пойдёт своим привычным путём — и мы измерим не то. Поэтому стенд запускает claude -p в «чистой комнате»: свежий CLAUDE_CONFIG_DIR только с кредами подписки (без хуков, плагинов, скиллов, памяти), --strict-mcp-config (виден только сервер этой руки), --disallowedTools на все встроенные инструменты (именно запрет, а не отсутствие в allow-list — в headless-режиме allow-list сам по себе ничего не запрещает) и --allowedTools mcp__<server>, чтобы автоматически разрешить единственный сервер руки.
Вторая ось: модели
Параллельно я варьировал модель, которая отвечает на вопрос:
Ключ |
model id |
|---|---|
|
|
|
|
|
|
Зачем вторая ось — станет ясно ближе к концу: оптимальный инструмент зависит от того, какую модель вы взяли. Это, пожалуй, самый неочевидный вывод всего замера.
Итого: 4 руки × 3 модели × 26 задач × 3 сида = 936 прогонов (на стеке Claude Code 2.1.187).
Что я считаю честным замером
Бенчмарки легко подкрутить под нужный вывод. Поэтому правила игры зафиксированы заранее, и вот они — без них цифрам верить нельзя.
Эталонные ответы выверены руками по исходникам на теге
6.0.0(каждая задача несёт ссылкуfile:line). Принципиально: эталон не генерируется ни одним из тестируемых инструментов (ни ty, ни pyright, ни самим graphlens). Иначе сравнение смещено в пользу того, чьим выводом мы размечали. Эталонные множества для set-задач выверены независимым оракулом — питоновскимast.У «наивной» руки есть руки.
filesystem— это grep + read, а не «агент без инструментов». «Наивно» ≠ «без рук».Стоимость индексации меряется отдельно, один раз. grep не платит за индекс ничего, граф — амортизирует. Смешивать эти валюты нельзя.
Детерминизма нет.
temperature=0у этих моделей не детерминирует вывод. Поэтому 3 сида, и в отчёте — медиана, а не среднее.Записаны версии моделей и каждого MCP-сервера, снимок цен и дата.
cost_usd— это API-эквивалент, а не ваш счёт. Подписка — flat-rate, так чтоcost_usd(его отдаёт CLI) — это сколько те же токены стоили бы по API. Это не ваш реальный чек, но это корректная относительная метрика $/задача для сравнения рук между собой.Прогоны в чистой комнате — токены отражают только системный промпт + инструменты MCP-руки, без вашего личного конфига.
Использовать инструмент обязательно. Системный промпт запрещает отвечать по памяти; прогон, не сделавший ни одного вызова инструмента, перезапускается (а упорный отказ помечается
__NO_TOOLS__). Ответ «из головы» про известный репозиторий не измерял бы провайдера контекста.
И отдельно — провал засчитывается как точность 0. Если grep упёрся в потолок 50 ходов и не выдал ответ — это не «нет данных», это «инструмент не справился в рамках бюджета». Так и считаем.
Задачи: два режима, и почему их нельзя смешивать
26 задач делятся на два класса.
SIMPLE — 20 точечных запросов («где определён X / от чего наследуется X»). Ответ — одна точка, проверяется вхождением подстроки:
Тип |
# |
Что проверяет |
|---|---|---|
|
7 |
Python-класс → файл определения |
|
5 |
Python-класс → базовый класс |
|
1 |
ABC → его абстрактные методы |
|
1 |
TS-хук → файл определения |
|
4 |
роут |
|
2 |
TS-потребитель → Python-обработчик через границу API |
HARD — 6 задач на радиус поражения и неоднозначность. Это режим, где структура и семантика должны бить текстовый поиск — и который точечные запросы в принципе не измеряют:
Тип |
# |
Что проверяет |
Оценка |
|---|---|---|---|
|
2 |
неоднозначное голое имя метода (напр. |
подстрока |
|
2 |
полный набор подклассов, переопределяющих метод базы |
F1 по множеству |
|
2 |
все файлы, вызывающие данный метод (радиус поражения) |
F1 по множеству |
Set-задачи оцениваются по F1: награда за полноту (найти всех) и штраф за мусор в точности (текстовый поиск любит вывалить каждое вхождение .get_indexes(). Эталонные множества держим маленькими (3–5 элементов, одно ≈17), чтобы их можно было исчерпывающе проверить руками.
Почему я стратифицирую, а не усредняю
Набор намеренно несбалансирован — 20 простых против 6 сложных. Если посчитать одно общее среднее, оно будет полностью продиктовано лёгкими задачами и спрячет ровно ту разницу, которую вскрывают сложные. Поэтому я докладываю каждый режим отдельно и никогда не смешиваю.
И да — я сознательно не «балансирую до 50/50» выкидыванием простых задач. Это потеряло бы данные и статистическую мощность и открыло бы дверь для cherry-pick. Стратификация нейтрализует перекос без выброса данных. Это, кстати, общий принцип: если режимы дают разные ответы, честнее показать оба, чем спрятать конфликт под усреднением.
Результаты
SIMPLE — 20 точечных запросов
Инструмент |
точность |
заверш. |
токены |
вызовы |
$/задача |
сек |
|---|---|---|---|---|---|---|
filesystem |
0.97 |
100% |
1780 |
10 |
$0.063 |
43 |
graphlens |
0.98 |
100% |
690 |
3 |
$0.038 |
13 |
serena |
0.99 |
100% |
402 |
3 |
$0.031 |
20 |
codegraph |
0.99 |
100% |
372 |
1 |
$0.022 |
10 |
Точность — ничья (формально: критерий Фридмана χ²=0.40, незначимо). Инструменты различаются только ценой: разброс ~3×, выигрывают самые «немногословные». graphlens здесь ничем не примечателен — крепкий середняк.
Вот ровно ту историю рассказал бы стенд, измеряющий только точечные запросы: «структурные инструменты — приятно, но grep почти справляется, а самый дешёвый ответ даёт codegraph». И это была бы неполная правда.
HARD — 6 задач на радиус поражения и неоднозначность
Инструмент |
точность |
заверш. |
токены |
вызовы |
$/задача |
сек |
|---|---|---|---|---|---|---|
filesystem |
0.71 |
83% |
12596 |
27 |
$0.424 |
165 |
graphlens |
0.84 |
100% |
748 |
1 |
$0.018 |
9 |
serena |
0.85 |
98% |
1368 |
5 |
$0.065 |
29 |
codegraph |
0.93 |
100% |
1114 |
2 |
$0.036 |
16 |
А вот тут инструменты расходятся.
grep схлопывается. Самая низкая точность (0.71), до финиша доходит лишь 83% прогонов (остальные упираются в потолок 50 ходов), а те, что доходят, стоят в 10–23 раза дороже (~$0.42 против $0.018–0.065) и работают в 10–18 раз дольше (~165 секунд против 9–29). Текстовый поиск тонет в шуме, когда вопрос — «все вызовы вот этого» или «какой именно из десятка одноимённых методов».
Структурные инструменты держатся дёшево и точно. И вот ключевое: graphlens — середняк на простых задачах — здесь самый дешёвый ($0.018) и самый быстрый (9 секунд). Его семантический граф наконец окупается: один вызов вместо двадцати семи. Самым точным оказывается codegraph (0.93). serena конкурентна (0.85).
То есть тот самый graphlens, который на точечных запросах выглядел невзрачно, в режиме реальной работы — про анализ влияния, про рефакторинг — становится самым экономичным. Ранжирование инвертируется между режимами.
Заметка о честности стенда. MCP-ресурсы отключены для всех рук. graphlens — единственный сервер, выставлявший ресурсы, и в одном из ранних прогонов агент уходил в их перечисление и раздувал стоимость ~на 24%, пока я это не запретил. Все цифры выше — с чистого перепрогона.
Где уходят деньги: механизм — это round-trips
Разница в цене — это в основном число обращений к инструменту, а оно вытекает из того, как сервер нарезает свои примитивы.
На простом «символ → файл» (where_defined) всем хватает одного вызова. Разрыв открывается на запросах об отношениях — наследование, роут → обработчик, межъязыковые связи. Здесь graphlens цепочкой дёргает мелкозернистые примитивы (find → neighbors → references), а codegraph упаковывает «исходник + пути вызовов за один заход» (explore / node).
Это не разница в том, что знает граф — графы знают примерно одно. Это разница в гранулярности API: меньше round-trips → дешевле и быстрее. Вот откуда у codegraph преимущество в эффективности на простых задачах, и вот почему grep на сложных задачах разоряется — он делает 27 обращений там, где графу хватает одного-двух.
Взаимодействие модель × инструмент: ранжирование плывёт от цены модели
Это самая неочевидная часть. Возьмём медианную $/задача (по обоим режимам) в разрезе модели:
Инструмент |
haiku |
sonnet |
opus |
|---|---|---|---|
filesystem |
$0.053 |
$0.080 |
$0.087 |
graphlens |
$0.020 |
$0.041 |
$0.046 |
serena |
$0.026 |
$0.033 |
$0.042 |
codegraph |
$0.023 |
$0.041 |
$0.031 |
Ранжирование по дешевизне внутри каждой модели:
haiku: graphlens $0.020 < codegraph $0.023 < serena $0.026 < filesystem $0.053
sonnet: serena $0.033 < graphlens $0.041 < codegraph $0.041 < filesystem $0.080
opus: codegraph $0.031 < serena $0.042 < graphlens $0.046 < filesystem $0.087
Смотрите, что происходит с graphlens. На haiku он самый дешёвый из всех. На opus он становится самым дорогим из структурных инструментов (хотя всё ещё дешевле grep).
Механизм: результаты graphlens токеноёмкие — окрестности графа, списки ссылок. На дешёвой модели этот многословный контекст почти бесплатен, на дорогой — opus тарифицирует те же токены кратно выше, и многословность бьёт по карману. serena и codegraph дёшевы на любой модели, потому что возвращают точечные результаты — они устойчивы к выбору модели, а graphlens нет.
Отсюда практический вывод, который дороже всех остальных: дешёвая модель на структурном инструменте бьёт дорогую модель на grep. codegraph + haiku (~$0.023, точность ~0.99) делает filesystem + opus (~$0.087, точность 0.93) по всем осям сразу.
Гипотеза, которая не подтвердилась
Я закладывал пару xlang_link как стресс-тест: TS-вызов резолвится в Python-обработчик через границу /api/v1/..., и я был уверен, что одноязычные инструменты на этом споткнутся.
Не споткнулись. Все руки, включая grep, решили обе межъязыковые задачи. Агент сам перешагивает границу — независимо от провайдера контекста. На этом наборе гипотеза не подтвердилась, и я докладываю это ровно так же громко, как и подтвердившиеся выводы. Бенчмарк, который рапортует только то, что хотелось увидеть, — это не бенчмарк.
Статистика честно
Критерий Фридмана по четырём инструментам, по блокам-задачам, внутри каждого режима (df=3; критические значения: 0.05 → 7.82, 0.01 → 11.34):
SIMPLE: точность n=20 χ²= 0.40 (н.з.) — ничья стоимость n=20 χ²=18.42 (p<.01) — serena < codegraph < graphlens < filesystem HARD: точность n= 6 χ²= 3.50 (н.з.) — недостаточно мощности стоимость n= 6 χ²=11.80 (p<.01) — graphlens < codegraph < serena < filesystem
Что отсюда честно сказать:
Разница в стоимости значима в обоих режимах (p<.01). На HARD graphlens достоверно самый дешёвый, grep достоверно самый дорогой. Это твёрдый результат.
Разница в точности на HARD большая, но статистически незначима при n=6 (χ²=3.50). Это сильный описательный сигнал, но ещё не доказанный. Шесть задач — мало.
Чтобы укрепить вывод про точность, нужно добавить сложных задач, а не убирать простые. Урезание простого режима не даёт сложному ни капли мощности — оно лишь выбрасывает хорошие данные.
Я специально оставляю это в статье. Соблазн написать «graphlens/codegraph точнее grep, доказано» велик, но n=6 этого не вытягивает, и притворяться было бы нечестно.
Амортизация индекса: разные валюты
Структурные инструменты строят индекс один раз — это чистая статика, ноль LLM-токенов, только wall-clock:
Инструмент |
разовая индексация |
|---|---|
filesystem |
0 с |
codegraph |
48 с |
graphlens |
84 с |
serena |
94 с |
grep не платит вперёд ничего, но платит больше за каждый запрос. Это разные валюты (секунды против $/токенов), поэтому никакой единой «точки безубыточности» я не рисую — это была бы натяжка. Картина простая: индекс — разовая трата времени без единого токена, а экономия $/задача капает на каждой задаче. На длинной сессии структурные инструменты амортизируются; на паре разовых запросов нулевой сетап grep может выиграть по «времени до первого ответа».
Выводы для бизнес-кейса
Вернёмся к исходному вопросу: чем кормить агента на большом проекте?
Ответа «вот этот инструмент всегда лучший» — нет. Есть ответ «зависит от того, какую работу вы поручаете»:
Разовые точечные справки («где определён класс», «от чего наследуется»): берите что угодно. grep справляется, точность та же, нулевой сетап. Платите вы тут разве что небольшим overhead'ом в токенах.
Постоянная работа с анализом влияния — рефакторинг, оценка радиуса поражения, разрешение неоднозначностей на большой кодовой базе: структурные инструменты режут стоимость в 10–23 раза и латентность в 10–18 раз против grep — и, что не менее важно, не упираются в потолок ходов. grep на этих задачах не просто дорог, он в 17% случаев вообще не доходит до ответа.
Выбор модели взаимодействует с выбором инструмента. Многословный граф дёшев на маленькой модели и дорог на большой. Если гоняете opus — берите инструмент с точечной отдачей (codegraph, serena). Если haiku — graphlens внезапно самый дешёвый.
Самая дешёвая комбинация — не «дорогая модель + простой инструмент», а «дешёвая модель + структурный инструмент».
И честные оговорки, без которых выводы нельзя переносить на ваш проект:
Один репозиторий (
apache/superset@ 6.0.0), один стенд, 26 задач (20 простых / 6 сложных). Режимы докладываются раздельно и никогда не смешиваются.cost_usd— API-эквивалент, а не счёт по подписке. Провал = точность 0. Это не универсальный рейтинг — это воспроизводимый замер на конкретном кейсе.
Где здесь graphlens
Раз уж это продолжение статьи про него — скажу прямо. Этот бенчмарк не доказывает, что graphlens «лучший». Он показывает конкретный режим, в котором его структурный граф окупается (анализ влияния, дёшево и быстро на дешёвых моделях), и так же прямо показывает, где он проседает (на opus его многословная отдача дороже, чем у codegraph и serena; codegraph точнее на сложных задачах).
Для меня это полезнее любой победной реляции. graphlens задумывался как движок и точная мультиязычная модель графа, а не как готовое приложение. Бенчмарк ровно это и подтверждает: на структурных вопросах граф бьёт текстовый поиск с большим запасом, и одновременно есть куда расти — гранулярность MCP-инструментов (меньше round-trips, как у codegraph) и компактность отдачи (чтобы не разоряться на дорогих моделях). Это мой следующий пункт работ, и он теперь подкреплён числами, а не интуицией.
Воспроизвести
Весь стенд и сырые данные — открыты. Прогон полностью детерминированно собирается из data/.
Репозиторий бенчмарка: https://github.com/Neko1313/agent-context-bench
Смотреть
metrics.ipynb(все графики и постатейная статистика) иREADME.md(методология).uv runmain.pyгоняет весь пайплайн (клонирование superset → сборка индексов → 936 прогонов, resumable в рамках лимитов подписки), дальше открываетеmetrics.ipynb.
Если у вас есть свой большой проект и желание прогнать стенд на нём — буду рад issue и результатам. Чем больше независимых прогонов на разных кодовых базах, тем ближе мы к ответу, который можно переносить, а не «работает на superset».
Комментарии (9)

Void-Cowboy
24.06.2026 15:53потыкал по разному, посмотрел исходный код и вот отчет:
прикольно но не для всех так сказать. Растягивать на весь диск небезопасно да и ресурсоемко. А по проектам это нужно каждый раз руками запускать, индексировать, подключать mcp и так далее. На пробу поэкспериментировал с созданием скила что бы кодовый агент сам запускал, подключал, трекал и тд но получается фигня (в теории скил можно вылизать что бы оно все само, но то уже заниматься надо)
как оно индексирует я так до конца и не понял - на сложном го проекте с vendor, replace и внешними либами оно очень криво определяло что может либа и какой метод сюда б подтянуть и использовать
большие вещи ложат намертво - один из моих рабочих репозиториев 52гб чисто кода с гит-историей так вот его я так и не дождался индексации и кильнул раньше
в целом пока разбирался, по коду выглядит не слишком сложно как по мне. Может когда-то как очередной пет-проект попробую что то подобное сделать но уже на чистом Го или Расте (там векторных баз данных хватает классных)
буду ли я использовать? нет. родного mcp от jetbrains хватает с головой для работы с лексическим деревом проекта а все остальное агент погрепает сам. Преимущества работы "из коробки" перекрывают все преимущества тех процентов улучшения поиска.

spacediver
24.06.2026 15:5352гб чисто кода с гит-историейА за счёт чего такие цифры, если не секрет?

Void-Cowboy
24.06.2026 15:53гигарепа, там сразу все
плюс много лет разработки разными командами каждый божий день
там только актуальных веток под 500, свою с поиском только найдешь

Neko1313 Автор
24.06.2026 15:53Спасибо, что не просто потыкали, а реально полезли в код и в граничные кейсы — такой фидбэк ценнее всего.
Сначала про рамку, она тут ключевая. graphlens — это библиотека/движок, а не продукт «поставил и работает». Это не отговорка, это зафиксированная область применения: в доке есть отдельный раздел Scope & Non-goals, где прямо перечислено, чего он сознательно не делает — https://neko1313.github.io/graphlens/docs/#scope--non-goals. Его задача — отдать структурный IR, а слой «само запускается, подключается, трекает» — ровно то, что строится сверху. Так что бóльшая часть трения, которое вы словили (ручной запуск, ручной MCP, скил-обвязка), — это отсутствующий продуктовый слой, и претензия честная. Скил — правильное направление, его надо вылизывать, и это отдельная работа, которую я пока не сделал.
По конкретике:
— «на весь диск»: оно индексирует не диск, а путь, который вы дали (
graphlens analyze ./repo). Но да — то, что это надо запускать руками на каждый проект и потом руками цеплять MCP, реальное неудобство, спорить не с чем.— Go с vendor / replace / внешними либами: честно слабое место. Type-aware рёбра резолвит gopls, и на vendored-зависимостях с
replaceв go.mod он требует правильно настроенного окружения, иначе кросс-модульные ссылки разрешаются криво — что вы и увидели. Если не лень, киньте issue с минимальным репро (go.mod с replace + vendor) — это прям полезный кейс, чтобы пофиксить настройку резолвера.— 52 ГБ репо: это сильно за пределами того, на что оно сейчас рассчитано — граф целиком держится в памяти (для superset это ~170 МБ, у вас был бы порядок гигабайтов), так что «легло намертво» ожидаемо. Отдельно: индексируется дерево исходников, а не история гита; если оно реально полезло в
.git— это баг и тоже повод для issue.— про векторные БД: вот тут поправлю, это частое недопонимание. В graphlens нет ни вектора, ни эмбеддингов, ни семантического поиска — это даже вынесено отдельным пунктом в тот же раздел Non-goals по ссылке выше («not a vector index»). Внутри только tree-sitter (парсинг в CST) и LSP-резолверы, которые дают точные рёбра по типам, а не «похожие по смыслу». Если соберёте пет-проект на Го/Расте с векторной БД — это будет другой инструмент, решающий другую задачу (семантический поиск). Здесь вектора нет принципиально, и не из-за языка.
А теперь главное — про «не буду использовать, jetbrains-mcp + греп хватает». Вы пришли ровно к тому выводу, который я измерял отдельным бенчмарком — https://github.com/Neko1313/agent-context-bench. Там я специально разделял результаты по типу задач: на простых («где определён», «от чего наследуется») все инструменты, включая греп, равны по точности, и удобство «из коробки» спокойно перекрывает пару процентов на поиске. Структурный граф окупается только на тяжёлых вопросах — радиус поражения, наборы переопределений, разрешение одноимённых методов; нет такой работы — родного тулинга правда достаточно. Так что это не «вы не оценили», а «вы независимо подтвердили числа». За это спасибо.
И раз код показался несложным — он таким и задуман: минимальное ядро это фича, а не недоработка, на нём проще строить. Контракт и IR под MIT, так что если дойдёт до пет-проекта на Расте — переиспользуйте без зазрения совести.

Void-Cowboy
24.06.2026 15:53могло и не полезть в гит, а хватить чисто кода раз все только в память выгружается причем с оверхедом на графовость как я понимаю
за минимальное репо я даже хз, это исследовать надо, будет время сделаю. но не обещаю
учитывая что оно все в память тянет - весь диск на такое и не затянуть, а жаль. Все же пересечения с либами тоже важны и которые агенты тем и хороши что сразу смотрят либу локально, а не гуглят или галюцинируют как оно может быть

lazarus_net
24.06.2026 15:53Чем бы дитя не тешилось …
Берем нормальный компилируемый язык. Меняем метод. Запускаем билд. Билд валится с сообщением об ошибке. Правим, запускаем билд. Повторяем. Агенту надо сделать два действия провести замену в одни месту и пересобрать проект.
далее у нас же есть тесты?
Запускаем тесты если валятся правим.
Если у вас нет нормального компилятора с проверкой типов и нет тестов, то АИ вас все равно не спасет - нет шанса проверить что он поменял то что надо и как надо.

Neko1313 Автор
24.06.2026 15:53По сути верно: строгий компилятор + плотные тесты — лучший оракул, что правка не сломала типы. Граф с этим не конкурирует.
Два момента, которые этот цикл не закрывает. Компилятор отвечает после правки и только про типовые поломки — а агенту надо понять, что и где менять, до (часто согласованно в N местах), и куча влияющих изменений компилируется чисто (смена семантики при той же сигнатуре, дефолты, сайд-эффекты). И жёсткие задачи в бенчмарке были на Python, где падающего билда на переименованный метод нет в принципе — там граф и выигрывал, потому что компилятора-оракула просто не существует.
Ну и граф ≠ «вместо компилятора». Find usages в вашей IDE — это и есть call-граф на LSP; вы ходите им по коду до правки, а не ломаете билд ради чтения ошибок. graphlens просто даёт агенту тот же find-usages, чтобы он не крутил build-fix-loop и не грепал.

Anton-Sergeevich
24.06.2026 15:53Очень вовремя наткнулся на это сравнение. Как раз ломаю голову, как лучше организовать контекст для агента, который работает с кодовой базой сложного Telegram-бота: десятки обработчиков, цепочки состояний, мидлвари — глазу зацепиться непросто. Ваш вывод про зависимость от типа задачи выглядит логично: условно, для точечных правок grep’а хватит, а для рефакторинга цепочки диалогов хочется, чтобы агент видел структурный граф и семантику. Есть ли среди этих «рук» конфигурация, которую вы бы посоветовали для проектов с глубоко вложенной событийной логикой (FSM, вебхуки, очереди)? Или пока универсального рецепта нет, и под каждый класс задач — свой сервер?
Void-Cowboy
ладно, убедили, пошел тестить
UPD
сходу хочу сказать что не хватает md-индексации
у меня в обсидиане целая цивилизация и с кодовым агентом удобно там грестись - векторный mcp стал бы вообще манной небесной