# ГЛАВА 13. АНТИГАЛЛЮЦИНАЦИОННЫЙ КОНТУР И ЗАЩИТА ОТ ДЕГРАДАЦИИ

---

## 13.1. Почему агенту нужен ревьюер

### Принцип разделения ролей

Представьте себе пилота и второго пилота в кабине самолёта. Пилот ведёт машину, второй пилот — контролирует показания приборов, перепроверяет высоту, сверяет курс. Никто не ожидает, что один человек будет одновременно управлять штурвалом и вычитывать чек-лист. То же самое с LLM: **Generator** — это пилот, **Verifier** — второй пилот. Два набора глаз всегда лучше одного.

Можно описать это иначе: писатель и редактор. Писатель создаёт текст — живой, богатый, иногда с ошибками. Редактор читает холодным взглядом — точно ли это? есть ли противоречия? Совмещать обе роли в одной голове тяжело человеку и ещё тяжелее модели.

Технически: генератор оптимизирован на **fluency** (гладкость текста), ревьюер — на **accuracy** (точность содержания). Совмещать обе функции в одном вызове — значит требовать от модели одновременно быть «креативной» и «критичной», что создаёт конфликт в attention-паттернах.

### Эмпирические данные

Разделение генерации и проверки почти всегда снижает hallucination rate по сравнению с одиночным вызовом, но величина выигрыша зависит от задачи, качества verifier'а и eval-протокола. CoVe (Dhuliawala et al., 2023) и последующие production-пайплайны показывают, что двухэтапная схема обычно окупается на задачах с высокой ценой ошибки.

### Архитектура: Generator + Verifier

```
┌──────────────┐     ┌──────────────┐     ┌──────────────┐
│  Generator   │ ──→ │   Output     │ ──→ │  Verifier    │
│  (high temp) │     │  (candidate) │     │  (low temp)  │
└──────────────┘     └──────────────┘     └──────┬───────┘
                                                  │
                                           ┌──────┴───────┐
                                           │              │
                                           ▼              ▼
                                      [PASS]         [FAIL]
                                        │               │
                                        ▼               ▼
                                   [Return]      [Retry / Fix]
```

**Generator**: температура 0.3–0.7, упор на полноту охвата и разнообразие.
**Verifier**: температура 0.0–0.1, упор на точность и согласованность.

Это могут быть:
- Два вызова одной модели с разными системными промптами.
- Две разные модели (generator = GPT-5.4, verifier = Claude Opus 4.6).
- Одна модель + внешние проверки (тесты, linter, schema validation).

> **Для начинающих.** Самый простой способ внедрить верификацию — добавить второй вызов модели после основного. Первый вызов генерирует ответ, второй получает промпт: «Вот ответ. Проверь каждый факт. Если найдёшь ошибку — исправь и объясни». Даже этот минимальный паттерн уже ловит часть галлюцинаций.

На уровне 2026 года архитектура Generator + Verifier стала обычным production-паттерном. Anthropic встроили эту идею в **Constitutional AI** (Bai et al., 2022) — подход, при котором модель сначала генерирует, потом сама оценивает ответ через набор принципов (constitution), и переписывает его. **RLAIF** (Reinforcement Learning from AI Feedback) обучает модель на таких самопроверках ещё на этапе тренировки — до деплоя (подробнее о post-training методах — в [Главе 19](19_fine_tuning_and_post_training.md)).

---

## 13.2. Chain-of-Verification (CoVe)

### Метод (Dhuliawala et al., 2023)

Если Generator + Verifier — это пилот и второй пилот, то **CoVe — это перекрёстный допрос в суде**. Свидетель (модель) дал показания (черновой ответ). Теперь адвокат (верификатор) разбивает показания на отдельные утверждения и задаёт по каждому точечный вопрос — причём в отдельной комнате, без подсказок от оригинальных показаний. Именно так работает снижение confirmation bias.

CoVe — четырёхэтапный протокол, специально разработанный для снижения галлюцинаций. Разберём его пошагово на конкретном примере:

**Этап 1: Draft (Черновик)**
```
Промпт: "Перечисли 5 крупнейших озёр Африки по площади."
Черновик: "1. Виктория, 2. Танганьика, 3. Малави, 4. Чад, 5. Туркана"
```

**Этап 2: Plan Verification Questions (Планирование проверки)**
```
Промпт: "Для каждого факта сформулируй проверочный вопрос."
Вопросы:
- "Виктория — одно из крупнейших озёр Африки?"
- "Танганьика — одно из крупнейших озёр Африки?"
- "Чад — одно из крупнейших озёр Африки по площади?"
- ...
```

**Этап 3: Answer Questions Independently (Независимые ответы)**

Критически важно: проверочные вопросы отвечаются **в отдельном контексте**, без видимости черновика. Это предотвращает confirmation bias.

```
"Чад — одно из крупнейших озёр Африки по площади?"
→ "Озеро Чад значительно сократилось и не входит в топ-5 по текущей площади.
   Альберт (Albert) — крупнее."
```

**Этап 4: Generate Verified Response (Финальный ответ)**
```
Исправленный ответ:
"1. Виктория, 2. Танганьика, 3. Малави, 4. Туркана, 5. Альберт"
```

### Почему CoVe работает

1. **Декомпозиция проверки**: вместо «проверь всё» — отдельные вопросы для каждого факта.
2. **Независимость**: ответы на проверочные вопросы не должны быть заражены черновиком.
3. **Итеративность**: можно запустить несколько раундов CoVe для повышения точности.

> **Промпт для генерации кода.** *«Реализуй async-функцию chain_of_verification(question, model) с четырьмя этапами CoVe: (1) черновик ответа (temp 0.3), (2) генерация проверочных вопросов для каждого факта (temp 0.1, JSON), (3) независимые ответы на вопросы без видимости черновика (temp 0.0) — критично для устранения confirmation bias, (4) финальный ответ с учётом проверок (temp 0.1). Используй актуальный SDK (OpenAI / Anthropic). Верни {draft, verifications, final_answer}.»*

---

## 13.3. Log-Driven Development (LDD)

### Принцип: данные вместо интуиции

Если CoVe — перекрёстный допрос, то **LDD — это бортовой самописец (чёрный ящик) самолёта**. После инцидента (а в LLM-системах инциденты — это галлюцинации, таймауты, некорректный JSON) вы открываете лог и видите: какой промпт был отправлен, какой ответ получен, сколько токенов стоил вызов, прошла ли валидация. Без логов диагностика невозможна — это как врач, которому описывают симптомы по телефону через неделю после болезни.

> **Отладка без логов — это диагноз без симптомов.** Вы видите, что ответ неправильный, но не знаете: проблема в промпте? в модели? в контексте, который был слишком длинным? LDD даёт вам симптомы.

Традиционный подход к промптингу: написал → попробовал → переписал → попробовал... Это метод тыка, маскирующийся под итерацию.

**LDD** — структурированный подход:

1. **Логируй всё**: промпт, параметры, output, validation, метрики.
2. **Анализируй**: где ошибки? На каком шаге? Какой тип?
3. **Формируй гипотезу**: «ошибка возникает, когда данные >5K токенов».
4. **Тестируй**: измени один параметр, проверь на тех же данных.
5. **Итерируй**: на основе данных, а не чутья.

### Что логировать

Каждый вызов LLM фиксируется в структуре `LLMCallLog` со следующими группами полей:

| Группа | Поля | Назначение |
|--------|------|------------|
| Идентификация | `call_id`, `timestamp`, `pipeline_name`, `step_name` | Привязка к конкретному шагу пайплайна |
| Вход | `system_prompt`, `user_prompt`, `model`, `temperature`, `max_tokens`, `tools` | Полный контекст запроса |
| Выход | `response`, `tool_calls`, `finish_reason` | Ответ модели и причина остановки (`stop` / `length` / `tool_calls`) |
| Метрики | `input_tokens`, `output_tokens`, `latency_ms`, `cost_usd` | Стоимость и производительность |
| Валидация | `schema_valid`, `factual_checks`, `human_rating` (1–5) | Качество ответа (автоматическое + ручное) |
| Контекст | `error`, `retry_count` | Для диагностики проблем |

> **Промпт для генерации кода.** *«Создай Python dataclass (или Pydantic BaseModel) LLMCallLog с полями из таблицы выше. Добавь to_json() для сериализации и from_dict() для десериализации.»*

### Метрики для отслеживания

| Метрика | Формула | Цель |
|---------|---------|------|
| **Schema compliance rate** | Valid outputs / Total outputs | >99% |
| **Hallucination rate** | Verified false claims / Total claims | <5% |
| **Retry rate** | Retries / Total calls | <10% |
| **Latency P95** | 95-й перцентиль response time | <3s |
| **Cost per task** | Σ(tokens × price) / tasks | Зависит от задачи |
| **Success rate** | Tasks completed / Tasks attempted | >90% |

### Инструменты для LDD

| Инструмент | Назначение | Тип |
|-----------|------------|-----|
| **LangSmith** (LangChain) | Tracing, debugging, evaluation | SaaS |
| **Weights & Biases (Prompts)** | Tracking, versioning | SaaS |
| **Braintrust** | Evaluation, logging | SaaS |
| **Phoenix (Arize)** | Observability, traces | Open-source |
| **OpenLLMetry** | OTel-инструментация LLM-вызовов | Open-source |
| **OpenTelemetry + custom** | DIY tracing | Open-source |
| **SQLite + JSON logs** | Минимальный локальный | DIY |

### 13.3.1. Выбор платформы

Таблица выше даёт обзор инструментов. Подробное сравнение платформ (LangSmith, Arize Phoenix, W&B Weave, OpenLLMetry), setup и рекомендации по выбору для разных сценариев — в [Главе 17, раздел 17.2](17_observability_and_operations.md).

Для минимального старта достаточно SQLite + JSON-логов с полями `LLMCallLog` (см. выше): записывайте каждый вызов и анализируйте SQL-запросами.

---

## 13.4. Anti-Loop Protocol: детекция зацикливания

### Паттерны зацикливания

**1. Вербальные петли**: модель повторяет одну и ту же фразу или абзац.

```
"Для решения этой задачи необходимо рассмотреть все аспекты. 
Рассмотрев все аспекты, мы можем заключить, что для решения 
необходимо рассмотреть все аспекты..."
```

**2. Tool-call петли**: агент вызывает одни и те же инструменты с одинаковыми аргументами.

```
Action: search_files("config.json")
Observation: Not found
Action: search_files("config.json")  ← повтор!
Observation: Not found
Action: search_files("config.json")  ← повтор!
```

**3. State oscillation**: агент переключается между двумя состояниями без прогресса.

```
State: "needs_fix" → fix_code() → test_fails → "needs_fix" → fix_code() → test_fails → ...
```

**4. Output inflation**: модель генерирует всё более длинные ответы, разбавляя содержание.

### Детекция

Детектор зацикливания (`LoopDetector`) хранит историю output'ов и tool-вызовов и проверяет три условия:

1. **Verbal loop**: разбивает output на предложения и считает повторы. Если одно предложение встречается ≥ N раз — срабатывание.
2. **Tool-call loop**: если последние N tool-вызовов идентичны (одинаковые имя и аргументы) — срабатывание.
3. **State stagnation**: если состояние агента не менялось N шагов подряд (сравнение через сериализацию) — срабатывание.

Порог N (обычно 3) и threshold схожести — настраиваемые параметры.

> **Промпт для генерации кода.** *«Реализуй класс LoopDetector с тремя методами: check_verbal_loop(output) — детекция повторяющихся предложений, check_tool_loop(tool_name, tool_args) — детекция повторяющихся tool-вызовов, check_progress(state_dict) — детекция застоя через сравнение сериализованных состояний. Параметры: max_repeats=3, similarity_threshold=0.9. Каждый метод возвращает bool.»*

### Реакция на зацикливание

| Тип петли | Действие |
|-----------|----------|
| Вербальная | Прервать генерацию, вернуть частичный результат |
| Tool-call | Изменить стратегию (другой tool, другие аргументы) |
| State oscillation | Откат к предыдущему стабильному состоянию + переформулировка |
| Output inflation | Установить жёсткий max_tokens |
| Все типы (после retry) | **Human-in-the-loop**: запросить помощь оператора |

---

## 13.5. Guardrails: защитные барьеры

Guardrails — это **отбойники на горной дороге**. Они не крутят руль за водителя и не выбирают маршрут. Но когда машина (модель) случайно уходит к краю пропасти — токсичный контент, утечка персональных данных, prompt injection — отбойники не дают ей упасть. Без них каждый поворот — русская рулетка.

К 2026 году guardrails-фреймворки — Guardrails AI, NVIDIA NeMo Guardrails, LLM Guard — стали зрелыми инструментами. Guardrails делятся на два класса:

- **Guardrails качества**: schema validation, PII-маскирование, content policy, детекция low-confidence ответов. Разбираем ниже.
- **Guardrails безопасности**: детекция prompt injection (трёхуровневая защита — regex, ML-классификатор, архитектурная изоляция), jailbreak-фильтры, dual-LLM pattern, secrets scanning, toxicity filtering. Подробно — в [Главе 15, §15.9](15_llm_system_security.md).

### Входные guardrails

На входе проверяйте: **длину** (лимит токенов), **PII** (маскирование до передачи модели), **формат** (если ожидается структурированный вход — валидируйте схему).

> **Промпт для генерации кода.** *«Напиши функцию validate_input(user_input) → (pass: bool, reason: str, sanitized_input: str): (1) ограничение по токенам, (2) маскирование PII (email, телефон, номер карты), (3) базовая schema-валидация. Логируй обнаруженные типы PII.»*

### 13.5.1. PII-маскирование

В enterprise-деплоях маскирование персональных данных — обязательный компонент. Пользователь может случайно отправить паспортные данные, номер карты, email коллеги. Маскирование применяется как на входе (до передачи модели), так и на выходе (модель может воспроизвести PII из контекста).

> **Промпт для генерации кода.** *«Напиши функцию mask_pii(text) → (masked_text, found_types): найди и замаскируй email → [EMAIL], российский телефон (+7...) → [PHONE], номер карты (16 цифр) → [CARD], SSN → [SSN], российский паспорт → [PASSPORT]. Используй regex. Верни маскированный текст и список типов.»*

### 13.5.2. Выходные guardrails

На выходе проверяйте:

1. **Schema validation**: JSON Schema проверка для structured outputs — 100% гарантия формата.
2. **PII leak detection**: сканируйте выход теми же regex-паттернами — модель может воспроизвести PII из контекста.
3. **Content policy**: запрещённые темы, упоминания конкурентов, медицинские/финансовые рекомендации — по конфигурируемому набору правил.
4. **Confidence check**: избыточное количество hedging-фраз («я не уверен», «возможно») сигнализирует о низкой уверенности.
5. **Hallucination markers**: фразы «as of my knowledge cutoff» указывают на параметрические знания вместо контекста.

> **Промпт для генерации кода.** *«Напиши функцию validate_output(output, schema=None, content_policy=None) → (is_valid: bool, issues: list[str]): (1) JSON Schema validation, (2) PII leak scan, (3) content policy (словарь regex-паттернов), (4) hedging phrase count > 3 → warning, (5) hallucination markers. Верни список обнаруженных проблем.»*

---

## 13.6. Цена верификации: баланс точности, задержки и стоимости

Каждый уровень защиты стоит денег и времени. Верификация — не бесплатная:

| Метод | Дополнительная задержка | Дополнительная стоимость | Типичный эффект |
|-------|------------------------|-------------------------|----------------|
| Второй LLM-вызов (Verifier) | +1–3 сек | около ×2 стоимости | Часто заметно снижает factual/runtime errors |
| Полный CoVe (4 этапа) | +5–15 сек | около ×3–5 стоимости | Даёт лучший контроль на high-risk задачах |
| Regex guardrails | <10 мс | ~бесплатно | Ловят только очевидное |
| LLM-классификатор injection | +0.5–1 сек | +$0.001–0.01 за запрос | Высокая для injection |
| Schema validation | <10 мс | ~бесплатно | 100% для формата |

**Стратегия: дифференцированная верификация.** Не нужно прогонять полный CoVe на каждый чат-ответ. Определите уровень риска задачи:

- **Низкий риск** (чат-бот отвечает на FAQ) → regex guardrails + schema validation.
- **Средний риск** (генерация контента для клиентов) → Verifier + content policy + PII check.
- **Высокий риск** (медицина, юриспруденция, финансы) → полный CoVe + human-in-the-loop + аудит-лог.

Функция `select_verification_level(task_metadata)` проверяет домен задачи (`medical`, `legal`, `financial` → full CoVe), флаг `external_facing` (→ Verifier + guardrails) или возвращает `lightweight` (только schema + regex).

---

## 13.7. Продакшн-мониторинг: дашборд на каждый день

Логи бесполезны, если их никто не смотрит. Настройте дашборд, который команда видит ежедневно:

### Рекомендуемые панели дашборда

| Панель | Что показывает | Алерт при |
|--------|---------------|----------|
| **Hallucination rate** (скользящее окно 24ч) | % ответов с подтверждёнными ошибками | Выше вашего SLO |
| **Latency P50 / P95** | Время ответа | P95 > 5 сек |
| **Error rate** | % вызовов с ошибками (timeout, 429, invalid JSON) | >2% |
| **Cost per task** (скользящее окно) | Средняя стоимость одного завершённого задания | Рост >20% за неделю |
| **Retry rate** | Доля запросов, потребовавших повтора | >15% |
| **Guardrail triggers** | Срабатывания по типу (injection, PII, toxicity) | Всплеск injection |
| **User satisfaction** (если есть thumbs up/down) | % положительных оценок | <80% |

### Минимальный стек мониторинга

Подробнее об observability-стеке, SLO, инструментах мониторинга и incident response — в [Главе 17](17_observability_and_operations.md).

---

## 13.8. Hallucination incident response: что делать, когда продакшн-система нагаллюцинировала

Галлюцинация в чат-боте — неприятно. Галлюцинация в агенте, который отправил письмо клиенту или выполнил SQL-запрос — инцидент. Этот playbook — протокол действий от обнаружения до предотвращения повторения.

### Фаза 0: Детекция

Галлюцинация обнаружена. Источники детекции:
- **Автоматическая** — Verifier (CoVe, schema validation, NLI) пометил ответ как недостоверный.
- **Пользовательская** — жалоба клиента, тикет в поддержку.
- **Мониторинг** — hallucination rate в дашборде превысил SLO (§13.7).
- **Ручная проверка** — инженер заметил при аудите логов.

### Фаза 1: Остановка ущерба (первые 15 минут)

Действия в порядке приоритета:

1. **Оцените масштаб.** Сколько пользователей затронуто? Ответ уже доставлен клиенту (email, SMS, публикация) или только в интерфейсе чата?
2. **Остановите распространение.** Если галлюцинация воспроизводится систематически — переключите трафик на fallback-модель или rule-based ответ. Если модель продолжает галлюцинировать на однотипных запросах — временно включите блокировку темы (content filter).
3. **Отзовите неверную информацию.** Если письмо отправлено — отправьте коррекцию. Если данные записаны в БД — пометьте как «требует верификации».
4. **Зафиксируйте инцидент.** Создайте запись: время, затронутые пользователи, тип галлюцинации, предположительная причина.

### Фаза 2: Диагностика (первые 2 часа)

1. **Восстановите контекст.** Какой промпт был отправлен? Какой ответ получен? Какие документы были в контексте (для RAG)? Какие tool calls предшествовали?
2. **Классифицируйте галлюцинацию** по таксономии из Главы 3:
   - **Factual fabrication** — модель выдумала факт (несуществующий API, вымышленное имя).
   - **Context contradiction** — модель проигнорировала контекст и выдала параметрические знания.
   - **Logical inconsistency** — внутреннее противоречие в ответе.
   - **Overgeneralization** — модель применила общее правило к частному случаю, где оно не работает.
3. **Проверьте воспроизводимость.** Запустите тот же промпт 5 раз с temp=0. Воспроизводится? Если да — проблема детерминированная (промпт, данные). Если нет — стохастическая (нужен verifier).
4. **Проверьте промпт и данные.** Есть ли в промпте неоднозначности? Есть ли в контексте (RAG) противоречивые или устаревшие данные?
5. **Проверьте модель.** Не было ли моделью апдейта в день инцидента? Нет ли known issues в changelog провайдера?

### Фаза 3: Исправление (первые 24 часа)

В зависимости от классификации:

| Тип галлюцинации | Краткосрочное исправление | Долгосрочное |
|-----------------|--------------------------|-------------|
| Factual fabrication | Добавить Verifier (CoVe) + citation grounding | Улучшить RAG-покрытие домена |
| Context contradiction | Усилить промпт ("Answer ONLY from context") + structured output с source_doc_id | Пересмотреть conflict cases в eval-наборе |
| Logical inconsistency | Добавить Self-Consistency (3+ сэмпла, голосование) | Улучшить chain-of-thought промпт |
| Overgeneralization | Добавить few-shot примеры с контрпримерами в промпт | Fine-tune на доменных данных |

### Фаза 4: Предотвращение повторения

1. **Добавьте тест-кейс в eval-набор.** Инцидент → тест-кейс → regression gate. Это главный механизм обучения системы на ошибках.
2. **Обновите guardrails.** Если галлюцинация могла быть поймана автоматически — добавьте правило (regex, content filter, confidence threshold).
3. **Проведите post-mortem.** Встреча команды: что произошло, почему не поймали, что изменим в процессе.
4. **Обновите runbook.** Добавьте данный тип инцидента в operational runbook команды.

### Чек-лист incident response

| # | Шаг | Тайминг | Статус |
|---|-----|---------|--------|
| 1 | Оценён масштаб (пользователи, доставка) | 5 мин | ☐ |
| 2 | Остановлено распространение (fallback/блокировка) | 15 мин | ☐ |
| 3 | Отозвана неверная информация (коррекция) | 30 мин | ☐ |
| 4 | Восстановлен контекст инцидента (логи) | 1 час | ☐ |
| 5 | Определён тип галлюцинации | 1 час | ☐ |
| 6 | Проверена воспроизводимость | 2 часа | ☐ |
| 7 | Применено краткосрочное исправление | 4 часа | ☐ |
| 8 | Тест-кейс добавлен в eval-набор | 24 часа | ☐ |
| 9 | Проведён post-mortem | 72 часа | ☐ |
| 10 | Runbook обновлён | 1 неделя | ☐ |

### Инструменты

> **Промпт для ИИ:** «Напиши Python-скрипт для автоматической классификации галлюцинаций в ответах LLM. Скрипт принимает запрос, ответ модели, retrieved context (опционально), ground truth (опционально). Классифицирует по четырём типам: factual_fabrication, context_contradiction, logical_inconsistency, overgeneralization. Для factual_fabrication — проверяет claims через верификацию (второй LLM-вызов или NLI). Для context_contradiction — сверяет claims с retrieved context. Для logical_inconsistency — ищет внутренние противоречия в ответе. Возвращает JSON с типом галлюцинации, confidence и affected claims. Используй OpenAI API или Anthropic API.»

---

## Практический вывод

### Минимальный антигаллюцинационный контур

```
Input → [Input Guardrails] → [Generator] → [Output Guardrails] →
   → [Verifier (CoVe / tests / schema)] → Output / Retry
```

### Чек-лист

| # | Компонент | Внедрено? |
|---|-----------|-----------|
| 1 | **Ревьюер отделён от генератора** | Generator ≠ Verifier (пилот + второй пилот) |
| 2 | **CoVe для фактуальных задач** | 4-step protocol (перекрёстный допрос) |
| 3 | **Логи всех вызовов** | Промпт, output, метрики, validation (чёрный ящик) |
| 4 | **Observability-платформа** | LangSmith / Phoenix / W&B (подробнее — [Глава 17](17_observability_and_operations.md)) |
| 5 | **Детекторы петель** | Verbal, tool-call, state oscillation |
| 6 | **Input guardrails** | Длина, PII-маскирование, injection detection (подробнее — [Глава 15](15_llm_system_security.md)) |
| 7 | **Output guardrails** | Schema, toxicity, content policy, PII leak |
| 8 | **Дифференцированная верификация** | Уровень проверки зависит от риска задачи |
| 9 | **Продакшн-дашборд** | Hallucination rate, latency, cost, alerts |
| 10 | **Human-in-the-loop** | Есть fallback к человеку для высокого риска? |

### Задания

1. **Внедрите Generator + Verifier для одного пайплайна.** Выберите задачу с высокой ценой ошибки (генерация ответов для клиентов, суммаризация документов). Добавьте второй LLM-вызов (Verifier) с промптом «Проверь каждый факт. Если найдёшь ошибку — исправь и объясни». Измерьте hallucination rate до и после на 20+ примерах. **Ожидаемый результат:** количественная оценка снижения галлюцинаций и понимание trade-off по латенси и стоимости.

2. **Настройте LDD-логирование.** Реализуйте `LLMCallLog` (таблица из §13.3) и начните писать логи всех LLM-вызовов в SQLite. Через неделю проанализируйте: какой retry rate? какие ошибки чаще всего? в каких шагах пайплайна? **Ожидаемый результат:** первый дашборд с метриками schema compliance rate, retry rate, latency P95.

3. **Проведите CoVe-сессию вручную.** Возьмите 5 фактуальных вопросов из вашей области. Для каждого: попросите модель ответить (черновик), сформулируйте проверочные вопросы, задайте их в отдельном контексте, сравните. **Ожидаемый результат:** понимание, какие типы ошибок ловит CoVe, а какие нет; оценка cost/benefit для вашей задачи.

4. **Проведите учебную тревогу (fire drill).** Сымитируйте инцидент: намеренно внесите галлюцинирующий промпт или уберите Verifier из пайплайна. Пройдите все 4 фазы playbook: детекция → остановка → диагностика → предотвращение. Замерьте время от обнаружения до исправления. **Ожидаемый результат:** заполненный incident response checklist + время реакции команды < 4 часов.

---

## Источники
- Dhuliawala, S., et al. (2023). "Chain-of-Verification Reduces Hallucination in Large Language Models."
- Rebedea, T., et al. (2023). "NeMo Guardrails: A Toolkit for Controllable and Safe LLM Applications with Programmable Rails." NVIDIA.
- Anthropic. "Reducing Hallucination." Claude Best Practices (2024–2026).
- Bai, Y., et al. (2022). "Constitutional AI: Harmlessness from AI Feedback." Anthropic.
- Guardrails AI. Documentation. https://www.guardrailsai.com/docs (2025–2026).
- LangSmith. "Tracing and Evaluation." https://docs.smith.langchain.com/
- Arize AI. "Phoenix: Open-Source LLM Observability." https://docs.arize.com/phoenix (2025–2026).
- Weights & Biases. "W&B Weave: LLM Monitoring." https://docs.wandb.ai/guides/weave (2025–2026).

---

**Навигация:**
- Назад: [Глава 12. RAG: когда модели не хватает собственных знаний](12_rag.md)
- Далее: [Глава 14. Оценка качества LLM-систем](14_llm_system_quality_evaluation.md)
