В 22% случаев онкологи не могут назначить лечение из-за рисков, связанных с хроническими заболеваниями. Сегодня разбираем кейс, в котором ИИ помогает врачам решать сложнейшие когнитивные задачи, связанные с лечением различных видов рака. Рассказываем про методологию GraphRAG, разбираем, как устроены и работают решения из кейса и проводим сравнительный анализ всех способов решить эту сложнейшую задачу.

Привет, Хабр! Это Андрей Носов, AI-архитектор из Raft. Я проектирую и создаю системы, которые должны стоять годами — сегодня речь пойдёт именно о них. В этой статье по мотивам моего доклада на AI Сonf 2025 я расскажу, как превратить стандартные RAG-системы из простых источников знаний в управляемый инструмент, способный справиться со сложным контекстом. Вас ждёт не просто технический обзор, а практическое руководство, где мы пойдём от прода к проду.
Рассказ будет предметным, основанным на реальном кейсе врача-онколога Анны. Перед ней ежедневно стоит сложная когнитивная задача, требующая максимальной точности. Например:
Какие риски несёт химиотерапия на основе цисплатина для пациента с немелкоклеточным раком легкого и сопутствующим сахарным диабетом?
Цисплатин может навредить. Если искать информацию о рисках с помощью стандартной RAG-системы, то она найдёт отдельные документы о цисплатине, диабете, но упустит самое главное — где лечим, а где калечим. То есть поиск найдет всё, но связать это не сможет. По Gartner в среднем такие ситуации встречаются в 22% случаев. Представьте себе, 22% пациентов мы просто не лечим.
Сегодня попробуем помочь Анне:
Погрузимся в проблему.
Затем подробно расскажу о методологии, которая нам позволит оставаться на плаву. Это методология Бенчмаркинга, которую мы создаем как объективный полигон для тестирования, включая стек, датасеты и метрики.
Центральной и самой насыщенной частью станет детальный разбор 8 способов GraphRAG, нашего полноценного арсенала решений.
После этого проведём сравнительный анализ. Это будет бизнес-анализ ближе к тому, чтобы принимать или не принимать в прод, но технических деталей будет также немало.
В завершение дам достаточно полезный инструмент, которым сам пользуюсь и который появился как раз на основе нескольких продакшен решений в ходе нашей совместной с Анной разработки.
Начнём с определений.
В графовых базах данных под сообществом подразумеваются кластеры — облака данных, в которые объединяются данные, чтобы взаимодействовать друг с другом.
Прежде, чем углубимся в детали, посмотрим, что же такое GraphRAG в целом.

Это гораздо больше, чем комбинация RAG и графовой базы. Это целое семейство архитектур, в которых граф знаний выступает не как пассивное хранилище, а как центральный активный элемент всего процесса извлечения и формирования контекста. В этой парадигме граф используется для интеллектуальной навигации по данным, агрегации разрозненной информации и, что наиболее важно для Анны, выявляет скрытые и неявные связи.
Первый вопрос Анны — почему я должна вам доверять? Чтобы ответить на него, родилась идея создать собственный бенчмарк, который будет замерять качество наших решений. Не просто набор документов, а полноценную систему оценки.
Для создания бенчмарка готовим золотой датасет. Затем стратифицируем его по трём уровням сложности. Ведь запросы у нас не всегда настолько сложные, как первый (в стиле проблемы вагонетки — знаменитой моральной дилеммы, где нужно выбрать, кто выживет).
Есть относительно простые запросы, например, «какое лекарство мне принять для того, чтобы перестала болеть голова?». Хотя и этот ответ может иметь под собой достаточно глубокий граф противопоказаний.
Бенчмарк мы создали на основе типичных вопросов для врача-онколога. Эти вопросы позволили нам с заказчиком договориться о критериях качества. С ними помогала сама Анна. Для каждого вопроса мы вместе с ней написали эталонный, максимально полный и точный ответ, который можно составить, используя только информацию из нашего корпуса.
Сразу обращаю внимание, что далее будет пример для медтеха. Для других областей нужно писать кастомный бенчмарк со своими вопросами.
Для ответа на вопрос Анны нужно найти информацию. Мы собрали несколько переработанных клинических рекомендаций. Это каждодневный когнитивный труд врачей-онкологов — они пишут себе шаблоны, те устаревают, как только выходит новое лекарство, шаблон заново переписывают.

Мы подготовили эталонный набор данных (ground truth), который позволил точно оценить качество ответов. Для проверки использовали фреймворк DeepEval. Это удобный инструмент, где «из коробки» доступно более 18 метрик оценки. Кроме того, он предлагает встроенное хранилище, легкую интеграцию с CI/CD и возможность гибкой настройки прямо в базе данных.
Из набора метрик, который предлагается в DeepEval, мы взяли оценку галлюцинаций (faithfulness) — нашу самую важную метрику. Каждый ответ, сгенерированный системой, мы разбивали на отдельные факты. Затем DeepEval автоматически проверял, можно ли найти доказательство каждому из этих утверждений в том контексте, который наша графовая RAG-система извлекала из базы знаний. Если факт не подтвердился, он считался галлюцинацией. Метрика, по сути, показывает долю выдуманных фактов. Причём уровень контроля «надуманности» мы устанавливаем сами.
Второй по важности метрикой мы выбрали релевантность ответа. Логика проста: если модель «галлюцинирует» или отвечает невпопад, то остальные показатели уже не важны. Для проверки мы использовали метод «LLM как судья» (LLM-as-a-Judge). Суть подхода в том, что мы не вычитываем ответы вручную, а поручаем это другой, более мощной нейросети (например, GPT-4o). Она выступает в роли арбитра: читает вопрос пользователя и ответ нашей модели, а затем оценивает, насколько ответ адекватен и соответствует теме. GPT-4o — достаточно мощная модель, она обладает хорошей базой знаний, наполненной медицинскими данными. Изначально мы использовали MedGemma, которая запускается на CPU. Но в какой-то момент поняли, что знания из PubMed, заложенные в MedGemma, оказались недостаточными для узких онкологических кейсов. А GPT обучалась на полноценном большом датасете. Однако мы до сих пор не теряем надежды заменить GPT на локальную хорошо натренированную модель, возможно, это будет следующая версия MedGemma.
Вернёмся к релевантности модели. GPT получает на вход исходный вопрос. Далее она оценивает сгенерированный системой ответ по шкале от 0 до 1, и показывает, насколько он точен по существу.
Ещё одна метрика, которую мы задействовали, это полнота контекста — Contextual Recall. Она показывает, вся ли найденная информация нам необходима в ответе. Очень часто клинические рекомендации содержат много гиперссылок и прочих вещей, которые являются избыточными для принятия того или иного решения, что увеличивает когнитивную нагрузку не только на мозг человека, но и на «мозг» LLM. Мы сравнивали контекст, извлеченный системой, с нашим эталонным ответом и смотрели, все ли ключевые факты из золотого стандарта присутствуют в извлечённом контексте.
Последние две метрики шли от бизнеса — это задержки (latency) и косты. Задержки мы измеряли как полное end-to-end время от момента отправки HTTP-запроса до получения конечного ответа. Косты мы рассчитывали на основе официальных прайсов, которые нам предоставляет OpenAI.
Теперь о том, из каких кубиков мы построили эту систему. Мы рассмотрели несколько вариантов и выбрали самый взвешенный.

В качестве СУБД мы взяли Neo4j, но выбирали, как минимум, из Arango и TigerGraph. Почему наш выбор пал на Neo4j? На сегодняшний день это не просто база данных, а мощная платформа, включающая в себя развитые механизмы индексации и поддержку ACID-транзакций. Это гарантирует целостность и полноту данных, а также делает инструмент эффективным в самых разных предметных областях. Такая универсальность была для нас ключевой, поскольку мы — продакшен-компания, работающая с широким спектром доменов.
Мы работаем с классной библиотекой GDS – Graph Data Science Library. Она пришла из исследовательской области, где её использовали для экспериментов. Мы адаптировали эту библиотеку как вычислительный движок для графовой аналитики. Активно используем до сих пор для всех наших практических реализаций, особенно в методах, которые касаются формирования кластеров, объединяющих в себе определённые доменные знания.
Следующим инструментом в нашем стеке стал LangChain. Важно уточнить: мы остановились именно на базовой библиотеке, а не на LangGraph. LangChain выступил в роли связующего звена («клея») нашей архитектуры. Его возможностей по оркестрации нам вполне достаточно для построения RAG-цепочек, управления промптами и взаимодействия с моделями.
OpenAI у нас используется для извлечения сущностей, ещё с его помощью мы строили векторы. Сейчас переехали на модель построения векторов от Gemini — она небольшая, всего лишь 300Mb. В этом кейсе мы использовали модель Text-Embedding-3-Large, потому что она обладает достаточной обобщающей способностью, чтобы переваривать медицинские данные.
Перед тем, как я расскажу о восьми способах обуздать широкий контекст, крайне важно понять фундамент, на котором базируются все последующие архитектуры.

На иллюстрации можно увидеть пайплайн построения графа знаний из неструктурированных текстовых данных. Он состоит из четырёх последовательных этапов:
Чанкинг. В статье из моего доклада на Saint HighLoad я уже рассказывал об этом процессе. В двух словах – это когда мы разбиваем данные на отрезки, чтобы «скармливать» их модели. Для этого есть много разных подходов.
Извлечение, так называемый retrieval, где LLM анализирует каждый фрагмент, извлекает сущности, отношения между ними, так называемые ребра.
Загрузка, когда структурированные данные перемещаются в Neo4j.
Индексация. Здесь происходит настройка индексов. Это нужно, чтобы ускорить чтение данных и чтобы любые запросы к ним выполнялись быстро.
Важно понимать, что этот процесс требует ресурсов. Обработка в нашем случае двух тысяч статей из клинических рекомендаций обошлась нам примерно в 30 долларов. Заняла она не так много времени, всего 35 минут. Но даже 30 долларов, как будто бы небольшая сумма, является необходимой инвестицией на старте проекта.
Для начала объясню, почему именно в таком порядке будут расположены способы. Очень важно как можно быстрее донести ценность до заказчика. Инженеры никогда не идут на большие риски на самом старте, а закладывают некий baseline, вдруг он устроит и потом постепенно усложняют проект по запросу заказчика.
Проблема: неструктурированный поиск
Базовый поиск по ключевым словам не находит все релевантные документы и не понимает символы, что приводит к неполным ответам.
Решение
Базовое извлечение сущностей и связей. Переход от поиска по тексту к поиску по структурированным сущностям.
Фундаментом был базовый GraphRAG. Его основная задача — решить проблему неструктурированного поиска, когда базовый поиск (в нашем случае по семантической близости) не способен понимать синонимы. Я имею в виду расширенную синонимию: гипонимы, гиперонимы, когда текст расширяется по включённости, по исключённости, по синонимии, по антонимии и так далее, и при этом все сущности иногда пересекаются. Этот поиск не способен был решить такую проблему. Он предполагал простое, фундаментально важное. Здесь мы переходили от поиска по сырому тексту к поиску по чётко определённым структурированным сущностям в графе.
В контексте задачи Анны это означало, что вместо неточного поиска по слову «цисплатин» происходил целенаправленный запрос на поиск узла, где этот термин содержался. Например, узла Drug (лекарства), таким образом обеспечивалась связность. У нас уже появляется не просто определение. В данном случае цисплатин точно оказывался лекарством, и это уже была победа.
Такой подход обеспечивал более высокую точность, но только на заданной выборке.
Здесь архитектура максимально прямолинейна. Пайплайн запроса представляет собой простой Cypher-запрос. Cypher — SQL-подобный язык, специально спроектированный, чтобы отражать сущности графов, как видно на иллюстрации ниже, достаточно интуитивный. Он ищет узлы в нашем случае с меткой entity, где его свойство name содержит текст пользовательского запроса. Критически важным для производительности элементов здесь является создание индекса на свойстве, у нас это name.

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


Первое — это контекстная изоляция. Мы находим два контекстно-изолированных ответа и должны их как-то между собой связывать уже дополнительными костылями. Метод отлично находит сам узел, но часто упускает из виду его важные связи.
Вторая проблема — ад синонимов, о котором я рассказывал выше. Например, без дополнительной обработки очень близкие понятия «инфаркт» и «МИ» (инфаркт миокарда) в графе раз за разом оказывались на очень разных расстояниях, как несвязанные между собой узлы.
Для преодоления этих проблем мы сделали костыли:
Иерархическое разрешение сущностей (ML). Чтобы заработал базовый GraphRAG, своего рода демоверсия, мы внедрили иерархическое разрешение сущностей и использовали словарь UMLS — обычный линейный словарь терминов.
Precomputed Entity Cache для 50k терминов. При A/B тестировании собрали достаточно хороший пул запросов, которые легли в базу кэша. То есть мы кэшировали результаты на самих тестах.
Вау-эффект сработал: базово у нас этот подход выдавал не больше 76% точности, а после этих двух маленьких дополнений показатель взлетел до 94%. Однако для чистоты эксперимента при переходе к следующим методам мы вернемся к базовому показателю 76%. Мы хотим построить системное архитектурное решение, а не полагаться только на "костыли" и кэширование, которые сложно масштабировать.
В какой-то момент Анна задала другие запросы, не те, которые были предусмотрены для тестирования. Она пришла к нам и сказала: «Ребята, но вот же два несвязанных факта — а где все-таки мышление?». Мы пообещали доработать, чтобы из разрозненных кусков данных, разбросанных по множеству документов собиралась релевантная картина.
Проблема: Фрагментация контекста
Ответы неполные, потому что релевантная информация разбросана по разным документам. Как собрать целостную картину?
Решение: Community-Based Retrieval
Связанные факты образуют плотные кластеры (сообщества) в графе.
Кейс Анны: Найдя "цисплатин", мы смотрим на все его "тематическое окружение", где находятся "нефротоксичность" и "почечная недостаточность".
Да, это сложно. Здесь мы пошли способом Community-Based Retrieval. Это подход, основанный на том, что связанные факты и понятия образуют в графе плотные кластеры — сообщества.
Для Анны это означает, что, найдя цисплатин, система автоматически подсвечивает его как тематическое окружение в рамках таких терминов, как «нефротоксичность», «почечная недостаточность». То есть указывает на ограничения, связанные с почками, которые имеет данное лекарство.
После демонстрации решения Анна была удивлена — отлично, нашли когнитивную связанность по сообществам! Архитектуру мы также презентовали.

Поиск по сообществам у нас построен на кластеризации, основанной на алгоритмах Лувена.
Сразу объясню, почему не Лейден. Хоть его и Майкрософт презентовал и это крутейший алгоритм, он спроектирован, чтобы обрабатывать максимально широкие знания по общему домену. А Лувен лучше работает на структуре данных, свойственной медицинским графам/PubMed. Поэтому Лувен показал у нас лучшую производительность, чем Лейден. То есть мы взяли вторую строчку, но с поправкой на домен. Поэтому всегда рекомендую смотреть алгоритмы (их больше десятка) с разными extension, от простых к самым сложным, для подборки сообществ, communities.
Мы не придумывали и не заводили алгоритм с нуля, не заводили ни одного его extension. Кто пробовал хоть раз заводить математические extensions, знает, насколько это большой труд не попасть в различные пространные области. Все эти вещи есть из-под капота в библиотеке GDS.
С помощью метода gds.louvain.write, который вызывает уже готовый алгоритм, мы анализировали весь граф сущностей, их отношения записывали в идентификатор сообщества. Этот метод тоже есть под капотом этой библиотеки. Это позволяло нам сохранять свойства в каждый узел и не вычислять сообщество при каждом запросе, а мгновенно получать их по ID. Согласитесь, это гораздо быстрее, чем в реальной жизни.
Пайплайн работы с запросом Анны выглядел так:
Сначала находим стартовый узел цисплатин.
Затем определяем communityid этого узла.
На последнем шаге извлекаем все узлы с тем же communityid.
Выглядит как обычный Postgres, ничего сложного. Но и этого было недостаточно, поэтому мы пришли к третьему способу.
В какой-то момент Анна спросила, почему там была почечная недостаточность, очень плотно связанная с цисплатином. Но алгоритм этого не объясняет, алгоритм ищет сообщество.
Проблема: "Непонятно, как Х влияет на Z"
Пользователям нужно понимать причинно-следственные связи, но традиционный поиск не показывает "цепочки влияния"
Решение: Pathffinding для анализа связей
Используем алгоритмы поиска путей для выявления причинно-следственных цепочек между сущностями.
Надо было продумать дополнительный алгоритм, который позволит объяснять связь X с Y, а именно causality — причинно-следственные связи. Мы пошли в следующее исследование и нашли продакшен решения, которые применили.
Оттолкнёмся от традиционного поиска. Он показывал, какие сущности связаны, но не объяснял характер этой связи. Выстроить цепочки влияния здесь может только человек. Мы нашли достаточно простой алгоритм, который называется Pathfinding (переводится как «нахождение пути»). Он позволяет находить причинно-следственные связи за счёт индексов. Мы ориентируемся по индексам, какой узел является причиной какого, и выставляем с их помощью дополнительные связи.
Основное ограничение — если Pathfinding запустить на бесконечность, он даст туннельное зрение. То есть однажды найдя причинно-следственную связь, алгоритм продлевает её дальше и дальше, и, возможно, уведёт совершенно в другую область. Чтобы такого не происходило, мы ограничились настройкой гиперпараметров этого алгоритма с помощью allShortestPaths. Изначально брали до 10 коротких путей и перевзвешивали их, чтобы найти максимально близкий на каждом отрезке. Таким образом мы были застрахованы от того, что поиск собьётся с пути и уведёт нас куда-то в космос.
Перейдём к тому, как всё это работает.

Поиск по путям реализуется с помощью алгоритмов поиска кратчайшего пути. Мы взяли алгоритм Дейкстры, потому что он является самым простым и объяснимым. Порог входа достаточно низкий, а для продакшен это важно. Мы не можем каждый раз нанимать великого дата-сайентиста для того, чтобы он сначала настраивал алгоритмы, а потом ещё и рассказывал, как они работают.
По счастью в библиотеке тоже есть GDS. То есть мы можем сразу же вызывать оттуда алгоритм Дейкстры, указывая начальный sourceNode и конечный targetNode. Важным параметром здесь является взвешивание-перевзвешивание коротких путей. Метод тоже присутствует в библиотеке, он позволяет учитывать вес отношений. Также чтобы эти пути как-то регулировать, мы задаем параметр maxDepth, чтобы ограничить длину пути. На каждой отметке ставим типы отношений relationshipTypes, чтобы поиск шёл только по значимым типам. Мы выставляем изначально эти настройки, чтобы каждый раз перевзвешивание было именно в нужном нам направлении.
Таким образом, мы получаем две дополнительные связи на графе:
Causes — что вызывает, допустим, лекарство, которое мы ввели (цисплатин).
Affects — на что оно влияет.
Но этого оказалось недостаточно. Нужно было ускорить процессы.
Давайте здесь проведём черту. Мы почти на середине пути. Можно было бы первые 3 способа пустить в продакшн, если бы не Анна. Она подталкивала нас к тому, чтобы прогресс осуществлялся постепенно, и мы нашли четвертый способ, который решал проблему работы с огромными массивами.
Проблема: Огромные массивы документов
"Как быстро понять суть огромного массива документов?". Пользователи тонут в деталях и не видят общую картину.
Решение: Взгляд с высоты птичьего полета
Иерархические саммари создают многоуровневое представление: от общего обзора к детальным фактам.
Чем больше массив, тем больше задержка ответа (latency). В графовых базах данных это линейная зависимость. Выход — некий взгляд с высоты, потому что модели, как и люди тонут в деталях и не видят общей картины. Через иерархическое summary система агрегирует факты от детального уровня к общему обзору, позволяя сначала охватить суть, а затем углубиться в детали. Основные ограничения — это потенциальные потери нюансов.
Важно обратить внимание на специфичность данных клинических рекомендаций. Здесь я не привел документ, но медики очень часто переписывают клинические рекомендации, так им удобнее выделить какой-нибудь тип фактов. В итоге имеем множество различных клинических рекомендаций просто со взглядом сбоку. Это значит, что мы найдём минимальное количество пересечений, применив обычную дедупликацию. Применив её, а затем и summary, мы решаем проблему уникальности контента, по крайней мере, в медтехе.
Основные ограничения — это, конечно, потенциальная потеря деталей и высокая стоимость вызовов LLM. Это можно смягчить с помощью кэширования или механизма drill-down.
Теперь про архитектуру, я же архитектор.

Архитектура этого метода основана на рекурсивном резюме — процесс работает снизу вверх. Сначала LLM создаёт краткое резюме для каждого отдельного документа — так называемые «листочки», leaf_summaries. Затем они сортируются по темам, и для каждой группы создается резюме темы. Наконец, из набора тематических резюме создается одно глобальное summary верхнего уровня, того самого взгляда с птичьего полёта. Этот рекурсивный подход позволяет эффективно обрабатывать огромные потоки информации. Мы обрабатываем их быстрее, потому что суммаризовали, сжали информацию, информации стало меньше, обработка ускорилась.
Но тут снова к нам пришла Анна и сказала, что теперь ей нужен контекст, по которому она принимает решения: ЭКГ, МРТ, лабораторные анализы, написанные от руки. Эти данные зачастую подтверждают диагноз и дополняют картину анамнеза.
В ответ на этот вызов мы решили посмотреть в сторону мультимодальных эмбеддингов, то есть мультимодального графа знаний, который интегрирует все модальности, позволяет выполнять кросс-модальный поиск.
Проблема: Данные не только текст
"Наши данные" - это не только текст, но и МРТ, ЭКГ, рентген, лабораторные анализы. Как объединить все в единую систему?"
Решение: Единый мультимодальный граф
Интеграция всех модальностей в единый граф знаний с возможностью кросс-модального поиска.
Результат: Улучшение диагностической точности на 23%.
В нашем исследовании это позволило улучшить диагностическую точность на целых 23%. Было 74%, стало почти 99%.
Такие сложности как высокая стоимость хранения Анну уже не волновали. Тем более, что мы предложили стратегию Tiered Storage — это разделение горячих и холодных данных. Сейчас такая стратегия применяется практически на всех облаках. Также предложили вычислять предварительно эмбеддинги, чтобы не тратить дополнительные вычислительные возможности, а использовать их из-под капота.
Немного об архитектуре. Очень важно понять, что мы не брали мультимодальность, которая стоит на острие, когда речь идёт о фьюжн-подходах. Мы брали достаточно традиционный подход к мультимодальности, то есть пайплайн из моделей, подобных CLIP и встроенных в Neo4j векторных индексов.

В CLIP происходит детекция изображения и его описание. Тем самым мы получаем на вход текстовое представление и работаем только с ним. Никакой сложности в построении и сравнении эмбеддингов здесь не возникает, по крайней мере, если сравнивать с мультимодальным фьюженом. В нём нужно определяться с early Fusion и late Fusion (с ранней и с поздней стадиями), когда эмбеддинги необходимо совмещать между собой. Эти эмбеддинги мы сохраняем как свойства в узлах графа, а затем, как показано в коде, создаём специальный вектор индекса на свойстве embedding. Это позволяет выполнять сверхбыстрый семантический поиск по сходству, например, найти изображение с признаками пневмонии, используя текстовый запрос.
Но кое-что пошло не так.
У нас отсутствовала гибкость в поиске. Мы решили сопровождать контекст гибкостью с помощью тех же Cypher-запросов и генерить их также.
Проблема: Слишком разнообразные запросы
"Наши запросы слишком разнообразны, статистический контекст не подходит. Нужна максимальная адаптивность".
Решение: Генерация Cypher "на лету"
LLM генерирует Cypher-запросы адаптированные под конкретный пользовательский вопрос, создавая релевантные подграфы.
Решение было таким: LLM анализирует вопрос пользователя, сама пишет адаптированный Cypher-запрос. Тем самым она, по сути, является контекстом для изменения и извлечения нужного подграфа. Всё дело в том, что когда запросы слишком разнообразны, статический контекст не подходит, а генерируя Cypher-запросы на лету, мы решаем проблему динамичности.
Это самый гибкий, но и самый хрупкий метод. Мы знаем, что здесь от галлюцинаций уйти сложно, придётся писать бенчмарк под бенчмарк. Поэтому в продакшене можно заткнуть костылем в виде fallback-логики. Мы сделали так для демонстрации, но в итоге от способа отказались из-за его нестабильности. Ещё можно валидировать саму схему графа перед выполнением запроса, но если схем и шаблонов много, то это будет очень большой дополнительной нагрузкой на инженеров.
Архитектура этого метода представляет собой прямой pipeline, от LLM к Cypher.

На иллюстрации приведён пример сгенерированного запроса «Найди препарат и его побочные эффекты». LLM генерирует сложный MATCH-запрос в Cypher, который точно описывает эту структуру в графе. Для анализа производительности сгенерированного кода здесь необходимо использовать уже встроенные в Neo4j команды, обвязка фреймворка это позволяет. Там есть команды PROFILE и EXPLAIN, которые показывают детальный план выполнения запроса.

Это был промежуточный этап. Его можно оставить, если вы вложите туда достаточно инженерных сил. Но именно галлюцинации нас толкнули чуть дальше. Вспомним стартовую точку — 22% галлюцинаций, которые присутствовали на том, чтобы GraphRAG работал.
Седьмой способ — это наше основное оружие против галлюцинаций. Решение заключается в том, чтобы переосмыслить само понятие чанка. Мы используем графовые базы, но предварительно подаём туда чанки. У нас работал рекурсивный чанкинг и подавал чанки распределённой длины по рекурсивности. Мы решили поэкспериментировать, наложить граф на граф, для этого использовали иерархический и логический графовые чанки. Такая гибридная система позволила нам сохранять логичность текста на входе, векторизовать его и обеспечивать связанность по графу.
Получилась система, которая уточняет саму себя. Это дало рост и в качестве и в производительности: поиск стал быстрее и точнее, снизился уровень галлюцинаций с 22% до 3,8%. В абсолютных величинах это 84% выпадения галлюцинаций.
Метод строился на концепции эго-сеть плюс доказательная база.

Как показано в коде, для нужного узла необходимо извлечь его эго-сеть — это сам узел и все его соседи на определённой глубине. Мы используем depth=2 (глубину 2). После проходим по каждому факту из этой сети и добавляем к нему ещё параметр evidence. Это прямые ссылки на исходные документы, чтобы у нас было подтверждение связности, и мы всегда могли понять, откуда факт был извлечён. Таким образом LLM получает не только сам факт, но уже и его подтверждение со всеми ссылками.
Но скорость опять упала и поэтому мы решили попробовать последний способ — гибрид, берущий лучшее из двух миров.
Нам нужна была широта охвата векторного поиска и точность связей графового. Решение пришло само собой, мы решили использовать Reciprocal Rank Fusion — гибридный поиск с использованием фьюжена.
Проблема: Нужно лучшее из двух миров
"Нам нужна и широта охвата (как в векторном поиске), и точность связей (как в графовом поиске). Как получить оба преимущества?".
Решение: Reciprocal Rank Fusion
Параллельный поиск по графу и векторам с умным объединением результатов через RRF алгоритм.
Здесь мы выполняли параллельный поиск одновременно и по графу, и по векторам. Затем с помощью алгоритма RRF объединяли результаты поиска. Этот алгоритм сложен в настройке, но обеспечивает наилучший баланс. Настраивать скрипт нужно один раз на тип данных, а дальше эта настройка применяется уже к расширенному доменному знанию. Если мы продолжим работать в тех же структурах и с теми же доменами, то перенастраивать алгоритм не понадобится. Но есть нюанс — он плохо работает на общем домене, потому что эта настройка позволяет настроиться именно на структуры, применяемые в заданном.
Архитектура данного метода представляет собой параллельный поиск плюс RRF.

Запрос пользователя одновременно отправляется в два контура: в Graph Search для извлечения структур связи и в Vector Search для поиска семантического сходства. Затем результаты поступают в функцию rrf_fusion. Здесь псевдокод наглядно демонстрирует, как для каждого документа из каждого списка вычисляется оценка. Она обратно пропорциональна его рангу. После итоговый список суммируется и сортируется. Очень напоминает базовые эвристические методы, но, тем не менее, неплохо работает.
Теперь, когда мы рассмотрели все 8 способов, сведём результаты воедино.

На радар-диаграмме сравнение трёх наиболее успешных архитектур:
Базовый векторный RAG
Графовый чанкинг (Graph-Native Chunking), чемпион по борьбе с галлюцинациями
Гибридный поиск (Hybrid Search), сбалансированный лидер
Отчётливо видно, что векторный RAG силен только по осям скорости и стоимости. Graph-Native Chunking является абсолютным лидером в снижении галлюцинаций, но платит за это скоростью. Hybrid Search демонстрирует наилучший перформанс, наиболее сбалансированный профиль по всем качественным метрикам. Забегая вперед, именно его мы предложили использовать заказчику, и Анна согласилась.
Если свести все данные нашего бенчмарка к трём ключевым выводам, когда мы проверяли результаты по нашему поиску:
Hybrid Search является лучшим решением по совокупности всех метрик.
Graph-Native Chunking — это абсолютный чемпион в борьбе с галлюцинациями. Если у вас на данных это основная проблема, рекомендуем именно его.
Vector RAG — база именно для быстрых решений, для решений на демо, чтобы донести максимально быстро ценность до заказчика.
Радар-диаграмма нам дала общее представление. Теперь погрузимся в конкретные цифры.
Итоговая таблица производительности выглядит так:

Самая критическая метрика для нашего мед. кейса — это faithfulness (галлюцинации). Чем ниже значение, тем лучше. Graph-Native Chunking с результатом 0,038 является абсолютным неоспоримым чемпионом в борьбе с выдуманными фактами. Это безопасный и надёжный метод. На другом конце спектра Base GraphRAG с результатом 0,18. Это значит, что он галлюцинирует почти в 5 раз чаще.
Но является ли борьба с галлюцинациями единственной целью? Посмотрим, что произойдёт, когда добавим второе измерение качества — это релевантность ответа. Эта метрика показывает, насколько полно и по существу система отвечает на заданный вопрос. Картина сразу становится интересней. Несмотря на то, что Hybrid Search немного уступает в борьбе с галлюцинациями, он показывает самую высокую релевантность ответа. Это классический компромисс — метод самый безопасный, никогда не скажет лишнего, но из-за этого ответ может быть не таким полным, то есть мы срезаем полноту. Такой консенсус можно регулировать, а Hybrid Search даёт самые исчерпывающие и полезные для врача ответы. Также обратите внимание на мультимодальный RAG. Он тоже очень силён по релевантности, потому что мы используем CLIP, где текстовые представления сравниваются между собой и дополняются. Это также подтверждает ценность использования нетекстовых данных.
Итак, у нас есть лидеры по качеству, но какова цена этого качества с точки зрения производительности? В данном случае latency — это как раз производительность, которую мы замеряли в миллисекундах, и здесь мы видим цену за высокое качество. Чемпион Graph-Native Chunking ушёл в пике до 5 секунд. Показаны идеализированные метрики, замеренные на самых хороших запросах, на деле было гораздо медленнее. Multimodal при этом оказывается самым ресурсоемким. Много данных разного порядка требуют много времени на обработку, особенно пайплайна с моделями. Это логично, они выполняют гораздо более сложную работу, пользователю здесь придется чуть-чуть подождать.
Самый быстрый — Base GraphRAG, он отвечает почти за одну секунду. Можно также раскрутить его и сделать чуть быстрее за счет дополнительных инстансов. Но это самый некачественный вариант решения. Hybrid Search опять демонстрирует достаточно хороший баланс. Его отличие от BaseRAG может быть не таким критичным. Хотя он отвечает почти за 2 секунды, что медленнее базового подхода, но почти в 2 раза быстрее всех остальных.
Последний, но не менее важный параметр — стоимость. Мы считали косты по официальным прайсам, там цены представлены в долларах, поэтому здесь тоже в долларах.
Здесь нет сюрпризов, стоимость напрямую коррелирует со сложностью. Мультимодальный способ самый дорогой, что неудивительно, из-за того, что он обрабатывает очень много разных данных. Hybrid Search снова подтверждает свой статус золотой середины. Он не самый дешевый, но за умеренную цену мы получаем почти максимальное качество и приемлемую скорость.
Теперь у нас есть все колонки для принятия решений. Эта итоговая таблица способна стать навигатором в мире компромиссов. Она наглядно показывает, что не существует лучшего метода для всех. Есть лучший метод для вашей конкретной заданной ситуации — под ваш бюджет,скорость, точность и галлюцинации.
Цифры — это лишь половина истории. Давайте вернёмся снова к Анне. Вот что ей ответил бы стандартный RAG на запрос: “Какие риски несет химиотерапия на основе цисплатина для пациента с НМРЛ и сопутствующим сахарным диабетом”

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

«Следует учитывать сочетанный риск. Цисплатин обладает нефротоксичностью, а диабет приводит к нефропатии, что создает кумулятивную нагрузку на почки (сразу выявили эту связь). Рекомендуется мониторинг функции почек и возможная коррекция дозы (сразу даны рекомендации)»
Это практически полноценный врачебный диагноз, который можно использовать дальше после валидации ответа онкологом. Благодаря этим решениям Анна пользуется ассистентом и по сей день. Она ставит диагнозы и назначает лечение гораздо быстрее и точнее.

Перед вами дерево решений, которое поможет выбрать правильную архитектуру, чтобы не только Анна наслаждалась решениями.
GraphRAG — это не просто набор управляемых решений, который превращает рискованный RAG в надёжный инструмент. Он позволяет снижать стоимость. Инвестиции в точность и безопасность на начальном этапе в таких критически важных областях, как медицина, окупаются сторицей. Вы можете за 6 месяцев, как в нашем случае, окупить первые инвестиции в RAG, и ROI взмоет в небеса. Полгода — не такой длинный срок для медицины. Возможно, ваша область требует более коротких сроков, а значит, более быстрых RAG.
В заключение мысль от моих коллег-инженеров.
GraphRAG — это не одна «волшебная» кнопочка. Методов существует много, это целый арсенал инструментов. Вы всегда выбираете, исходя из баланса цена — скорость — качество.
Грядущей весной обсудим тренды, новые интересные кейсы и эксперименты с ИИ на AI Сonf 2026. Бронируйте участие уже сейчас, перед конференцией мест гарантировано не останется!