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 недель |
Стоимость рассчитывается индивидуально — зависит от объёма документов, требуемой точности и сложности схемы графа. Обращайтесь к нам для детального расчёта.







