Полная платформа для оценки RAG

ТЕХНИЧЕСКОЕ ЗАДАНИЕ: Полная платформа для оценки RAG

1. Цель задачи

Разработать production-ready платформу для автоматической оценки RAG-систем (Retrieval-Augmented Generation) с использованием библиотеки RAGAS. Платформа должна предоставлять единую точку запуска оценки («одна кнопка»), визуализировать метрики через дашборд, интегрироваться в CI/CD пайплайн и отправлять алерты при падении метрик ниже порога. Результатом станет воспроизводимый конвейер, который можно встроить в мониторинг любого RAG-проекта.

Ключевой результат Рабочий Docker-контейнер (или docker-compose), запускающий полный пайплайн оценки RAG из одного скрипта и отображающий историю метрик в Grafana с алертами в Telegram.

2. Исходные данные

Что нужноОткуда взять
Датасет для оценки RAG (вопросы, контексты, ответы)Сгенерировать синтетически с помощью LLM (например, через OpenAI API) или использовать открытые датасеты (например, fiqa, nq из ragas.datasets)
Эмбеддинг-модель для пайплайна RAGИспользовать sentence-transformers/all-MiniLM-L6-v2 (открытая) или ada-002 (платная)
RAG-система для оценкиВзять простую LangChain цепочку «RetrievalQA» с FAISS и HuggingFace LLM (или OpenAI GPT-3.5)
Документы для корпусаДо 20 текстовых файлов (например, статьи из интернета о RAG) — скачать или написать вручную
Telegram Bot TokenСоздать бота через @BotFather и получить токен

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

  1. Для LLM без API использовать Ollama с моделью llama3:8b (локально).
  2. Для эмбеддингов — Ollama или fastembed.
  3. Вместо полноценного CI/CD (GitLab/Jenkins) — GitHub Actions с триггером по push или cron.
  4. Для дашборда Grafana — поднять в docker-compose вместе с InfluxDB или Prometheus (использовать pushgateway для метрик).

3. Технологический стек

КомпонентИнструментыНазначение
Оценка RAGRAGAS, LangChain, HuggingFace HubРасчёт метрик: faithfulness, relevancy, context precision, answer correctness
RAG-системаLangChain, FAISS, Ollama (LLM + embeddings)Сборка и запуск пайплайна
Хранение метрикInfluxDB 2.x / TimescaleDB / SQLite + Prometheus PushgatewayХранение временных рядов результатов оценки
ВизуализацияGrafana (подключена к InfluxDB)Дашборд с историей метрик, порогами
АлертыGrafana AlertingTelegram (через webhook/бот)Уведомления при снижении метрик ниже заданного уровня
CI/CDGitHub ActionsАвтоматический запуск при пушах в main или по расписанию
КонтейнеризацияDocker + docker-composeУпаковка всех сервисов

4. Этапы выполнения

Этап 1: Подготовка инфраструктуры и датасета (оценка: 1 день)

Действия

  1. Создать репозиторий rag-eval-platform с README и структурой папок:
    rag-eval-platform/
    ├── docker-compose.yml
    ├── eval_pipeline/
    │   ├── __init__.py
    │   ├── rag_pipeline.py
    │   ├── eval_runner.py
    │   ├── metrics_sender.py
    │   └── config.yaml
    ├── data/
    │   ├── documents/ (исходные тексты)
    │   ├── generated_testset.parquet
    │   └── results/
    ├── grafana/ (дашборды, provisioning)
    ├── alerts/ (templates)
    └── .github/workflows/eval.yml
    
  2. Написать скрипт generate_testset.py, который:
    • Загружает корпус из data/documents/ (произвольные .txt файлы).
    • Использует RAGAS TestsetGenerator с OpenAI (или Ollama) для генерации 20-30 пар вопрос-ответ-контекст.
    • Сохраняет результат в data/generated_testset.parquet.
    • Если нет доступа к OpenAI — использует Ollama с моделью llama3:8b через LangChain и RAGAS (поддерживает кастомный LLM).
  3. Создать config.yaml с настройками:
    llm:
      provider: ollama
      model_name: llama3:8b
      temperature: 0.2
    embeddings:
      provider: ollama
      model_name: nomic-embed-text
    rag:
      chunk_size: 512
      chunk_overlap: 50
      top_k: 3
    evaluation:
      metrics: ["faithfulness", "answer_relevancy", "context_precision"]
      threshold_faithfulness: 0.7
      threshold_relevancy: 0.8
    alerts:
      telegram_bot_token: "YOUR_TOKEN"
      chat_id: "YOUR_CHAT_ID"
    
  4. Написать rag_pipeline.py с классом SimpleRAG:
    • Загрузка документов, разделение на чанки, индексация FAISS.
    • Метод answer(question) -> dict{"question", "answer", "contexts"}.
    • Использовать Ollama LLM и Ollama embeddings.
  5. Проверить, что rag_pipeline.answer("Что такое RAG?") возвращает осмысленный ответ.

Ожидаемый результат этапа

  • Сгенерированный тестовый набор generated_testset.parquet (20+ записей).
  • Рабочий класс SimpleRAG в rag_pipeline.py.
  • Корневая структура проекта с config.yaml.

Этап 2: Пайплайн оценки с RAGAS и отправка метрик (оценка: 1 день)

Действия

  1. Реализовать eval_runner.py:
    • Загружает датасет и конфиг.
    • Для каждого примера вызывает rag_pipeline.answer.
    • Передаёт вопросы, ответы и контексты в RAGAS Dataset и запускает evaluate() с выбранными метриками.
    • Важно Для метрик context_precision и answer_relevancy RAGAS требует LLM — передать тот же Ollama через langchain_community.chat_models.ChatOllama.
    • Результаты сохраняет в data/results/ с меткой времени (YYYY-MM-DD_HH-MM-SS.json).
  2. Написать metrics_sender.py:
    • Читает результаты оценки.
    • Формирует метрики в формате prometheus_client или напрямую в InfluxDB line protocol.
    • Отправляет через HTTP POST на pushgateway (если Prometheus) или в InfluxDB через influxdb_client.
    • Пример метрик:
      rag_faithfulness{run_id="2025-04-01_10-00"} 0.85
      rag_answer_relevancy{run_id="2025-04-01_10-00"} 0.78
      
  3. Объединить этапы в единый скрипт run_eval.sh или run_eval.py (одна команда — вся оценка):
    python eval_runner.py && python metrics_sender.py
    
  4. Протестировать локально: запустить оценку, проверить появление файла в results/ и отображение метрик в InfluxDB (через UI localhost:8086).

Ожидаемый результат этапа

  • eval_runner.py и metrics_sender.py.
  • Результат оценки в data/results/.
  • Метрики появились в InfluxDB (проверить через influx query).

Этап 3: Дашборд в Grafana и алерты (оценка: 1 день)

Действия

  1. Настроить docker-compose.yml с сервисами:
    • influxdb (образ influxdb:2.7, проброс порта 8086, volume для данных).
    • grafana (образ grafana/grafana:latest, порт 3000, volume для provisioning).
    • pushgateway (если используете Prometheus) — опционально.
  2. Создать конфиг provisioning для Grafana (grafana/provisioning/datasources/influxdb.yml):
    apiVersion: 1
    datasources:
      - name: InfluxDB
        type: influxdb
        access: proxy
        url: http://influxdb:8086
        secureJsonData:
          token: my-super-secret-token
    
  3. Создать дашборд в JSON (grafana/dashboards/rag_eval.json):
    • Панели: временные ряды faithfulness, answer_relevancy, context_precision (среднее за каждый запуск).
    • Статистики: текущее значение, минимальное, максимальное.
    • Thresholds на каждой панели (например, красная линия на 0.7).
  4. Настроить алерты:
    • В Grafana Alerting создать правило: avg by (run_id) (rag_faithfulness) < 0.7 → оценка каждые 5 минут.
    • Contact point: Telegram через бот (настроить через grafana/provisioning/alerting/ или вручную).
    • Проверить отправку уведомления в Telegram при падении метрики.
  5. Перезапустить docker-compose up -d, импортировать дашборд через API (или через файл provisioning).

Ожидаемый результат этапа

  • Работающий дашборд в Grafana с историей метрик после нескольких запусков оценки.
  • Алерт в Telegram при падении faithfulness ниже 0.7.

Этап 4: CI/CD и автоматизация (оценка: 1 день)

Действия

  1. Создать GitHub Actions workflow .github/workflows/eval.yml:
    name: RAG Evaluation
    on:
      push:
        branches: [ main ]
      schedule:
        - cron: '0 2 * * 1' # каждый понедельник в 2:00
    jobs:
      evaluate:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v4
          - name: Set up Python
            uses: actions/setup-python@v5
            with:
              python-version: '3.11'
          - name: Install dependencies
            run: |
              pip install -r requirements.txt
          - name: Run RAG evaluation
            run: |
              python run_all.py
          - name: Upload results
            uses: actions/upload-artifact@v4
            with:
              name: eval-results
              path: data/results/
    
  2. Внести изменения, чтобы скрипт run_all.py (единая точка входа) проверял переменные окружения для токенов и запускал всю цепочку: генерация тестового набора (если нет), запуск RAG, оценка, отправка метрик.
  3. Добавить шаг в workflow: после оценки отправить уведомление в Telegram о завершении и сводку метрик (через curl или Python скрипт).
  4. Настроить секреты репозитория:
    • TELEGRAM_BOT_TOKEN
    • TELEGRAM_CHAT_ID
    • INFLUX_TOKEN (для отправки метрик из CI, если InfluxDB развёрнут удалённо или в том же docker-compose на сервере).
  5. Протестировать: сделать push в main -> проверить, что workflow запустился, результаты оценки загружены в артефакты, метрики появились в Grafana (если сервер доступен).

Ожидаемый результат этапа

  • GitHub Action, автоматически запускающий оценку на каждый push (или по расписанию).
  • Метрики попадают в InfluxDB, алерты работают.
  • Артефакты с результатами сохраняются.

Этап 5: Интеграция «одной кнопки» и финальное тестирование (оценка: 0.5 дня)

Действия

  1. Создать файл run_all.py (главный скрипт):
    #!/usr/bin/env python3
    """One button: запуск всей оценки RAG."""
    from eval_pipeline.rag_pipeline import SimpleRAG
    from eval_pipeline.eval_runner import run_evaluation
    from eval_pipeline.metrics_sender import send_metrics
    
    if __name__ == "__main__":
        rag = SimpleRAG()
        results = run_evaluation(rag)
        send_metrics(results)
        print("Evaluation completed. Check Grafana.")
    
  2. Убедиться, что для запуска нужна только команда python run_all.py (при условии запущенных сервисов InfluxDB, Ollama и т.д.).
  3. Добавить Makefile с целью eval:
    .PHONY: eval
    eval:
    	docker compose up -d influxdb grafana
    	@echo "Waiting for services..."
    	@sleep 10
    	python run_all.py
    
  4. Протестировать полный цикл на чистой машине (локально или в GitHub Codespaces):
    • Выполнить make eval.
    • Проверить логи, отсутствие ошибок.
    • Открыть Grafana (localhost:3000) и убедиться, что появились новые данные.
    • Сознательно снизить качество RAG (например, уменьшить top_k до 1) — запустить повторно, убедиться, что метрики упали и пришёл алерт в Telegram.
  5. Дополнительно: добавить раздел в README «Quick Start» с одной командой запуска.

Ожидаемый результат этапа

  • Финальная версия run_all.py + Makefile.
  • Подтверждение, что вся система запускается одной командой и работает корректно.
  • README с инструкциями.

5. Критерии приемки (Definition of Done)

  • Сгенерирован тестовый набор размером не менее 20 примеров.
  • RAG-пайплайн использует локальный LLM (Ollama) — никаких внешних API, кроме возможно Telegram.
  • run_all.py (или make eval) успешно выполняется и выводит в лог итоговые метрики.
  • Метрики (faithfulness, answer_relevancy, context_precision) записаны в InfluxDB.
  • В Grafana создан дашборд, отображающий временной ряд каждой метрики с пороговыми линиями.
  • Настроено алертное правило в Grafana, и при падении faithfulness ниже 0.7 приходит сообщение в Telegram.
  • GitHub Actions workflow запускает оценку при каждом пуше в main; артефакты с результатами загружены.
  • Весь проект упакован в docker-compose: docker compose up -d поднимает InfluxDB, Grafana, и после ручного запуска скрипта метрики попадают в БД.
  • В README описан quick start: git clone ... && cd ... && make eval.
  • Код покрыт комментариями на английском, есть docstrings для ключевых функций.

6. Ожидаемый результат

Основной артефакт
Репозиторий rag-eval-platform со структурой, указанной в Этапе 1, содержащий:

  • docker-compose.yml и конфиги для InfluxDB/Grafana.
  • Пайплайн оценки (eval_pipeline/).
  • Готовый тестовый набор generated_testset.parquet.
  • Пример дашборда в Grafana (provisioning).
  • GitHub Actions workflow.
  • README с инструкцией и мета-информацией.

Опционально (при желании):

  • Скрипты для A/B сравнения разных RAG-конфигураций.
  • Web UI на Streamlit для ручного запуска (ещё одна «кнопка»).
  • Экспорт отчёта в PDF.

7. Возможные сложности и их решение

СложностьРешение
RAGAS не поддерживает локальные LLM (требует OpenAI)Использовать кастомный langchain LLM с ChatOllama; передать его в evaluate через llm=.... Обновить RAGAS до версии 0.2+.
InfluxDB + Grafana через Docker — путаница с сетямиОбъединить все сервисы в одной сети в docker-compose.yml, прописать имена сервисов вместо localhost.
GitHub Actions не может обратиться к локальному InfluxDBРазвернуть InfluxDB как сервис в workflow (services.influxdb) или использовать pushgateway и внешний сервер. В ТЗ — InfluxDB в CI не обязателен, можно только как демонстрация.
LLM слишком медленный для CI (Ollama)Ограничить датасет 5-10 примерами в CI, оставив полный датасет для локального запуска. Использовать --dataset-split параметр.
Telegram алерты не приходятПроверить правильность токена и chat_id, убедиться, что бот может отправлять сообщения (написать боту /start). Использовать requests.get для теста.

8. Бюджет времени (оценка)

ЭтапВремя (человеко-дни)
1. Подготовка инфраструктуры и датасета1
2. Пайплайн оценки с RAGAS и отправка метрик1
3. Дашборд в Grafana и алерты1
4. CI/CD и автоматизация1
5. Интеграция «одной кнопки» и финальное тестирование0.5
Итого4.5

Примечание Для первого раза (без опыта с RAGAS и Grafana) время может увеличиться до 6-7 дней. Рекомендуется выделить дополнительный день на отладку.

9. Связанные вопросы из базы знаний

ВопросТема
42Как оценивать качество ответов LLM?
107RAGAS: метрики и их интерпретация
188Настройка Grafana + InfluxDB в Docker
223CI/CD для ML-проектов с GitHub Actions
305Работа с LangChain и Ollama локально
412Telegram Bot API: отправка сообщений через Python
518Синтетическая генерация датасетов для RAG
634Docker compose для ML-сервисов
771Алертинг в Grafana: threshold rules
889Prometheus Pushgateway для метрик от batch-задач

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

  • Я сгенерировал тестовый набор и проверил его корректность (вопросы осмысленны, ответы есть в документах).
  • RAG-пайплайн работает без ошибок, возвращает ответы даже для сложных вопросов.
  • RAGAS использует ту же LLM и эмбеддинги, что и RAG-пайплайн (консистентность).
  • Метрики записываются в InfluxDB с правильными тегами (run_id, timestamp).
  • При запуске make eval или python run_all.py не возникает ошибок импорта или отсутствующих файлов.
  • Дашборд в Grafana визуализирует минимум 3 метрики, пороги отмечены линиями.
  • Алерт срабатывает при ручном снижении качества RAG (например, удаление контекста).
  • GitHub Actions workflow успешно выполнялся хотя бы один раз.
  • Весь код закоммичен, в репозитории нет больших файлов (кроме .parquet <10MB).
  • README содержит чёткие шаги для воспроизведения, включая список переменных окружения.