Дата публикации
ai_products

Как одна библиотека почти заменила RAG и векторный поиск по коду

Что появилось / что изменилось

Команда ecom.tech долго искала способ автоматически вытаскивать из кода REST‑эндпоинты и Kafka‑топики, чтобы потом кормить их LLM и собирать документацию. Они прошли через Tree‑sitter, классический и гибридный RAG, grep с монструозными регэкспами — и в итоге упростили всё до одной библиотеки Grep‑AST.

Ключевые изменения по сравнению с их прошлым стеком:

  • Вместо тяжёлого RAG‑пайплайна с эмбеддером gte‑multilingual‑base и BM‑25 теперь используется лёгкий поиск по абстрактному синтаксическому дереву (AST).
  • Средняя точность по всем языкам в RAG‑подходе была около 85%. Grep‑AST команда внедрила именно потому, что RAG всё равно пропускал нужные файлы и работал медленно. В новом варианте они добились более надёжного покрытия без постоянного тюнинга.
  • Сильно сократились накладные расходы: больше не нужно считать эмбеддинги для сотен репозиториев, поднимать отдельный векторный стор и держать гибридный поиск плюс ре‑ранжирование.
  • Поддержка правил стала проще. Вместо горы хрупких регулярных выражений команда описывает несколько паттернов на уровне AST для каждого языка и фреймворка.

Важно: конкретных чисел по ускорению и стоимости авторы не приводят. Можно честно сказать только одно: Grep‑AST уменьшил сложность системы и убрал тяжёлый векторный поиск из контура.

Как это работает

Задача ecom.tech — сделать reverse engineering документации: восстановить описание REST API и Kafka по живому коду. Репозитории пёстрые: Golang, Kotlin, Ruby, Elixir, PHP, плюс разные фреймворки — от Gin и Echo до Spring, Rails, Phoenix и Laravel.

При этом архитектурные стандарты внутри компании жёсткие. Точки входа в API и Kafka всегда выглядят предсказуемо:

  • REST:

    • Go: хендлеры, привязанные через http.HandleFunc, GET/POST в Gin/Echo.
    • Kotlin: контроллеры Spring с @RestController, @RequestMapping, либо маршруты Ktor routing { get("/") { ... } }.
    • Ruby: контроллеры Rails и routes.rb с resources или get.
    • Elixir: Phoenix.Router, макросы get "/", PageController, :index.
    • PHP: маршруты в routes/api.php Laravel или аннотации в контроллерах Symfony.
  • Kafka:

    • Go: producer.SendMessage из Sarama, consumer.Subscribe.
    • Kotlin/Spring: KafkaTemplate.send, @KafkaListener.
    • Ruby: producer.produce в ruby‑kafka.
    • Elixir: KafkaEx.produce, GenConsumer.
    • PHP: KafkaProducer::send поверх php‑rdkafka, консьюмер‑группы.

На бумаге это похоже на задачу «найти по строке». На практике всё ломают обёртки, базовые контроллеры, DSL и метапрограммирование, особенно в Ruby и Elixir. Для парсера вроде Tree‑sitter вызовы фреймворка выглядят как обычные функции, и он либо пропускает реальные эндпоинты, либо ловит шум.

Grep‑AST решает это иначе:

  1. Строит AST кода для нужного языка.
  2. Даёт возможность описывать поисковые паттерны не как строки, а как шаблоны по дереву: «функция с такой аннотацией», «вызов метода с таким именем и сигнатурой», «маршрут внутри такого блока».
  3. Применяет эти паттерны ко всем файлам репозитория и возвращает только те участки, которые действительно являются точками входа, а не комментариями или строковыми литералами.

Команда пробовала делать что‑то похожее руками на Tree‑sitter, но споткнулась о поддержку: для каждого языка и фреймворка приходилось писать собственные правила, зависящие от стиля кода и версии библиотек. Grep‑AST дал им более удобный слой поверх AST и уменьшил количество кода, который нужно обслуживать.

Что это значит для вас

Если у вас десятки или сотни микросервисов на разных языках и фреймворках, и вы хотите искать в коде не по словам, а по смыслу конструкции — Grep‑AST выглядит как здравый вариант.

Где библиотека особенно полезна:

  • Автоматическая документация. Как у ecom.tech: находите все REST‑эндпоинты и Kafka‑топики, выдёргиваете нужные куски кода и дальше уже подключаете LLM.
  • Codebase‑поиск для внутренних инструментов. Например, нужно быстро найти все места, где сервис открывает HTTP‑порт или пишет в конкретный Kafka‑топик.
  • Аудит архитектурных правил. Можно проверить, что все новые контроллеры используют нужную базовую абстракцию или что продюсеры Kafka создаются только через один пакет.

Где Grep‑AST вам почти точно не поможет:

  • Если у вас маленький монолит на одном языке, обычный grep или поиск IDE будет дешевле по времени внедрения.
  • Если в коде нет устойчивых архитектурных паттернов, а каждый сервис пишет HTTP и Kafka по‑своему, придётся тратить время на настройку паттернов AST.
  • Если вы уже живёте в экосистеме полноценного code search (Sourcegraph и аналоги) и вас устраивает качество, переход на Grep‑AST не даст радикальной выгоды.

Про доступность: авторы нашли библиотеку на GitHub, она открыта. Для использования VPN не нужен, ограничений по России нет.

Место на рынке

Если сравнивать Grep‑AST с тем, что чаще всего используют для поиска по коду, картина такая:

  • Против RAG + эмбеддинги (gte‑multilingual‑base) + BM‑25:

    • Плюсы Grep‑AST: проще инфраструктура, нет векторного стора, предсказуемое поведение, не нужно постоянно дообучать и перенастраивать пайплайн. В кейсе ecom.tech RAG давал 85% точности и всё равно пропускал нужные файлы.
    • Минусы: AST‑подход жёстко завязан на конкретные языки и фреймворки. Если вы ищете «по смыслу» в произвольном тексте или документации, векторный поиск всё ещё лучше.
  • Против Tree‑sitter напрямую:

    • Плюсы Grep‑AST: менее больная поддержка паттернов, особенно когда поверх фреймворков наращены DSL и обёртки. Tree‑sitter в их кейсе либо терял реальные эндпоинты, либо давал много ложных срабатываний.
    • Минусы: вы всё равно живёте в мире AST и должны понимать, как устроено дерево для каждого языка.
  • Против обычного grep и регэкспов:

    • Плюсы Grep‑AST: не нужно «выкручивать» регулярки, чтобы отфильтровать комментарии, строки, импорты и легаси‑хаос. Форматирование строк, перенос аннотаций, дополнительные декораторы больше не ломают поиск.
    • Минусы: входной порог выше, чем у grep. Для маленьких проектов это может быть оверкилл.

Если вы строите свои инструменты вокруг LLM и хотите, чтобы модель видела не случайные файлы, а реальные точки входа в системы, Grep‑AST — честный способ выкинуть часть сложной RAG‑машины и оставить только то, что действительно опирается на структуру кода.

Как одна библиотека почти заменила RAG и векторный поиск по коду — VogueTech | VogueTech