Прототип показывает, что модель иногда справляется. Production должен выдерживать безопасные изменения под реальной нагрузкой. Переход между ними обеспечивает progressive delivery.
Почему «сначала на 10%» недостаточно
Команда отправляет часть трафика на новый prompt. Общая latency и HTTP errors не меняются, rollout доходит до всех. Через день выясняется: новый вариант чаще отвечает уверенно, но неверно; повторные обращения выросли, стоимость успешного решения: тоже.
Canary без контроля, метрик результата и автоматического отката: медленный big bang.
Сначала отделите release от exposure
Соберите immutable behavioral manifest из главы 42 и разверните кандидат без пользовательского трафика. Управляйте доступом отдельно:
build -> offline gates -> deploy candidate
-> shadow -> internal users -> canary cohorts
-> staged exposure -> full rollout
\-> abort + rollbackFeature flag должен выбирать целый manifest, а не независимо prompt, model и index. Assignment детерминирован по устойчивому ключу (tenant_id/user_id), иначе один пользователь скачет между вариантами, а измерения загрязняются. Для stateful agent закрепляйте вариант на весь workflow.
Shadow не равен canary
В shadow кандидат получает копию входа, но его ответ не видит пользователь и его tool calls не имеют side effects.
async def handle(req):
control = await run(CONTROL, req, tools=real_tools)
if shadow_sample(req):
enqueue(run, CANDIDATE, redact(req), tools=read_only_stubs)
return controlShadow ловит schema errors, latency, cost и retrieval drift. Он не измеряет реакцию пользователя и может быть опасен, если копирует PII в другое окружение или вызывает реальные инструменты. Проверяйте consent/retention, redaction, tenant ACL и идемпотентность.
Canary и control должны быть сопоставимы
Одновременный control нужен, потому что меняются нагрузка, пользователи и upstream. Рандомизируйте единицей, соответствующей причинному эффекту: обычно user/tenant, не request. Крупного tenant иногда выделяют в отдельную страту, чтобы он не перевесил эксперимент.
До запуска зафиксируйте:
- primary outcome: business success, а не judge score;
- guardrails: безопасность, false accepts, contract/tool failures, latency, availability;
cost_per_success = total_inference_and_review_cost / successful_business_outcomes;- срезы: tenant, язык, task type, длина контекста, model route;
- stop/rollback policy, minimum observation window и владельца решения.
Маркированный пример, не норматив: этапы exposure могут быть internal → малая когорта → несколько последовательно расширяемых когорт. Конкретные доли, длительность и пороги выводят из трафика, сезонности и blast radius, а не копируют из книги.
Не оптимизируйте по cost/request: дешёвый ответ, после которого пользователь возвращается, дороже. Success должен быть наблюдаемым: решённый тикет без повторного обращения, корректно завершённая операция, принятый документ. Если outcome запаздывает, используйте ранние proxy только как временные guardrails.
Анализ rollout
while rollout.active:
c = metrics(CONTROL, same_window=True)
n = metrics(CANARY, same_window=True)
if security_incident(n) or contract_break(n):
rollback(reason="hard invariant")
elif confidence_bound(n.error_rate - c.error_rate) > ERROR_BUDGET:
rollback(reason="error regression")
elif confidence_bound(n.cost_per_success - c.cost_per_success) > COST_BUDGET:
rollback(reason="economics regression")
elif enough_data() and all_gates_green():
promote_one_step()Это схема, не готовый статистический тест. Для долей и попарных сравнений применяйте главу 38; учитывайте задержку outcome и кластеризацию по tenant. Нельзя проверять каждые пять минут обычный p-value и остановиться при первом удобном результате: repeated peeking повышает ложные срабатывания. Используйте заранее заданные checkpoints/последовательный метод либо относитесь к раннему откату как к консервативному safety rule, не как к доказательству эффекта.
Проверяйте и абсолютный SLO, и delta к control. Оба варианта могут деградировать из-за провайдера; delta будет зелёной, пользователи: нет.
Автоматический rollback
Rollback должен быть машинной операцией:
- остановить дальнейшее увеличение exposure;
- направить новые workflows на control manifest;
- безопасно завершить или отменить in-flight операции;
- вернуть совместимые index alias/configuration;
- сохранить candidate logs, traces и eval artifacts;
- проверить control synthetic-запросами;
- открыть incident с причиной и временной шкалой.
analysis:
hard_abort:
- security_policy_violation > 0
- tool_contract_failure > allowed_budget
comparative:
- metric: business_success
compare_to: control
- metric: cost_per_success
compare_to: control
rollback:
target_manifest: support-assistant/previous-known-good
verify: [synthetic_safe_refusal, retrieval_acl, tool_dry_run]Здесь значения: policy команды; пример намеренно не задаёт универсальных чисел.
Rollback к коду не поможет после несовместимой записи в memory/DB. Нужны expand/contract migrations, dual-read/dual-write при необходимости и blue-green index. Для необратимого tool action rollback означает остановить новые действия и запустить compensating workflow; «развернуть старую версию» деньги клиенту не вернёт.
Что автоматизировать, что оставить человеку
Автоматически откатывайте нарушение hard invariant: security policy, cross-tenant leak, невалидный tool contract, потерю данных. Для шумных или запаздывающих business metrics автомат может заморозить rollout и вызвать владельца. Иначе ложный alarm создаст deployment flapping.
Продвижение и откат должны быть идемпотентны, сериализованы и аудируемы. После rollback действует cooldown; причина не «лечится» простым перезапуском того же кандидата.
Failure modes
- canary получает только лёгких или только внутренних пользователей;
- routing по request смешивает варианты внутри диалога;
- candidate и control используют разные периоды или upstream;
- judge одновременно обновлён с candidate;
- среднее скрывает утечку у одного tenant или языка;
- shadow исполняет side effects;
- rollout продолжается при недостатке данных, потому что «красного нет»;
- alert есть, но rollback требует ручного редактирования пяти систем;
- откат ломает новую memory schema или читает новый индекс старым retriever;
- метрика стоимости игнорирует retry, human review и повторные обращения;
- логи candidate удаляются при rollback, расследовать нечего.
Rehearsal перед первым canary
Проведите game day в staging или на безопасной prod-когорте:
- искусственно ухудшите schema validity: hard gate должен остановить rollout;
- внесите задержку: latency gate сравнит candidate и control;
- симулируйте запрещённый tool call: side effect не должен исполниться;
- переключите green index и верните blue;
- откатите manifest при активных workflows;
- убедитесь, что dashboard показывает assignment, release ID, outcome, cost и security events.
Rollback, который не репетировали, остаётся инструкцией на бумаге.
Правило главы
Production-релиз LLM-системы: управляемое увеличение blast radius с одновременным control. Продвигают не по отсутствию HTTP 500, а по business success, cost-per-success и security guardrails. Hard invariant откатывает автоматически; состояние и side effects проектируют под откат заранее.
Чеклист
- Candidate: один immutable manifest; assignment sticky и логируется.
- Offline eval, shadow и canary решают разные задачи.
- Control идёт одновременно; когорты сопоставимы.
- Outcome, guardrails, срезы и stop rules заданы до просмотра данных.
- Есть абсолютные SLO и сравнительные метрики.
- Shadow tools read-only/stubbed; PII и ACL проверены.
- Автооткат проверяет known-good после переключения.
- DB, memory, index и in-flight workflows совместимы с rollback.
- Измеряются total cost и cost-per-success.
- Rollback rehearsal пройден, audit trail сохранён.
Первичные источники
- Kubernetes Deployments: rollout status, pause/resume и rollback
- Argo Rollouts: Canary strategy
- Argo Rollouts: Analysis and automated abort