中文翻译暂不可用,显示俄语原文。
Как вы решаете проблему “я знаю, что ответ есть в документах, но retrieval не находит”?
Краткий тезис
Проблема «знаю, что ответ есть, но retrieval не находит» — одна из самых частых в RAG-системах. Её корень — несоответствие между тем, как пользователь формулирует запрос, и тем, как документы закодированы в векторном пространстве. Решение — системный подход: сначала улучшаем запрос (query rewriting, expansion), затем улучшаем индексацию (чанкинг, метаданные), и только потом переходим к сложным multi-step стратегиям (HyDE, step-back). Query rewriting — самое простое и эффективное первое действие.
1. Термин: Retrieval (поиск) и его ограничения
Retrieval — этап RAG, где система ищет в векторной БД чанки, семантически близкие к запросу пользователя. Проблема возникает, когда семантическая близость не равна релевантности.
Почему это происходит
- Плохой запрос пользователь использует общие слова, синонимы, или формулирует вопрос иначе, чем написано в документах.
- Шум в чанках чанк содержит много нерелевантного текста, разбавляющего полезную информацию.
- Неудачный чанкинг разрыв логической единицы (например, ответ на вопрос разорван между двумя чанками).
- Несовпадение эмбеддингов модель эмбеддингов не улавливает тонкие связи (например, «как исправить ошибку 404» vs «настройка .htaccess для перенаправления»).
Термин «Семантический разрыв» (semantic gap) — разница между смыслом запроса и смыслом документа в векторном пространстве.
2. Первый шаг: Улучшение запроса (Query-side)
2.1 Query Rewriting (переписывание запроса)
Что это: LLM переписывает исходный запрос пользователя в более чёткую, поисковую форму.
Пример:
- Исходный запрос: «Почему у меня не работает?»
- Переписанный: «Причины неработоспособности функции X в версии Y и способы их устранения».
Код (псевдо):
def rewrite_query(user_query: str) -> str:
prompt = f"""Перепиши запрос пользователя для поиска в базе знаний.
Сделай его конкретным, добавь ключевые термины.
Запрос: {user_query}
Переписанный запрос:"""
return llm.generate(prompt)
Почему это эффективно LLM понимает контекст и может сформулировать запрос так, как он мог бы быть написан в документации.
2.2 Query Expansion (расширение запроса)
Что это: Добавление к запросу синонимов, связанных терминов, переводов.
Пример:
- Исходный запрос: «Как настроить SSL?»
- Расширенный: «Как настроить SSL? (SSL, TLS, сертификат, https, шифрование, Let's Encrypt)»
Методы
| Метод | Описание | Плюсы | Минусы |
|---|---|---|---|
| LLM-генерация | LLM генерирует синонимы | Гибко, контекстно | Дорого, latency |
| Тезаурус/WordNet | Статический словарь | Быстро, дёшево | Не учитывает контекст |
| Back-translation | Перевод на другой язык и обратно | Добавляет вариативность | Может исказить смысл |
Важно Query expansion может увеличить шум, если синонимы выбраны неудачно. Нужно тестировать.
3. Второй шаг: Улучшение индексации (Index-side)
Если улучшение запроса не помогло, проблема может быть в том, как документы закодированы.
3.1 Smaller / Smarter Chunking (умный чанкинг)
Проблема Слишком большие чанки разбавляют релевантную информацию; слишком маленькие — теряют контекст.
Решения
- Semantic chunking разбивать по смысловым границам (абзацы, предложения), а не по фиксированной длине.
- Overlapping chunks перекрытие чанков (например, 10-20% overlap) — если ответ разорван, он попадёт в соседний чанк.
- Hierarchical chunking хранить чанки разного размера (small для точного поиска, large для контекста).
3.2 Добавление метаданных (Metadata)
Что это: Добавление к каждому чанку тегов: источник, дата, тип документа, заголовок, ключевые слова.
Как помогает Можно фильтровать поиск по метаданным (например, «только документация по версии 2.0»), что резко сужает пространство поиска.
Пример структуры метаданных
{
"chunk_id": "123",
"source": "docs/api_v2.pdf",
"title": "Настройка аутентификации",
"tags": ["auth", "security", "v2.0"],
"date": "2024-01-15"
}
Фильтрация в векторной БД (Pinecone, Qdrant):
results = index.query(
vector=query_embedding,
filter={"tags": {"$contains": "auth"}},
top_k=5
)
4. Третий шаг: Multi-step retrieval (многошаговый поиск)
Если простые методы не работают, используем более сложные стратегии.
4.1 HyDE (Hypothetical Document Embeddings)
Что это: LLM генерирует гипотетический документ, который мог бы быть ответом на запрос. Затем этот документ используется для поиска похожих реальных документов.
Процесс
- Запрос → LLM → Гипотетический ответ (документ)
- Гипотетический ответ → Эмбеддинг → Поиск в векторной БД
- Результаты поиска → LLM → Финальный ответ
Почему работает Гипотетический ответ семантически ближе к реальным документам, чем исходный запрос.
Код (псевдо):
def hyde_retrieval(query: str) -> list[str]:
hypothetical_doc = llm.generate(f"Напиши гипотетический документ, отвечающий на запрос: {query}")
embedding = embedder.embed(hypothetical_doc)
results = vector_db.search(embedding, top_k=5)
return results
4.2 Step-back Prompting (шаг назад)
Что это: Сначала генерируется более общий запрос (step-back), затем по нему ищутся документы, и только потом — уточняющий поиск.
Пример:
- Исходный запрос: «Как исправить ошибку E123 в модуле X?»
- Step-back запрос: «Общие принципы работы модуля X и типичные ошибки»
- Поиск по step-back запросу → контекст → уточняющий поиск по исходному запросу
Плюсы Находит документы, которые объясняют причину, а не только симптом.
5. Четвёртый шаг: Human-in-the-loop (человек в контуре)
Когда автоматические методы исчерпаны, добавляем возможность ручного вмешательства.
Варианты
- Пользователь может указать документ вручную кнопка «Прикрепить файл» или выбор из списка.
- Администратор может добавить синонимы/правила например, «если запрос содержит "ошибка 404", искать по тегу "перенаправление"».
- Feedback loop если пользователь оценил ответ как нерелевантный, система запоминает запрос и предлагает администратору добавить правило.
Почему это важно В production всегда будут крайние случаи, которые не покрываются автоматикой. Human-in-the-loop — страховка.
6. Диагностика: как понять, что именно не так?
Прежде чем лечить, нужно поставить диагноз. Используйте оффлайн-метрики (см. вопрос 5).
| Метрика | Что показывает | Если плохо → проблема в |
|---|---|---|
| Hit Rate@k | Есть ли хоть один релевантный документ в top-k | Индексация, эмбеддинги |
| MRR | На каком месте первый релевантный документ | Ранжирование, запрос |
| Recall@k | Сколько всех релевантных документов нашлось | Чанкинг, coverage |
Пример диагностики
- HR@5 = 0.9, MRR = 0.3 → релевантный документ есть, но он глубоко в выдаче → проблема в запросе или ранжировании.
- HR@5 = 0.4 → релевантного документа часто нет вообще → проблема в индексации или чанкинге.
7. Сравнение методов: что выбрать первым?
| Метод | Сложность | Эффективность | Latency | Когда использовать |
|---|---|---|---|---|
| Query Rewriting | Низкая | Высокая | Низкая | Всегда, как первая линия |
| Query Expansion | Низкая | Средняя | Низкая | Если запрос слишком короткий |
| Smarter Chunking | Средняя | Высокая | Нулевая (однократно) | Если HR низкий |
| Metadata Filtering | Средняя | Высокая | Низкая | Если есть структурированные данные |
| HyDE | Высокая | Высокая | Высокая | Если простые методы не работают |
| Step-back | Высокая | Средняя | Высокая | Для сложных, многосоставных вопросов |
| Human-in-the-loop | Очень высокая | Максимальная | Нулевая (для системы) | Как крайняя мера |
Пет-проект для закрепления
Задача Создать RAG-систему для технической документации (например, документация Flask или FastAPI), где 20% запросов не находят ответа, хотя он есть.
Инструменты Python, LangChain, FAISS (векторная БД), OpenAI API (эмбеддинги + LLM), Streamlit (UI).
Шаги:
- Загрузка данных Скачать документацию Flask (HTML/PDF), разбить на чанки (semantic chunking с overlap 15%).
- Индексация Создать эмбеддинги (text-embedding-3-small), сохранить в FAISS с метаданными (заголовок, раздел).
- Базовый retrieval Простой поиск по косинусной близости.
- Добавление query rewriting LLM (GPT-4o-mini) переписывает запрос перед поиском.
- Добавление query expansion LLM генерирует 3 синонима к запросу.
- Тестирование Собрать 50 запросов, где базовый retrieval не находит ответ. Проверить, сколько из них исправляет rewriting + expansion.
- Добавление HyDE Для оставшихся запросов применить HyDE.
- Human-in-the-loop Добавить кнопку «Указать документ вручную» в UI.
- Оценка Посчитать HR@5, MRR до и после каждого улучшения.
Ожидаемый результат Вы увидите, как каждый метод повышает метрики. Например:
- Базовый: HR@5 = 0.6
- +Query Rewriting: HR@5 = 0.75
- +Query Expansion: HR@5 = 0.82
- +HyDE: HR@5 = 0.9
- +Human-in-the-loop: HR@5 = 0.98 (с учётом ручных указаний)
Связь с другими вопросами
| Вопрос | Тема |
|---|---|
| 5 | Оценка качества retrieval (метрики для диагностики) |
| 3 | Стратегии chunking (как улучшить индексацию) |
| 7 | Уменьшение latency (как не замедлить систему при multi-step) |
| 10 | Self-RAG (альтернативный подход к улучшению retrieval) |
| 15 | Обработка запросов без ответа (смежная проблема) |
| 20 | Метаданные и фильтрация (как улучшить индексацию) |
Навигация
- Предыдущий: 85
- Следующий: 87
- Индекс: 00. Индекс разборов