Смена модели данных графа знаний — семейства типов, детерминированный каталог мастер-данных, проверка связей по схеме — подняла соответствие связей онтологии с 7.5% до 100% и сократила граф с 7.4 до 4.7 млн вершин. Задержка графовой стадии упала с таймаута в 5 с до десятков миллисекунд. Чего мы пока не можем показать, так это заметного вклада графа в топ-10 выдачи: его ценность сейчас — в глубине пула кандидатов, строках таблиц и контексте для модели и агентов.

Если коротко — для бизнеса

  • Поиск перестал ждать граф: графовая стадия раньше добавляла около 5 с к каждому ответу и возвращала пустоту, теперь она укладывается в 51 мс на проде.
  • Граф стал меньше и чище: 4.7 млн вершин вместо 7.4 млн, ложных сущностей больше нет (было 62% узлов), все проверенные связи соответствуют схеме.
  • Реестр мастер-данных обрабатывается без LLM: около 67 тысяч карточек в час на один поток вместо ~410 вики-документов, которым нужна модель.
  • Честная оговорка: в первой десятке выдачи пользы графа пока не видно. Он помогает глубже — в пуле кандидатов и в многошаговой работе агентов, а это ещё предстоит измерить.

О цикле «RAG в проде»

Четыре статьи о том, как за две-три недели октября 2026 года мы перестроили поиск корпоративного RAG-ассистента. «Мы» — это автор и AI-агенты, которым он делегировал часть исследований и правок. Компания и системы обезличены, цифры настоящие.

  1. Гибридный поиск: как «ноги» усиливают друг друга
  2. Индексы под гибридный поиск в PostgreSQL
  3. Структурный чанкинг и контекстные эмбеддинги
  4. Граф знаний в RAG ← вы здесь
Термины за минуту
  • Граф знаний — сеть сущностей (систем, процессов, стандартов, организаций) и связей между ними, извлечённая из документов [5].
  • Сущность — один объект реального мира, одна на весь корпус. Упоминание — факт, что сущность встречается в конкретном документе и чанке.
  • Онтология — схема графа: какие бывают типы сущностей, как они сгруппированы в семейства и какие связи между какими типами допустимы.
  • Тройка «тип — связь — тип» — например, «Система — использует — Справочник». Тройка допустима, если её разрешает онтология.
  • Суперузел — вершина с огромным числом связей (у нас до 34 тысяч). Тормозит обходы и обычно означает ошибку моделирования.
  • Мастер-данные, каталог — эталонные справочники организации (договоры, коды). Каталог — сущности, построенные из них без LLM.
  • Grounding — привязка упоминания из текста к сущности каталога.
  • Дедупликация — слияние копий одной сущности, созданных разными документами или под разными типами.
  • Сид — стартовая сущность для обхода графа; у нас — сущности из найденных чанков.
  • Обход в ширину — поиск соседей шаг за шагом: сначала прямые связи, потом связи связей.
  • MCP-инструмент — функция, которую агент вызывает по протоколу Model Context Protocol (например, «найти соседей сущности»).
  • Personalized PageRank — оценка важности вершин относительно заданных стартовых; используется для многошагового поиска (HippoRAG [2]).
  • п.п. — процентные пункты. 95%-й бутстреп-интервал [a; b] — если не включает ноль, эффект статистически значим.

Исходные условия

Кому особенно полезен раздел:Бизнес и продуктИнженеры

Аудит схемы в начале октября показал, что граф большой, но в значительной части не про то. Сущности извлекались LLM из каждого документа, включая 600 тысяч карточек реестра, и писались без проверки по схеме.

  • 7.4 млн вершин и 8.6 млн рёбер, суперузлы степенью до 34 тысяч; при наполнении графовая БД сидела на 100% CPU.
  • 62% вершин-«сущностей» сущностями не были. Это либо узлы, дублирующие сами документы (632 тысячи), либо значения атрибутов вроде кодов и номеров (640 тысяч).
  • Связи не соответствовали онтологии: только 7.5% троек «тип — связь — тип» и ~22% пар типов были допустимы по схеме (выборка 200 тысяч рёбер).
  • Одна сущность жила в нескольких копиях разных типов: 5 293 таких группы, 10 734 узла; в крайнем случае одно имя было 9 сущностями шести типов.
  • Графовая стадия поиска таймаутила в 100% запросов (150 из 150) и добавляла ~5.08 с к каждому ответу, возвращая пустой результат; расширение для агентов отвечало за 3.9 с (p50).
  • Вклад в качество был спорным. На эталонном наборе (разметка LLM-судьёй [6]) отключение графа даже чуть поднимало общий nDCG@10 (0.635 → 0.646) и многошаговые запросы (0.595 → 0.637), но роняло строки таблиц (0.813 → 0.711).

Зачем граф в RAG

Кому особенно полезен раздел:Бизнес и продуктАрхитекторы

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

У графа три роли:

  1. Расширение пула кандидатов. От топа гибридного поиска граф идёт через сущности к документам, которые не похожи на запрос ни по словам, ни по смыслу. Этих кандидатов оценивает тот же реранкер, что и остальные (подробно — в первой статье).
  2. Графовый контекст для модели. Вместе с топ-10 чанков модель получает сущности из них и связи между ними. Это структура, которую модели иначе пришлось бы восстанавливать из текста [1] [4].
  3. Навигация для агентов. Агент через инструменты расширения и соседей идёт от найденной сущности к связанным и строит исследование по шагам, а не одним поисковым запросом.

Сейчас в графе около 650 тысяч документов, 750 тысяч сущностей (из них ~590 тысяч — сущности каталога мастер-данных), 2.2 млн упоминаний сущностей в документах, 185 тысяч смысловых связей между сущностями и 64 типа сущностей в онтологии. Хранится он в Memgraph рядом с PostgreSQL, в котором лежат тексты и векторы.

Смена модели данных: от «всё, что нашла LLM» к типизированной онтологии

Кому особенно полезен раздел:АрхитекторыML и исследователи

Главное решение — разделить, что извлекает LLM и что можно знать точно. Смена схемы шла пятью фазами, каждая со своим контрактом и приёмкой.

  1. Документ — не сущность. Документы получили собственную метку и связь «упоминание в документе», а значения атрибутов (коды, номера) ушли из вершин в свойства сущностей. Это убрало 62% ложных сущностей.

  2. Связи проверяются по семействам типов. Онтология описывает 64 типа в 19 семействах и 16 типов связей. Ребро пишется, только если типы его концов допустимы для этой связи; проверка идёт по семейству, а не по каждому типу.

  3. Идентичность через семейство. Типы наследуются одиночно, и над ними стоят семь «семейств идентичности» (организация, подразделение, персона, проект, ссылка на документ и др.). Идентификатор сущности считается от корня семейства, а не от конкретного типа, так что модель, спутавшая подтип, больше не рождает дубль:

    entity_id=sha1(identity_root ∣ name ∣ scope)\mathrm{entity\_id} = \mathrm{sha1}(\mathrm{identity\_root} \,|\, \mathrm{name} \,|\, \mathrm{scope})
  4. Каталог мастер-данных без LLM. Для карточек реестра сущность строится детерминированно из самой карточки, а её ключи (коды, номера) становятся отдельными узлами-ключами. Упоминания из вики привязываются к каталогу (grounding) с учётом прав доступа: нет уверенности — нет связи.

  5. Гейт и дедупликация. LLM или NER-модель предлагает сущность, отдельная небольшая модель-судья решает: принять, перетипизировать или слить с существующей. Спорные слияния не выполняются, а помечаются ребром «возможно то же» для разбора.

Модель данных графа после смены схемы: текст остаётся в PostgreSQL, граф хранит только ссылку на чанкМодель данных графа после смены схемы: текст остаётся в PostgreSQL, граф хранит только ссылку на чанкреализацияключсмысловая связь16 типов, по схемеупомянута вв документеchunk_idтекст по idТип сущности64 типа, 19 семействСущностькаталог илиизвлечённаяКлюч каталогакод, номер,идентификаторУпоминаниесвойство chunk_idДокументверсия, источникЧанкне узел, только ссылкаPostgreSQLтекст, векторы, права
Модель данных графа после смены схемы: текст остаётся в PostgreSQL, граф хранит только ссылку на чанк

Сущность одна на весь корпус, упоминание — одно на документ и чанк. Поиск идёт от чанка к упоминанию, от него к сущности, дальше по смысловым связям и обратно через упоминания к другим документам.

Что это дало

Кому особенно полезен раздел:Бизнес и продуктML и исследователи

Замеры — на пробном перенаполнении (6 870 документов) и на проде после перехода.

Граф до и после смены схемы. «Проба» — пробное перенаполнение 6 870 документов, «прод» — прод после перехода. «После» — на момент замера сразу после перехода; сейчас смысловых связей около 185 тыс.
ПоказательДоПослеГде измерено
Тройки, допустимые по схеме7.5%100% (n = 1 014)проба
Пары типов, допустимые по схеме~22%88.5%проба
Ложные сущности (документы, атрибуты)62% узлов0проба
Вызовов LLM на карточку реестра≥ 10прод
Вершин / рёбер в графе7.4 млн / 8.6 млн4.7 млн / 6.4 млнпрод
Смысловых связей между сущностями1.23 млн176 тыс.прод
Максимальная степень сущностидо 34 тыс.4 152; у 96.8% — не больше 10прод
Привязка упоминаний к каталогу, точность—~95% (39 из 41)проба

Каталог сделал реестр дешёвым: ~67 тысяч карточек в час на один поток против ~410 вики-документов, которым нужен LLM.

Чего таблица не показывает

  • Grounding точный, но редкий. Точность высокая, но покрытие малое: в 1 638 из 1 670 случаев кандидата в каталоге не нашлось.
  • Раздробленность осталась: 41 тысяча групп «имя + тип» на 137 тысяч узлов.
  • Выборки маленькие. «100%» допустимых троек — это n = 1 014, точность grounding — 39 из 41, ошибочных слияний 0 из 5. Для последней цифры выборка слишком мала для выводов.

Гейт пришлось ослабить. Первая версия с порогом 0.75 выбрасывала 44% сущностей при точности принятых ~0.94 — ценой потери примерно трети полноты. Вторая версия только перетипизирует (0.14–0.27% сущностей) и замедляет наполнение на ~8%. Дедупликация распределяет новые упоминания так: 97.9% — точное совпадение, 0.4% — слияние, 0.3% — на разбор, 1.2% — новая сущность.

Почему в графе нет чанков

Кому особенно полезен раздел:АрхитекторыИнженеры

Граф у нас «без чанков»: в нём нет ни узлов-чанков, ни их текста. Связь с текстом — одно свойство chunk_id у упоминания сущности в документе. Текст, векторы, права доступа и признак «живой/удалённый» живут в PostgreSQL.

Ранняя схема содержала узлы чанков и рёбра «упоминание → чанк». От них отказались до перф-программы, и прямого замера «с чанками / без» у нас нет. Есть три аргумента и косвенные цифры.

  1. Размер и стоимость неиндексированных обходов. Уже сейчас упоминания дают 2.16 из 4.67 млн вершин. Чанки (сейчас ~930 тысяч живых) с рёбрами от каждого упоминания добавили бы ещё полтора–два миллиона объектов. Каждый запрос, промахнувшийся мимо индекса, сканирует все вершины — у нас это стоило 1.2–1.7 с на запрос и полный таймаут графовой стадии.
  2. Чанки — самая изменчивая часть данных. Каждая новая версия документа и каждая перенарезка меняет их идентификаторы. Даже с chunk_id как свойством после перечанкинга корпуса в графе осталось 59 461 ссылка на удалённые чанки, а один документ до чистки версий нёс в графе 410 chunk_id при 37 актуальных. Узлы-чанки превратили бы каждую такую перестройку в массовую перезапись графа.
  3. Один источник правды для доступа и удаления. Текст отдаётся только из PostgreSQL, где применяются фильтры прав и признак живости. Граф не может «вернуть» удалённый или закрытый документ, даже если в нём осталась устаревшая ссылка.

Обратная сторона тоже измерена. Мы долго держали вторую копию связей «сущность — чанк» в PostgreSQL: 11.7 млн строк, из которых живых 2.74 млн, 9.9 ГБ. Фоновая пересвязка этой копии занимала 93% времени базы (подробнее — во второй статье). После отказа от неё единственным источником связи стало свойство в графе.

Архитектору

Правило, которое мы вынесли: связь хранится один раз, текст — один раз, и не в одном и том же месте. Граф знает структуру и ссылается на текст; реляционная БД знает текст, права и живость. Любая вторая копия связи быстро становится главной статьёй расходов на синхронизацию.

Как граф влияет на выдачу сейчас

Кому особенно полезен раздел:ML и исследователиБизнес и продукт

На топ-10 — почти никак, на глубину пула — значимо. На новой схеме отключение графа даёт nDCG@10 +0.1 п.п. [−0.9; +1.1] и key-doc R@10 −0.1 п.п. [−1.4; +1.2], но снижает полноту пула из 50 кандидатов на 2.1 п.п. [−3.1; −1.2]. На старой схеме без графа проседали строки таблиц (−2.9 п.п. nDCG после дооценки) и короткие запросы.

Почему так. Граф приводит кандидатов, которые не похожи на запрос, и чаще всего реранкер ставит их ниже прямых попаданий. Это осознанный выбор. Когда графовые попадания сливались с остальными через RRF, сотни графовых чанков вытесняли векторные, и средний скор реранкера в выдаче падал до 0.06. Сейчас графовых кандидатов не больше 30, и решает реранкер (средний скор вернулся к 0.92; цифра из журнала разработки, не из эталонного прогона).

Как работает стадия

Кому особенно полезен раздел:Инженеры

  • сиды — сущности, упомянутые в чанках топа после RRF;
  • обход в ширину до двух шагов, до 25 соседей на шаг, с пропуском уже посещённых вершин;
  • документы ранжируются по числу разных сущностей, через которые они достижимы;
  • чанки документов берутся из PostgreSQL, до 5 на документ и до 200 всего;
  • стадия идёт параллельно с первым проходом реранкера, с жёстким таймаутом и отказом без ошибки.

Задержка: форма запроса важнее индекса

Кому особенно полезен раздел:Инженеры

Индексы в графовой БД были, но запросы вида MATCH (n) WHERE n.id IN $list планировщик исполнял полным сканом 4.7 млн вершин. Форма UNWIND $ids AS x MATCH (n:Label {id: x}) идёт по индексу.

Задержка графовых запросов до и после смены формы запроса. «> 6 000» — время запроса без ограничения; в проде стадию обрывал таймаут 5 с, отсюда ~5.08 с к каждому ответу
ЗапросДо, мсПосле, мс
Графовая стадия поиска целиком> 6 00051 на проде
Сущности по 30 чанкам1 6906
Обход в ширину1 22433–56
Расширение сущностей для агента1 12721
Подграф для агента1 1257

Проверьте у себя

Наличие индекса не гарантирует, что планировщик им воспользуется. Сравните EXPLAIN для двух форм:

// полный скан всех вершин
MATCH (n) WHERE n.id IN $list RETURN n;

// поиск по индексу для каждого id
UNWIND $ids AS x
MATCH (n:Label {id: x})
RETURN n;

Важны обе детали: метка :Label, по которой построен индекс, и разворачивание списка через UNWIND.

Отдельно дорогим оказался LLM-фильтр графового контекста: 3.9 с на запрос, из них сам вызов модели — 0.35 с, остальное — эмбеддинг каждого имени сущности. Теперь, когда клиенту нужны только метрики графа, фильтр пропускается.

Связь сущностей с чанками

Кому особенно полезен раздел:ML и исследователиИнженеры

Качество сидов зависит от того, к каким чанкам привязаны упоминания: чанк без сущностей не может стать сидом. После перехода на структурный чанкинг линкер учитывает путь раздела и термины чанка, и доля живых чанков с сущностями выросла с 70.8% до 73.3%. Дальше потолок — извлечение: LLM отдаёт 10–35 сущностей на документ независимо от его длины (см. третью статью цикла).

Глубокое исследование агентами

Кому особенно полезен раздел:АрхитекторыБизнес и продукт

Для агентов граф — не часть поиска, а карта местности. Один поисковый запрос возвращает десять чанков; с графом агент видит, какие сущности в них упомянуты, с чем они связаны и в каких ещё документах встречаются. Это база для многошаговых вопросов вида «какие регламенты затронет замена системы X».

Цепочка MCP-инструментов агента: граф отдаёт только структуру, текст агент получает только через expandЦепочка MCP-инструментов агента: граф отдаёт только структуру, текст агент получает только через expandновый запросqueryчанки + сущностив каждом попаданииkg_entity_lookupсущность по имени итипуkg_neighbors /kg_subgraphсоседи на 1–3 шага,без текстаСвязанные документыссылки из упоминанийсущностейexpand(doc)текст чанков изPostgreSQL,с правамиОтвет агентаили следующий шагисследования
Цепочка MCP-инструментов агента: граф отдаёт только структуру, текст агент получает только через expand

Инструменты получили то же ускорение, что и поиск. До исправления формы запросов расширение документа с графом занимало ~7 с (p50 на 20 сценариях пользователя), и графовая часть была непустой в 13 из 20 случаев. Сейчас каждый из графовых запросов инструментов занимает единицы–десятки миллисекунд (см. таблицу выше), и агент может делать много шагов без заметной цены.

Чего мы не знаем

Кому особенно полезен раздел:ML и исследователиБизнес и продукт

Измерения того, насколько граф улучшает ответы агента, у нас нет: эталонный набор оценивает один поисковый запрос, а не исследование из нескольких шагов. Косвенные наблюдения скорее отрезвляют:

  • многошаговые запросы через сущности долго были самым слабым классом (nDCG@10 0.34 против 0.53–0.64 у остальных), в основном из-за слишком строгого порога релевантности;
  • их рост с 0.39 до 0.59 дали правки лексики и слияния, а не граф;
  • граф теряет сиды, когда лексическая нога ничего не нашла: сущности берутся только из уже найденных чанков.

ML-исследователю

Следующий шаг — набор задач для агента с оценкой итогового ответа (а не выдачи) и сравнением «с графовыми инструментами / без». Для многошагового ранжирования в самом поиске мы рассматриваем Personalized PageRank по сущностям запроса, как в HippoRAG [2] [3], но пока не строили.

Выводы

Кому особенно полезен раздел:Бизнес и продуктАрхитекторыИнженерыML и исследователи

  • Схема важнее объёма. Граф из всего, что нашла LLM, был больше и хуже: 62% ложных сущностей и 7.5% связей, допустимых по схеме. Типизация по семействам, проверка связей и детерминированный каталог сделали его меньше и чище.
  • Всё, что можно знать точно, не надо извлекать LLM. Карточки мастер-данных превращаются в сущности детерминированно, в сто с лишним раз быстрее и без ошибок типизации.
  • Граф хранит структуру, а не текст. Чанки и права доступа остаются в реляционной БД; в графе только ссылки на них. Это держит граф маленьким и переживает перенарезку корпуса без перестройки.
  • В графовой БД форма запроса решает всё. Одна замена IN $list на UNWIND сняла 5 с с каждого ответа.
  • Польза графа пока не в топ-10. Он расширяет пул кандидатов и даёт структуру модели и агентам. Чтобы превратить это в метрики выдачи, нужны три вещи: извлечение сущностей из всего длинного документа, сиды из самого запроса (а не только из найденных чанков) и оценка на уровне ответа агента.

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

Литература

Кому особенно полезен раздел:ML и исследователи

  1. Edge D. et al. From Local to Global: A Graph RAG Approach to Query-Focused Summarization. arXiv:2404.16130, 2024.
  2. Jiménez Gutiérrez B. et al. HippoRAG: Neurobiologically Inspired Long-Term Memory for Large Language Models. arXiv:2405.14831, 2024 — Personalized PageRank по сущностям запроса для многошагового поиска.
  3. Jiménez Gutiérrez B. et al. From RAG to Memory: Non-Parametric Continual Learning for Large Language Models. arXiv:2502.14802, 2025.
  4. Guo Z. et al. LightRAG: Simple and Fast Retrieval-Augmented Generation. arXiv:2410.05779, 2024 — двухуровневый поиск по сущностям и связям.
  5. Pan S. et al. Unifying Large Language Models and Knowledge Graphs: A Roadmap. arXiv:2306.08302, 2023.
  6. Upadhyay S. et al. UMBRELA: UMbrela is the (Open-Source Reproduction of the) Bing RELevance Assessor. arXiv:2406.06519, 2024 — LLM-судья для эталонного набора.

Идентификаторы arXiv сверены с API arXiv 25 октября 2026.