English translation is not available yet. Showing Russian content.
Интегрировать тестирование в CI/CD
ТЕХНИЧЕСКОЕ ЗАДАНИЕ: Интегрировать тестирование в CI/CD
1. Цель задачи
Разработать и внедрить процесс автоматизированного тестирования AI-агента, который выполняется при каждом Pull Request. Настроить quality gates — пороговые метрики, при падении которых PR блокируется. В результате команда получает CI/CD pipeline, гарантирующий стабильное качество основного сценария агента перед мержем.
Ключевой результат Pipeline в Actions (или аналоге), который при каждом PR запускает тесты агента, сравнивает метрики с порогами и блокирует мерж при их падении.
2. Исходные данные
| Что нужно | Откуда взять |
|---|---|
| Репозиторий с кодом AI-агента (любой агент на LangGraph / LangChain / custom) | Собственный пет-проект, Pet 221 (RAG-агент), или учебный репозиторий |
| Тестовые сценарии (не менее 3-х) | Реальные примеры запросов + эталонные ответы (вручную или синтезированные) |
| CI-система с доступом к репозиторию | GitHub Actions, GitLab CI, Jenkins — предпочтительно GitHub Actions |
| Базовые метрики агента (pass rate, latency, cost) | Запуск тестов на main ветке до изменений |
| Docker / Python окружение для воспроизведения | Dockerfile или requirements.txt |
Если нет реального агента — симулируем:
- Создать минимального RAG-агента на LangChain: retriever (FAISS с тестовыми документами) + LLM (любая дешёвая модель, например gpt-3.5-turbo или локальная через Ollama).
- Подготовить 10 тестовых вопросов с эталонными ответами (txt/csv).
- Опубликовать репозиторий на GitHub.
3. Технологический стек
| Компонент | Инструменты | Назначение |
|---|---|---|
| CI/CD | GitHub Actions | Автоматический запуск тестов на PR |
| Тестовый фреймворк | pytest + pytest-cov | Написание и выполнение тестов |
| Метрики качества | RAGAS (или самописные: точность ответа, latency) | Оценка ответов агента |
| Оркестрация агента | LangChain / LangGraph | Основной код агента |
| Векторное хранилище | FAISS (тестовая in-memory) | Retrieval для тестов |
| LLM | Ollama (llama3 8B) или OpenAI | Генерация ответов |
| Докеризация | Docker + docker-compose | Изолированный запуск в CI |
| Quality gates | Скрипт проверки метрик (Python) | Сравнение с порогами |
4. Этапы выполнения
Этап 1: Подготовка тестового окружения и репозитория (1 час)
Действия
- Форкнуть или создать репозиторий с кодом агента. Убедиться, что проект собирается локально (pip install -r requirements.txt).
- Добавить конфигурацию Docker
- Dockerfile с Python 3.11, установкой зависимостей, копированием кода.
- docker-compose.yml для запуска тестов (опционально – с LLM через Ollama).
- Создать папку
tests/с файлом conftest.py для фикстур (агент, тестовые данные). - Зафиксировать baseline-метрики
Ожидаемый результат этапа Рабочее Docker-окружение, структура тестов, baseline-метрики.
Этап 2: Написание тестов для агента (2-3 часа)
Действия
-
Unit-тесты компонентов
test_retriever.py— проверка, что retriever возвращает не менее K документов на тестовый запрос.test_llm.py— проверка, что LLM не возвращает пустой ответ.test_agent.py— проверка корректной маршрутизации (если используется router).
-
Интеграционные тесты
test_full_flow.py— запуск агента на заранее подготовленных 10 вопросах, сравнение ответов с эталонными или оценка через RAGAS.
-
Написание тестов с использованием pytest
# example test_full_flow.py import pytest from agent import Agent from metrics import compute_accuracy, compute_latency TEST_QUESTIONS = [...] # 10 вопросов EXPECTED_ANSWERS = [...] # эталонные ответы @pytest.fixture def agent(): return Agent() def test_accuracy(agent): correct = 0 for q, a in zip(TEST_QUESTIONS, EXPECTED_ANSWERS): response = agent.run(q) if similarity(response, a) > 0.7: # порог для ручной проверки correct += 1 accuracy = correct / len(TEST_QUESTIONS) assert accuracy >= 0.6, f"Accuracy {accuracy} < 0.6" def test_latency(agent): latencies = [] for q in TEST_QUESTIONS: t0 = time.time() agent.run(q) latencies.append(time.time() - t0) avg_latency = sum(latencies) / len(latencies) assert avg_latency <= 5.0, f"Avg latency {avg_latency} > 5.0s" -
Добавить тесты на безопасность (опционально):
- Проверка, что агент не выдает запрещённые ответы (фильтр токсичности).
Ожидаемый результат этапа Пакет тестов, которые проходят на baseline (main) и могут быть запущены через pytest.
Этап 3: Реализация quality gates (1 час)
Действия
-
Создать скрипт
quality_gate.py -
Пороги (пример):
-
- Использовать pytest.ini с настройками.
- В conftest.py добавить хуки для сбора метрик в JSON.
Ожидаемый результат этапа Скрипт, который можно запустить после тестов и получить результат «proceed» или «block».
Этап 4: Настройка CI/CD pipeline (2 часа)
Действия
-
Создать
.github/workflows/test_on_pr.ymlname: PR Tests & Quality Gates on: pull_request: branches: [ main ] jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Build Docker image run: docker build -t agent-test . - name: Run tests run: docker run --rm agent-test pytest tests/ --json-report=report.json - name: Upload test report uses: actions/upload-artifact@v4 with: name: test-report path: report.json - name: Check quality gates run: docker run --rm agent-test python quality_gate.py --report report.json # quality_gate.py вернёт exit 1 → PR будет помечен как failed -
Добавить защиту ветки main (branch protection):
-
Проверить pipeline на реальном PR
- Создать ветку с намеренным ухудшением (например, уменьшить количество документов в retriever).
- Убедиться, что тесты падают, quality gate блокирует, PR не мержится.
Ожидаемый результат этапа Работающий pipeline, блокирующий PR при падении тестов или выходе метрик за порог.
Этап 5: Документация и демонстрация (1 час)
Действия
-
Написать README.md в репозитории с описанием:
- Как запустить тесты локально.
- Какие quality gates настроены.
- Скриншот успешного и неуспешного PR.
-
Создать небольшой слайд (или раздел в wiki) для команды: цель, метрики, процесс.
-
Зафиксировать артефакты
- Baseline метрики.
- Пример отчёта с падением.
Ожидаемый результат этапа Документированный процесс, готовый к использованию.
5. Критерии приемки (Definition of Done)
- Pipeline запускается на каждый PR в main и на каждый push в PR.
- Тесты включают как unit, так и интеграционные (не менее 3).
- Quality gates проверяют как минимум: точность ответов и среднюю задержку.
- При падении любого теста или выходе метрики за порог PR получает статус failed.
- Настроена защита ветки main: требуется успешный статус pipeline.
- Документация (README) описывает, как добавить новый тест или изменить порог.
- Baseline-метрики зафиксированы в репозитории.
- Pipeline выполняется менее чем за 10 минут (с учётом загрузки модели/докера).
- Все тесты проходят на ветке main.
- В репозитории есть файл
quality_gate.pyс читаемыми порогами.
6. Ожидаемый результат
Основной артефакт Репозиторий с кодом агента и настроенным CI/CD pipeline.
- Файл
.github/workflows/test_on_pr.yml. - Папка
tests/с тестами. - Файл
quality_gate.py. - Файл
baseline.json. - README.md с инструкцией.
Дополнительно Демонстрация, что PR с плохим кодом блокируется, а хороший — проходится.
7. Возможные сложности и их решение
| Сложность | Решение |
|---|---|
| LLM модель недоступна в CI (требует API ключ) | Использовать локальную модель через Ollama в Docker. Или мокировать LLM в тестах. |
| Долгий запуск (скачивание модели) | Закешировать Docker слои с моделью; использовать cache: actions/cache для Ollama. |
| Метрики субъективны (точность ответа) | Использовать LLM-as-judge (например, GPT-4 оценивает ответ) или метрики RAGAS. |
| Flaky тесты из-за недетерминизма LLM | Зафиксировать seed/температуру=0; использовать deterministic модели (например, local small model). |
| Пороги quality gates устаревают | Baseline обновлять после каждого успешного мержа (commit baseline.json с новыми значениями). |
8. Бюджет времени (оценка)
| Этап | Время |
|---|---|
| Этап 1: Подготовка окружения | 1 час |
| Этап 2: Написание тестов | 2-3 часа |
| Этап 3: Quality gates | 1 час |
| Этап 4: CI/CD pipeline | 2 часа |
| Этап 5: Документация | 1 час |
| Итого | 7-8 часов |
Примечание: для первого раза может потребоваться до 10 часов из-за отладки инфраструктуры Docker/GitHub Actions.
9. Связанные вопросы из базы знаний
| Вопрос | Тема |
|---|---|
| 157 | Интеграция тестирования в CI/CD (данная задача) |
| 12 | Как написать assert для метрик качества ответа |
| 38 | Настройка GitHub Actions для Python проекта |
| 41 | Использование Docker в CI для воспроизводимости |
| 89 | Что такое quality gates и как их настроить |
| 103 | Оценка качества RAG-агента (RAGAS) |
| 144 | Лучшие практики тестирования LLM-агентов |
| 215 | Защита веток в GitHub (branch protection) |
| 301 | Mocking LLM в тестах |
| 442 | Подходы к детерминированному тестированию |
10. Чек-лист самопроверки
- Я подключил репозиторий к CI и настроил триггер на PR.
- Написал хотя бы 3 теста, включая интеграционный, и они проходят локально.
- Скрипт quality_gate.py корректно завершается с exit 1 при плохих метриках.
- В .github/workflows/ есть корректный YAML, и pipeline запустился на тестовом PR.
- Ветка main защищена: требуется статус pipeline перед мержем.
- README содержит как минимум команды для локального запуска тестов.
- Файл baseline.json закоммичен и соответствует реальным метрикам на main.
- Поменял код так, чтобы тест упал, — pipeline действительно заблокировал PR.
- Pipeline не превышает лимит времени выполнения (10 минут).