Проблема: ложная метка «галлюцинации»
В статье отмечается, что термин «галлюцинация» (hallucination) в контексте RAG часто используется некорректно. Строго говоря, галлюцинация — это вымысел модели на основе её параметрической памяти. Однако в RAG-системах модель опирается на предоставленный контекст. Если ответ неверен, причина кроется на этапе извлечения (parsing, retrieval) или в самом контракте генерации, а не в «воображении» LLM. Называя ошибку правильно, можно точно определить, где именно нужно вмешательство.
Решение: Типизированный контракт вместо строки
Автор предлагает отказаться от выдачи ответа в виде свободной строки текста. Вместо этого ответ должен быть структурированным объектом (например, Pydantic-моделью), который включает:
- Конкретные значения (числа, даты, списки).
- Цитаты-ссылки (evidence) с точными номерами строк.
- Флаги достоверности (fidelity flags).
- Поля самооценки (self-assessment).
Это превращает LLM из «оракула» в функцию, результат работы которой можно валидировать до показа пользователю.
7 паттернов надежной генерации
Статья выделяет семь ключевых принципов (паттернов) для построения такой системы. Первые шесть формируют сам контракт, седьмой касается ограничений для малых моделей.
| Паттерн | Суть подхода | Пример и выгода |
|---|---|---|
| 1. LLM как функция | Ответ — строго типизированный объект, а не текст. | Вместо фразы «премия $124» возвращается структура: Amount(value=124, currency="USD") с точной ссылкой на источник. Это упрощает парсинг и аудит. |
| 2. Извлечение, а не вычисление | Модель только извлекает сырые данные, Python делает математику. | Если нужно сравнить валюты, модель возвращает 124 USD, а конвертация в EUR происходит в коде с фиксацией курса в логах. Это обеспечивает воспроизводимость расчетов. |
| 3. Полнота через структуру | Проверка полноты ответа на уровне извлечения документов. | Вместо того чтобы спрашивать модель «всё ли найдено?», система проверяет границы секций документа. Если список продолжается на следующей странице, он подгружается автоматически. |
| 4. Два булевых флага вместо confidence | Разделение на «найдено ли вообще» и «полный ли ответ». | Вместо неясного confidence=0.6 используются answer_found=True и complete_answer_found=False. Это четко указывает оркестратору: нужно ли продолжать поиск или отказываться от ответа. |
| 5. Один промпт на форму ответа | Динамическая сборка промпта из фрагментов. | Для разных типов ответов (дата, список, число) используются разные шаблоны. Это делает промпты воспроизводимыми и упрощает отладку ошибок формата. |
| 6. Валидация перед выдачей | Проверка объекта по схеме до контакта с пользователем. | Валидатор проверяет соответствие Pydantic-схеме. Если данные не сходятся или отсутствуют обязательные поля, система обрабатывает ошибку, а не выдает «сломанный» ответ. |
| 7. Декомпозиция для малых моделей | Упрощение задачи для слабых LLM. | Малые модели хуже справляются со сложными контрактами. Паттерн предполагает разбивку сложной задачи на более простые шаги или упрощение схемы для таких моделей. |
Почему это важно для индустрии
Переход от «черного ящика» к структурированным данным позволяет внедрять RAG в критически важные бизнес-процессы (финансы, юриспруденция), где важна не только точность, но и прослеживаемость (auditability). Код-репозиторий с примерами реализации (doc-intel/notebooks-vol1) демонстрирует, как эти паттерны работают на практике, позволяя малым моделям достигать качества, близкого к флагманским решениям, за счет правильной архитектуры, а не только мощности модели.
Источник: Towards Data Science ↗
