Смена модели данных графа знаний — семейства типов, детерминированный каталог мастер-данных, проверка связей по схеме — подняла соответствие связей онтологии с 7.5% до 100% и сократила граф с 7.4 до 4.7 млн вершин. Задержка графовой стадии упала с таймаута в 5 с до десятков миллисекунд. Чего мы пока не можем показать, так это заметного вклада графа в топ-10 выдачи: его ценность сейчас — в глубине пула кандидатов, строках таблиц и контексте для модели и агентов.
Если коротко — для бизнеса
- Поиск перестал ждать граф: графовая стадия раньше добавляла около 5 с к каждому ответу и возвращала пустоту, теперь она укладывается в 51 мс на проде.
- Граф стал меньше и чище: 4.7 млн вершин вместо 7.4 млн, ложных сущностей больше нет (было 62% узлов), все проверенные связи соответствуют схеме.
- Реестр мастер-данных обрабатывается без LLM: около 67 тысяч карточек в час на один поток вместо ~410 вики-документов, которым нужна модель.
- Честная оговорка: в первой десятке выдачи пользы графа пока не видно. Он помогает глубже — в пуле кандидатов и в многошаговой работе агентов, а это ещё предстоит измерить.
О цикле «RAG в проде»
Четыре статьи о том, как за две-три недели октября 2026 года мы перестроили поиск корпоративного RAG-ассистента. «Мы» — это автор и AI-агенты, которым он делегировал часть исследований и правок. Компания и системы обезличены, цифры настоящие.
Термины за минуту
- Граф знаний — сеть сущностей (систем, процессов, стандартов, организаций) и связей между ними, извлечённая из документов [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
Кому особенно полезен раздел:Бизнес и продуктАрхитекторы
Векторный и лексический поиск находят текст, похожий на запрос. Граф знаний находит текст, связанный с уже найденным через общую сущность: систему, процесс, стандарт, карточку реестра. В корпоративной базе знаний ответ часто размазан по таким связям: регламент ссылается на систему, описание системы — на справочник, а справочник живёт в реестре.
У графа три роли:
- Расширение пула кандидатов. От топа гибридного поиска граф идёт через сущности к документам, которые не похожи на запрос ни по словам, ни по смыслу. Этих кандидатов оценивает тот же реранкер, что и остальные (подробно — в первой статье).
- Графовый контекст для модели. Вместе с топ-10 чанков модель получает сущности из них и связи между ними. Это структура, которую модели иначе пришлось бы восстанавливать из текста [1] [4].
- Навигация для агентов. Агент через инструменты расширения и соседей идёт от найденной сущности к связанным и строит исследование по шагам, а не одним поисковым запросом.
Сейчас в графе около 650 тысяч документов, 750 тысяч сущностей (из них ~590 тысяч — сущности каталога мастер-данных), 2.2 млн упоминаний сущностей в документах, 185 тысяч смысловых связей между сущностями и 64 типа сущностей в онтологии. Хранится он в Memgraph рядом с PostgreSQL, в котором лежат тексты и векторы.
Смена модели данных: от «всё, что нашла LLM» к типизированной онтологии
Кому особенно полезен раздел:АрхитекторыML и исследователи
Главное решение — разделить, что извлекает LLM и что можно знать точно. Смена схемы шла пятью фазами, каждая со своим контрактом и приёмкой.
Документ — не сущность. Документы получили собственную метку и связь «упоминание в документе», а значения атрибутов (коды, номера) ушли из вершин в свойства сущностей. Это убрало 62% ложных сущностей.
Связи проверяются по семействам типов. Онтология описывает 64 типа в 19 семействах и 16 типов связей. Ребро пишется, только если типы его концов допустимы для этой связи; проверка идёт по семейству, а не по каждому типу.
Идентичность через семейство. Типы наследуются одиночно, и над ними стоят семь «семейств идентичности» (организация, подразделение, персона, проект, ссылка на документ и др.). Идентификатор сущности считается от корня семейства, а не от конкретного типа, так что модель, спутавшая подтип, больше не рождает дубль:
Каталог мастер-данных без LLM. Для карточек реестра сущность строится детерминированно из самой карточки, а её ключи (коды, номера) становятся отдельными узлами-ключами. Упоминания из вики привязываются к каталогу (grounding) с учётом прав доступа: нет уверенности — нет связи.
Гейт и дедупликация. LLM или NER-модель предлагает сущность, отдельная небольшая модель-судья решает: принять, перетипизировать или слить с существующей. Спорные слияния не выполняются, а помечаются ребром «возможно то же» для разбора.
Сущность одна на весь корпус, упоминание — одно на документ и чанк. Поиск идёт от чанка к упоминанию, от него к сущности, дальше по смысловым связям и обратно через упоминания к другим документам.
Что это дало
Кому особенно полезен раздел:Бизнес и продуктML и исследователи
Замеры — на пробном перенаполнении (6 870 документов) и на проде после перехода.
| Показатель | До | После | Где измерено |
|---|---|---|---|
| Тройки, допустимые по схеме | 7.5% | 100% (n = 1 014) | проба |
| Пары типов, допустимые по схеме | ~22% | 88.5% | проба |
| Ложные сущности (документы, атрибуты) | 62% узлов | 0 | проба |
| Вызовов LLM на карточку реестра | ≥ 1 | 0 | прод |
| Вершин / рёбер в графе | 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.
Ранняя схема содержала узлы чанков и рёбра «упоминание → чанк». От них отказались до перф-программы, и прямого замера «с чанками / без» у нас нет. Есть три аргумента и косвенные цифры.
- Размер и стоимость неиндексированных обходов. Уже сейчас упоминания дают 2.16 из 4.67 млн вершин. Чанки (сейчас ~930 тысяч живых) с рёбрами от каждого упоминания добавили бы ещё полтора–два миллиона объектов. Каждый запрос, промахнувшийся мимо индекса, сканирует все вершины — у нас это стоило 1.2–1.7 с на запрос и полный таймаут графовой стадии.
- Чанки — самая изменчивая часть данных. Каждая новая версия документа и каждая перенарезка меняет их идентификаторы. Даже с chunk_id как свойством после перечанкинга корпуса в графе осталось 59 461 ссылка на удалённые чанки, а один документ до чистки версий нёс в графе 410 chunk_id при 37 актуальных. Узлы-чанки превратили бы каждую такую перестройку в массовую перезапись графа.
- Один источник правды для доступа и удаления. Текст отдаётся только из 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 | 51 на проде |
| Сущности по 30 чанкам | 1 690 | 6 |
| Обход в ширину | 1 224 | 33–56 |
| Расширение сущностей для агента | 1 127 | 21 |
| Подграф для агента | 1 125 | 7 |
Проверьте у себя
Наличие индекса не гарантирует, что планировщик им воспользуется. Сравните 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».
Инструменты получили то же ускорение, что и поиск. До исправления формы запросов расширение документа с графом занимало ~7 с (p50 на 20 сценариях пользователя), и графовая часть была непустой в 13 из 20 случаев. Сейчас каждый из графовых запросов инструментов занимает единицы–десятки миллисекунд (см. таблицу выше), и агент может делать много шагов без заметной цены.
Чего мы не знаем
Кому особенно полезен раздел:ML и исследователиБизнес и продукт
Измерения того, насколько граф улучшает ответы агента, у нас нет: эталонный набор оценивает один поисковый запрос, а не исследование из нескольких шагов. Косвенные наблюдения скорее отрезвляют:
- многошаговые запросы через сущности долго были самым слабым классом (nDCG@10 0.34 против 0.53–0.64 у остальных), в основном из-за слишком строгого порога релевантности;
- их рост с 0.39 до 0.59 дали правки лексики и слияния, а не граф;
- граф теряет сиды, когда лексическая нога ничего не нашла: сущности берутся только из уже найденных чанков.
ML-исследователю
Выводы
Кому особенно полезен раздел:Бизнес и продуктАрхитекторыИнженерыML и исследователи
- Схема важнее объёма. Граф из всего, что нашла LLM, был больше и хуже: 62% ложных сущностей и 7.5% связей, допустимых по схеме. Типизация по семействам, проверка связей и детерминированный каталог сделали его меньше и чище.
- Всё, что можно знать точно, не надо извлекать LLM. Карточки мастер-данных превращаются в сущности детерминированно, в сто с лишним раз быстрее и без ошибок типизации.
- Граф хранит структуру, а не текст. Чанки и права доступа остаются в реляционной БД; в графе только ссылки на них. Это держит граф маленьким и переживает перенарезку корпуса без перестройки.
- В графовой БД форма запроса решает всё. Одна замена
IN $listнаUNWINDсняла 5 с с каждого ответа. - Польза графа пока не в топ-10. Он расширяет пул кандидатов и даёт структуру модели и агентам. Чтобы превратить это в метрики выдачи, нужны три вещи: извлечение сущностей из всего длинного документа, сиды из самого запроса (а не только из найденных чанков) и оценка на уровне ответа агента.
Открытый вопрос для нас: после перехода на новую схему не было чистого сравнения «граф включён / выключен» по классам запросов на финальном конвейере. Это первое, что мы сделаем, прежде чем вкладываться в граф дальше.
Литература
Кому особенно полезен раздел:ML и исследователи
- Edge D. et al. From Local to Global: A Graph RAG Approach to Query-Focused Summarization. arXiv:2404.16130, 2024.
- Jiménez Gutiérrez B. et al. HippoRAG: Neurobiologically Inspired Long-Term Memory for Large Language Models. arXiv:2405.14831, 2024 — Personalized PageRank по сущностям запроса для многошагового поиска.
- Jiménez Gutiérrez B. et al. From RAG to Memory: Non-Parametric Continual Learning for Large Language Models. arXiv:2502.14802, 2025.
- Guo Z. et al. LightRAG: Simple and Fast Retrieval-Augmented Generation. arXiv:2410.05779, 2024 — двухуровневый поиск по сущностям и связям.
- Pan S. et al. Unifying Large Language Models and Knowledge Graphs: A Roadmap. arXiv:2306.08302, 2023.
- 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.