Как вы обрабатываете запросы, на которые нет ответа в документах?

Краткий тезис

В 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)

Шаги

  1. Создать векторную БД с 100 документами по одной теме (например, инструкции к продукту)
  2. Подготовить тестовый набор из 50 запросов:
    • 20 запросов, на которые есть ответ в документах
    • 20 запросов, на которых нет ответа (другая тема)
    • 10 пограничных (частичная релевантность)
  3. Реализовать три стратегии:
    • Только confidence threshold
    • Только LLM self-check
    • Гибридную (confidence + LLM)
  4. Замерить для каждой стратегии:
    • Отказы на запросах без ответа (должны быть высокими)
    • Галлюцинации (ложные ответы) — должны быть низкими
    • Правильные ответы на запросы с ответом — должны сохраниться
  5. Подобрать оптимальный confidence threshold (0.5, 0.6, 0.7, 0.8)
  6. Написать отчёт с рекомендациями

Ожидаемый результат Система, которая честно говорит «не знаю» на вопросы не по документам и не галлюцинирует.


Связь с другими вопросами

ВопросТема
5Оценка качества RAG (faithfulness, галлюцинации)
16Метрики качества генерации (faithfulness, answer relevance)
17Уменьшение галлюцинаций в RAG
67Prompt injection (защита от вредоносных запросов)
86Retrieval не находит (даже когда ответ есть в документах)
96Предотвращение галлюцинаций в production

8. Как вы обрабатываете запросы, на которые нет ответа в документах|8. Как вы обрабатываете запросы, на которые нет ответа в документах|8. Как вы обрабатываете запросы, на которые нет ответа в документах|8 полностью разобран. Переходим к вопросу 9, когда будете готовы|Вопрос 8 полностью разобран. Переходим к вопросу 9, когда будете готовы]]


Навигация