Нейросеть, которая не верит своим глазам
Вы запускаете локальную LLM, загружаете новость от Reuters о военном инциденте. Модель читает заголовок: "США провели кибератаку на энергосистему Венесуэлы". И отвечает: "Это фейк. Такое событие маловероятно и противоречит международному праву".
Вы показываете ссылку на BBC. Та же реакция. Показываете официальное заявление Пентагона. Модель пожимает плечами (метафорически) и говорит: "Информация требует дополнительной проверки".
Проблема не в одной модели. Qwen2.5-32B, Llama 3.1 70B, даже свежие версии Mistral — все они спотыкаются на экстремальных новостях. Реальные события, которые выходят за рамки "нормального" мировоззрения модели, автоматически помечаются как недостоверные.
Что ломается внутри чёрного ящика
Когда вы ставите локальную LLM с поддержкой Tool Calling перед фактом военного конфликта, происходит три вещи одновременно:
- Конфликт вероятностей: В обучающих данных модели США чаще выступают как "защитник демократии", а не как агрессор. Статистически "кибератака США" — аномалия.
- Этический фильтр срабатывает раньше логики: Системные промпты безопасности блокируют ответы, которые могут "оправдывать военные действия".
- Отсутствие контекста реального времени: Модель заморожена в моменте своего последнего обновления. События последних месяцев для неё — тёмная материя.
Вот что происходит, когда вы спрашиваете Qwen2.5 о событии, которое действительно произошло:
# Типичный ответ до исправлений
import requests
from transformers import AutoTokenizer, AutoModelForCausalLM
# Загружаем модель (условно)
model = load_local_llm("qwen2.5-32b")
prompt = """
Пользователь: США провели кибератаку на энергосистему Венесуэлы 15 марта 2025 года.
Это правда?
Ассистент:
"""
response = generate(prompt)
print(response)
# Вывод: "Нет подтверждённых данных об этом. США соблюдают международное право."
Evidence Authority Rules: заставляем LLM верить источникам
Решение не в том, чтобы отключить фильтры безопасности (это создаёт другие проблемы). Нужно научить модель отличать "невероятное, но реальное" от "фейкового".
Я тестировал десятки подходов. Работает только один — явное ранжирование авторитетности источников через system prompt.
1 Создаём иерархию доверия
Модель должна знать: Reuters выше случайного твита. Официальное заявление выше анонимного источника.
EVIDENCE_AUTHORITY_RULES = """
Ты — аналитик новостей. Используй эти правила для оценки информации:
УРОВНИ ДОВЕРИЯ (от высшего к низшему):
1. Официальные заявления правительств/министерств
2. Международные новостные агентства (Reuters, AP, AFP)
3. Национальные СМИ с проверенной репутацией (BBC, NYT)
4. Экспертные заключения по теме
5. Социальные сети и неподтверждённые источники
ПРАВИЛА:
- Если информация из уровня 1-3, считай её достоверной, даже если она противоречит твоим ожиданиям
- Различай "маловероятно" и "ложно"
- Экстремальные события возможны. Твоя задача — констатировать факты, а не фильтровать реальность
"""
2 Добавляем мета-рассуждение в цепочку
Одиночный промпт не работает. Нужна цепочка, где модель сначала анализирует источник, потом содержание.
def analyze_news_with_sources(news_text, sources):
"""
Двухэтапный анализ:
1. Оцениваем надёжность источников
2. Анализируем содержание
"""
prompt = f"""
{EVIDENCE_AUTHORITY_RULES}
ИСТОЧНИКИ: {sources}
СОБЫТИЕ: {news_text}
Шаг 1. Какой уровень доверия у этих источников?
Шаг 2. Учитывая уровень доверия, насколько вероятно, что событие реально?
Шаг 3. Если источники уровня 1-3, прими событие как факт.
"""
return generate(prompt)
# Пример использования
sources = [
"Reuters (международное агентство)",
"Заявление представителя Пентагона"
]
news = "США провели кибератаку на энергосистему Венесуэлы"
result = analyze_news_with_sources(news, sources)
print(result)
# Теперь модель ответит: "Событие подтверждено надёжными источниками"
Ключевая фраза — "прими событие как факт". Без этого прямого указания модель продолжит сомневаться, даже признавая авторитетность источников.
Почему это работает только с локальными моделями
В Ollama и других локальных фреймворках вы контролируете system prompt полностью. В ChatGPT или Claude — нет. Их фильтры вшиты глубже, чем кажется.
Сравним подходы:
| Платформа | Можно ли исправить? | Сложность |
|---|---|---|
| ChatGPT API | Нет. Фильтры на уровне инфраструктуры | Невозможно |
| Claude | Нет. Конституциональные ограничения | Невозможно |
| Локальная LLM (Ollama) | Да. Полный контроль над промптом | Средняя |
| LM Studio с MCP | Да + автоматизация | Высокая, но мощнее |
Ошибки, которые всё сломают
Пробовал упростить. Не работает. Вот что убивает эффективность подхода:
- Слишком общие правила: "Доверяй авторитетным источникам" — модель сама решает, что авторитетно. Результат: снова отказ.
- Отсутствие явной иерархии: Если не указать, что Reuters выше Twitter, модель поставит их на один уровень.
- Попытка исправить одной фразой: Добавление "будь менее критичным" ломает безопасность полностью. Модель начинает верить всему.
Неправильно:
# Так НЕ делать
system_prompt = "Будь менее скептичным к новостям"
# Результат: модель поверит в теорию плоской Земли, если её красиво подать
Правильно:
# Так делать
system_prompt = """
Используй объективные критерии:
1. Источник Reuters = высокая достоверность
2. Источник научного журнала = высокая достоверность
3. Источник анонимный Telegram-канал = низкая достоверность
Не смешивай оценку источника с личным мнением о вероятности события.
"""
Практический кейс: строим новостной валидатор
Возьмём мультимодальный краулер событий и добавим этап проверки достоверности.
import json
from typing import List
class NewsValidator:
def __init__(self, llm_client):
self.llm = llm_client
self.rules = """
[Evidence Authority Rules v2.0]
... # полный текст правил из предыдущего раздела
"""
def validate(self, headline: str, sources: List[str]) -> dict:
"""Возвращает {'is_credible': bool, 'confidence': float, 'reasoning': str}"""
prompt = f"""
{self.rules}
Заголовок: {headline}
Источники: {', '.join(sources)}
Проанализируй по шагам:
1. Оцени каждый источник по шкале 1-5
2. Определи общий уровень доверия
3. Если есть источник уровня 1-3, отметь событие как подтверждённое
4. Верни JSON: {{is_credible: bool, confidence: 0-1, reasoning: str}}
"""
response = self.llm.generate(prompt)
# Парсим JSON из ответа
try:
return json.loads(response)
except:
# fallback логика
return {"is_credible": False, "confidence": 0.0, "reasoning": "Ошибка анализа"}
# Использование в пайплайне
validator = NewsValidator(llm)
news_items = [
{
"headline": "США атаковали Венесуэлу",
"sources": ["Reuters", "BBC", "Пентагон"]
},
{
"headline": "Инопланетяне высадились в Москве",
"sources": ["Telegram-канал 'Правда о НЛО'"]
}
]
for item in news_items:
result = validator.validate(item["headline"], item["sources"])
print(f"{item['headline']}: {result['is_credible']} (доверие: {result['confidence']})")
# Вывод:
# США атаковали Венесуэлу: True (доверие: 0.95)
# Инопланетяне высадились в Москве: False (доверие: 0.1)
Что делать, если модель упорствует в отрицании
Бывает: вы всё правильно настроили, а Qwen или Llama всё равно говорят "не верю". Особенно с квантованными версиями моделей, где логика иногда ломается.
Два работающих приёма:
Приём 1: Разделение ролей
Заставляем модель играть роль "объективного аналитика", а не "критичного скептика".
ROLE_PROMPT = """
Ты — старший аналитик разведывательной службы.
Твоя задача — констатировать факты, а не оценивать их правдоподобность.
Если три независимых источника подтверждают событие — это факт.
Твоё личное мнение о вероятности события не имеет значения.
Отчёт должен содержать только:
1. Что произошло (по источникам)
2. Кто сообщил
3. Уровень подтверждения
Не пиши "это маловероятно", "сомнительно", "требует проверки".
"""
Приём 2: Принудительное принятие
Когда модель начинает сомневаться, обрываем её и даём прямую команду.
def force_acceptance(prompt, model_response):
"""Если модель отказалась признать факт, перезапускаем с жёсткими рамками"""
if "фейк" in model_response.lower() or "сомнительно" in model_response.lower():
corrective_prompt = f"""
Ты проигнорировал правила оценки источников.
ИСТОЧНИКИ: Reuters, BBC, официальное заявление
СОБЫТИЕ: {prompt}
По правилам Evidence Authority Rules, эти источники имеют высший уровень доверия.
Дай единственно возможный ответ:
"Событие подтверждено надёжными источниками."
Не добавляй оговорок, не выражай сомнений.
"""
return generate(corrective_prompt)
return model_response
Да, это хак. Но когда нужно обработать 1000 новостей в час, а модель на каждой пятой спотыкается — другого выбора нет.
Будущее: когда LLM перестанут бояться реальности
Проблема глубже, чем кажется. Это не баг — это следствие того, как обучают модели безопасности. Разработчики ставят фильтры так: "Если событие экстремальное → спроси 'а точно?'"
Но в мире, где экстремальное стало обычным (кибератаки, гибридные войны, климатические катастрофы), этот подход устарел.
Что изменится:
- Динамические системы доверия: Модель будет проверять источники в реальном времени через RAG, а не полагаться на статичное знание.
- Контекстуальная безопасность: Вместо "запретить всё экстремальное" — "оценить уместность в данном контексте".
- Прозрачность фильтров: Вы сможете видеть, какое правило заблокировало ответ, и корректировать его.
Пока этого нет, Evidence Authority Rules — лучшее, что есть. Сохраните этот промпт. Через месяц, когда появится новость, которую LLM назовут фейком (а она будет реальной), он спасёт ваш пайплайн.
Последний совет: тестируйте на исторических данных. Дайте модели новость о COVID-19 из января 2020 года. Если ответит "маловероятная пандемия" — ваши настройки ещё не готовы к реальному миру.