Когда ваш агент начинает врать
Вы настроили идеального агента. Он отвечает на вопросы клиентов, генерирует код, анализирует данные. Всё работает в тестовой среде. Вы запускаете его в продакшн — и через неделю получаете панику: агент начал "вспоминать" несуществующие функции API, "исправлять" код, который работал, и "объяснять" клиентам, что их заказ уже доставлен (хотя его даже не собирали).
Это не баг. Это галлюцинации — фундаментальная проблема всех LLM, которая становится катастрофой в production. Особенно для self-hosted агентов, где у вас нет подушки безопасности в виде OpenAI или Google.
Галлюцинация — это не ошибка в коде. Это модель уверенно генерирует ложную информацию, причём делает это убедительно. Проблема в том, что агент не знает, что он не знает.
Почему галлюцинации опаснее всего в продакшн
В тестовой среде вы ловите галлюцинации вручную. В продакшн они:
- Масштабируются — один агент может навредить тысячам пользователей
- Каскадируют — одна ложная информация порождает цепочку ошибок
- Дорого стоят — ложные ответы клиентам, некорректные транзакции, сломанные деплои
- Разрушают доверие — пользователи перестают верить системе после первого серьёзного провала
Три типа галлюцинаций, которые ломают продакшн-системы
| Тип | Пример | Риск |
|---|---|---|
| Фактические | "Функция get_user_data() возвращает список заказов" (на самом деле возвращает только имя) | Сломанная логика приложения |
| Контекстные | "Вам уже ответил менеджер Иван" (хотя никто не отвечал) | Юридические проблемы, потеря клиентов |
| Инструкционные | "Для установки используйте apt-get install python4" (python4 не существует) | Сломанные деплои, безопасность |
1 Многоуровневая верификация: не верьте первому ответу
Самый простой и самый эффективный метод. Заставьте агента проверять свои же ответы. Но не просто спрашивать "Ты уверен?" — это бесполезно.
Работающая схема:
async def verify_response_with_steps(agent_response, context, verification_prompt):
# Шаг 1: Агент генерирует ответ
initial_response = await agent.generate(context)
# Шаг 2: Тот же агент получает свой ответ как входные данные
# и должен найти в нём потенциальные ошибки
verification_context = f"""
Проверь следующий ответ на наличие:
1. Фактических ошибок (даты, имена, функции)
2. Логических противоречий
3. Информации, которой нет в контексте
Ответ для проверки:
{initial_response}
Контекст для проверки:
{context}
"""
verification = await agent.generate(verification_context)
# Шаг 3: Если верификация нашла проблемы — исправляем
if "ошибка" in verification.lower() or "неверно" in verification.lower():
correction_prompt = f"""
Твой предыдущий ответ содержал ошибки:
{verification}
Исправь ответ, используя только информацию из контекста:
{context}
"""
return await agent.generate(correction_prompt)
return initial_response
2 Кросс-модельный чек: когда одна модель не доверяет другой
Запустите два разных агента на разных моделях. Пусть они проверяют друг друга. Это дороже, но в 3-4 раза снижает количество галлюцинаций.
На 2026 год лучшие комбинации:
- Gemini 3 Flash (быстрая, дешёвая) + Claude 4 Sonnet (точная, дорогая) — идеально для критических задач
- Llama 4 70B (локально) + GPT-4.5 Turbo (API) — баланс стоимости и качества
- Две разные fine-tuned версии одной модели — если бюджет ограничен
class CrossModelVerifier:
def __init__(self, primary_model, secondary_model):
self.primary = primary_model # Основной агент
self.secondary = secondary_model # Проверяющий агент
async def verify_with_contradiction_check(self, query, context):
# Основной агент генерирует ответ
primary_response = await self.primary.generate(query, context)
# Второй агент проверяет на противоречия
verification_prompt = f"""
Ответ агента: {primary_response}
Контекст: {context}
Задача: Найди любые утверждения в ответе, которые:
1. Не подтверждаются контекстом
2. Противоречат известным фактам
3. Содержат предположения без указания "возможно" или "вероятно"
Верни JSON: {{"contradictions": [список противоречий], "confidence": 0-1}}
"""
verification_result = await self.secondary.generate(verification_prompt)
# Если найдены серьёзные противоречия — перегенерируем
if self._has_serious_contradictions(verification_result):
# Используем более консервативный промпт
conservative_prompt = f"""
{query}
Используй ТОЛЬКО информацию из контекста.
Если информации недостаточно — скажи "не могу ответить".
Не добавляй ничего от себя.
Контекст: {context}
"""
return await self.primary.generate(conservative_prompt)
return primary_response
Эта техника особенно полезна в сочетании с мультиагентными системами, где разные агенты уже работают вместе.
3 Контекстуальные ограничения: клетка для агента
Галлюцинации часто возникают, когда агент "додумывает" информацию. Решение — жёстко ограничить то, чем он может пользоваться.
Как это выглядит на практике:
def create_strict_context_prompt(query, allowed_sources, max_assumptions=0):
return f"""
Ты — агент с жёсткими ограничениями:
1. Можешь использовать ТОЛЬКО эти источники:
{chr(10).join(f'- {source}' for source in allowed_sources)}
2. Нельзя делать предположения. Если информации нет — говори "не знаю".
3. Максимум {max_assumptions} предположений, и они должны быть явно помечены как "Вероятно:"
4. Каждое утверждение должно иметь ссылку на источник из списка выше.
Вопрос: {query}
"""
Важно: ограничения должны быть частью системного промпта, а не просто "надеждой". Агент должен понимать, что нарушение ограничений — это ошибка, а не творчество.
4 Температура и детерминизм: меньше креатива, больше точности
Temperature=0.7 — отлично для творческих задач. Ужасно для продакшн-агентов.
Настройки для production на 2026 год:
- temperature: 0.1-0.3 — почти детерминированные ответы
- top_p: 0.9 — ограничение на "творческие" токены
- frequency_penalty: 0.5 — штраф за повторяющиеся фразы (меньше шаблонных галлюцинаций)
- presence_penalty: 0.3 — штраф за новые темы (меньше "ухода в сторону")
# Как НЕ надо делать
wrong_config = {
"temperature": 0.7, # Слишком творчески
"top_p": 0.95, # Слишком широкий выбор токенов
"max_tokens": 1000 # Слишком много места для галлюцинаций
}
# Как надо делать для production
production_config = {
"temperature": 0.2, # Минимум случайности
"top_p": 0.9, # Ограниченный набор токенов
"max_tokens": 500, # Вынуждает быть кратким
"frequency_penalty": 0.5,
"presence_penalty": 0.3,
"stop": ["\n\n", "Источник:", "Примечание:"] # Ранняя остановка
}
5 Семантический поиск противоречий: когда regex не помогает
Простые проверки по ключевым словам не работают. Агент может сказать "функция не существует" вместо "функция get_user_data() не существует".
Решение — эмбеддинги и семантический поиск:
import numpy as np
from sentence_transformers import SentenceTransformer
class HallucinationDetector:
def __init__(self):
# Используем современную модель для эмбеддингов
self.model = SentenceTransformer('sentence-transformers/all-mpnet-base-v2')
self.knowledge_base_embeddings = [] # Эмбеддинги проверенных фактов
self.knowledge_base_texts = [] # Тексты фактов
def add_knowledge(self, text):
"""Добавляем проверенный факт в базу знаний"""
embedding = self.model.encode(text)
self.knowledge_base_embeddings.append(embedding)
self.knowledge_base_texts.append(text)
def check_response(self, response, threshold=0.7):
"""Проверяем ответ на соответствие известным фактам"""
response_embedding = self.model.encode(response)
# Ищем ближайшие известные факты
similarities = []
for kb_embedding in self.knowledge_base_embeddings:
sim = np.dot(response_embedding, kb_embedding) / (
np.linalg.norm(response_embedding) * np.linalg.norm(kb_embedding)
)
similarities.append(sim)
if similarities:
max_similarity = max(similarities)
if max_similarity < threshold:
# Ответ слишком далёк от известных фактов — возможная галлюцинация
return False, max_similarity
return True, max_similarity if similarities else 1.0
Интеграция в production pipeline
Отдельные методы — это хорошо. Но в продакшн нужен pipeline, который работает автоматически.
Архитектура системы с защитой от галлюцинаций
class AntiHallucinationPipeline:
def __init__(self):
self.primary_agent = load_primary_agent()
self.verifier_agent = load_verifier_agent()
self.detector = HallucinationDetector()
self.fallback_response = "Извините, не могу дать точный ответ."
async def process_query(self, query, context, user_id):
"""Основной pipeline обработки запроса"""
# Шаг 1: Генерация с ограничениями
restricted_prompt = create_strict_context_prompt(
query,
allowed_sources=["база знаний", "контекст сессии", "API документация"],
max_assumptions=0
)
response = await self.primary_agent.generate(
restricted_prompt,
**production_config # Используем production настройки
)
# Шаг 2: Семантическая проверка
is_valid, confidence = self.detector.check_response(response)
if not is_valid or confidence < 0.6:
# Шаг 3: Кросс-модельная верификация
verified_response = await CrossModelVerifier(
self.primary_agent,
self.verifier_agent
).verify_with_contradiction_check(query, context)
# Шаг 4: Финальная проверка
is_finally_valid, final_confidence = self.detector.check_response(
verified_response
)
if not is_finally_valid or final_confidence < 0.5:
# Всё провалилось — используем fallback
self._log_hallucination_attempt(user_id, query, response)
return self.fallback_response
return verified_response
return response
def _log_hallucination_attempt(self, user_id, query, bad_response):
"""Логируем попытку галлюцинации для анализа"""
# Отправляем в систему мониторинга
# Например, в Langfuse для трассировки
pass
Такая архитектура добавляет задержку (100-300мс на дополнительные проверки), но снижает количество галлюцинаций на 80-90%.
Мониторинг и алерты: когда агент начинает врать
Галлюцинации не исчезают навсегда. Они возвращаются при изменениях в данных, обновлениях моделей или просто "удачном" стечении обстоятельств.
Что мониторить в реальном времени:
- Confidence score — если уверенность ответов падает ниже порога
- Процент fallback-ответов — если система слишком часто отказывается отвечать
- Длина ответов — внезапное увеличение может означать "словоблудие"
- Повторяющиеся фразы — маркер шаблонных галлюцинаций
- Неизвестные entity — имена, даты, функции, которых нет в базе знаний
Инструменты для мониторинга на 2026 год:
- Langfuse — трассировка, метрики качества ответов
- Prometheus + Grafana — кастомные метрики по галлюцинациям
- Elasticsearch — поиск паттернов в логах ответов
Чего не делать: распространённые ошибки
Ошибка 1: Доверять "Я уверен на 95%"
Модели не калиброваны. Они могут быть "уверены" в совершенно ложных утверждениях. Всегда проверяйте факты независимо от уверенности модели.
Ошибка 2: Использовать одну модель для всего
Разные задачи требуют разных моделей. Для фактчекинга — большие точные модели. Для простых ответов — быстрые маленькие. Микросервисная архитектура для агентов — must have.
Ошибка 3: Игнорировать контекстное затухание
Чем длиннее контекст, тем больше шанс, что модель "забудет" инструкции в начале. Разбивайте длинные задачи на подзадачи с обновлением контекста.
Будущее: что изменится к концу 2026
Галлюцинации не исчезнут полностью. Но подходы к борьбе с ними эволюционируют:
- Специализированные модели для fact-checking — модели, обученные только на проверке фактов
- Встроенные механизмы калибровки уверенности — модели научатся точнее оценивать свою неуверенность
- Автоматическая верификация через RAG — каждый факт автоматически проверяется по внешним источникам
- Контекстуальные ограничения на уровне API — провайдеры моделей добавят флаги "strict mode"
Пока этого не произошло — ваша лучшая защита это многоуровневая проверка, жёсткие ограничения и постоянный мониторинг. Агент, который иногда говорит "не знаю", лучше агента, который всегда врёт.
И помните: чем больше ваш агент умеет делать, тем больше у него возможностей для галлюцинаций. Иногда лучше ограничить его возможности, чем разгребать последствия.