Команда добавила router, critic и judge к генератору ответов. Доля принятых оператором черновиков выросла с 82% до 84%, задержка с 3,1 до 11,8 секунды, стоимость почти вчетверо. На ста запросах система дала два дополнительных пригодных ответа и купила триста лишних вызовов. Названия ролей звучали солиднее результата.
Дополнительный модельный шаг оправдан, когда у него есть измеримая работа: выбрать существенно более дешёвый маршрут, обнаружить конкретный риск или оценить ответ по критерию, который нельзя надёжно проверить кодом.
Router
Router выбирает маршрут до основной работы. Сначала попробуйте правило: язык, MIME type, размер документа, tenant и доступные функции известны без модели. LLM-router нужен для смысловой границы, например между вопросом о доставке и претензией на возврат.
class Route(BaseModel):
target: Literal["faq", "refund", "human"]
confidence: float = Field(ge=0, le=1)
evidence: str
route = await route_ticket(text)
if route.confidence < 0.75:
return enqueue_human(text)
return await handlers[route.target](text)Оценивайте router по итоговой цене ошибок. False positive в faq может отправить формальную отписку на претензию; false positive в human лишь увеличит очередь. Одинаковая accuracy скрывает эту разницу.
Evaluator и judge
Evaluator измеряет результат на тестовом наборе. Judge обычно означает LLM-evaluator. В production он полезен только как ограниченный фильтр, потому что сам имеет ошибки, дрейф версии и стоимость.
Хороший rubric содержит наблюдаемые критерии:
{
"supported_by_sources": true,
"contains_required_order_id": true,
"makes_refund_promise": false,
"violations": []
}Сначала исполняются обычные проверки: JSON Schema, ссылки на существующие источники, длина, запрещённые идентификаторы. Judge получает остаток, где требуется смысловая оценка. Его решение сравнивают с разметкой людей на отдельном наборе, а версию модели и rubric фиксируют.
Critic и repair
Critic полезен, когда может назвать исправимую ошибку. Ответ «можно сделать яснее» только добавляет токены. Передавайте генератору структурированный список нарушений и разрешайте не больше одной починки.
review = await critic(draft, verified_facts, rubric)
if review.violations:
repaired = await rewrite(draft, review.violations, verified_facts)
return deterministic_validate(repaired)
return draftНе поручайте critic-у проверять факт, которого нет во входных данных. Он не получит знания из должности. Не показывайте ему скрытое рассуждение генератора: оно повышает склонность согласиться с исходным ответом.
Как решить, добавлять ли роль
Запишите базовую линию на размеченном наборе: качество, p95, стоимость и долю ручной обработки. Затем добавьте один шаг и повторите прогон. Считайте стоимость предотвращённой ошибки:
дополнительная стоимость / число дополнительно пойманных существенных ошибокЕсли critic стоит $20 на прогон и ловит две ошибки, каждая стоит $10. Для медицинского заключения это может быть дёшево. Для категоризации отзывов обычно нет.
Failure modes
Одинаковая модель в ролях генератора и judge часто разделяет одни слепые зоны. Для критичного контроля используйте независимую модель, правила или человека. Judge может предпочитать длинные ответы и знакомый стиль; порядок кандидатов тоже влияет на выбор. Рандомизируйте порядок, калибруйте rubric и проверяйте межэкспертное согласие.
Router создаёт раннюю точку невозврата. Сохраняйте его решение и evidence, вводите fallback для низкой уверенности. Critic loop без лимита колеблется между формулировками и никогда не доказывает улучшение. Один repair, затем ручная очередь или прежний безопасный ответ.
Правило главы
Добавляйте роль только после того, как названы класс ошибок, метрика и цена дополнительного вызова. Если шаг нельзя независимо проверить на размеченном наборе, его название не превращает его в архитектуру.
Чеклист главы
- Детерминированные правила выполняются до LLM-ролей.
- Для router посчитана стоимость разных ошибок.
- Judge откалиброван против человеческой разметки.
- Critic возвращает структурированные, исправимые нарушения.
- Repair loop ограничен одной попыткой.
- Абляционный тест показывает вклад каждого шага.
Практикум
Задача 17.1. Абляция ролей. Возьмите 200 размеченных обращений и сравните четыре конфигурации: генератор; router + генератор; генератор + critic; router + генератор + critic + judge.
Критерии приёмки:
- Для каждой конфигурации измерены качество, p50/p95, токены, стоимость и ручная очередь.
- Ошибки router представлены матрицей с разной ценой классов.
- Judge сравнен минимум с двумя человеческими разметчиками.
- Посчитана стоимость каждой дополнительно предотвращённой существенной ошибки.
- Хотя бы одна роль удалена или её необходимость доказана числами.