Настроить correlation метрик (граф зависимостей retrieval → generation latency)
ТЕХНИЧЕСКОЕ ЗАДАНИЕ: Настроить correlation метрик (граф зависимостей retrieval → generation latency)
1. Цель задачи
Разработать систему мониторинга, которая строит граф зависимостей между временем выполнения компонента retrieval и задержкой генерации (generation latency) в RAG-пайплайне. Научиться выявлять, как изменения в retrieval (скорость поиска, размер результата) влияют на общую генерацию, и определять корневую причину (root cause) деградации latency.
Ключевой результат Граф корреляций в Grafana, позволяющий за <5 минут определить, какой именно этап (retrieval, embedding, контекстная подготовка) стал причиной роста latency генерации.
2. Исходные данные
Перед началом необходимо иметь:
| Что нужно | Откуда взять |
|---|---|
| RAG-система с измерением latency по этапам | Существующий pet-проект (или система на базе LangChain / LlamaIndex) |
| Метрики latency retrieval (p50, p95, p99) | Prometheus (экспорт из приложения) |
| Метрики latency генерации (TTFT, TPOT) | Prometheus (экспорт из LLM-сервера, например vLLM) |
| Трассировки (spans) каждого запроса | OpenTelemetry Collector + Jaeger / Grafana Tempo |
| Дашборд Grafana (базовый) | Grafana с подключённым Prometheus и Tempo |
| Инструмент для анализа корреляций | Python (pandas, scipy) или Jupyter notebook |
Если нет реального инструмента — симулируем:
- Развернуть RAG-пайплайн на локальной машине (например, на базе LangChain + Ollama + ChromaDB).
- Создать нагрузочный тест с помощью locust или vegeta с разными параметрами retrieval (top_k от 3 до 20, разные embedding-модели).
- Эмулировать изменение latency retrieval (например, принудительно добавить time.sleep(random.uniform(0.1, 1.0)) в метод search).
- Собрать метрики latency в Prometheus через клиентскую библиотеку (prometheus_client) и трассировки через OpenTelemetry SDK.
3. Технологический стек
| Компонент | Инструменты | Назначение |
|---|---|---|
| Мониторинг метрик | Prometheus + prometheus_client (Python) | Сбор latency retrieval и generation по шагам |
| Трассировка | OpenTelemetry SDK + Jaeger или Grafana Tempo | Получение спанов каждого запроса |
| Визуализация | Grafana (Node Graph / Service Graph) | Построение графа зависимостей |
| Анализ данных | Python (pandas, scipy, networkx) | Вычисление корреляций, построение графа offline |
| Нагрузочное тестирование | locust / vegeta | Генерация трафика с контролируемыми изменениями |
| LLM-сервер (если нет production) | vLLM / Ollama | Генерация ответов |
4. Этапы выполнения
Этап 1: Сбор метрик и трассировок (1–1.5 часа)
Действия
-
Инструментировать RAG-пайплайн OpenTelemetry
- Установить opentelemetry-api, opentelemetry-sdk, opentelemetry-exporter-otlp.
- В ключевых точках кода (вызов embedding, retrieval, контекстная сборка, запрос к LLM) создать spans с атрибутами: retrieval.latency_ms, generation.latency_ms, top_k, model_name.
- Экспортировать трассы в Jaeger или Grafana Tempo.
-
Экспонировать метрики через Prometheus
-
Подготовить нагрузочный тест
Ожидаемый результат этапа Prometheus содержит временные ряды retrieval_latency_seconds и generation_latency_seconds с одинаковыми метками (запрос → можно коррелировать).
Этап 2: Подготовка данных для корреляции (1 час)
Действия
-
Выгрузить метрики из Prometheus
- Использовать Prometheus API (или PromQL) для получения временных рядов
avg(rate(retrieval_latency_seconds_sum[1m]) / rate(retrieval_latency_seconds_count[1m]))и аналогично для generation. - Экспортировать в CSV через
pandas+prometheus-api-client.
- Использовать Prometheus API (или PromQL) для получения временных рядов
-
Агрегировать и выровнять по времени
-
Вычислить базовые статистики
- Сдвиг между рядами (cross-correlation) для учёта задержки влияния.
- Проверить стационарность (ADF test) — при необходимости взять разности.
Ожидаемый результат этапа Очищенный DataFrame с колонками timestamp, retrieval_latency, generation_latency.
Этап 3: Вычисление корреляций и построение графа зависимостей (1.5–2 часа)
Действия
-
Рассчитать корреляцию Пирсона и Спирмена
pearsonr(линейная зависимость) междуretrieval_latencyиgeneration_latency.spearmanr(монотонная зависимость) — на случай нелинейных эффектов.- Интерпретация: если p-value < 0.05 и |r| > 0.5 — значимая корреляция.
-
Оценить лаговую корреляцию (cross-correlation):
- Использовать
scipy.signal.correlateилиpandas.Series.autocorrсо сдвигом от -10 до +10 минут. - Найти максимальный коэффициент и соответствующий лаг — это укажет, через какое время изменение retrieval сказывается на генерации.
- Использовать
-
Построить граф зависимостей
- Узлы:
Embedding,Search,Context Preparation,LLM call. - Рёбра: на основе корреляционных матриц, полученных из трассировок (можно вычислить корреляцию между spans разных этапов внутри одного запроса).
- Использовать
networkxдля построения графа, визуализировать в виде дашборда Grafana Node Graph (потребуется экспорт в Prometheus в виде метрик графа).
- Узлы:
-
Интегрировать граф в Grafana
Ожидаемый результат этапа Интерактивный граф в Grafana, где толщина/цвет рёбер показывает силу корреляции между этапами.
Этап 4: Поиск корня (root cause) на основе графа (1 час)
Действия
-
Смоделировать инцидент
- Запустить нагрузку с внезапным увеличением retrieval latency (например, сценарий C).
- Наблюдать, как изменяются рёбра графа (корреляция с generation latency резко возрастает).
-
Определить аномальные узлы/рёбра
- Настроить пороги: если корреляция между
SearchиLLM call> 0.8 при лаге < 30 секунд — помечать узелSearchкак потенциальную причину. - Использовать цветовую маркировку: зелёный – норма, жёлтый – предупреждение, красный – аномалия.
- Настроить пороги: если корреляция между
-
Сформулировать вывод
-
Написать отчёт
- Краткое описание инцидента, скриншот графа, вывод по корреляции.
Ожидаемый результат этапа Идентифицированный root cause, подтверждённый данными корреляции и визуализацией.
Этап 5: Автоматизация проверки (опционально, 30 минут)
Действия
-
Написать скрипт на Python, который раз в N минут:
- Получает свежие метрики из Prometheus.
- Вычисляет корреляцию за последние 30 минут.
- Если корреляция превышает порог (например, 0.7) и лаг меньше 1 минуты — отправляет alert в Alertmanager.
-
Добавить дашборд с мониторингом корреляции
- Панель "Cross-correlation heatmap" (время на оси X, лаги на оси Y, цвет – сила корреляции).
Ожидаемый результат этапа Alert на случай, если retrieval latency начинает влиять на generation выше допустимого.
5. Критерии приемки (Definition of Done)
- В Grafana создан дашборд с графом зависимостей (минимум 3 узла: retrieval, context, generation).
- Граф отображает корреляцию между latency retrieval и generation latency (числовое значение и цвет).
- При нагрузочном тесте с изменением top_k или задержкой retrieval корреляция визуально меняется.
- Написан Python-скрипт, который вычисляет корреляцию Пирсона/Спирмена и выводит результат в консоль.
- Создан Prometheus alert для превышения порога корреляции > 0.7 с лагом < 30 секунд.
- Раздел "Root cause" в отчёте содержит однозначный вывод, какой компонент является узким местом.
- Время от запуска дашборда до нахождения корня по графу не превышает 2 минут.
- Трассировки (spans) доступны в Jaeger/Tempo и показывают соответствие метрик.
6. Ожидаемый результат
Основной артефакт
- Дашборд Grafana (JSON-модель), содержащий граф зависимостей (Node Graph) и панель с cross-correlation.
Сопроводительные артефакты
- Python-ноутбук (Jupyter) с расчётом корреляций и построением графа через networkx.
- Скрипт
correlation_check.pyдля мониторинга и отправки alert. - Отчёт (markdown) с описанием смоделированного инцидента и найденного корня.
- Конфигурация Prometheus (prometheus.yml) с правилами записи (recording rules) для агрегированных метрик.
7. Возможные сложности и их решение
| Сложность | Решение |
|---|---|
| Метрики retrieval и generation имеют разную частоту дискретизации | Выполнить ресемплинг к общему временному шагу (агрегация средних за 1 минуту) |
| Нелинейная зависимость, корреляция Пирсона низкая | Использовать Spearman rank correlation; дополнительно проверить взаимную информацию |
| Лаг между cause и effect может быть переменным | Применить cross-correlation с поиском максимума по окну ±5 минут |
| Шум в данных (регулярные флуктуации) | Сгладить временные ряды скользящим средним (окно 3-5 точек) |
| Граф в Grafana требует метрик в формате Prometheus | Экспортировать рёбра графа через prometheus_client как Gauge с метками source, target, correlation |
| Некорректные данные при сбое индекса или кэша | Добавить health-чеки для Vector DB и LLM-сервера; исключать аномальные точки (outlier detection, IQR) |
8. Бюджет времени (оценка)
| Этап | Время |
|---|---|
| Этап 1: Сбор метрик и трассировок | 1.5 ч |
| Этап 2: Подготовка данных | 1 ч |
| Этап 3: Вычисление корреляций и граф | 2 ч |
| Этап 4: Поиск корня | 1 ч |
| Этап 5: Автоматизация (опционально) | 0.5 ч |
| Итого | 6 ч |
Примечание: для первого выполнения (с нуля) может потребоваться до 8 часов из-за настройки OpenTelemetry и Prometheus. Если инфраструктура уже готова — 4 часа.
9. Связанные вопросы из базы знаний
| Вопрос | Тема |
|---|---|
| 121 | Как инструментировать Python-приложение OpenTelemetry? |
| 122 | Основы PromQL: агрегация метрик |
| 135 | Настройка alerting в Prometheus |
| 210 | Визуализация графа в Grafana (Node Graph) |
| 215 | Cross-correlation временных рядов |
| 300 | Сбор трассировок с Jaeger |
| 340 | RAG-система: измерение latency по шагам |
| 455 | Spearman vs Pearson correlation |
| 500 | Мониторинг LLM-сервера (vLLM) |
| 612 | Load testing RAG с locust |
10. Чек-лист самопроверки
- Я развернул и настроил OpenTelemetry для всех ключевых этапов RAG-пайплайна.
- Я проверил, что метрики retrieval и generation latency имеют одинаковые метки (trace ID).
- Я выполнил ресемплинг и слияние временных рядов без потери данных.
- Я вычислил корреляцию Пирсона и Спирмена, получил статистически значимый результат (p < 0.05).
- Я построил граф зависимостей в Grafana и подтвердил, что при изменении retrieval latency граф визуально меняется.