中文翻译暂不可用,显示俄语原文。

Настроить 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)

Если нет реального инструмента — симулируем:

  1. Создать тестовое приложение на Python, которое имитирует вызов LLM с разными версиями промптов. Использовать time.sleep(random.uniform(0.5, 2.0)) для симуляции latency, случайные ошибки (5% вызовов) и фиксированное количество токенов (например, 150–500).
  2. Сгенерировать логи в формате JSONL: каждая строка содержит timestamp, prompt_version, latency_ms, tokens, status (ok/error), quality_score (0–1, можно симулировать на основе длины ответа).
  3. Настроить Prometheus с prometheus_client для сбора метрик в реальном времени. Если нет возможности установить Prometheus — использовать pushgateway или эмуляцию через prometheus-push-client.
  4. 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 часа)

Действия

  1. Развернуть 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).

  2. Написать генератор трафика (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))
    
  3. Запустить генератор и убедиться, что Prometheus видит метрики (http://localhost:9090/targets).

Ожидаемый результат этапа Prometheus и Grafana запущены, генератор отправляет метрики, в Prometheus доступны метрики prompt_latency_seconds, prompt_tokens_total, prompt_errors_total, prompt_quality_score.


Этап 2: Инструментирование реального приложения (1–2 часа)

Действия

  1. Добавить метрики в существующее LLM-приложение (или использовать генератор как основу). Для каждого вызова:

    • Замерить latency с помощью time.perf_counter().
    • Получить количество токенов из ответа LLM (если API возвращает usage).
    • Определить статус (success/error) и зафиксировать версию промпта.
    • Вычислить quality score (например, через RAGAS или простую эвристику: длина ответа / max_length).
  2. Создать файл с метриками (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
    
  3. Интегрировать метрики в основной код — обернуть вызов LLM декоратором или middleware.

  4. Добавить label version — брать из конфига или переменной окружения PROMPT_VERSION.

Ожидаемый результат этапа Код приложения инструментирован, метрики обогащены лейблами версий, приложение экспортирует метрики на /metrics.


Этап 3: Построение дашборда в Grafana (1.5–2 часа)

Действия

  1. Подключить Prometheus как источник данных в Grafana (Settings → Data Sources → Prometheus, URL: http://prometheus:9090).

  2. Создать дашборд с панелями:

    • 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)
      
    • Error rate:

      sum(rate(prompt_errors_total[5m])) by (version) / sum(rate(prompt_latency_seconds_count[5m])) by (version)
      

      Умножить на 100 для процентов.

    • Quality score:

      avg(prompt_quality_score) by (version)
      

      Добавить пороговую линию (например, 0.8).

    • Общее количество вызовов:

      sum(rate(prompt_latency_seconds_count[5m])) by (version)
      
  3. Настроить переменные дашборда (например, $version — мультивыбор из метрик label_values(prompt_latency_seconds_count, version)).

  4. Добавить описание и аннотации для версий (например, отметить момент смены версии).

Ожидаемый результат этапа Дашборд с 5–6 панелями, фильтр по версиям, возможность увидеть деградацию за последние 15–30 минут.


Этап 4: Настройка алертов (1 час)

Действия

  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 }}"
    
  2. Добавить правило в Prometheus — смонтировать файл в контейнер и указать в prometheus.yml:

    rule_files:
      - "alerts.yml"
    
  3. Настроить Alertmanager (в docker-compose добавить сервис alertmanager) и указать получателя (email, Slack webhook). Для теста можно использовать webhook в локальный сервер.

  4. Проверить алерты — симулировать деградацию (увеличить error rate до 20% в генераторе) и убедиться, что алерт срабатывает в Grafana (раздел Alerting).

Ожидаемый результат этапа Алерты настроены и работают: при превышении порогов появляются уведомления в Grafana и (опционально) в Slack/email.


Этап 5: Тестирование и валидация (30–45 минут)

Действия

  1. Симулировать деградацию:

    • Временно изменить генератор: увеличить latency в 2 раза, error rate до 20%, quality score до 0.5.
    • Запустить на 5 минут, наблюдать дашборд.
    • Убедиться, что алерты срабатывают.
  2. Проверить фильтрацию по версиям:

    • Добавить новую версию (например, v3.0-test) с плохими метриками.
    • Убедиться, что дашборд показывает её отдельно и алерты приходят именно по этой версии.
  3. Написать простой тест (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

  • Описание архитектуры (схема: приложение → PrometheusGrafana + 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: Построение дашборда в Grafana1.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
600Best practices по observability для LLM

10. Чек-лист самопроверки

  • Я настроил Prometheus и Grafana, приложение экспортирует метрики с лейблом version.
  • Я построил дашборд с панелями latency, токены, error rate, quality score, разбитыми по версиям.
  • Я настроил алерты на деградацию (error rate > 10%, quality < 0.7, latency p95 > 3s) и проверил их срабатывание.
  • Я задокументировал все шаги в README и экспортировал дашборд в JSON.
  • Я протестировал симуляцию деградации и убедился, что алерты приходят в течение 2 минут.