中文翻译暂不可用,显示俄语原文。
Настроить prompt observability
ТЕХНИЧЕСКОЕ ЗАДАНИЕ: Настроить prompt observability
1. Цель задачи
Научиться настраивать observability для промптов в production-системе: собирать ключевые метрики (latency, количество токенов, частота ошибок, качество ответов) по каждой версии промпта, визуализировать их на дашборде и настроить алерты для автоматического обнаружения деградации. В результате вы получите работающий дашборд в Grafana, который позволяет за 10 секунд оценить состояние всех активных версий промптов и мгновенно заметить аномалии.
Ключевой результат Дашборд Grafana с метриками по каждой версии промпта (latency p50/p95, токены, error rate, качество) и настроенные алерты в Alertmanager, которые срабатывают при падении качества или росте ошибок более чем на 20% от baseline.
2. Исходные данные
| Что нужно | Откуда взять |
|---|---|
| Система, использующая промпты (LLM-приложение) | Пет-проект или существующее приложение (например, чат-бот, RAG) |
| Логи вызовов LLM с указанием версии промпта | Генерировать скриптом или взять из реальных логов (JSONL, CSV) |
| Метрики: latency, токены, статус ответа (success/error) | Prometheus client library (Python) или OpenTelemetry |
| Дашборд для визуализации | Grafana (локально или облачная версия) |
| Система алертов | Alertmanager (в составе Prometheus) |
| Версии промптов (идентификатор, текст, дата изменения) | Git-репозиторий или таблица в БД (PostgreSQL, SQLite) |
Если нет реального инструмента — симулируем:
- Создать тестовое приложение на Python, которое имитирует вызов LLM с разными версиями промптов. Использовать time.sleep(random.uniform(0.5, 2.0)) для симуляции latency, случайные ошибки (5% вызовов) и фиксированное количество токенов (например, 150–500).
- Сгенерировать логи в формате JSONL: каждая строка содержит
timestamp,prompt_version,latency_ms,tokens,status(ok/error),quality_score(0–1, можно симулировать на основе длины ответа). - Настроить Prometheus с
prometheus_clientдля сбора метрик в реальном времени. Если нет возможности установить Prometheus — использоватьpushgatewayили эмуляцию черезprometheus-push-client. - Grafana установить локально через Docker (
grafana/grafana:latest) или использовать бесплатный облачный экземпляр (Grafana Cloud free tier).
3. Технологический стек
| Компонент | Инструменты | Назначение |
|---|---|---|
| Приложение-генератор трафика | Python 3.10+, prometheus_client, random, json | Имитация вызовов LLM с разными версиями промптов |
| Сбор метрик | Prometheus (pull) + prometheus_client (экспорт на /metrics) | Хранение временных рядов метрик |
| Хранение логов | Loki (опционально) или файл JSONL | Детальный анализ запросов |
| Визуализация | Grafana (v9+) | Дашборды с панелями по версиям промптов |
| Алерты | Alertmanager (в составе Prometheus) | Отправка уведомлений при деградации |
| Управление версиями промптов | Git + SQLite (таблица prompt_versions) | Хранение метаданных о версиях (id, текст, дата, автор) |
| Контейнеризация (опционально) | Docker, docker-compose | Быстрый запуск стека (Prometheus + Grafana + приложение) |
4. Этапы выполнения
Этап 1: Подготовка инфраструктуры и генерация трафика (1–1.5 часа)
Действия
-
Развернуть Prometheus и Grafana через docker-compose:
version: '3.8' services: prometheus: image: prom/prometheus:latest volumes: - ./prometheus.yml:/etc/prometheus/prometheus.yml ports: - "9090:9090" grafana: image: grafana/grafana:latest ports: - "3000:3000" environment: - GF_SECURITY_ADMIN_PASSWORD=adminНастроить
prometheus.ymlдля сбора метрик с приложения (target:app:8000). -
Написать генератор трафика (
generator.py):from prometheus_client import start_http_server, Histogram, Counter, Gauge import time, random, json # Метрики LATENCY = Histogram('prompt_latency_seconds', 'Latency of prompt call', ['version']) TOKENS = Histogram('prompt_tokens_total', 'Tokens used per call', ['version']) ERRORS = Counter('prompt_errors_total', 'Error count', ['version']) QUALITY = Gauge('prompt_quality_score', 'Quality score (0-1)', ['version']) versions = ['v1.0', 'v1.1', 'v2.0'] def simulate_call(version): latency = random.uniform(0.5, 2.0) tokens = random.randint(100, 500) error = random.random() < 0.05 quality = random.uniform(0.7, 1.0) if not error else 0.0 return latency, tokens, error, quality if __name__ == '__main__': start_http_server(8000) while True: v = random.choice(versions) lat, tok, err, qual = simulate_call(v) LATENCY.labels(version=v).observe(lat) TOKENS.labels(version=v).observe(tok) if err: ERRORS.labels(version=v).inc() QUALITY.labels(version=v).set(qual) time.sleep(random.uniform(0.1, 0.5)) -
Запустить генератор и убедиться, что Prometheus видит метрики (http://localhost:9090/targets).
Ожидаемый результат этапа Prometheus и Grafana запущены, генератор отправляет метрики, в Prometheus доступны метрики prompt_latency_seconds, prompt_tokens_total, prompt_errors_total, prompt_quality_score.
Этап 2: Инструментирование реального приложения (1–2 часа)
Действия
-
Добавить метрики в существующее LLM-приложение (или использовать генератор как основу). Для каждого вызова:
- Замерить latency с помощью
time.perf_counter(). - Получить количество токенов из ответа LLM (если API возвращает
usage). - Определить статус (success/error) и зафиксировать версию промпта.
- Вычислить quality score (например, через RAGAS или простую эвристику: длина ответа / max_length).
- Замерить latency с помощью
-
Создать файл с метриками (
metrics.py):from prometheus_client import Histogram, Counter, Gauge import time prompt_latency = Histogram('prompt_latency_seconds', 'Latency', ['version', 'model']) prompt_tokens = Histogram('prompt_tokens_total', 'Tokens', ['version']) prompt_errors = Counter('prompt_errors_total', 'Errors', ['version', 'error_type']) prompt_quality = Gauge('prompt_quality_score', 'Quality', ['version']) def instrument_call(version, model, func): start = time.perf_counter() try: result = func() latency = time.perf_counter() - start tokens = result.get('usage', {}).get('total_tokens', 0) quality = compute_quality(result) prompt_latency.labels(version=version, model=model).observe(latency) prompt_tokens.labels(version=version).observe(tokens) prompt_quality.labels(version=version).set(quality) return result except Exception as e: prompt_errors.labels(version=version, error_type=type(e).__name__).inc() raise -
Интегрировать метрики в основной код — обернуть вызов LLM декоратором или middleware.
-
Добавить label
version— брать из конфига или переменной окруженияPROMPT_VERSION.
Ожидаемый результат этапа Код приложения инструментирован, метрики обогащены лейблами версий, приложение экспортирует метрики на /metrics.
Этап 3: Построение дашборда в Grafana (1.5–2 часа)
Действия
-
Подключить Prometheus как источник данных в Grafana (Settings → Data Sources → Prometheus, URL:
http://prometheus:9090). -
Создать дашборд с панелями:
-
Latency p50 и p95 по версиям (PromQL):
histogram_quantile(0.50, sum(rate(prompt_latency_seconds_bucket[5m])) by (le, version)) histogram_quantile(0.95, sum(rate(prompt_latency_seconds_bucket[5m])) by (le, version))Тип панели: Time series, несколько линий по
version. -
Количество токенов (среднее):
avg(rate(prompt_tokens_total_sum[5m]) / rate(prompt_tokens_total_count[5m])) by (version) -
sum(rate(prompt_errors_total[5m])) by (version) / sum(rate(prompt_latency_seconds_count[5m])) by (version)Умножить на 100 для процентов.
-
avg(prompt_quality_score) by (version)Добавить пороговую линию (например, 0.8).
-
Общее количество вызовов:
sum(rate(prompt_latency_seconds_count[5m])) by (version)
-
-
Настроить переменные дашборда (например,
$version— мультивыбор из метрикlabel_values(prompt_latency_seconds_count, version)). -
Добавить описание и аннотации для версий (например, отметить момент смены версии).
Ожидаемый результат этапа Дашборд с 5–6 панелями, фильтр по версиям, возможность увидеть деградацию за последние 15–30 минут.
Этап 4: Настройка алертов (1 час)
Действия
-
Создать файл правил алертов
alerts.yml:groups: - name: prompt_degradation rules: - alert: HighErrorRate expr: | (sum(rate(prompt_errors_total[5m])) by (version) / sum(rate(prompt_latency_seconds_count[5m])) by (version)) > 0.1 for: 2m labels: severity: critical annotations: summary: "High error rate for prompt version {{ $labels.version }}" description: "Error rate is {{ $value | humanizePercentage }} for version {{ $labels.version }}" - alert: LowQualityScore expr: | avg(prompt_quality_score) by (version) < 0.7 for: 3m labels: severity: warning annotations: summary: "Low quality score for prompt version {{ $labels.version }}" description: "Quality score is {{ $value }} for version {{ $labels.version }}" - alert: LatencySpike expr: | histogram_quantile(0.95, sum(rate(prompt_latency_seconds_bucket[5m])) by (le, version)) > 3.0 for: 2m labels: severity: warning annotations: summary: "Latency spike for version {{ $labels.version }}" -
Добавить правило в Prometheus — смонтировать файл в контейнер и указать в
prometheus.yml:rule_files: - "alerts.yml" -
Настроить Alertmanager (в docker-compose добавить сервис
alertmanager) и указать получателя (email, Slack webhook). Для теста можно использоватьwebhookв локальный сервер. -
Проверить алерты — симулировать деградацию (увеличить error rate до 20% в генераторе) и убедиться, что алерт срабатывает в Grafana (раздел Alerting).
Ожидаемый результат этапа Алерты настроены и работают: при превышении порогов появляются уведомления в Grafana и (опционально) в Slack/email.
Этап 5: Тестирование и валидация (30–45 минут)
Действия
-
Симулировать деградацию:
-
Проверить фильтрацию по версиям:
- Добавить новую версию (например,
v3.0-test) с плохими метриками. - Убедиться, что дашборд показывает её отдельно и алерты приходят именно по этой версии.
- Добавить новую версию (например,
-
Написать простой тест (pytest), который запускает генератор на 30 секунд и проверяет, что метрики экспортируются и алерты можно получить через API Prometheus.
Ожидаемый результат этапа Подтверждено, что observability работает: деградация видна на дашборде и алерты срабатывают в течение 2–3 минут.
5. Критерии приемки (Definition of Done)
- Дашборд Grafana содержит минимум 4 панели: latency (p50/p95), токены, error rate, quality score, с разбивкой по версиям промптов.
- На дашборде реализована переменная
$versionдля фильтрации по одной или нескольким версиям. - Настроены алерты на: error rate > 10% (critical), quality score < 0.7 (warning), latency p95 > 3s (warning).
- Алерты срабатывают в течение 2 минут после возникновения аномалии и отображаются в Grafana Alerting.
- Код инструментирования приложения выложен в Git-репозиторий с README, описывающим добавление метрик.
- docker-compose.yml позволяет развернуть весь стек одной командой
docker-compose up. - Проведено тестирование: симуляция деградации показала корректную работу дашборда и алертов.
- Документация содержит описание метрик, их лейблов и порогов алертов.
6. Ожидаемый результат
Основной артефакт Папка проекта со следующей структурой:
prompt-observability/
├── docker-compose.yml
├── prometheus/
│ ├── prometheus.yml
│ └── alerts.yml
├── app/
│ ├── generator.py # или основное приложение с метриками
│ ├── metrics.py
│ └── requirements.txt
├── grafana/
│ └── dashboards/
│ └── prompt_observability.json # экспортированный дашборд
├── tests/
│ └── test_observability.py
└── README.md
Содержание README.md
- Описание архитектуры (схема: приложение → Prometheus → Grafana + Alertmanager).
- Инструкция по запуску (
docker-compose up). - Описание метрик и лейблов.
- Скриншоты дашборда.
- Примеры алертов и их пороги.
Опциональные дополнительные результаты
- Интеграция с Loki для просмотра логов по версиям промптов.
- Настройка уведомлений в Slack через webhook.
- Добавление метрики
prompt_version_info(Gauge) с информацией о текущей активной версии.
7. Возможные сложности и их решение
| Сложность | Решение |
|---|---|
| Метрики latency имеют высокий шум из-за сетевых задержек | Использовать гистограммы с несколькими бакетами (0.1, 0.5, 1, 2, 5) и смотреть p95 вместо среднего |
| Версии промптов не размечены в коде | Добавить обязательный label version во все метрики; брать из переменной окружения PROMPT_VERSION или из конфига |
| Алерты срабатывают ложно при кратковременных скачках | Увеличить for: до 2–3 минут; использовать rate() с окном 5 минут |
| Нет доступа к production-логам | Использовать симулятор (генератор) с реалистичными распределениями; параметры взять из документации LLM API |
| Grafana не видит метрики из-за CORS или сети | Проверить network в docker-compose (общая сеть); убедиться, что target в Prometheus доступен по имени сервиса |
| Не хватает метрик качества (quality score) | Использовать прокси-метрику: длина ответа / максимальная длина (если нет RAGAS) или 1 для успешных, 0 для ошибок |
8. Бюджет времени (оценка)
| Этап | Время |
|---|---|
| Этап 1: Подготовка инфраструктуры и генерация трафика | 1–1.5 часа |
| Этап 2: Инструментирование реального приложения | 1–2 часа |
| Этап 3: Построение дашборда в Grafana | 1.5–2 часа |
| Этап 4: Настройка алертов | 1 час |
| Этап 5: Тестирование и валидация | 30–45 минут |
| Итого | 5–7 часов |
Примечание Для первого раза рекомендуется заложить 8 часов с учётом отладки и изучения документации.
9. Связанные вопросы из базы знаний
| Вопрос | Тема |
|---|---|
| 15 | Основы мониторинга ML-систем |
| 42 | Метрики качества ответов LLM |
| 78 | Настройка Prometheus для ML-приложений |
| 101 | Инструментирование Python-кода метриками |
| 155 | Проектирование дашбордов в Grafana |
| 200 | Алерты на основе временных рядов |
| 301 | Управление версиями промптов |
| 450 | Обнаружение дрейфа данных в промптах |
| 512 | Интеграция Alertmanager с Slack |
| 600 | Best practices по observability для LLM |
10. Чек-лист самопроверки
- Я настроил Prometheus и Grafana, приложение экспортирует метрики с лейблом
version. - Я построил дашборд с панелями latency, токены, error rate, quality score, разбитыми по версиям.
- Я настроил алерты на деградацию (error rate > 10%, quality < 0.7, latency p95 > 3s) и проверил их срабатывание.
- Я задокументировал все шаги в README и экспортировал дашборд в JSON.
- Я протестировал симуляцию деградации и убедился, что алерты приходят в течение 2 минут.