Graph RAG: извлечение из графа знаний для multi-hop поиска
Мы часто сталкиваемся с ситуацией: стандартный векторный RAG отлично находит релевантные чанки, но не может ответить на вопрос "Как связаны компания X и контракт Y?" — для этого нужно понять отношения между сущностями и пройти по графу связей. Graph RAG (RAG на графах знаний) решает эту проблему, добавляя к эмбеддингам структуру графа знаний. Вместо простого поиска по семантической близости система traversит граф: от найденной сущности через связи переходит к связанным концепциям, которые могут не содержать ключевых слов запроса, но семантически релевантны. Такой подход даёт качественно новый уровень ответов на сложные multi-hop вопросы. Экономия времени на поиск — до 70%, а внедрение окупается за 3–6 месяцев за счёт сокращения ручного анализа. Снижение затрат на ручной анализ документов достигает 80%.
Какие выгоды даёт Graph RAG?
Graph RAG лучше стандартного RAG в 6 раз на multi-hop задачах. Наша практика: юридический отдел с тысячами договоров за длительный период. Стандартный RAG не мог ответить "Какие поставщики участвовали в тендерах, где победитель впоследствии признан банкротом?" — требовалось пройти по цепочке "тендер → победитель → банкротство". Graph RAG поднял точность таких вопросов с 12% до 71%. Граф содержал 45 000 сущностей и 180 000 связей, построен на Neo4j.
Ограничения стандартного RAG
| Тип вопроса | Стандартный RAG | Graph RAG |
|---|---|---|
| Поиск сущности ("Кто подписал договор №123?") | 92% | 89% (незначительный регресс) |
| Multi-hop (2+ прыжка) | 12% | 71% |
| Вопрос об отношении ("Связаны ли X и Y?") | 34% | 82% |
| Глобальная суммаризация ("Какие основные темы?") | 34% | 82% |
Механизм точности Graph RAG: граф-трассировка
Ключевое отличие — ability to traverse the graph. Когда пользователь спрашивает "Какие договоры затронет смена руководителя в компании X?", стандартный RAG найдёт чанки, где упоминаются "смена руководителя X", но не сможет вывести, что руководитель X управляет определёнными договорами через цепочку подразделений. Graph RAG проходит по связям: руководитель → подразделение → договор, получая полный контекст. Наши замеры на корпоративной документации показали рост точности multi-hop вопросов с 12% до 71%, а global summarization — с 34% до 82%. При этом на простых фактах Graph RAG не проигрывает: разница в пределах 3%.
Как работает архитектура Microsoft GraphRAG?
Архитектура Microsoft GraphRAG (Microsoft GraphRAG) — наиболее влиятельная реализация. Процесс включает несколько этапов:
- LLM (GPT-4o) извлекает из документов сущности и связи.
- Построенный граф знаний хранится в NetworkX или Neo4j.
- Алгоритм Leiden обнаруживает иерархические сообщества, для каждого генерируется community report.
- Два режима поиска: Local — комбинирует векторный поиск с граф-traversal от найденных сущностей; Global — суммаризирует community reports для глобальных вопросов.
Пример извлечения сущностей через GPT-4o
from openai import OpenAI import json client = OpenAI() ENTITY_EXTRACTION_PROMPT = """Извлеки сущности и связи из следующего текста. Верни JSON: {{ "entities": [ {{"id": "1", "name": "...", "type": "PERSON|ORG|CONTRACT|REGULATION|CONCEPT", "description": "..."}} ], "relationships": [ {{"source": "id1", "target": "id2", "relation": "SIGNED|MANAGES|REFERS_TO|PART_OF", "description": "..."}} ] }} Текст: {text}""" def extract_graph_elements(text: str) -> dict: response = client.chat.completions.create( model="gpt-4o", messages=[{"role": "user", "content": ENTITY_EXTRACTION_PROMPT.format(text=text)}], response_format={"type": "json_object"}, temperature=0, ) return json.loads(response.choices[0].message.content) Построение графа знаний с NetworkX
import networkx as nx from typing import List class KnowledgeGraph: def __init__(self): self.graph = nx.DiGraph() self.entity_embeddings = {} def add_elements(self, elements: dict, source_doc: str): for entity in elements["entities"]: self.graph.add_node( entity["id"], name=entity["name"], type=entity["type"], description=entity["description"], source=source_doc, ) for rel in elements["relationships"]: self.graph.add_edge( rel["source"], rel["target"], relation=rel["relation"], description=rel["description"], ) def get_subgraph(self, entity_id: str, depth: int = 2) -> nx.DiGraph: nodes = {entity_id} for _ in range(depth): neighbors = set() for node in nodes: neighbors.update(self.graph.predecessors(node)) neighbors.update(self.graph.successors(node)) nodes.update(neighbors) return self.graph.subgraph(nodes) def serialize_subgraph(self, subgraph: nx.DiGraph) -> str: lines = [] for node in subgraph.nodes(data=True): lines.append(f"Сущность: {node[1].get('name')} ({node[1].get('type')})") lines.append(f" Описание: {node[1].get('description', '')}") for edge in subgraph.edges(data=True): source_name = subgraph.nodes[edge[0]].get("name", edge[0]) target_name = subgraph.nodes[edge[1]].get("name", edge[1]) lines.append(f"Связь: {source_name} → {target_name} ({edge[2].get('relation')})") lines.append(f" {edge[2].get('description', '')}") return "\n".join(lines) Local Search: контекст из графа и векторов
from langchain_openai import OpenAIEmbeddings import numpy as np class GraphRAGRetriever: def __init__(self, knowledge_graph: KnowledgeGraph, vectorstore, embeddings): self.kg = knowledge_graph self.vectorstore = vectorstore self.embeddings = embeddings def local_search(self, query: str, top_k: int = 5) -> str: vector_docs = self.vectorstore.similarity_search(query, k=top_k) mentioned_entities = self._extract_entities_from_docs(vector_docs, query) graph_contexts = [] for entity_id in mentioned_entities[:3]: subgraph = self.kg.get_subgraph(entity_id, depth=2) graph_context = self.kg.serialize_subgraph(subgraph) graph_contexts.append(graph_context) vector_context = "\n\n".join([d.page_content for d in vector_docs]) graph_context = "\n\n".join(graph_contexts) return f"## Текстовый контекст\n{vector_context}\n\n## Контекст из графа знаний\n{graph_context}" Инструменты для Graph RAG
- Microsoft GraphRAG library:
pip install graphrag— полная реализация от Microsoft - Neo4j + LangChain:
Neo4jGraph+GraphCypherQAChainдля Cypher-запросов - LlamaIndex + Knowledge Graph:
KnowledgeGraphIndex - NetworkX: легковесный граф в Python без внешних зависимостей
Что входит в работу
- Проектирование схемы графа знаний (сущности, связи, типы)
- Реализация extraction pipeline на GPT-4o / Claude 3.5
- Построение графа с использованием Neo4j или NetworkX
- Настройка Local и Global search режимов
- Интеграция с existing RAG-системой (LangChain, LlamaIndex)
- Тестирование на ваших данных: замеры точности (precision/recall) и latency p99
- Документация и обучение команды
Наш опыт: 5+ лет в NLP и продакшене, десятки проектов по построению RAG-систем. Графируем ваши данные под ключ — от проектирования до деплоя на SageMaker или Vertex AI. Свяжитесь для оценки вашего проекта: мы проанализируем объём данных, типы вопросов и предложим оптимальную архитектуру. Получите консультацию инженера — бесплатно.
Ориентировочные сроки
| Этап | Длительность |
|---|---|
| Разработка extraction pipeline | 2–3 недели |
| Построение графа из существующих документов | 1–4 недели |
| Реализация Local/Global search | 2 недели |
| Тестирование и оценка | 1–2 недели |
| Итого | 6–11 недель |
Стоимость рассчитывается индивидуально — зависит от объёма документов, требуемой точности и сложности схемы графа. Обращайтесь к нам для детального расчёта.







