Production и облако · Production and cloud · урок 3 · 13 мин

Выкатка: CI, shadow, canary, rollback

Shipping: CI, shadow, canary, rollback

ТемыProductionСтатистика

Зачем

После урока ты расскажешь путь изменения агента до клиента целиком: что такое версия агента, что блокирует слияние в CI, чем shadow отличается от canary, сколько canary должен длиться и почему откат образа не откатывает данные. Это вопрос «how do you ship a change to the agent without a customer seeing a bad version?», который на собеседовании в банк или финтех звучит почти всегда.

Версия агента — это набор, а не образ

У обычного сервиса версия — это код. У агента поведение меняется и без строчки кода: новый prompt, новая модель, новый индекс. Поэтому версия агента — неизменяемый bundle (набор), который версионируют целиком:

ID набора пишется в каждый trace. Тогда на вопрос аудитора «какая версия ответила клиенту 3 марта и кто её утвердил» есть ответ одной строкой из журнала и одним commit в Git.

CI: ворота до слияния

Путь начинается с pull request. CI (continuous integration, автоматические проверки на каждое изменение) запускает unit-тесты, linters (проверки стиля кода) и offline eval suite (набор задач с проверкой ответа) как ворота. Слияние блокируется, если доля нарушений политики выросла или успех задач упал ниже порога, записанного заранее. Пороги считают отдельно по сегментам, которые важны бизнесу, — например, по языкам: средний балл скрывает провал на 20 % трафика.

Дальше: сборка образа, подпись (cosign кладёт подпись в registry, кластер принимает только подписанные образы), неизменяемый digest вместо tag. Staging (тестовая среда) синхронизируется из Git, проходят smoke-тесты (быстрые проверки «живо ли»). Миграция схемы базы — отдельный шаг, который падает, если версия схемы не та, что ждёт код. Без этого шага код новой версии встречает старую схему и падает молча.

Shadow: настоящий трафик без риска

Shadow (теневой режим, traffic mirroring) отправляет новой версии копию реальных запросов. Она отвечает, но ответы отбрасываются: клиенты видят только старую версию. В Istio это описано как «fire and forget», долю копируемого трафика задаёт mirrorPercentage. Сравнивают старую и новую версию на одних и тех же запросах: маршрут, вызванные tools, отказы, latency.

Ловушка: tools в shadow — только на чтение или mock (заглушка). Иначе теневая версия по-настоящему заблокирует карту клиента. Shadow — единственный этап, где ни один клиент не видит новую версию. Поэтому банк начинает с него.

Rolling, blue-green, canary — когда что

Стратегия Как работает Когда подходит Риск
Rolling update меняет pods по частям (по умолчанию 25 % лишних, 25 % недоступных) патч библиотеки, настройки журналов нет анализа качества, версии работают вперемешку
Blue-green две полные среды, переключение всего трафика разом версии нельзя смешивать, нужен мгновенный откат все клиенты сразу на новой версии; двойные GPU на время перехода
Canary малая доля трафика, рост по шагам с анализом метрик новая модель, prompt, маршрутизация — всё, что меняет ответы нужна достаточная выборка

Canary — правило для всего, что меняет поведение агента: 1 % → 5 % → 25 % → 100 %. В Argo Rollouts анализ описывает AnalysisTemplate: метрики, пороги (successCondition) и допустимое число провалов (failureLimit). При провале, по документации, «the Rollout aborts, setting the canary weight back to zero». Метрики привязаны к вреду: доля передач человеку, нарушения по детерминированным проверкам, ошибки маршрута на размеченной выборке, жалобы, latency p95 — в сравнении со стабильной версией в то же время.

Как выглядят пороги на практике (числа — пример, их выбирают до старта и записывают в Git): - передачи человеку: canary не больше стабильной версии плюс 2 процентных пункта, считать не раньше 300 разговоров; - нарушения по детерминированным проверкам (действие без подтверждения, сумма не совпала с таблицей тарифов): ноль, первое же — abort; - latency p95: не больше 1,2 × стабильной версии; - ошибки маршрута на размеченной выборке: не хуже стабильной версии.

Сравнение идёт с живой стабильной версией, а не со вчерашним числом: утром и вечером трафик разный, и сравнение с прошлым смешивает изменение версии с изменением потока.

Сколько ждать: считай по выборке, а не по часам

Утверждение: «новая версия не подняла тяжёлые сбои до 1 %». Если сбой на самом деле 1 %, вероятность увидеть хотя бы один за n разговоров равна 1 − 0,99ⁿ. Для 95 % нужно n ≈ 300.

Пример. Поток — 2 000 разговоров в час (допущение). Canary на 5 % — 100 разговоров в час. Значит, 3 часа, только чтобы заметить сбой с частотой 1 %. Обратная сторона, rule of three (правило трёх): 0 сбоев в n разговорах даёт верхнюю границу частоты около 3/n с уверенностью 95 %. После 100 разговоров без сбоев можно сказать только «ниже ~3 %».

Отсюда два вывода. Первый: «час на 5 % без тревог» ничего не доказывает про редкие нарушения. Редкое тяжёлое нарушение закрывают дизайном — правами tools, подтверждением действий, — а canary ловит заметные регрессии. Второй: выборку считают по сегментам. Если сегмент даёт 30 % трафика, его выборка втрое меньше, и canary стоит дольше либо этот сегмент проверяют результатами shadow.

Откат: что откатывается, а что нет

kubectl rollout undo возвращает прежнюю ревизию Deployment за секунды. Но откатываются только pods, не база и не индекс. Если новая версия добавила колонку и пишет записи по-новому, старый код после отката встретит незнакомые данные.

Решение — expand → migrate → contract. Сначала расширить схему, не ломая старый код (добавить колонку). Потом выкатить код, который понимает оба варианта. И только в следующем выпуске убрать старое. Тогда откат образа безопасен на любом шаге. С индексом RAG то же самое: новый индекс строят рядом со старым и переключают по alias (псевдониму); откат — вернуть alias назад.

После 100 % наблюдение не заканчивается: containment (доля решённых без человека), передачи человеку, повторное обращение за 48 часов, жалобы и ручная выборка разговоров раз в неделю (урок a7-8).

Схема

Термины · Key terms

bundle (release bundle)
неизменяемый набор: образ, модель, prompt, tools, индекс, eval
CI
автоматические проверки на каждое изменение до слияния
eval gate
порог качества, ниже которого изменение не сливают
shadow / traffic mirroring
копия трафика новой версии, ответы отбрасываются
canary
малая доля реального трафика на новой версии с ростом по шагам
blue-green
две полные среды и переключение всего трафика разом
AnalysisTemplate
описание метрик и порогов для автоматического анализа canary
rollback
возврат прежней версии
expand / contract migration
миграция в два выпуска, чтобы откат был безопасен
rule of three
0 событий в n попытках даёт верхнюю границу частоты около 3/n

Сделай сам

Нарисуй схему: pull request → CI с eval-воротами → образ → shadow → canary 5 % → 100 % → наблюдение. Отметь, где появляется запись о версии для model risk. Затем посчитай: сколько часов нужно canary на 5 %, чтобы с вероятностью 95 % увидеть сбой с частотой 0,5 %, при потоке 2 000 разговоров в час.

Обсуди с тьютором: покажи схему и расчёт; спроси, какие три метрики ты бы поставил в AnalysisTemplate для изменения prompt маршрутизации и почему не accuracy.

Проверь себя · ответ под вопросом

1Shadow и canary: в чём разница, и почему банк начинает с shadow?
В shadow новая версия получает копию трафика, но её ответы отбрасываются, клиенты видят только старую. В canary часть реальных клиентов получает ответы новой версии. Shadow — единственный этап без риска для клиента, поэтому с него начинают; tools в shadow работают только на чтение.
2Что блокирует слияние изменения агента в CI?
Unit-тесты, linters и offline eval suite с порогами, записанными заранее. Блок срабатывает, если выросла доля нарушений политики или упал успех задач, причём считают по важным сегментам, например по языкам. Средний балл без разбивки может скрыть провал на части трафика.
3По каким метрикам срабатывает автоматический откат?
По метрикам, привязанным к вреду: доля передач человеку, нарушения по детерминированным проверкам, ошибки маршрута на размеченной выборке, жалобы, latency p95. Их сравнивают со стабильной версией в то же время. Пороги и число допустимых провалов задают в AnalysisTemplate до старта canary.

Interview questions · US / UK

1How do you get a fix to the agent into production without a customer ever seeing a bad version?
Strong answer: version the whole bundle; eval gate in CI per segment; signed immutable image; staging with migrations as a step; shadow with read-only tools and side-by-side comparison; canary with automated analysis and abort; honest caveat that only shadow means zero customers, so pre-canary gates are strict.
2Your canary has been at 5% for an hour with no alerts. Can we go to 100%?
Strong answer: ask how many conversations and per segment; seeing a 1% failure with 95% probability needs about 300; zero failures in n bounds the rate at about 3/n; rare severe violations are covered by design, not canary statistics; go to the next step, not 100%, if the sample is small.
3A release adds a column and changes how the agent writes records. You roll back the Deployment and the old version starts failing. What happened?
Strong answer: rollout undo reverts pods, not schema or data; old code meets the new shape; should have been expand, migrate, contract across releases; migration as a gated pipeline step; the RAG index built side by side and switched by alias, so rollback flips the alias.

Ключевые фразы · Say it aloud

Материалы