ЧТО ТАКОЕ ГАЛЛЮЦИНАЦИЯ И ПОЧЕМУ ЭТО НЕ ОШИБКА В КОДЕ
Галлюцинация — это когда LLM выдаёт уверенное, грамматически безупречное утверждение, которое не соответствует реальности: несуществующая функция в библиотеке, выдуманная цитата, ссылка на статью, которой нет, номер закона с потолка. Ключевое слово — уверенно. Модель не сигналит «я не знаю», она заполняет пробел самым вероятным продолжением.
Академически точнее термин confabulation (конфабуляция) — как у человека с повреждением памяти, который на голубом глазу достраивает недостающие куски. Модель делает ровно то же самое: у неё нет внутреннего датчика «правда/неправда», есть только распределение вероятностей над словарём. И это фундаментально: даже идеально обученная модель, минимизирующая кросс-энтропию, будет иногда генерировать ложь, потому что цель обучения — правдоподобие, а не достоверность.
ПОЧЕМУ МОДЕЛЬ ВРЁТ: ЧЕТЫРЕ КОРНЯ ПРОБЛЕМЫ
Разложим на причины, потому что лечение зависит от корня.
- Природа обучения. Next-token prediction награждает беглость, а не факт. На SFT и RLHF модель ещё и «учат» всегда давать полезный ответ — это подталкивает угадывать, когда честнее было бы промолчать.
- Пробелы в данных. Редкие факты (long-tail), свежие события после cutoff, узкоспециальные API — там, где данных мало, модель интерполирует. Отсюда выдуманные методы SDK и «фантомные» параметры функций.
- Сжатие знаний. Веса — это lossy-компрессия интернета. Точные цифры, даты, идентификаторы хранятся плохо. Модель помнит «форму» ответа, но путает детали.
- Провокация промптом. Наводящий вопрос («какую награду получил этот учёный в 2019?») заставляет модель придумать награду, даже если её не было. Sycophancy — стремление согласиться с пользователем — усиливает эффект.
Отдельно стоит различать типы вымысла, потому что метрики для них разные.
| Тип | Что это | Пример | Чем ловить |
|---|---|---|---|
| Фактическая (intrinsic) | Противоречит предоставленному контексту | В документе «выручка 10 млн», ответ — «12 млн» | NLI-проверка ответа против источника |
| Открытая (extrinsic) | Факт не проверить по контексту, взят «из головы» | Выдуманная цитата эксперта | Внешний retrieval + фактчек |
| Логическая | Верные посылки, неверный вывод | Ошибка в арифметике/цепочке | Self-consistency, tool use (калькулятор, код) |
| Инструментальная | Вымышленный API/сигнатура | Несуществующий метод библиотеки | Прогон кода, схема функций |
GROUNDING: ПРИЗЕМЛЯЕМ МОДЕЛЬ НА ФАКТЫ
Grounding — привязка генерации к проверяемому источнику. Идея простая: не дай модели отвечать по памяти, дай ей факты в контекст и заставь опираться только на них. Это самый мощный рычаг против галлюцинаций из доступных в проде.
На практике grounding — это три слоя:
- Инъекция контекста — релевантные документы в промпт.
- Констрейнт в инструкции — «Отвечай только на основе приведённого текста. Если ответа нет — скажи, что не знаешь».
- Атрибуция — модель обязана цитировать источник (номер чанка, span), чтобы ответ был трассируемым.
Последний пункт критичен: атрибуция превращает «поверьте мне» в «вот откуда я это взял», и её можно автоматически верифицировать. Инструменты для построения таких пайплайнов (векторные БД, реранкеры, фреймворки атрибуции) выходят почти каждую неделю — свежие релизы удобно отслеживать в каталоге REDDYX.
RAG И ЕГО ЛОВУШКИ
RAG (Retrieval-Augmented Generation) — это grounding в промышленном исполнении: перед генерацией система ищет релевантные куски в базе знаний и подкладывает их в контекст. По замерам сообщества правильно собранный RAG снижает частоту фактических галлюцинаций в разы по сравнению с голой моделью. Но у него свои грабли.
RAG не панацея
- Retrieval промахивается. Достали не тот чанк — модель добросовестно галлюцинирует по мусорному контексту. Мусор на входе = мусор на выходе.
- Модель игнорирует контекст. Даже с правильными фактами в промпте LLM иногда «перебивает» их выученным знанием. Особенно на длинном контексте — эффект lost-in-the-middle: факты в середине окна теряются.
- Конфликт источников. Два документа противоречат друг другу, модель молча выбирает один.
- Чанкинг рвёт смысл. Факт разрезан между чанками — retrieval достаёт половину.
Что реально помогает в 2026: гибридный поиск (dense + BM25), реранкер поверх top-k, а главное — верификация ответа против источников уже после генерации. RAG отвечает за достоверность на входе, детектор — за контроль на выходе.
КАК ЧИНИТЬ: РАБОЧИЙ СТЕК ПРИЁМОВ
Ни один метод не убирает галлюцинации в одиночку. Работает эшелонированная оборона.
| Метод | Против чего | Стоимость | Эффект |
|---|---|---|---|
| Grounding + инструкция «не знаю — молчи» | Открытые галлюцинации | Низкая | Высокий |
| RAG (гибрид + реранк) | Свежие/редкие факты | Средняя | Высокий |
| Tool use (код, калькулятор, API) | Логика, арифметика, сигнатуры | Средняя | Очень высокий на своём домене |
| Self-consistency (N сэмплов + голосование) | Логические, нестабильные ответы | Высокая (xN токенов) | Средний |
| NLI-верификация выхода | Intrinsic-вымысел | Средняя | Высокий как страховка |
| Понижение температуры | Разброс/креатив-вымысел | Нулевая | Малый, но бесплатный |
Практический порядок внедрения: сначала жёсткая инструкция и температура под задачу, потом grounding/RAG, потом tool use там, где можно проверить машинно, и в конце — детектор на выходе для критичных сценариев.
КОД: ДЕТЕКТОР ГАЛЛЮЦИНАЦИЙ ЧЕРЕЗ ФАКТ-РАЗБИВКУ
Базовый, но рабочий приём: разбить ответ на атомарные утверждения и проверить каждое против источников NLI-моделью (entailment). Если утверждение не следует из контекста — флаг. Ниже минимальный пример на Python.
import re
from sentence_transformers import CrossEncoder
# NLI cross-encoder: на входе пара (premise, hypothesis)
# на выходе логиты [contradiction, entailment, neutral]
nli = CrossEncoder("cross-encoder/nli-deberta-v3-base")
def split_claims(answer: str) -> list[str]:
# грубая разбивка на предложения-утверждения
parts = re.split(r"(?<=[.!?])\s+", answer.strip())
return [p for p in parts if len(p) > 15]
def verify(answer: str, sources: list[str], thr: float = 0.5):
flagged = []
for claim in split_claims(answer):
# берём максимальный entailment по всем источникам
pairs = [(src, claim) for src in sources]
scores = nli.predict(pairs, apply_softmax=True)
best_entail = max(s[1] for s in scores) # индекс 1 = entailment
if best_entail < thr:
flagged.append({"claim": claim, "support": round(best_entail, 3)})
return {
"grounded": len(flagged) == 0,
"unsupported_claims": flagged,
}
sources = [
"Выручка компании за 2025 год составила 10 млн долларов.",
"Штат — 40 сотрудников.",
]
answer = "Выручка составила 12 млн долларов. В компании работает 40 человек."
print(verify(answer, sources))
# -> grounded: False, флагнет утверждение про 12 млн (нет поддержки в источниках)
Это не финальное решение, а каркас. В проде поверх ставят декомпозицию на атомарные факты через саму LLM, а флагнутые утверждения либо режут, либо помечают в UI как непроверенные. Дёшево, детерминированно, ловит intrinsic-вымысел, который чаще всего и бьёт по доверию пользователей.
МЕТРИКИ: КАК ИЗМЕРИТЬ, ЧТО СТАЛО ЛУЧШЕ
Без измерения любая борьба с галлюцинациями — вкусовщина. Что реально мерить:
- Groundedness / faithfulness — доля утверждений, подтверждённых источником. Главная метрика для RAG.
- Answer relevance — отвечает ли ответ на вопрос (чтобы не путать «не соврал» с «ушёл от темы»).
- Context precision/recall — качество retrieval отдельно от генерации. Часто галлюцинация — это провал поиска, а не модели.
- Abstention rate — как часто модель честно говорит «не знаю» там, где данных нет. Рост этой метрики — хороший знак.
Стандарт де-факто в 2026 — прогонять пайплайн через LLM-as-judge (типа RAGAS-подхода) на фиксированном golden-наборе и следить за трендом от релиза к релизу. Абсолютные цифры бенчмарков меняются, важна дельта на вашем домене.
ЧТО НЕ РАБОТАЕТ (ИЛИ РАБОТАЕТ ХУЖЕ, ЧЕМ ОБЕЩАЮТ)
- «Не галлюцинируй» в промпте. Плацебо. Модель не знает, когда галлюцинирует, так что инструкция ни на что не опирается.
- Слепая вера в logprobs. Уверенность модели слабо коррелирует с правотой — она уверенно врёт. Полезно только как сырьё для более сложных детекторов (например, семантической энтропии по нескольким сэмплам).
- «Возьмём модель побольше». Крупнее — реже, но не ноль. Масштаб не отменяет природу next-token prediction.
- Просто накинуть RAG. Без реранка, оценки retrieval и верификации выхода RAG добавляет новый источник ошибок — мусорный контекст.
Частые вопросы
Можно ли полностью убрать галлюцинации LLM?
Нет. Это математическое следствие обучения на предсказание правдоподобного токена. Можно снизить частоту в разы через grounding, RAG и верификацию выхода, но гарантированный ноль недостижим — закладывайте в архитектуру человека или машинную проверку на критичных решениях.
Чем grounding отличается от RAG?
Grounding — общий принцип: заставить модель опираться на проверяемый источник, а не на память. RAG — конкретная реализация: система сначала ищет релевантные документы, потом кладёт их в контекст перед генерацией. Любой RAG — это grounding, но grounding возможен и без retrieval, например через прямую инъекцию известного контекста.
Почему модель уверенно выдаёт ложь?
У LLM нет внутреннего датчика истины — только распределение вероятностей над словами. Уверенный тон вырабатывается на этапе обучения и не связан с фактической правотой, поэтому текстовая уверенность модели не является признаком достоверности.
Как измерить достоверность ответов на практике?
Собрать golden-набор вопрос-ответ-источник и мерить groundedness (доля подтверждённых источником утверждений), answer relevance и abstention rate. Автоматизируется через LLM-as-judge или NLI-верификацию. Следите за дельтой на своём домене, а не за абсолютными цифрами публичных бенчмарков.
Галлюцинации — это не сбой, а поведение по умолчанию, с которым живёт весь индустриальный ИИ 2026 года. Инструменты для grounding, retrieval и фактчекинга обновляются буквально каждый час — если хотите ловить рабочие релизы раньше остальных, залетайте в Telegram-канал REDDYX AI — новые репозитории каждые 30-60 минут.