- BrainTools - https://www.braintools.ru -

Как я построил Graph RAG систему с точностью 96.7% за 5 дней: от научных статей до production-ready пайплайна

Skeleton Indexing [1] (KDD 2025) + HippoRAG 2 [2] (ICML 2025) + VectorCypher [3] + Datalog Reasoning + 10 итераций оптимизации


TL;DR

Я реализовал Graph RAG систему, которая комбинирует 5 техник из свежих научных статей в единый пайплайн с декларативным reasoning-движком, полной провенансной трассировкой и типизированным API. Результат: 174/180 (96.7%) на билингвальном бенчмарке из 30 вопросов, оценённых в 6 режимах retrieval. Три режима достигли 100%. Ноль persistent failures.

GitHub: vpakspace/agentic-graph-rag [4]

Проблема: почему обычный RAG недостаточен

Классический RAG — “разбей документ на чанки, сделай embeddings, найди похожие” — работает для простых фактоидных вопросов. Но он ломается на:

  • Вопросах о связях: “Как метод X связан с компонентом Y?” — ответ разбросан по разным чанкам

  • Multi-hop рассуждениях: “Что произойдёт, если изменить A, учитывая что A влияет на B, а B на C?”

  • Глобальных вопросах: “Перечисли все 7 архитектурных решений” — ответ в 7 разных местах документа

  • Кросс-языковых запросах: русский вопрос о концепциях из английского документа

Моя цель — система, которая справляется со всеми этими типами вопросов, а не только с простыми.


Архитектура: 5 техник из 2025 года

1. Skeleton Indexing (KET-RAG, KDD 2025)

Проблема: извлечение сущностей из всех чанков — дорого (O(n) вызовов LLM).

Решение: строим KNN-граф по embeddings чанков → PageRank [5] → извлекаем сущности только из top-25% “скелетных” чанков. Периферийные чанки привязываем через keyword matching.

Chunks → KNN Graph → PageRank → Top-β Skeletal (full extraction)
                                → Peripheral (keyword linking only)
Как я построил Graph RAG систему с точностью 96.7% за 5 дней: от научных статей до production-ready пайплайна - 1 [6]

Результат: 75% меньше вызовов LLM при сопоставимом качестве. Это не трюк — это математика [7]: PageRank выделяет чанки, которые наиболее “центральны” в семантическом пространстве документа.

2. Dual-Node Structure (HippoRAG 2, ICML 2025)

Проблема: обычный GraphRAG теряет контекст полных пассажей. Обычный RAG теряет связи между сущностями.

Решение: два типа узлов в Neo4j [8]:

  • PhraseNode — сущность (имя, тип, PageRank score, embedding)

  • PassageNode — полный текст чанка (контент, embedding)

  • MENTIONED_IN — связывает сущности с пассажами

  • RELATED_TO — ко-вхождения между сущностями

Это даёт и навигацию по графу (через PhraseNode), и полный контекст (через PassageNode).

3. VectorCypher Retrieval

Гибридный retrieval в три фазы, вдохновлённый VectorCypherRetriever [3] из Neo4j GraphRAG:

  1. Vector Index → находим ближайшие PhraseNode через cosine similarity

  2. Cypher [9] Traversal → расширяем через RELATED_TO (до 3 хопов)

  3. PassageNode Collection → собираем связанные пассажи → GraphContext

Ключевой инсайт: cosine re-ranking по реальным embeddings PassageNode из Neo4j бьёт RRF-фьюжн [10].

4. Agentic Router с Self-Correction

Три уровня маршрутизации с каскадным fallback:

Tier

Метод

Confidence

Описание

1

Mangle (Datalog [11])

0.7

65 билингвальных ключевых слов

2

LLM (GPT-4o-mini)

0.85

Классификация нейросетью

3

Pattern (regex)

0.5

Regex-паттерны как fallback

Если качество retrieval ниже порога (relevance < 2.0 из 5), система эскалирует по цепочке инструментов:

vector_search → cypher_traverse → hybrid_search → comprehensive_search → full_document_read
Как я построил Graph RAG систему с точностью 96.7% за 5 дней: от научных статей до production-ready пайплайна - 2 [6]

Каждая попытка перефразирует запрос через LLM. Лучшие результаты отслеживаются по всем попыткам.

5. PyMangle — Datalog-движок на Python

Полная реимплементация Google Mangle [12] (2,919 строк):

  • Lark [13]-based парсер с кастомной грамматикой

  • Semi-naive evaluation со стратифицированным отрицанием

  • 35+ встроенных функций (арифметика, строки, списки, словари)

  • Temporal evaluation

  • Filter pushdown для внешних предикатов

Три файла правил:

  • routing.mg — маршрутизация запросов (65 ключевых слов)

  • access.mg — RBAC (role inheritance + permit/deny)

  • graph.mg — граф-инференс (reachable, common_neighbor, evidence)

% Транзитивное замыкание по графу
reachable(X, Y, 1) :- edge(X, R, Y).
reachable(X, Z, D) :- reachable(X, Y, D1), edge(Y, R, Z),
    D = fn:plus(D1, 1), D < 5.

% Общие соседи двух сущностей
common_neighbor(A, B, N) :- edge(A, R1, N), edge(B, R2, N), A != B.
Как я построил Graph RAG систему с точностью 96.7% за 5 дней: от научных статей до production-ready пайплайна - 3 [6]

Бенчмарк: от 38% до 96.7% за 10 итераций

Дизайн бенчмарка

  • 30 вопросов: 7 simple, 7 relation, 6 multi_hop, 6 global, 4 temporal

  • 2 документа: Doc1 (русский, граф знаний) + Doc2 (английский, архитектура SCL)

  • 6 режимов retrieval: vector, cypher, hybrid, agent_pattern, agent_llm, agent_mangle

  • 180 оценок (30 × 6) через hybrid judge: embedding similarity + keyword overlap + LLM-as-judge [14]

Эволюция результатов

v3:  38%  ████░░░░░░░░░░░░░░░░  Baseline (вопросы на EN, документы на RU)
v4:  67%  █████████░░░░░░░░░░░  +29pp — вопросы на RU (language match!)
v5:  73%  ██████████░░░░░░░░░░  +6pp  — comprehensive_search для global
v10: 65%  █████████░░░░░░░░░░░  -8pp  — добавили 15 новых вопросов
v11: 80%  ████████████░░░░░░░░  +15pp — enumeration prompt
v12: 93%  ██████████████████░░  +13pp — hybrid judge
v14: 96.7%███████████████████░  +3.7pp — semantic judge
Как я построил Graph RAG систему с точностью 96.7% за 5 дней: от научных статей до production-ready пайплайна - 4 [6]

Финальные результаты (v14)

Режим

Результат

Vector

30/30 (100%)

Чистый embedding search

Hybrid

30/30 (100%)

Vector + Graph

Agent (Mangle)

30/30 (100%)

Datalog правила

Agent (LLM)

29/30 (96%)

GPT-4o-mini роутер

Agent (Pattern)

28/30 (93%)

Regex паттерны

Cypher

27/30 (90%)

Граф-траверсал

Итого

174/180 (96.7%)

0 persistent failures


10 уроков оптимизации

1. Язык вопросов = язык документов (+29pp)

Самое большое улучшение за всю историю проекта. Вопросы на английском о русском документе давали 38%. Переключение на русские вопросы — 67%. Embeddings хорошо справляются с кросс-языковым поиском, но LLM-генератор теряет контекст.

2. Failures — это не retrieval, а generation + evaluation

Ключевой инсайт v11: для глобальных вопросов ВСЕ нужные ключевые слова находились в top-30 чанков. Проблема была в том, что генератор не перечислял все пункты, а judge обрезал ответ до 500 символов.

3. CoT-промпт для judge — катастрофа

Попытка сделать judge “умнее” через Chain-of-Thought [15] (“перечисли найденные ключевые слова → посчитай → выдай вердикт”) вызвала регрессию с 144/180 до 48/180. GPT-4o-mini буквально искал английские строки в русском тексте. Простой промпт “match CONCEPTS, not strings” работает в 3 раза лучше.

4. Cosine re-ranking бьёт RRF

Hybrid search с Reciprocal Rank Fusion [10] давал худшие результаты, чем cosine re-ranking по реальным embeddings из Neo4j. RRF хорош для combining разных сигналов, но когда оба сигнала — embedding-based, прямое cosine similarity точнее.

5. Embedding similarity для judge (threshold 0.65)

Для вопросов с reference answer: cosine similarity между ответом системы и эталоном >= 0.65 → auto-PASS. Калибровка: правильный ответ ~0.677, неправильный (другой документ) ~0.570. Порог 0.65 идеально разделяет.

6. Кросс-языковая маршрутизация

Русский вопрос о концепциях из английского документа (Doc2/SCL) ломает vector_search — он возвращает Doc1. Решение: детектируем кросс-языковой глобальный запрос → напрямую full_document_read вместо vector_search.

7. Comprehensive search размывает результаты

comprehensive_search (multi-query fan-out) генерирует N подзапросов → каждый через vector_search → RRF merge. Но если все подзапросы возвращают Doc1, то единственный full_document_read результат для Doc2 тонет в RRF-merge.

8. Self-correction loop должен сохранять лучшее

Ранний баг: каждая попытка перезаписывала предыдущие результаты. Если attempt 1 дал score 2.5, а attempt 2 — score 1.8, система возвращала 1.8. Фикс: трекаем best_results и best_score по всем попыткам.

9. Enumeration prompt — специальный формат

Для глобальных вопросов (“перечисли все…”) обычный prompt генерирует текст, а не список. Специальный enumeration prompt: “Output a numbered list. Scan ALL chunks. Do not stop early.”

10. Judge limit 500 → 2000 символов

Обрезка ответа до 500 символов для judge убивала enumeration-ответы (7 пунктов ~ 1500 символов). Увеличение до 2000 — мгновенный +5pp.


Typed API и провенанс

Каждый запрос создаёт PipelineTrace:

{
  "trace_id": "tr_abc123def456",
  "router_step": {
    "method": "mangle",
    "decision": {"query_type": "simple", "suggested_tool": "vector_search"}
  },
  "tool_steps": [{
    "tool_name": "vector_search",
    "results_count": 10,
    "relevance_score": 3.2,
    "duration_ms": 150
  }],
  "escalation_steps": [],
  "generator_step": {
    "model": "gpt-4o-mini",
    "confidence": 0.82
  },
  "total_duration_ms": 1800
}
Как я построил Graph RAG систему с точностью 96.7% за 5 дней: от научных статей до production-ready пайплайна - 5 [6]

API: FastAPI [16] REST (/api/v1/) + FastMCP [17] (SSE/MCP) — и для REST-клиентов, и для AI-агентов.


Цифры проекта

Метрика

Значение

Python LOC

16,206 (118 файлов)

Тесты

586 (320 core + 108 PyMangle + 158 rag-core)

Зависимости

26 пакетов

Итерации бенчмарка

10 (v2 → v14)

Файлы результатов

15 JSON (~4.7 MB)

Mangle-правила

111 строк (3 файла)

Классы

36 (14 data models, 8 services, 6 config, 4 reasoning)


Что дальше

  • Personalized PageRank [18] для query-focused графового обхода

  • Human evaluation в дополнение к LLM-as-judge

  • Streaming ответы в Streamlit [19] UI

  • Больше Mangle-правил — temporal reasoning, conflict resolution


Стек

Компонент

Технология

LLM

OpenAI GPT-4o / GPT-4o-mini [20]

Embeddings

text-embedding-3-small [21] (1536 dim)

Graph DB

Neo4j 5.x [8] (Vector Index + Cypher)

Reasoning

PyMangle (Datalog [12], 2,919 LOC)

Doc Parsing

Docling [22] (PDF/DOCX/PPTX + GPU)

Graph Algorithms

NetworkX [23] (PageRank, KNN, PPR)

API

FastAPI [16] (REST) + FastMCP [17] (SSE/MCP)

UI

Streamlit [19] (7 tabs)

Testing

pytest [24] (586 tests) + ruff [25]

CI/CD

GitHub Actions [26]


Если вам интересны детали реализации или вы хотите обсудить Graph RAG — пишите в комментариях или открывайте issue на GitHub [4].

Автор: VladSpace

Источник [27]


Сайт-источник BrainTools: https://www.braintools.ru

Путь до страницы источника: https://www.braintools.ru/article/26125

URLs in this post:

[1] Skeleton Indexing: https://arxiv.org/abs/2502.09304

[2] HippoRAG 2: https://arxiv.org/abs/2502.14802

[3] VectorCypher: https://neo4j.com/docs/neo4j-graphrag-python/current/user_guide_rag.html

[4] vpakspace/agentic-graph-rag: https://github.com/vpakspace/agentic-graph-rag

[5] PageRank: https://en.wikipedia.org/wiki/PageRank

[6] Image: https://sourcecraft.dev/

[7] математика: http://www.braintools.ru/article/7620

[8] Neo4j: https://neo4j.com/

[9] Cypher: https://neo4j.com/docs/cypher-manual/current/introduction/

[10] RRF-фьюжн: https://plg.uwaterloo.ca/~gvcormac/cormacksigir09-rrf.pdf

[11] Datalog: https://en.wikipedia.org/wiki/Datalog

[12] Google Mangle: https://github.com/google/mangle

[13] Lark: https://github.com/lark-parser/lark

[14] LLM-as-judge: https://arxiv.org/abs/2306.05685

[15] Chain-of-Thought: https://arxiv.org/abs/2201.11903

[16] FastAPI: https://fastapi.tiangolo.com/

[17] FastMCP: https://github.com/jlowin/fastmcp

[18] Personalized PageRank: https://en.wikipedia.org/wiki/Personalized_PageRank

[19] Streamlit: https://streamlit.io/

[20] OpenAI GPT-4o / GPT-4o-mini: https://platform.openai.com/docs/models

[21] text-embedding-3-small: https://platform.openai.com/docs/guides/embeddings

[22] Docling: https://github.com/docling-project/docling

[23] NetworkX: https://networkx.org/

[24] pytest: https://docs.pytest.org/

[25] ruff: https://github.com/astral-sh/ruff

[26] GitHub Actions: https://github.com/features/actions

[27] Источник: https://habr.com/ru/articles/1003064/?utm_source=habrahabr&utm_medium=rss&utm_campaign=1003064

www.BrainTools.ru

Rambler's Top100