Ragex MCP-сервер: гибридный RAG для анализа кода на Elixir с AST и графами знаний | AiManual
AiManual Logo Ai / Manual.
04 Янв 2026 Инструмент

Ragex: как создать гибридный RAG для анализа кода на Elixir с AST и графами знаний

Как создать гибридный RAG для семантического поиска по коду на Elixir. AST-парсинг, векторные эмбеддинги и графы знаний в одном инструменте.

Представьте: вы спрашиваете у ИИ "где у нас обработка платежей", а он в ответ кидает вам три файла с функциями, названными по-разному, без понимания, как они связаны. Обычный RAG для кода работает примерно так — как слепой, пытающийся описать слона по одному хоботу.

Ragex ломает эту парадигму. Это MCP-сервер, который смотрит на код не как на текст, а как на структурированную вселенную. AST, векторы и графы — три кита, на которых стоит эта система. И да, она написана на Elixir, что для некоторых уже достаточная причина её попробовать.

Почему обычный RAG для кода — это провал

Возьмите стандартную RAG-систему из нашего руководства по созданию RAG за 15 минут. Она отлично работает с документацией, статьями, даже с правилами настольных игр (как в агенте для объяснения настолок). Но код — это другой зверь.

Проблема в контексте. Функция process_payment может вызывать validate_card, которая тянет за собой log_transaction, а та зависит от конфигурации в payment_config.ex. Обычный RAG видит только куски. Ragex видит связи.

Если вы уже работали с гибридным поиском для RAG, знаете: BM25 + векторы дают прирост точности. Но для кода этого недостаточно. Нужна третья ось — структурная.

Три головы одного дракона: архитектура Ragex

Ragex не выбирает один подход. Он использует все три одновременно:

1 AST-парсер: код как дерево

Elixir отлично парсит сам себя. Ragex использует это для разбора кода на узлы:

# Вот как выглядит разбор функции
defmodule PaymentProcessor do
  def process(%{card: card, amount: amount}) do
    # AST узел: функция process с двумя аргументами
    # Вложенные узлы: паттерн-матчинг, вызовы функций
    validate_card(card)
    |> charge(amount)
    |> log_transaction()
  end
end

Каждый узел получает уникальный идентификатор, тип (function, module, variable) и метаданные. Это не просто текст — это структура.

2 Векторные эмбеддинги: семантический поиск

Здесь Ragex делает хитрость: эмбеддинг строится не только из текста функции, но и из её сигнатуры, типов аргументов, возвращаемого значения. process_payment/1 и handle_payment/1 получат близкие векторы, даже если названия разные.

Под капотом — модель наподобие тех, что используются в мультимодальном RAG, но адаптированная для кода.

3 Граф знаний: карта зависимостей

Это самая мощная часть. Каждый узел AST становится вершиной графа. Рёбра — это связи:

  • PaymentProcessor.process/1callsCardValidator.validate/1
  • PaymentProcessorimportsLogger
  • Transactionhas_fieldamount

Когда вы спрашиваете "покажи цепочку обработки платежа", Ragex не ищет текст. Он идёт по графу.

💡
Графы знаний — это не новинка. В Skill Seekers они используются для связывания навыков. Но в Ragex граф строится автоматически из кода, а не из документации.

Установка: не так страшно, как кажется

Если вы думаете, что настройка MCP-сервера — это ад из конфигов, расслабьтесь. Ragex работает как обычное Elixir-приложение:

# Клонируем
git clone https://github.com/yourusername/ragex.git
cd ragex

# Ставим зависимости
mix deps.get
mix compile

# Индексируем проект
mix ragex.index /path/to/your/elixir/project

# Запускаем MCP-сервер
mix ragex.serve

Сервер поднимается на порту 8080 и предоставляет три основных инструмента через MCP:

Инструмент Что делает
search_code Гибридный поиск по AST + векторам
trace_dependencies Построение цепочек вызовов через граф
find_similar Поиск семантически похожего кода

Пример: как это работает на реальном коде

Допустим, у вас есть проект на 200 файлов. Вы подключаете Ragex к Claude через MCP (как в production-ready AI-агенте) и спрашиваете:

"Где у нас логируются ошибки валидации платежей?"

Обычный RAG нашёл бы все файлы со словами "log", "error", "validation". Ragex делает иначе:

  1. Находит через AST все вызовы функций валидации
  2. Ищет в графе, какие из них вызывают функции логирования
  3. Возвращает не просто файлы, а конкретные цепочки: validate_payment → log_validation_error → Logger.error

Вот как выглядит запрос через MCP:

{
  "tool": "trace_dependencies",
  "params": {
    "function_name": "PaymentValidator.validate/1",
    "depth": 3,
    "direction": "forward"
  }
}

И ответ:

{
  "path": [
    {
      "node": "PaymentValidator.validate/1",
      "type": "function",
      "file": "lib/payment/validator.ex"
    },
    {
      "edge": "calls",
      "node": "ErrorLogger.log_validation/2",
      "type": "function",
      "file": "lib/utils/logger.ex"
    },
    {
      "edge": "calls",
      "node": "Logger.error/1",
      "type": "function",
      "file": "deps/logger/lib/logger.ex"
    }
  ]
}

Сравнение с альтернативами: почему именно Ragex?

Есть другие инструменты для анализа кода. Но у каждого свои грабли:

Инструмент Плюсы Минусы Для кого
Ragex Гибридный поиск, графы знаний, интеграция с Claude через MCP Только Elixir, требует настройки Команды Elixir с большими проектами
Sourcegraph Многоподдержка языков, продвинутый поиск Только текстовый поиск, нет семантики Большие компании с разными языками
CodeQL Статический анализ, поиск уязвимостей Сложный язык запросов, не для повседневного поиска Команды безопасности
Обычный RAG Простая настройка, работает с любым текстом Не понимает структуру кода, теряет контекст Для документации, не для кода

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

Если ваш проект на 10 файлов — Ragex overkill. Но если у вас 100+ файлов, микросервисы, и вы тратите полдня на поиск "где же эта функция вызывается", он окупится за неделю.

Под капотом: как устроена индексация

Ragex не работает в реальном времени. Сначала нужно проиндексировать проект. Процесс трёхэтапный:

# 1. Парсинг AST
ast_nodes = Code.string_to_quoted!(file_content)
|> Ragex.ASTParser.parse()

# 2. Построение графа
graph = Ragex.GraphBuilder.build(ast_nodes)

# 3. Генерация эмбеддингов
embeddings = ast_nodes
|> Enum.map(&Ragex.Embedder.encode/1)
|> Enum.into(%{})

Индексация среднего проекта (50K строк кода) занимает 2-3 минуты. Зато потом поиск работает за миллисекунды.

Хранилище — комбинация ETS для графа и векторов + PostgreSQL для метаданных. Можно заменить на что-то своё, если хочется боли.

Интеграция с Claude и другими ИИ

MCP (Model Context Protocol) — это стандарт от Anthropic для подключения инструментов к ИИ. Ragex реализует MCP-сервер, поэтому работает с Claude Desktop из коробки.

Конфиг для Claude Desktop:

{
  "mcpServers": {
    "ragex": {
      "command": "/path/to/ragex/_build/dev/rel/ragex/bin/ragex",
      "args": ["start"],
      "env": {
        "RAGEX_PROJECT_PATH": "/path/to/your/project"
      }
    }
  }
}

После этого в Claude можно спрашивать прямо в чате: "Найди все места, где мы используем Redis для кэширования" или "Покажи цепочку вызовов от контроллера пользователя до отправки email".

Технически, можно подключить и к другим ИИ через MCP, но Claude пока самый удобный вариант.

Ограничения и подводные камни

Идеальных инструментов не бывает. Вот что бесит в Ragex:

  • Только Elixir. Если у вас микросервисная архитектура на пяти языках — Ragex покрывает только Elixir-часть. Для остального придётся использовать что-то ещё (или ждать, пока кто-то портирует идею).
  • Индексация при каждом изменении. Не инкрементальная. Добавили файл — переиндексируйте весь проект. Для CI/CD это нормально, для локальной разработки — раздражает.
  • Память. Граф для большого проекта жрёт RAM. 100K строк кода — около 500MB. Не критично, но учитывайте.
  • Сложность отладки. Если поиск выдаёт странные результаты, понять почему сложно. Логов маловато.

Но главное ограничение — ментальное. Ragex меняет подход к поиску кода. Вместо "найди файл с этим текстом" вы начинаете думать "найди все функции, которые вызывают эту функцию и логируют ошибки". Это требует перестройки мышления.

Кому подойдёт Ragex (а кому нет)

Берите Ragex, если:

  • Ваш проект на Elixir больше 50 файлов
  • У вас есть legacy-код, который никто полностью не понимает
  • Вы интегрируете Claude в разработку и хотите дать ему "зрение" по кодовой базе
  • Вы устали объяснять новичкам "а вот эта функция вызывается отсюда, а та — отсюда"

Не тратьте время, если:

  • Проект маленький или на другом языке
  • Вам нужен только текстовый поиск по коду (Ctrl+F достаточно)
  • Вы не используете ИИ-ассистентов в разработке
  • У вас нет времени на настройку и обучение команды
💡
Если вы работаете с мультимодальными данными (не только код), посмотрите мультимодальный RAG. Но для чистого кода Ragex эффективнее.

Что дальше? Будущее гибридных RAG для кода

Ragex — не конечная точка. Это эксперимент, который показывает: код нужно анализировать структурно. Что можно улучшить:

  1. Инкрементальная индексация. Watch за файлами, обновление графа на лету.
  2. Поддержка больше языков. TypeScript, Python, Go — те же принципы работают везде.
  3. Интеграция с IDE. Плагин для VS Code, который показывает граф зависимостей на ховере.
  4. Предсказание рефакторинга. Анализ графа для поиска "пахучих мест".

Самая интересная возможность — использовать Ragex для обучения ИИ-агентов работе с кодом. Представьте агента, который не просто читает файлы, а понимает архитектуру проекта. Как в production-ready агенте, но со знанием структуры.

Пока большинство RAG-систем бьются над улучшением поиска по документации (как в Skill Seekers), Ragex идёт в другую сторону: глубина вместо широты. Лучше понимать один язык идеально, чем все языки поверхностно.

Если вы работаете с большими Elixir-проектами — попробуйте. Первые полчаса будете ругаться на настройку. Потом зададите вопрос "покажи все места, где мы обрабатываем ошибки этого типа" и поймёте, что назад пути нет.