Как делать canary deployment для промптов (5% трафика)?
Краткий тезис
Canary deployment (deployment|канареечное развёртывание) для промптов — это техника постепенного введения новой версии промпта (prompt) на малый процент трафика (например, 5%) с параллельным мониторингом метрик и автоматическим откатом (auto-rollback) при ухудшении качества. В контексте RAG|Agentic RAG это позволяет безопасно экспериментировать с промптами для retrieval, генерации и агентов, минимизируя риски для пользователей и затраты. Ключевые компоненты: feature flags, A/B-тестирование, онлайн-оценка и пороговые условия отката.
1. Термин: Canary deployment (канареечное развёртывание)
Canary deployment — метод развёртывания, при котором новый релиз сначала получает небольшая подгруппа пользователей (канарейки), затем доля постепенно увеличивается до 100% при отсутствии проблем. Название происходит от метафоры «канарейка в угольной шахте» — раннее предупреждение об опасности.
Для промптов canary deployment означает, что новая версия системного промпта (например, инструкция для LLM) применяется к случайной доле запросов (например, 5%), а остальные 95% продолжают работать на старой версии. Метрики (точность, faithfulness, error rate, latency) сравниваются между группами. Если новая версия хуже — автоматический откат к старой.
Отличие от A/B-тестирования: A/B-тест часто проводится для статистического сравнения двух вариантов, может длиться дольше и требует фиксированной выборки. Canary deployment — это скорее процедура безопасного rollout'а с мониторингом, обычно с быстрым принятием решения (минуты–часы).
2. Зачем нужно canary deployment для промптов в Agentic RAG
Изменение промпта может вызвать непредсказуемые эффекты:
- Ухудшение faithfulness (ответ перестаёт опираться на документы).
- Рост error rate (LLM отказывается отвечать, возвращает ошибки или пустые строки).
- Изменение стиля (становится менее полезным или токсичным).
- Рост стоимости (новый промпт может заставлять LLM генерировать больше токенов).
- Негативное влияние на агентов (если промпт для инструментов — агент может начать вызывать неправильные функции).
Постепенное развёртывание на 5% трафика снижает риск до нуля для 95% пользователей и даёт возможность быстро выявить аномалии до полного включения.
3. Фазы канареечного развёртывания: от 1% до 100%
Типичная схема rollout'а для промпта:
| Фаза | Доля нового промпта | Длительность | Критерий перехода |
|---|---|---|---|
| 0 (pre-canary) | 0% (только бета-тест) | несколько часов | внутреннее тестирование |
| 1 | 1% | 10–30 мин | метрики не ухудшились |
| 2 | 5% (запрашиваемая) | 30–60 мин | faithfullness < +2%, error rate < +0.5% |
| 3 | 20% | 1–4 часа | аналогично, плюс latency / cost |
| 4 | 50% | 4–12 часов | стабильность и бизнес-метрики |
| 5 | 100% | финально | полный rollout |
Важно: на каждом этапе сравниваются метрики новой версии (canary) против baseline (старой версии) с использованием статистической значимости (p-value < 0.05). Если достоверных различий нет, переход разрешён.
4. Инфраструктура: feature flags и конфигурация
Для canary deployment нужен механизм динамического переключения между версиями промпта. Самый популярный подход — feature flags (фиче-флаги).
Варианты реализации
- Управляемые платформы: LaunchDarkly, Split.io, Flagsmith. Позволяют менять процент включения в реальном времени без деплоя кода.
- Самописный конфиг-сервер: Redis + JSON-конфиг, который периодически загружается сервисом.
Пример простой реализации на Python с Redis:
import redis
import json
import hashlib
r = redis.Redis(host='localhost', port=6379, decode_responses=True)
def get_prompt_version(user_id: str) -> str:
# получить конфиг canary из Redis
config = json.loads(r.get('canary_prompt_config') or '{"old_version":"v1.0","new_version":"v2.0","percentage":0.05}')
# детерминированное распределение: хэш user_id mod 100
bucket = int(hashlib.md5(user_id.encode()).hexdigest(), 16) % 100
if bucket < config['percentage'] * 100:
return config['new_version']
else:
return config['old_version']
def get_prompt(version: str) -> str:
prompts = {
'v1.0': 'Answer based on the context: {context}',
'v2.0': 'You are a helpful assistant. Use the following context to answer the question: {context}'
}
return prompts[version]
Здесь percentage можно менять через Redis CLI, и все инстансы сервиса мгновенно подхватят новое значение.
5. Метрики мониторинга и сравнения
Для canary промпта критично отслеживать не только технические, но и качественные метрики. Рекомендуемый набор:
| Метрика | Где считать | Порог auto-rollback |
|---|---|---|
| Faithfulness (доля ответов, не противоречащих контексту) | LLM-as-judge (RAGAS, Prometheus) | ухудшение >5% относительно baseline |
| Answer relevance (полезность ответа) | LLM-as-judge | ухудшение >10% |
| Error rate (доля запросов с ошибкой LLM, пустой ответ, status code 500) | backend | рост >1% |
| Latency p95 | backend мониторинг | рост >20% |
| Cost per request | логи количества токенов | рост >15% |
| User satisfaction (лайки/дизлайки) | product metrics | падение >5% |
Важно: метрики должны считаться для обеих групп (canary и baseline) в реальном времени, например, через Prometheus + Grafana или Datadog.
6. Auto-rollback: условия и реализация
Auto-rollback должен срабатывать автоматически при нарушении порогов. Пример логики в Python:
def check_rollback():
metrics_canary = get_metrics('canary_prompt_v2.0')
metrics_baseline = get_metrics('baseline_prompt_v1.0')
if metrics_canary['faithfulness'] < metrics_baseline['faithfulness'] * 0.95:
trigger_rollback()
return True
if metrics_canary['error_rate'] > metrics_baseline['error_rate'] + 0.01:
trigger_rollback()
return True
# добавить другие метрики
return False
def trigger_rollback():
# откатить конфиг: установить percentage=0
r.set('canary_prompt_config', json.dumps({'old_version':'v1.0','new_version':'v2.0','percentage':0.0}))
alert_team('Rollback triggered due to metric degradation')
После срабатывания отката команда анализирует причины, фиксит промпт и начинает новый canary с 1%.
7. Пример реализации на Python + FastAPI
Покажем, как canary deployment встраивается в endpoint RAG-агента:
from fastapi import FastAPI, Request
import hashlib
app = FastAPI()
def decide_prompt_version(request: Request) -> str:
user_id = request.headers.get('X-User-Id', 'default')
return get_prompt_version(user_id)
@app.post("/rag/answer")
async def ask_rag(request: Request, body: dict):
version = decide_prompt_version(request)
prompt = get_prompt(version)
# извлекаем контекст из retrieval
context = retrieve(body['query'])
# вызываем LLM с выбранным промптом
response = call_llm(prompt.format(context=context))
# логируем метрики (версия, latency, токены и т.д.)
log_metrics(version, response)
return {"answer": response}
# Для мониторинга /metrics эндпоинт для Prometheus
Логирование версии и метрик позволяет в Grafana построить дэшборд сравнения.
8. Интеграция с RAG-пайплайном
В Agentic RAG промпты могут быть разных типов:
- Prompt для retrieval (например, query rewriting, hyde).
- Prompt для генерации ответа (system + user).
- Prompt для агента (определяющий выбор инструмента или планирования).
Canary должен уметь переключать любой из них. Рекомендуется централизованное хранилище промптов (например, Prompt Registry), где каждая версия промпта имеет идентификатор. Feature flag выбирает не просто версию, а целый сет промптов для всех этапов пайплайна.
Пример структуры в Redis:
{
"prompt_set_id": "v2.0",
"retrieval_prompt": "...",
"generation_prompt": "...",
"agent_prompt": "..."
}
9. Продвинутые практики
Помимо простого canary по проценту трафика, можно использовать:
- Shadow testing: новый промпт применяется на всех запросах, но ответ пользователю отправляется от старого. Метрики сравниваются offline. Безопаснее, но требует двойного вызова LLM.
- Multi-armed bandit: алгоритм (например, Thompson sampling) динамически регулирует долю трафика на основе наградного сигнала (например, пользовательских лайков). Быстрее находит лучший вариант.
- Стратифицированное распределение: разделение трафика не случайное, а по сегментам (регион, устройство), чтобы обеспечить репрезентативность.
Для 5% трафика простой random split с мониторингом часто достаточен.
10. Пет-проект для закрепления
Задача: Реализовать canary deployment для промптов чат-бота на основе RAG, который отвечает на вопросы по документации.
Инструменты: Python, FastAPI, Redis (или файл конфига), библиотека sim для синтетических метрик.
Шаги:
- Создайте два варианта промпта: старый (краткий) и новый (подробный с пошаговыми инструкциями).
- Напишите эндпоинт, который по
user_idвыбирает версию (5% на новый). - Добавьте логирование метрик (faithfulness, error rate) в файл или БД.
- Напишите скрипт, который имитирует запросы (например, 1000 запросов с разными user_id) и собирает метрики.
- Реализуйте авто-откат: если faithfulness нового промпта упал ниже 0.9, а старого >0.95, то установите процент в 0.
- Визуализируйте метрики в простом Streamlit-дэшборде.
Ожидаемый результат: Система, которая безопасно переключает промпт на 5% трафика, автоматически откатывает при ухудшении, и вы можете видеть, какая версия лучше.
11. Связь с другими вопросами
| Вопрос | Тема |
|---|---|
| 801 | Как тестировать промпты в production? |
| 804 | Как делать A/B-тестирование промптов? |
| 736 | CI/CD для ML-моделей и RAG-пайплайнов |
| 802 | Мониторинг качества RAG в реальном времени |
| 805 | Версионирование и хранение промптов |
12. Навигация
- Предыдущий: 802
- Следующий: 804
- Индекс: 00. Индекс разборов
Навигация
- Предыдущий: 802
- Следующий: 804
- Индекс: 00. Индекс разборов