Hybrid Retrieval на LightRAG
RAG-контур в этом проекте построен вокруг LightRAG. Его роль — принять подготовленный текст, разложить его на индексируемые представления и дать API для вопросов по базе знаний.
В отличие от простой схемы «файл → embeddings → ближайшие чанки», здесь используется связка векторного и графового поиска.
Основные хранилища
RAG-сервер поднимается с несколькими backend-хранилищами:
- Qdrant — векторный слой для embeddings и семантического поиска;
- Neo4j — граф знаний для сущностей и связей;
- PostgreSQL — метаданные документов, статусы, сессии и история чата.
LightRAG соединяет Qdrant и Neo4j как retrieval engine. PostgreSQL не заменяет поисковый индекс, но помогает управлять документами, статусами и диалогами.
Ingestion pipeline
Документ попадает в RAG через POST /api/v1/ingest. На входе сервер вычисляет MD5-хеш, проверяет дубликат в PostgreSQL, извлекает текст из поддержанных форматов и создаёт запись со статусом PENDING.
Дальше индексация уходит в фон:
- статус обновляется на
INDEXING; - LightRAG запускает
ainsert(text); - текст разбивается на чанки;
- embeddings сохраняются в Qdrant;
- сущности и связи извлекаются через LLM и сохраняются в Neo4j;
- статус становится
COMPLETEDилиERROR; - если указан webhook, сервер отправляет уведомление о завершении.
PFRAG может отдавать в этот контур уже очищенный Markdown. Это снижает риск, что LightRAG будет индексировать навигационный шум, дубли или плохо распознанный текст.
Query modes
Для чата доступны режимы поиска:
naive— простой векторный поиск;local— поиск с локальным контекстом графа;global— глобальный обход графа;hybrid— комбинированный режим.
hybrid полезен как режим по умолчанию, потому что он не ограничивается только ближайшими embeddings и может использовать графовые связи. Но остальные режимы тоже важны: они помогают диагностировать, где именно retrieval даёт лучший контекст для конкретной базы.
Multi-turn chat
RAG-сервер хранит историю чата в PostgreSQL. Если в запросе передать session_id, backend подгружает последние сообщения сессии и добавляет их в контекст. Это нужно для уточняющих вопросов: пользователь может спросить «а подробнее?» без повторения всей темы.
Если session_id не передан, сервер создаёт новый UUID. Для внешнего UI это простой контракт: сохранять один session id на диалог и передавать его в следующих запросах.
REST, SSE и WebSocket
Чат можно подключать несколькими способами:
POST /api/v1/chat— обычный JSON-ответ;POST /api/v1/chat/stream— SSE-стриминг, когда текст появляется по частям;WS /api/v1/ws/chat— WebSocket для real-time сценариев.
Это делает backend гибким. Telegram-боту часто достаточно REST. Web UI удобнее подключать через SSE или WebSocket, чтобы пользователь видел ответ по мере генерации.
Управление документами и healthcheck
Кроме чата, RAG-контур даёт endpoints для списка документов, статуса по хешу, удаления и переиндексации. Есть статистика и healthcheck, который проверяет PostgreSQL, Qdrant и Neo4j.
Для базы знаний это важно не меньше самого чата: оператор должен понимать, какие документы уже готовы, какие зависли, где произошла ошибка и живы ли основные хранилища.
Роль LightRAG в общей системе
LightRAG в этом pipeline — не замена подготовке данных. Он хорошо работает как retrieval engine, когда получает нормальный текст. Поэтому лучший результат получается на границе двух контуров: PFRAG отвечает за чистый вход, а RAG отвечает за индекс, query modes и интерфейсы ответа.