← Dashboard

GraphRAG — Справка

Как работает поиск, какие параметры за что отвечают, и что в итоге попадает в ответ.

Как выбирается ветка ответа

Система определяет режим работы по двум параметрам:

РежимУсловиеЧто вы получите
Извлечение ключа Указан json_key Система найдёт все значения указанного ключа по каталогу. LLM для ответа не вызывается. llm_answer_enabled игнорируется.
LLM-ответ llm_answer_enabled=true, json_key не указан LLM сгенерирует текстовый ответ на основе найденных чанков и графового контекста
Только данные llm_answer_enabled=false, json_key не указан Вернутся только найденные чанки, граф и структуры — без текстового ответа

Путь запроса: от вопроса до ответа

1 Поиск по векторной базе (pgvector)

Это всегда первый шаг — независимо от режима. Система ищет чанки, похожие на ваш вопрос.

ПараметрДефолтЧто происходит
top_k4 Сколько чанков вернуть. Система ищет в 4× больше кандидатов, но в итоге оставляет только top_k лучших. Увеличьте, если нужно больше контекста (6–8 для каталога, 4–5 для LLM).
hybrid_enabledtrue Добавить поиск по ключевым словам. Если включён — к векторному поиску добавляется нечёткий поиск по тексту. Результаты смешиваются: 75% семантика + 25% ключевые слова. Выключайте, если хотите чисто семантический поиск.
correction_enabledtrue Исправлять опечатки. Перед поиском система пробует исправить ошибки в запросе. Полезно для пользовательского ввода, можно отключить для точных запросов.
score_threshold0.0 Отсеять слабые результаты. Чанки с оценкой ниже порога не попадут в ответ. 0 = не фильтровать (подходит для каталога). 0.3–0.5 для LLM — убрать шум.

2 Обогащение из графа (Neo4j)

Когда срабатывает: если graph_enabled=true (по умолчанию) и найдены чанки с object_id (т.е. структурированные данные — JSON/XLSX). Если выключить — поиск опирается только на векторную базу.

Система берёт найденные чанки и по их object_id идёт в Neo4j за дополнительными данными:

Что Neo4j отдаётПараметрДефолтПростыми словами
Связи между сущностями
Entity → Entity (общий бренд, категория...)
graph_context_limit8 Сколько связей тащить из графа. Связь = «объект А и объект Б имеют общую сущность». Чем больше — тем шире контекст, но медленнее. Также ограничивает количество seed-объектов, от которых идёт поиск.
Структура объектов
Item = {Название: "...", Цена: "..."}
neo4j_items_limit5 Сколько карточек объектов вернуть. Каждый объект — набор полей ключ:значение. Для json_key эти данные сканируются при извлечении. Для LLM — попадают в промпт.
Смысловые блоки текста
SemanticBlock = разделы PDF/DOCX
graph_context_limit Только для текстовых документов. Лимитируется тем же graph_context_limit.
Похожие объекты
«У этих объектов общая категория/бренд»
graph_context_limit Объекты, связанные через общие сущности. Для LLM попадают в промпт с properties связанных объектов.

Если graph_enabled=false — весь этот шаг пропускается. Ответ строится только на чанках из pgvector.

3 Расширение для каталога (json_key)

Когда срабатывает: только если указан json_key и graph_enabled=true.

Помимо чанков из шага 1, система находит похожие объекты через граф и дофетчивает все их чанки. Это нужно, чтобы найти значения ключа в записях, которые не попали в первый поиск, но связаны через общие сущности.

ПараметрДефолтЧто происходит
graph_expand_limit
только json_key
6 Сколько связанных объектов найти. Система идёт в Neo4j и по сущностям из чанков находит объекты с общими связями. Каждый объект = запись в каталоге. Увеличьте для полноты, уменьшите для скорости. Влияет только при указанном json_key.
max_graph_k
только json_key
10 Максимум дополнительных чанков. Найденные объекты содержат неизвестное число чанков (1 объект может дать 3-5 чанков). Этот параметр ограничивает итоговое число дополнительных чанков. Защита от взрывного роста ответа. Влияет только при указанном json_key.
graph_score_threshold0.6 Минимальный балл для запуска расширения. Если лучший чанк набрал меньше — система считает, что поиск не попал в цель, и не тратит время на графовое расширение.

4 Формирование ответа

json_key — извлечение значений

Система сканирует все найденные данные и извлекает значения указанного ключа:

  1. Structured-поля чанков ({NAME: "iPhone"})
  2. Текст чанков (regex: NAME: iPhone)
  3. Свойства neo4j_items ({NAME: "iPhone"})

Результат: массив значений key_values. LLM не вызывается.

ОПЦИОНАЛЬНО key_llm_enabled=true — LLM отфильтрует найденные значения по релевантности вопросу.

LLM — генерация ответа

Все найденные данные собираются в промпт для LLM:

  1. Чанки → векторный контекст
  2. Рёбра + похожие объекты → графовый контекст
  3. Блоки текста + структура Neo4j → смысловой контекст

Результат: сгенерированный текст answer.

Как лимиты каскадно ограничивают друг друга

Лимиты работают последовательно — каждый следующий обрезает результат предыдущего. Итог всегда ограничен наименьшим звеном в цепочке.

Для neo4j_items (LLM + граф)

graph_context_limit определяет сколько записей каталога (object_id) отправить в Neo4j-запрос. neo4j_items_limitсколько карточек (ключ:значение) вернуть из тех, что Neo4j нашёл.

top_k чанков → уникальные object_id (записи каталога)
  → [:graph_context_limit]             ← сколько записей спросить у Neo4j
  → get_items_by_object_ids(...)      ← Neo4j возвращает карточки {Название: "...", Цена: "..."}
  → [:neo4j_items_limit]               ← сколько карточек оставить
graph_context_limitneo4j_items_limitИтог neo4j_itemsЧто произошло
252Спросили про 2 записи → получили max 2 карточки → лимит 5 не сработал
822Спросили про 6 записей → получили 6 карточек → обрезали до 2
353Спросили про 3 → получили 3 → лимит 5 не сработал
886Нашлось всего 6 записей (top_k=6) → оба лимита не ограничили

Совет: ставьте graph_context_limitneo4j_items_limit, иначе первый будет «душить» второй. Если хотите 5 карточек — graph_context_limit=8, neo4j_items_limit=5.

Для graph_expanded_chunks (json_key + граф)

graph_expand_limit — сколько похожих записей каталога найти через граф (у них общие сущности с вашими чанками: тот же бренд, категория...). max_graph_k — сколько чанков из этих записей реально вернуть в ответ. Одна запись = несколько чанков (строк таблицы).

seed_oids (object_id из top_k чанков — найденные записи)
  → get_related_item_object_ids(limit=graph_expand_limit)  ← найти похожие записи через граф
  → related_oids (похожие записи: общая категория, бренд...)
  → fetch_chunks_by_object_ids(...)                       ← fetch ВСЕХ чанков каждой записи
  → graph_expanded_chunks (может быть много: 3 записи × 4 чанка = 12)
  → [:max_graph_k]                                        ← оставить только лучшие
graph_expand_limitmax_graph_kЧанков пришлоИтог expandedЧто произошло
35~125Нашли 3 похожие записи → fetch дал 12 чанков → оставили 5 лучших
65~245Нашли 6 записей → 24 чанка → всё равно 5, max_graph_k не дал разрастись
320~1212Нашли 3 записи → 12 чанков → лимит 20 не сработал, всё прошло
210~88Нашли 2 записи → 8 чанков → лимит 10 не сработал

Совет: для каталога ставьте graph_expand_limit побольше (6–10) — найдёт больше похожих записей. А max_graph_k ограничит итог — защита от раздувания ответа. Хорошая пара: graph_expand_limit=6, max_graph_k=10.

Что попадает в ответ: сравнение режимов

Зелёный = эти данные используются для формирования ответа. Серый = возвращаются, но не влияют. Красный = отсутствуют.

Влияет на ответ
Есть в ответе, но не влияет
Отсутствует
Данные json_key + граф json_key без графа LLM + граф LLM без графа
Чанки из pgvector Сканируются для извлечения ключа + возвращаются То же, но без расширения Попадают в промпт LLM Попадают в промпт LLM
Доп. чанки из похожих объектов Тоже сканируются Не запускается Не создаётся Не запускается
Карточки объектов (neo4j_items) Сканируются для извлечения ключа Не запускается Попадают в промпт Не запускается
Рёбра (Entity → Entity) Возвращаются, но ключи не извлекают Не запускается Попадают в промпт Не запускается
Похожие объекты (related links) Возвращаются Не запускается Попадают в промпт Не запускается
Смысловые блоки Возвращаются Не запускается Попадают в промпт Не запускается

Все параметры: полная таблица

Включатели (true/false)

ПараметрДефолтЧто меняет
graph_enabledtrueГлавный выключатель графа. Если false — поиск только по векторной базе.
graph_context_enabledtrueПохожие объекты + блоки. Работает только при graph_enabled=true.
hybrid_enabledtrueСмешанный поиск. Векторный + ключевые слова.
correction_enabledtrueИсправлять опечатки.
reranker_enabledfalseПересортировать чанки нейросетью.
citations_enabledfalseДобавить цитаты (откуда данные).
key_llm_enabledfalseLLM фильтрует найденные ключи (json_key).
llm_answer_enabledfalseГенерировать ответ через LLM. При json_key — игнорируется.

Лимиты (числа)

ПараметрДефолтПростыми словамиКогда влияет
top_k4 Сколько чанков вернуть из поиска. Всегда
graph_context_limit8 Сколько связей из графа тащить. Ограничивает количество seed-объектов, смысловых блоков, похожих объектов. LLM + граф
neo4j_items_limit5 Сколько карточек объектов (ключ:значение) вернуть из Neo4j. json_key + граф, LLM + граф
graph_expand_limit только json_key6 Для json_key: сколько похожих записей найти через граф. json_key + граф
max_graph_k только json_key10 Максимум доп. чанков от похожих объектов. json_key + граф
graph_hops1 Глубина обхода графа. 1 = прямые соседи, 2 = соседи соседей. LLM + граф

Пороги (фильтры)

ПараметрДефолтПростыми словами
graph_score_threshold0.6 Порог для расширения. Если лучший чанк набрал меньше — расширение не стартует.
score_threshold0.0 Порог для чанков. 0 = все проходят. 0.3–0.5 = отсеивать слабые.

Типы чанков в ответе

Каждый чанк имеет поле search_type:

search_typeКак появился
semanticНайден векторным поиском по смыслу
keywordНайден поиском по ключевым словам (hybrid_enabled)
expandedДофетчен как принадлежащий тому же объекту
graph_expandedДофетчен из похожего объекта через граф (json_key)

Все чанки хранятся в pgvector. Neo4j используется только для определения какие объекты дофетчить.

Поля ответа

ПолеЧто содержит
answerОтвет LLM, или значения ключа, или пустая строка
key_valuesМассив значений json_key. [] для LLM
chunksВсе чанки: top_k + graph_expanded
graph_contextСвязи из графа + похожие объекты
neo4j_itemsКарточки объектов: {ключ: значение}
semantic_blocksСмысловые блоки документов
citationsЦитаты (если citations_enabled)
search_msВремя поиска (мс)
llm_msВремя LLM (мс)
total_msОбщее время (мс)

Примеры запросов

Минимальный

curl -X POST http://localhost:8007/ask \
  -H "Content-Type: application/json" \
  -d '{"user_id":"search","question":"Ассимилятор"}'

Извлечь значение ключа

curl -X POST http://localhost:8007/ask \
  -H "Content-Type: application/json" \
  -d '{"user_id":"search","question":"Ассимилятор","json_key":"NAME","top_k":6}'

LLM-ответ с графом

curl -X POST http://localhost:8007/ask \
  -H "Content-Type: application/json" \
  -d '{"user_id":"search","question":"какие смартфоны дешевле 50000?","llm_answer_enabled":true,"graph_context_limit":12}'