Загружаем изображение…
Загружаем изображение…
Тестируем RAG и боремся с галлюцинациями
Контекст:
Как за 30 минут развернуть локального RAG-помощника на LLM
📌 Тестируем
Загружаем в RAG таблицу с расходами на рекламу по нескольким каналам, в том числе:
tgads | 22.06.2026 | 18 311 р.
tgads | 22.06.2026 | 3 593 р.
Вопрос: «Посчитай сумму расходов по tgads». Ожидаем: 21 904 р.
Ответ: 549 330 р. 🤯
549 330 = 18 311 × 30. Модель взяла первую строку, умножила на 30 дней, вторую — проигнорировала.
✅ Да, это RAG!
С одной стороны — ура! RAG работает (самый надёжный способ убедиться — посмотреть цитаты-ссылки на источник, работает без доп.настроек (см. скрин)
С другой — что за глюки?
🔬 Галлюцинации
Это когда LLM уверенно генерирует правдоподобный ответ, который не соответствует предоставленному контексту.
В научной литературе также используются термины: конфабуляция (confabulation), фабрикация (fabrication), иллюзия (delusion) и даже пустословие (bullshitting).
🤖 Важно! Это не баг, а функция трансформера: он строит ответ как вероятностное продолжение на основе статистических паттернов из обучающих данных, а не как проверенный факт.
❓ Почему LLM галлюцинируют
1. Данные — ошибки, шумы, противоречия и пробелы в обучающих данных.
2. Архитектура — модель хранит не факты, а веса (числовые матрицы). Трансформер не извлекает информацию — он достраивает текст по вероятностям.
3. Процесс обучения модели — честное «не знаю» ⚠️ штрафуется сильнее, чем уверенная догадка.
📂 Типы
1. Фактические галлюцинации (Factuality Hallucination)
Модель выдаёт неверную информацию о реальном мире. Пример: придумывает несуществующие судебные дела, факты, цитаты.
2. Галлюцинации верности (Faithfulness Hallucinations) — наш случай
Модель генерирует ответ, который не следует из предоставленного контекста.
Конфликт: между априорным распределением (веса модели, выученные на интернете) и условным распределением (контекст, который мы дали).
В нашем случае: модель выбрала паттерн «расход в день → расход за месяц» как наиболее вероятный. Модель не различает задачи «сложи» и «спрогнозируй» — она просто выбирает паттерн из весов (максимизирует $P(токен \mid контекст, веса)$).
🛠️ Как бороться
Работа строится на трёх уровнях:
1. До генерации — промпт-инжиниринг
- Точный промпт
❌ «Рассчитай расходы по каналу tgads»
✅ «Найди в таблице все строки с utm_source = tgads и сложи суммы из столбца sum»
- Системный промпт с правилами
В нашем случае бухгалтерская роль: «Ты — бухгалтер. Отвечай строго на основе данных из файла. Если данных нет — скажи честно. Не делай прогнозов»
💪 Системный промпт сужает распределение вероятностей — модель выбирает токены, согласованные и с контекстом, и с инструкцией.
- Настройки RAG в Open WebUI
`Настройки администратора → Настройки → Документы`
Выбрать подходящий режим
• Обычный RAG: чанкирует документ, ищет релевантные фрагменты (для больших документов, нескольких файлов)
• Полный контекст: весь документ целиком, но эмбеддинги создаются (для маленьких документов, где важна каждая деталь)
• Обход встраивания: весь документ целиком, RAG отключён (очень маленькие файлы, модель может выдать ошибку n_keep >= n_ctx (превышение длины контекста))
2. На этапе инференса — управление параметрами
Temperature: 0.1–0.3 (ниже → точнее)
Top-P: 0.9
Top-K: 40 (ограничивает количество рассматриваемых слов)
3. После генерации — валидация
- Задать вопросы:
«Подтверди, что каждый факт есть в документе»
«На основе каких строк ты сделал вывод?»
- Использовать отдельную LLM как оценщика (LLM-as-Judge)
🔍 Как детектировать галлюцинации
1. Проверить, не придумала ли модель того, чего нет в документе
2. Включить показ контекста в Open WebUI (отладка), чтобы увидеть, какие фрагменты попали в промпт
3. Перепроверить цифры — LLM часто ошибается в расчётах
📌 Итог
Задача инженера — сделать условное распределение доминирующим через:
- Точные промпты
- Системные правила
- Валидацию ответов
Корректируем промт → получаем 21 904 р. ✅
RAG работает, модель не галлюцинирует!