Как вы обрабатываете запросы, на которые нет ответа в документах?
Краткий тезис
В production RAG-системах запросы без ответа в документах — обычная ситуация. Худшее, что можно сделать — заставить LLM галлюцинировать (выдумать ответ). Лучшие стратегии: честный отказ с объяснением, fallback к общей LLM (без ограничения документами) или запрос на уточнение у пользователя. Ключевой навык — надёжно детектировать такие запросы через confidence score retrieval или специальный промпт.
1. Термин: Запрос без ответа (Out-of-knowledge query)
Что это Запрос пользователя, на который нет релевантной информации в проиндексированных документах.
Примеры
- В базе знаний только инструкции по продукту А, пользователь спрашивает про продукт Б
- В документах нет информации о новом законе (документы не обновлялись)
- Запрос слишком специфичный («какого цвета была кошка у директора в 2018 году»)
Термин «Out-of-domain» Запрос вне домена системы (спросили про погоду в юридическом RAG).
Термин «Relevant document» Документ, который содержит информацию, отвечающую на запрос пользователя.
2. Детекция: как понять, что ответа нет
2.1 Confidence score от retrieval
Что такое confidence score Мера уверенности retrieval в том, что найденные документы релевантны запросу.
Как измерить confidence
| Метод | Формула | Порог |
|---|---|---|
| Cosine similarity | Максимальная косинусная близость между запросом и найденными чанками | < 0.7 → низкая уверенность |
| Distance | Расстояние до ближайшего соседа в ANN | > 0.5 → далеко, не уверены |
| Ранги RRF | Сумма обратных рангов | < 0.01 → плохо |
Пример кода
# Qdrant возвращает scores (косинусная близость, чем выше, тем лучше)
results = client.search(...)
max_score = max([r.score for r in results])
THRESHOLD = 0.7 # настраивается экспериментально
if max_score < THRESHOLD:
return "Нет релевантных документов в базе знаний"
else:
return generate_answer(results)
Термин «Порог» (Threshold Граничное значение, выше которого считаем, что документ релевантен. Подбирается экспериментально на валидационном датасете.
Цифра На практике хороший порог cosine similarity для BGE-m3 — 0.65-0.75.
2.2 Специальный промпт (LLM как детектор)
Что это Инструкция LLM самому определить, может ли он ответить на вопрос на основе контекста.
Пример промпта
Инструкция: У тебя есть контекст из документов.
Если информации достаточно для полного ответа на вопрос — ответь.
Если информации НЕТ или её НЕДОСТАТОЧНО — НЕ ВЫДУМЫВАЙ.
Вместо этого ответь ровно: "У меня нет информации по этому вопросу в доступных документах."
Контекст: {context}
Вопрос: {question}
Термин «Self-reflection» (саморефлексия LLM оценивает свою способность ответить на вопрос до того, как сгенерирует ответ.
Плюсы Учитывает не только retrieval (документы могут быть релевантны, но LLM не может извлечь ответ).
Минусы Добавляет latency (один дополнительный LLM-вызов).
2.3 Гибридная детекция (confidence + LLM)
Лучшая практика Комбинация обоих методов.
def has_answer(query, context):
# 1. Быстрая проверка через retrieval
max_score = get_max_similarity(query)
if max_score < 0.5:
return False # очевидно нет
elif max_score < 0.7:
# 2. Пограничный случай — проверим через LLM
return llm_check_if_can_answer(query, context)
else:
return True # высокая уверенность
3. Стратегии обработки запросов без ответа
3.1 Отказ от ответа (честный refusal)
Что это Система прямо говорит, что не может ответить на вопрос из-за отсутствия информации.
Варианты формулировок
| Тон | Пример |
|---|---|
| Нейтральный | «Информация по вашему вопросу не найдена в доступных документах.» |
| Помогающий | «Я не нашёл информацию о {тема}. Попробуйте переформулировать вопрос или обратитесь к документам X, Y.» |
| Предлагающий альтернативу | «У меня нет точного ответа на ваш вопрос. Возможно, вас интересует {связанная тема}?» |
Когда использовать Default стратегия Честность укрепляет доверие пользователя.
Термин «Refusal» (отказ LLM отказывается отвечать, а не выдумывает.
3.2 Fallback к общей LLM (без RAG)
Что это Если в документах нет ответа, система обращается к общей LLM (которая обучена на интернете) для ответа без ограничения документами.
Архитектура
Запрос → RAG с документами
│
┌───────┴───────┐
▼ ▼
Есть ответ? Нет ответа?
│ │
▼ ▼
RAG ответ Fallback LLM
(GPT-4 / Llama)
Когда использовать
- Система не обязана отвечать только по документам (общий чат-бот с доступом к документам)
- Пользователь явно хочет общий ответ ("а что в целом известно о...")
- Осторожно Может противоречить документам (LLM скажет одно, документы — другое)
Пример:
- В документах нет информации о новом законе
- Fallback LLM отвечает на основе своих знаний (которые могут быть устаревшими)
3.3 Запрос на уточнение у пользователя
Что это Система просит пользователя уточнить вопрос или предоставить больше информации.
Примеры
| Ситуация | Уточнение |
|---|---|
| Запрос слишком общий | «Какой именно продукт вас интересует? У нас есть А, Б, В.» |
| Не хватает контекста | «Пожалуйста, уточните дату или номер документа.» |
| Запрос вне домена | «Я специализируюсь на вопросах о {домен}. Могу я помочь с этим?» |
Когда использовать Когда запрос нечёткий или ambiguus (многозначный).
Термин «Disambiguation» (снятие неоднозначности Уточнение, чтобы понять, что именно имел в виду пользователь.
4. Гибридный подход (рекомендуемый)
Комбинация всех трёх стратегий
def handle_query(query):
# 1. Retrieval с confidence
context, scores = retrieve(query)
max_score = max(scores)
# 2. Кейс 1: явно есть ответ
if max_score > 0.75:
return generate_with_context(query, context)
# 3. Кейс 2: нет ответа (уверенно)
if max_score < 0.4:
return f"Извините, я не нашёл информацию по вашему вопросу в документах. "
f"Попробуйте переформулировать или обратитесь к документам: {list_sources()}"
# 4. Кейс 3: пограничный случай (0.4-0.75)
# Проверяем через LLM, есть ли ответ
can_answer = llm_check_if_can_answer(query, context)
if can_answer:
return generate_with_context(query, context)
# 5. Если LLM тоже не уверен — fallback или уточнение
if is_ambiguous(query):
return ask_clarification(query) # уточнение
return fallback_to_general_llm(query) # общая LLM
5. Чего НЕЛЬЗЯ делать
| Что нельзя | Почему | Пример плохого поведения |
|---|---|---|
| Галлюцинировать | Пользователь поверит ложной информации | «Согласно документам, цена 1000 рублей» (хотя в документах нет цены) |
| Отвечать "не знаю" на всё | Система бесполезна | На любой вопрос «Я не знаю» |
| Игнорировать контекст | Fallback LLM противоречит документам | Документы говорят одно, LLM — другое |
| Бесконечные уточнения | Раздражает пользователя | «Уточните», «Уточните», «Уточните» |
Термин «Галлюцинация» (Hallucination LLM генерирует факты, которых нет в контексте.
6. Метрики для оценки обработки out-of-knowledge запросов
| Метрика | Что измеряет | Как считать | Цель |
|---|---|---|---|
| Refusal rate | Доля отказов на запросы без ответа | #refusals / #out_of_knowledge_queries | Высокий (>0.9) |
| False positive rate | Система ответила на запрос без ответа (галлюцинация) | #hallucinations / #out_of_knowledge_queries | Низкий (<0.05) |
| User satisfaction | Пользователь доволен отказом? | Опрос или косвенные метрики (повторные уточнения) | >0.8 |
Термин «False positive» (ложное срабатывание Система сказала, что ответ есть, хотя на самом деле его нет.
7. Практический кейс (пример для собеседования)
«В проекте юридического RAG для договоров мы столкнулись с тем, что пользователи спрашивали про условия, которых нет в договорах (например, "есть ли штраф за X?"). Модель иногда галлюцинировала, придумывая штрафы.
Мы добавили двухступенчатую детекцию: сначала retrieval confidence (порог 0.7), затем LLM проверяла, можно ли ответить на вопрос из контекста. Если оба метода говорили "нет" — система возвращала: "В предоставленных договорах нет информации о штрафах за X. Рекомендуем обратиться к юристу."
Результат: галлюцинации снизились с 15% до 2%, отказы выросли с 5% до 18% (пользователи стали доверять системе больше).»
8. Пет-проект для закрепления
Задача Реализовать обработку out-of-knowledge запросов в вашем RAG.
Инструменты Python, Qdrant, BGE-m3, Llama-3 (через Ollama)
Шаги
- Создать векторную БД с 100 документами по одной теме (например, инструкции к продукту)
- Подготовить тестовый набор из 50 запросов:
- 20 запросов, на которые есть ответ в документах
- 20 запросов, на которых нет ответа (другая тема)
- 10 пограничных (частичная релевантность)
- Реализовать три стратегии:
- Только confidence threshold
- Только LLM self-check
- Гибридную (confidence + LLM)
- Замерить для каждой стратегии:
- Отказы на запросах без ответа (должны быть высокими)
- Галлюцинации (ложные ответы) — должны быть низкими
- Правильные ответы на запросы с ответом — должны сохраниться
- Подобрать оптимальный confidence threshold (0.5, 0.6, 0.7, 0.8)
- Написать отчёт с рекомендациями
Ожидаемый результат Система, которая честно говорит «не знаю» на вопросы не по документам и не галлюцинирует.
Связь с другими вопросами
| Вопрос | Тема |
|---|---|
| 5 | Оценка качества RAG (faithfulness, галлюцинации) |
| 16 | Метрики качества генерации (faithfulness, answer relevance) |
| 17 | Уменьшение галлюцинаций в RAG |
| 67 | Prompt injection (защита от вредоносных запросов) |
| 86 | Retrieval не находит (даже когда ответ есть в документах) |
| 96 | Предотвращение галлюцинаций в production |
8. Как вы обрабатываете запросы, на которые нет ответа в документах|8. Как вы обрабатываете запросы, на которые нет ответа в документах|8. Как вы обрабатываете запросы, на которые нет ответа в документах|8 полностью разобран. Переходим к вопросу 9, когда будете готовы|Вопрос 8 полностью разобран. Переходим к вопросу 9, когда будете готовы]]
Навигация
- Предыдущий: 7
- Следующий: 9
- Индекс: 00. Индекс разборов