Learnly

Продвинутые техники RAG для повышения качества

Продвинутые техники RAG для повышения качества

Базовый RAG, embed → vector search → LLM, даёт качество 60–75% на корпоративных задачах. До prod-уровня (85–93%) система доходит за счёт цепочки техник, каждая из которых решает конкретный класс ошибок.

В этом уроке, современный арсенал 2024–2026: что есть, какую проблему решает, цена внедрения, ожидаемый прирост качества.

Откуда берутся ошибки в базовом RAG

Ошибка Причина Где исправлять
Не нашёл нужный чанк Asymmetric query/document, узкая терминология Indexing + query rewriting
Нашёл, но не в топе Bi-encoder слабоват Reranker
В чанке нет контекста (например, «Срок, 14 дней» без указания, чего срок) Чанк вырван из документа Contextual Retrieval, parent-document
Точные термины не находит Только vector search Hybrid + BM25
Сложный многошаговый вопрос Один retrieval не покрывает Decomposition, agentic
Нет связей между сущностями Текстовый поиск этого не видит GraphRAG
Ответ выдуман LLM не следует инструкциям Self-RAG, CRAG, citation validation

Техника 1. Hybrid search (Dense + Sparse)

Проблема. Vector search силён на семантике, но проваливается на конкретных терминах: артикул SKU-XJ-2847, имя клиента ООО Ромашка, ключ конфига TLS_VERSION_MIN. BM25 (sparse) их находит на ура, он считает совпадения слов.

Решение. Параллельно делать оба поиска и сливать результаты через Reciprocal Rank Fusion (RRF):

def rrf(rankings: list[list[Doc]], k: int = 60) -> list[Doc]:
    scores = {}
    for ranking in rankings:
        for rank, doc in enumerate(ranking):
            scores[doc.id] = scores.get(doc.id, 0) + 1.0 / (k + rank)
    return sorted(scores, key=scores.get, reverse=True)

dense  = vector_db.search(embed(query), top_k=50)
sparse = bm25.search(query, top_k=50)
candidates = rrf([dense, sparse])[:50]

Прирост качества. Anthropic: recall@20 поднимается с 5.7% (только embeddings) до 4.0% (только BM25) до 2.9% failure при гибриде, то есть failure rate падает почти в 2 раза. На общих корпоративных корпусах: +10–25% к recall@10.

Цена. +1 индекс (Elasticsearch / OpenSearch / Tantivy) + копеечный sparse-запрос. Окупается всегда.

Техника 2. Contextual Retrieval (Anthropic, Sept 2024)

Проблема. Чанк «Срок, 14 дней» в индексе. Что это за срок, не понять. Embedder не видит контекста документа.

Решение. ДО эмбеддинга обогатить каждый чанк коротким контекстом из всего документа, сгенерированным LLM:

prompt = f"""
<document>{full_document}</document>
<chunk>{chunk}</chunk>
Дай короткий (≤100 токенов) контекст, объясняющий,
куда этот чанк помещается в документе. Только контекст, без преамбулы.
"""
ctx = claude_haiku(prompt)
indexed_text = f"{ctx}\n\n{chunk}"
embed(indexed_text)  # эмбеддинг идёт уже от обогащённого

Чанк становится: «Из раздела "Отпуск" регламента 2026 (про сроки подачи заявления): Срок, 14 дней».

Прирост качества. Anthropic: failure rate retrieval'а −49% (с 5.7% до 2.9% на их бенчмарке). С rerank'ом, −67%.

Цена. Один Haiku-вызов на чанк при индексации (~$1 на 1M токенов корпуса). Prompt caching снижает цену в 9 раз, сам документ кэшируется на стороне Anthropic, переиспользуется для всех его чанков.

Техника 3. HyDE (Hypothetical Document Embeddings)

Проблема. Запрос «Как взять отпуск?» (5 токенов) и документ «Положение о ежегодном оплачиваемом отпуске устанавливает порядок предоставления...» (500 токенов) по-разному устроены. Их эмбеддинги в разных частях пространства.

Решение. Сначала LLM пишет «гипотетический ответ», потом ищем по нему:

hypo = llm(f"Напиши краткий ответ на вопрос: {query}")
# hypo: "Чтобы взять отпуск, нужно за 14 дней подать заявление руководителю..."
candidates = vector_db.search(embed(hypo), top_k=50)

Гипотетический ответ может быть фактически неверным, но по форме он похож на реальный документ. Это сильно поднимает попадание.

Прирост качества. +5–15% на recall@10. Особенно помогает на коротких/расплывчатых запросах.

Цена. Дополнительный быстрый LLM-call (Haiku/mini-модели). +200–500 мс к latency.

Техника 4. Multi-Query / RAG-Fusion

Проблема. Один запрос, один взгляд. Пользователь сформулировал «как взять отпуск?», а в документе написано «оформление отгулов и отпусков».

Решение. LLM генерирует 3–5 переформулировок, делаем по каждой retrieval, сливаем через RRF:

variants = llm(f"Дай 4 разных перефраза вопроса: {query}").split("\n")
all_results = [vector_db.search(embed(v), top_k=20) for v in [query] + variants]
candidates = rrf(all_results)[:50]

RAG-Fusion (Raudaschl, 2023), это формализованная версия с RRF; стандартный паттерн в LlamaIndex/LangChain.

Прирост качества. +5–15% на recall, особенно для коротких запросов.

Цена. 1 LLM-call + N×search вместо 1×search. Latency +0.5 сек.

Техника 5. Parent-Document / Sentence-Window

Проблема. Маленькие чанки (256 токенов), точный retrieval, но мало контекста в LLM. Большие (1500), много контекста, но топ-50 загрязняется случайным.

Решение 1, Parent-Document (LangChain): индексируем мелкие, но в LLM передаём родительский чанк (или весь документ).

индекс: chunk_small (256 tok)  →  embed  →  vector_db
выдача: chunk.parent_id  →  load parent_chunk (1500 tok)  →  LLM

Решение 2, Sentence-Window (LlamaIndex): в индексе хранится 1 предложение, при выдаче возвращается ±3 соседних предложения.

Прирост качества. +10–20% на complex QA. Особенно полезно, когда ответ, конкретное число/имя в большом контексте.

Цена. Только усложнение кода indexing'а. Никаких extra LLM-calls.

Техника 6. Reranking (cross-encoder)

Уже разбирали в прошлом уроке как обязательный компонент. Краткое напоминание:

Bi-encoder (для retrieval): эмбеддинг вопроса и документа считается отдельно, потом сравниваются векторы. Быстро, грубовато.

Cross-encoder (reranker): пара (вопрос, документ) идёт в трансформер вместе, выдаёт скор 0..1. Точнее, но нельзя предвычислить.

candidates = retrieve(query, top_k=50)
reranked = cohere.rerank(query=query, documents=[c.text for c in candidates],
                         top_n=5, model="rerank-v3.5")
top_chunks = [candidates[r.index] for r in reranked.results]

Прирост качества. Anthropic: failure rate с 2.9% (hybrid + contextual) до 1.9% при добавлении rerank'а, ещё −34%. Универсально даёт +5–15% к Precision@5.

Цена. $1 / 1K rerank-calls (Cohere) или GPU-инференс BGE-reranker-v2-m3. +50–200 мс latency.

Техника 7. ColBERT и late-interaction

Идея. Вместо одного вектора на документ, по вектору на каждый токен. На запросе: для каждого токена вопроса ищется ближайший токен документа, скоры суммируются. Это «softmax над матрицей похожестей».

Где работает: очень точный retrieval на длинных документах с разнородным контентом. ColBERT-v2, топ на BEIR-бенчмарках.

Минус: индекс в 10–50 раз больше обычного. Нужен специализированный движок: Vespa, RAGatouille, jina-colbert-v2.

Когда брать: научная литература, юриспруденция, длинные технические документы, там качество окупает.

Техника 8. GraphRAG (Microsoft, 2024)

Проблема. «Кто из сотрудников отдела продаж работал с клиентами из строительной отрасли в Q3?», вопрос про связи, не про текст.

Решение. Помимо текстового индекса строится граф знаний:

  1. LLM проходит по корпусу, извлекает entities (Person, Company, Project) и relations (worked_with, reports_to).
  2. Граф кластеризуется (Leiden algorithm) на тематические сообщества.
  3. На запрос: ищется по графу + по тексту, ответы агрегируются.

Реализации:

  • Microsoft GraphRAG (open-source, Python), reference implementation.
  • LightRAG (HKU, 2024), упрощённый вариант с двухуровневым retrieval (low-level facts + high-level themes), в 5–10× дешевле GraphRAG.
  • Neo4j + LangChain, связка для production.
  • TigerGraph CoPilot, Memgraph MAGE, managed варианты.

Прирост качества. На multi-hop вопросах GraphRAG обходит baseline RAG на 20–50% (Microsoft research). На простых факт-вопросах, на уровне baseline или чуть хуже (overhead).

Цена. Дорого: построение графа = LLM-вызов на каждый чанк (~$10–100 на индексацию 10M токенов). Поддержка графа при обновлениях нетривиальна.

Когда брать: домены с густыми связями (юриспруденция, медицина, корпоративные knowledge graphs, аналитика клиентов).

Техника 9. Self-RAG / Reflection

Идея (Self-RAG, Asai et al. 2023). LLM сам решает, нужен ли вообще retrieval для конкретного вопроса, и сам критикует найденные документы и свой ответ через специальные «reflection tokens»:

  • [Retrieve], нужно искать?
  • [IsRel], релевантен ли документ?
  • [IsSup], поддерживается ли утверждение источниками?
  • [IsUse], полезен ли финальный ответ?

Модель дотренирована генерировать эти токены наряду с обычным текстом.

Прирост качества. На FactScore точность улучшается на 15–30% против стандартного RAG. Снижает галлюцинации в полтора-два раза.

Цена. Нужна fine-tuned модель (есть открытые self-rag-llama2-7b, self-rag-llama2-13b). Или эмулировать через стандартный LLM с правильными промптами.

Техника 10. CRAG (Corrective RAG)

Идея (Yan et al. 2024). После retrieval лёгкий classifier оценивает: документы (а) корректны, (б) неоднозначны, (в) некорректны. По результату:

  • Correct: обычная генерация.
  • Incorrect: делать web search (fallback), брать оттуда контекст.
  • Ambiguous: комбинировать оба источника.

Реализуется через любой evaluator (T5-large, GPT-mini как judge).

Прирост качества. На PopQA и Biography бенчмарках, стабильное превосходство над baseline и Self-RAG.

Цена. +1 LLM-call (judge), потенциально +1 web search.

Техника 11. Query Routing

Проблема. В компании несколько источников: HR-регламенты, тех-документация, CRM-данные. Бить во все одновременно, шум. Иметь один индекс на всё, путаница терминологии.

Решение. LLM-classifier (или fine-tuned small model) на входе решает, в какой источник идти:

intent = classify(query)
match intent:
    case "hr": kb = hr_index
    case "tech": kb = tech_index
    case "crm": return crm_agent.query(query)  # function call вместо RAG
    case "general": return llm(query)  # без RAG

Прирост качества. Снижает false positives, ускоряет ответ, удешевляет (не делать ненужный retrieval).

Цена. 1 классификатор на входе. Для классификации можно использовать gpt-5-mini ($0.0001 на запрос) или fine-tuned BERT.

Техника 12. Agentic RAG

Идея. LLM, не просто генератор ответа, а агент: рассуждает, планирует, вызывает инструменты (включая retrieval как один из tools), сам решает, когда остановиться.

[вопрос: "Сколько мы заработали на клиенте N в прошлом году?"]
     │
     ▼
[Agent loop]
  ├─ tool: crm_lookup(name="N") → клиент с тремя дочками
  ├─ tool: rag_search("выручка по дочерним компаниям клиента N 2025")
  ├─ tool: sql_query("SELECT SUM(amount) FROM revenue WHERE client_id IN (...)")
  └─ synthesize → "Совокупная выручка ~$2.4M (CRM + ERP + RAG)"

Реализации: LangGraph (LangChain), CrewAI, AutoGen (Microsoft), Semantic Kernel, Anthropic Agents SDK / Claude Code SDK, OpenAI Assistants API.

Прирост качества. На сложных multi-step вопросах, качественно другой уровень. На простых, overhead, ниже точность из-за «лишних» рассуждений.

Цена. 5–20 LLM-вызовов на сложный запрос. Latency 10–60 сек. Стоимость ×5–20 от обычного RAG.

Техника 13. Long-context post-processing (Map-Reduce, Refine)

Проблема. Иногда ответ требует синтеза из 50–100 чанков, не из 5.

Решения (LlamaIndex / LangChain паттерны):

  • Map-Reduce: для каждого чанка, мини-ответ; потом reduce-LLM объединяет.
  • Refine: последовательно, каждый следующий чанк уточняет предыдущий ответ.
  • Tree summarize: иерархическое сжатие.

Когда нужно: обзорные вопросы («суммируй всё, что у нас есть про продукт X»). Не для precision-задач.

Сводная таблица: что когда применять

Техника Прирост Цена внедрения Когда обязательно
Hybrid search +10–25% recall Низкая Всегда
Reranker +5–15% precision Низкая Всегда
Contextual Retrieval −49% failure Средняя ($) Длинные документы с глобальным контекстом
HyDE +5–15% recall Низкая Короткие/расплывчатые запросы
Multi-query / RAG-Fusion +5–15% recall Низкая Разнообразный язык пользователей
Parent-Document / Sent-Window +10–20% answer quality Низкая (только код) Точные ответы в больших документах
ColBERT +10–20% precision Высокая (инфра) Юриспруденция, наука, длинные тех-доки
GraphRAG +20–50% multi-hop Высокая ($$$) Связи между сущностями
Self-RAG +15–30% factuality Средняя (fine-tune) Высокая цена галлюцинаций
CRAG Стабильность Средняя Возможен fallback на веб
Query Routing Снижение шума Низкая Несколько источников
Agentic Качественно Очень высокая ($$$$) Сложные multi-step

Что важно понимать

Базовый рецепт прода 2026: hybrid search + Contextual Retrieval + reranker. Это даёт ~85% качества за разумные деньги. Дальше, точечно, под обнаруженные проблемы.

Не сваливайте всё сразу. Каждая техника решает конкретный класс ошибок. Без эталонного датасета (см. следующий урок) вы не поймёте, какая помогла, а какая всё запутала.

Цена усложнения растёт быстрее качества. Переход baseline → hybrid + rerank даёт +20% за 5% работы. Переход prod → agentic GraphRAG даёт +5% за 50% работы. Считайте окупаемость.

Самый недооценённый рычаг, данные. Чистый и хорошо структурированный корпус с базовым RAG бьёт грязный корпус с самыми продвинутыми техниками. Об этом, следующий урок: подводные камни и как мерить качество.

AI-тест
1 / 19

Что такое базовый RAG и как он работает?