Как собрать промышленный RAG без галлюцинаций и кэширующего лага — 4 июля 2026 г. в 23:40:12.496
Как собрать промышленный RAG без галлюцинаций и кэширующего лага Большинство публичных демо RAG рушатся под нагрузкой: модель тянет нерелевантные чанки, ответы затягиваются на 10+ секунд, а контекст забивается мусором. В продакшене это не «особенность», а архитектурный долг. Ниже — готовый шаблон локального пайплайна, который держит latency <2c и даёт детерминированные ответы для внутренних витрин знаний, DevOps-рутин и корпоративных ассистентов. Архитектура строится на трёх принципах: строгая семантическая фильтрация до подачи в LLM, асинхронная индексация с deduplication, и mandatory reranking. Забудьте про naive vector search — один эмбеддинг не заменяет бизнес-логику. В основе лежит разделение on-the-fly ingestion и query-time retrieval. Документы парсятся по формату: PDF через pdfplumber/marker, код через AST-парсеры, markdown через recursive splitter с overlap 15%. Чанки не должны превышать 800 tokens — на больших окнах качество поиска падает из-за размывания векторного пространства и потери локальной семантики. Всегда храните исходный layout в метаданных: это критично для таблиц, кода и технической документации. Индексация идёт в Qdrant с HNSW индексом. Ключевой момент — payload schema. Не храните raw текст, кладите нормализованные метаданные: source_id, chunk_hash, section_depth, confidence_score. Это ускоряет hybrid search (vector + keyword) и позволяет делать post-filtering без дополнительных запросов к БД. Для локальных эмбеддингов сейчас оптимален BGE-M3 — он поддерживает многоязычность, длинные контексты и даёт более плотное кластеризование, чем старые E5-модели. Запускаем через Ollama или vLLM с квантованием Q4_K_M. Для query-time трансформации внедряем HyDE (Hypothetical Document Embeddings): сначала LLM генерирует гипотетический ответ, затем его эмбеддинг используется для поиска. Это закрывает проблему лексики в query и повышает recall на 18–25%. Самая частая ошибка — прыгать сразу в LLM после retrieval. В продакшене всегда ставим Cross-Encoder reranker между векторной БД и языковой моделью. Модели типа bge-reranker-v2-m3 или jina-reranker-v2-turbo пересчитывают релевантность чанков с учётом конкретного query, отсёкая 60–70% шума. Это снижает cost inference и убирает галлюцинации от контекстного перегруза. Reranker работает в batch-режиме, поэтому latency растёт на 200–400ms, но качество ответа скачкообразно повышается. Обвязываем это через async FastAPI middleware с timeout 800ms и fallback на top-1 chunk при падении сервиса. Никогда не шлите в LLM более 3 reranked chunks — контекстное окно должно оставаться под контролем. Финальный этап — prompt template с explicit instructions для LLM. Не используйте open-ended системные промпты. Фиксируйте format: Answer strictly using provided context. If no match, return "No data". Cite chunk IDs. Локальные модели (Llama-3.1-8B-Instruct, Hermes-2-Pro, Qwen2.5) отлично следуют этому формату при температуре 0.1–0.3. Для ускорения внедряем semantic cache на уровне Redis: hash(query + top_k_chunks) → cached_response. При совпадении >0.95 возвращаем кэш за <50ms. Мониторинг latency и cache-hits идёт через Prometheus, алертинг при деградации p95. Готовый стек выдерживает 150k+ документов без деградации поиска. Масштабирование идёт горизонтально через Qdrant clusters, а LLM inference отделяется в отдельный GPU-node с vLLM tensor parallelism. #AI #LLM #OpenSource #RAG

