A B C D E F G H I J K L M N O P Q R S T V W Y Z А Б В Г Е И К М О П С Т Ц

GraphRAG

GraphRAG

GraphRAG (graph retrieval-augmented generation) это разновидность RAG, в которой контекст для языковой модели ищется не только по векторной близости текстовых фрагментов, но и по графу знаний с сущностями и связями между ними. Подход придумали в Microsoft Research, чтобы закрыть слабое место обычного поиска по эмбеддингам. Тот находит документы, похожие на вопрос. Но собрать ответ, размазанный сразу по нескольким документам, он не умеет. Разберём, как GraphRAG устроен внутри, сколько стоит его индексация и когда он не окупается.

 

Что такое GraphRAG и чем он отличается от векторного RAG

Классический RAG работает так. Корпус режется на фрагменты, каждый фрагмент превращается в вектор. Вопрос тоже превращается в вектор. Дальше из векторной базы данных достаются ближайшие к нему фрагменты. Схема отлично отвечает на вопросы вида «что написано про X». Ответ на такой вопрос обычно лежит в одном абзаце.

Проблема начинается там, где ответа целиком нет ни в одном фрагменте. Возьмём вопрос про то, в какую дирекцию входит подразделение, обслуживающее конкретного клиента. Чтобы ответить, надо пройти по цепочке: клиент, договор, менеджер, отдел, филиал, дирекция. Каждое звено записано в своём документе. Ни один из этих документов по отдельности на вопрос не похож. Векторный поиск такие связи не видит принципиально: близость считается между текстами, а не между фактами.

GraphRAG решает задачу иначе. На этапе индексации языковая модель проходит по всему корпусу. Она вытаскивает из текста сущности и отношения между ними. Получившийся граф знаний (knowledge graph, KG) хранит связи явно. Поэтому запрос может ходить по рёбрам, а не только сравнивать векторы. Именно поэтому подход относят к тому же семейству, что и KAG, где структурированное знание тоже первично.

 

Архитектура графа знаний в GraphRAG

Индексация в GraphRAG это конвейер из нескольких шагов, каждый из которых складывает свой артефакт на диск. Разберём слои, из которых состоит итоговый индекс.

GraphRAG, этапы конвейера индексации от документов до отчётов по сообществам

 

 

 

Сущности, связи и сообщества

Первый слой строится вызовом модели на каждый чанк текста. Модель получает промпт с перечнем нужных типов сущностей. В ответ она отдаёт список найденных объектов и отношений между ними. Дальше одинаковые сущности из разных чанков объединяются по названию. Их описания суммаризуются ещё одним вызовом модели.

Второй слой это кластеризация. Полученный граф разбивается на сообщества (communities) алгоритмом Лейдена. Алгоритм группирует плотно связанные узлы. Кластеризация иерархическая: сообщества нижнего уровня вкладываются в более крупные. Получается дерево от отдельных сущностей до тематических блоков всего корпуса.

 

Отчёты по сообществам как слой обобщения

Третий слой самый интересный и самый дорогой. Для каждого сообщества модель пишет отчёт: о чём этот кластер, кто в нём главный, какие факты важны. Отчёты нужны для вопросов про корпус целиком, когда конкретной сущности в вопросе нет вообще. Читать весь корпус при этом не требуется. Хватает нескольких десятков отчётов.

Все три слоя складываются в файлы формата parquet. Тексты отчётов и фрагментов дополнительно векторизуются и уходят в хранилище LanceDB. Таким образом, GraphRAG не заменяет векторный поиск, а надстраивается над ним.

 

Режимы поиска и как они используют граф

Готовый индекс обслуживает несколько принципиально разных типов вопросов, поэтому режимов запроса тоже несколько.

  • Local search. Находит в вопросе конкретные сущности, забирает их соседей по графу, связанные фрагменты исходного текста и отчёты сообществ, куда эти сущности входят. Это рабочая лошадка для вопросов про конкретный объект.
  • Global search. Игнорирует отдельные сущности и работает по отчётам сообществ в два прохода: сначала модель отвечает по каждому отчёту отдельно, потом сводит частные ответы в один. Режим для вопросов вида «какие основные темы в корпусе».
  • DRIFT search. Гибрид: стартует от сущностей как local search, но подмешивает контекст сообществ и уточняет запрос по ходу обхода графа. Дороже двух предыдущих, зато точнее на вопросах, где непонятно, от какой сущности отталкиваться.

Выбор режима это не настройка производительности, а решение о том, какой вопрос вы вообще задаёте: про конкретный объект или про корпус в целом.

ИИ-агенты для оптимизации бизнес-процессов

Код курса
AGENT
Ближайшая дата курса
26 октября, 2026
Продолжительность
24 ак.часов
Стоимость обучения
66 000

 

Сколько на самом деле стоит индексация

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

Вот цифры с локального стенда. Корпус из девяти коротких документов общим объёмом 324 слова, модель qwen2.5:7b через Ollama. Индексация с нуля заняла 734 секунды, больше двенадцати минут. Из них 401 секунда ушла на извлечение графа и 326 секунд на отчёты по сообществам. На векторизацию потрачено 7 секунд, меньше процента общего времени. Деталь важная: векторизация и есть вся работа обычного RAG. Наивный векторный поиск построил индекс по тому же корпусу за 1,5 секунды. Генеративную модель он не вызвал ни разу.

GraphRAG, разбивка времени индексации по этапам с долей извлечения графа и отчётов по сообществам

Разница почти в пятьсот раз объясняется просто. Там, где вектору хватает одного дешёвого прогона эмбеддера, графу нужен полноценный вывод языковой модели. На облачных моделях время сократится, а счёт за токены останется. И он тем больше, чем крупнее корпус. Второй момент: при обновлении документов граф надо пересобирать. Кэш спасает только неизменившиеся куски. Повторный запуск на нетронутом корпусе укладывается в 6 секунд. Но любая правка документа возвращает вызовы модели.

 

Где GraphRAG ломается

Качество графа целиком упирается в качество извлечения сущностей, а извлекает их та же самая языковая модель со всеми её слабостями. Вот что реально оказалось в графе после прогона на небольшой модели.

  • Дубли узлов. Один и тот же объект попал в граф дважды под разными названиями: отдельно ДГ-1042 и отдельно Договор обслуживания ДГ-1042. Слияние идёт по строковому совпадению названия, поэтому любая вариация написания рождает новую сущность.
  • Искажение имён. Из фамилии Гущин модель сделала два разных узла с разными опечатками, из Голубева получился Голобев. В графе это уже не опечатка в тексте, а два несуществующих человека.
  • Придуманные сущности. Из фразы про филиал Приморский модель произвела узел с типом подразделение и названием, не имеющим отношения к банку. Проверить такое можно только глазами.
  • Язык промптов протекает в результат. Штатные промпты написаны по-английски. На русском корпусе часть отчётов по сообществам вышла с английскими заголовками, а филиал Заречный в ответах превратился в Zarechnyy.
  • Ссылки на источники не гарантированы. В ответе global search модель сослалась на документы с идентификаторами, которых в корпусе нет.
  • Ответ приходит размеченным. Global search любит отдавать текст с заголовками markdown и списками. Если вы вставляете ответ в свой интерфейс, разметку придётся либо рендерить, либо вычищать.

 

Отсюда практический вывод. GraphRAG не бывает готовым из коробки. Промпт извлечения дорабатывается под предметную область, список типов сущностей задаётся явно. А размер модели напрямую влияет на то, сколько мусора окажется в графе.

 

Разработка и внедрение ML-решений

Код курса
MLOPS
Ближайшая дата курса
24 августа, 2026
Продолжительность
24 ак.часов
Стоимость обучения
66 000

 

Когда подход оправдан, а когда нет

Сравнение двух подходов по параметрам, которые реально влияют на выбор.

Параметр Векторный RAG GraphRAG
Вызовы LLM при индексации Нет На каждый чанк и на каждое сообщество
Вопросы про один документ Отвечает хорошо Отвечает, но переплата
Вопросы по связям между документами Не собирает ответ Основной сценарий
Вопросы про корпус целиком Не отвечает Global search по отчётам
Обновление корпуса Пересчёт эмбеддингов Частичная пересборка графа
Чувствительность к качеству модели Низкая Высокая, мусор попадает в граф

Если пользователи задают вопросы про отдельные факты, граф не нужен. Обычный поиск дешевле и точнее. GraphRAG начинает окупаться на других формулировках: кто с кем связан, что общего у этих объектов, о чём вообще эта база документов. Гибридные архитектуры, где графовый и векторный поиск работают вместе, разобраны в материале блога Не только векторные БД: графовый RAG для LLM и агентского ИИ.

 

Практика на локальном стенде

По традиции весь код используемый в статье выкладываем на наш GitHub репозиторий
GraphRAG from airflow import DAG from airflow.operators.bash import BashOperator from datetime import datetime with DAG( dag_id="spark_submit_demo", start_date=datetime(2025, 1, 1), schedule="@daily", catchup=False ) as dag: run = BashOperator( task_id="run_job", bash_command="spark-submit app.py" ) GitHub code example GraphRAG

Корпус для проверки собран так, чтобы ответ нельзя было найти в одном документе. Это девять справок про клиентов, договоры, менеджеров, отделы, филиалы и дирекции банка. Пакет graphrag требует Python версии ниже 3.14.

Версия Python не выше 3.13 иначе GraphRAG не доступен

Модель подключается через litellm, который склеивает имя провайдера и имя модели через слэш. Отсюда получается такая конфигурация для локальной Ollama.

# settings.yaml, проверено на graphrag 3.1.1, litellm 1.92.0, Ollama 0.32.9
completion_models:
  default_completion_model:
    type: litellm
    model_provider: ollama_chat   # для чат-моделей нужен именно суффикс _chat
    model: qwen2.5:7b
    api_base: http://localhost:11434
    api_key: ollama               # заглушка, Ollama ключ не проверяет

embedding_models:
  default_embedding_model:
    type: litellm
    model_provider: ollama        # у эмбеддера провайдер без суффикса
    model: nomic-embed-text
    api_base: http://localhost:11434
    api_key: ollama

Сборка индекса и запрос выполняются двумя командами. Первая читает документы из каталога input. вторая задаёт вопрос, ответ на который требует пройти по цепочке связей.

Первоначальная индексация документов GraphRAG занимает долгое время

вторая задаёт вопрос, ответ на который требует пройти по цепочке связей.

# Проверено на graphrag 3.1.1, Python 3.12.13

# Запрос через local search: старт от сущностей вопроса и обход их соседей
graphrag query --root . --method local \
  "В какую дирекцию банка входит подразделение, которое обслуживает ООО Северный Ветер?"

 

 

Что показал прогон

Из девяти документов получилось 24 сущности, 23 связи и четыре сообщества. Нужная цепочка собралась целиком и заняла четыре перехода: клиент, менеджер, отдел корпоративного кредитования, филиал, дирекция.

GraphRAG, цепочка из четырёх переходов по графу знаний от клиента до дирекции банка

Ни в одном исходном документе этой цепочки нет.

GraphRAG, путь из четырёх переходов по графу знаний от клиента банка до дирекции

Наивный векторный RAG на том же вопросе честно сдался. Он вытащил два ближайших документа. Самым похожим оказалась справка про совсем другой филиал. И модель сообщила, что связей для ответа не хватает.

GraphRAG, вывод наивного векторного RAG, который сообщает о нехватке связей для ответа

GraphRAG в режиме local search назвал правильную дирекцию. И сослался на конкретные документы, из которых собрал цепочку.

GraphRAG, ответ local search с названием дирекции и ссылками на исходные документы

А вот global search повёл себя хуже. На вопрос про корпус целиком он порекомендовал изучить документы с идентификаторами 34, 46 и 64, хотя документов всего девять.

GraphRAG, ответ global search со ссылками на несуществующие идентификаторы документов

Ответ приходит из графа, а рассказ про него генерирует модель. Ссылки в этом рассказе надо проверять. Скрипт сравнения обоих подходов лежит в репозитории под именем rag_baseline.py. Разбор графа и поиск пути в файле graph_stats.py.

 

Заключение

GraphRAG это осознанный размен. Дорогая индексация в обмен на ответы про связи и про корпус целиком. Граф знаний строит языковая модель. Значит, все её ошибки становятся узлами и рёбрами, которые потом попадут в ответ. Прежде чем внедрять подход, соберите небольшой стенд на своих документах. Посмотрите глазами на список извлечённых сущностей. И честно посчитайте, сколько будет стоить полная переиндексация корпуса. Если реальные вопросы пользователей не требуют обхода связей, хватит обычного векторного поиска. Практику построения таких систем разбирают на курсе ИИ-агенты для оптимизации бизнес-процессов.

 

Референсные ссылки