RAG · Retrieval-augmented generation · урок 6 · 13 мин
Диагностика неверного ответа RAG
Debugging a wrong RAG answer
ТемыRAG
Зачем
После урока ты ответишь на самый вероятный вопрос технического раунда по RAG: «клиенту назвали неверную комиссию — что ты делаешь?». Сильный ответ начинается не с исправления, а с диагностики: каждая проверка делит поиск причины пополам. Тот же порядок нужен и на работе, когда жалоба приходит в пятницу вечером.
Главная ошибка: чинить до диагноза
Типичный слабый ответ звучит так: «добавлю в prompt (инструкцию модели) правило брать свежий тариф» или «поставлю ещё одного агента-проверяющего». Оба — исправления наугад. Причина не найдена, значит неизвестно, исправлено ли хоть что-то, и сколько ещё вопросов ломается так же.
Сильный ответ начинается с вопроса «какое доказательство укажет место поломки?». Помогает факт из устройства RAG (retrieval-augmented generation, генерация с опорой на найденные документы): две его половины ломаются независимо. Retrieval (выборка) мог не принести нужный chunk (кусок документа), или generation (генерация ответа) могла неверно использовать принесённое. Первая проверка отвечает именно на это.
Порядок: назад от ответа
Идём от ответа к источнику, и каждая проверка отсекает половину возможных причин.
Шаг 1. Открыть trace (подробный журнал этого запроса: что искали, какие chunks с какими версиями попали в context — всё, что модель видела в запросе, — что ответила модель). Вопрос: был ли верный факт в chunks, которые видела модель?
- Да → retrieval сработал, это сбой generation: модель проигнорировала или неверно прочитала факт. Подтверждаем проверкой groundedness (опоры каждого утверждения ответа на найденный текст): неверная цифра не найдётся ни в одном chunk.
- Нет → идём выше.
Шаг 2. Есть ли верный факт в index вообще? Ищем напрямую по индексу, в обход всего pipeline (конвейера).
- Есть, но не найден или стоит низко → проблема retrieval или rerank (переранжирования). Смотрим ранг нужного chunk до и после reranker и metadata filters (отсев по карточке: дата, язык, доступ) — не отрезал ли фильтр нужное.
- Нет → данные потеряны раньше: документ не прошёл ingestion (приём), parsing (разбор PDF) испортил таблицу, chunking (нарезка) разрезал её пополам, normalization (приведение к единому виду) исказила цифры.
Шаг 3. На каждом шаге искать конкурирующую старую версию. Для неверной комиссии в банке это самая вероятная причина: в индексе живут тарифы 2025 и 2026 годов, и старый выиграл ранжирование.
Пример: прошлогодняя комиссия
Жалоба: клиенту назвали комиссию за досрочное погашение 2% вместо 1,5% по новому тарифу. Открываем trace. В context пять chunks: на 1-м месте пункт тарифа 2025 года с «2%», на 4-м — тариф 2026 года с «1,5%». Модель процитировала первый. Это значит: retrieval принёс и верное, и неверное; модель выбрала то, что выше. Корень не в модели, а в том, что истёкшая версия вообще могла соревноваться за вопрос о текущей комиссии, а выбор версии был оставлен модели.
Дальше второй вопрос: почему старый документ выше нового? Например, у старого был chunk с заголовком таблицы, а у нового таблица разрезана — это уже ошибка нарезки, и её надо чинить отдельно.
Исправление: у каждого chunk поля valid_from и valid_to; retrieval фильтрует по дате, которая важна для вопроса: сегодня для нового клиента, дата договора для старого, если так велят условия. Старые версии остаются в индексе, но не конкурируют случайно.
Доказательство исправления, а не надежда: детерминированный тест retriever на оба случая дат; набор вопросов о версиях, прогнанный до и после; полный регрессионный набор; наблюдение за жалобами на комиссии после выкатки. А в долгую — комиссию называет tool (функция, читающая из системы учёта), а не текст.
Если виновата generation
Ветка «факт был в context, а ответ неверный» тоже требует диагноза, а не правила в prompt. Частые причины: в context два противоречащих chunks (старая и новая версия — снова шаг 3); нужный chunk утонул среди длинного шумного context; число стоит в таблице, которую parsing превратил в кашу, и модель прочитала не ту колонку; инструкция не требует ссылки на источник для каждого числа. Проверка простая: прогнать тот же вопрос с одним верным chunk в context. Если ответ стал верным — виноват шум или конфликт, и чинить надо отбор и порядок chunks. Если нет — смотреть, как chunk выглядит после parsing.
Сначала защитить клиента
Если ошибка задевает клиентов прямо сейчас, порядок меняется: сначала остановить вред — откатить последнее изменение или направить этот тип вопросов человеку, — а потом спокойно диагностировать. Идеальный диагноз не стоит ещё сотни неверных ответов.
Классы поломок
Barnett и соавторы (2024) по трём проектам из разных областей (исследования, образование, биомедицина) выделили семь точек отказа RAG. Их удобно разложить по нашей схеме:
| Точка отказа | Что произошло | Где искать |
|---|---|---|
| Missing content | ответа нет в корпусе, а система всё равно отвечает | ingestion; поведение «не знаю» |
| Missed top ranked | ответ в корпусе, но ниже top-k (первых k результатов) | retrieval, rerank |
| Not in context | найден, но отброшен при сборке context | сборка context, лимит длины |
| Not extracted | был в context, модель не извлекла | generation, шум и противоречия |
| Wrong format | нарушен требуемый формат | generation |
| Incorrect specificity | слишком общо или слишком подробно | вопрос и инструкция |
| Incomplete | часть ответа пропущена | generation, многочастные вопросы |
Сценарий «документ обновился, а индекс нет» — частный случай: верный факт есть в источнике, но не в index (шаг 2, ветка «нет»), а старая версия конкурирует (шаг 3). Это та же болезнь, что прошлогодний тариф.
Что построить заранее
Такая диагностика возможна, только если заранее есть три вещи:
- Traces с chunk IDs, версиями документов и рангами до и после rerank.
- Effective dates (даты действия) в metadata каждого документа.
- Golden set — набор вопросов с известным верным источником, чтобы проверить исправление и не сломать остальное.
Без traces шаг 1 невозможен, без дат исправление невозможно, без golden set невозможно доказательство.
Схема
Термины · Key terms
- trace
- журнал одного запроса: запрос, chunks с версиями и рангами, ответ
- retrieval failure
- нужный chunk не попал в найденное
- generation failure
- chunk был в context, а модель ответила неверно
- groundedness check
- проверка, что каждое утверждение есть в найденном тексте
- metadata filter
- отсев chunks кодом по дате, языку, доступу
- effective date
- дата вступления документа в силу, поля valid_from и valid_to
- golden set
- вопросы с известным верным источником для проверки
- regression suite
- набор тестов, который ловит поломку того, что работало
- failure point
- класс поломки RAG по Barnett и соавторам
Сделай сам
Не подглядывая в урок, ответь вслух за 2 минуты на вопрос: «Клиенту назвали прошлогоднюю комиссию за досрочное погашение. Что ты делаешь?» Запиши голосовую заметку. Потом проверь: начался ли ответ с диагностики, назвал ли ты три шага, старую версию и три вещи, которые нужны заранее.
Обсуди с тьютором: перескажи свой ответ текстом и попроси тьютора отметить, где ты предложил исправление раньше, чем нашёл доказательство.
Проверь себя · ответ под вопросом
1Какой первый вопрос ты задаёшь trace, и куда идёшь при ответе «да» и при ответе «нет»?
2Чем сценарий «документ обновился, а embeddings нет» похож на старую версию тарифа?
3Какие три вещи надо построить заранее, чтобы такая диагностика вообще была возможна?
Interview questions · US / UK
1A customer was quoted last year's early-settlement fee by your RAG assistant. What do you do?
2Follow-up probe: the right chunk was at rank 4 and the model quoted the stale one at rank 1. How do you fix it, and how do you prove the fix?
3What would you instrument before launch so that this kind of bug is debuggable?
Ключевые фразы · Say it aloud
- I'd work backwards from the answerиду назад от ответа
- Was the right fact in the context the model saw?был ли верный факт в context модели?
- Indexed but not retrieved, or never indexed?в индексе, но не найден, или не попал в индекс?
- Check for a competing older versionпроверить, нет ли конкурирующей старой версии
- Diagnose before fixingсначала диагноз, потом исправление
- The proof is a test, not a hopeдоказательство — тест, а не надежда
Материалы
- Barnett et al., 2024 — Seven Failure Points When Engineering a RAG System — раздел с семью точками отказа и выводы (15 мин)
- Hamel Husain — Your AI Product Needs Evals — почему сначала смотреть в traces, а не чинить (15 мин)