English translation is not available yet. Showing Russian content.
Настроить regression test suite для AI-агента
ТЕХНИЧЕСКОЕ ЗАДАНИЕ: Настроить regression test suite для AI-агента
1. Цель задачи
Создать регрессионный набор тестов (regression test suite), состоящий из 100 golden кейсов, для автоматической проверки поведения AI-агента при каждом pull request. Тесты должны гарантировать, что внесённые изменения не ломают ключевые сценарии работы агента (ответы, вызовы инструментов, обработку ошибок). Автоматизировать запуск набора в CI и настроить блокировку PR при падении хотя бы одного теста.
Ключевой результат 100% успешное прохождение всех golden кейсов при каждом PR, полная автоматизация в Actions с фиксацией результатов.
2. Исходные данные
Перед началом необходимо иметь:
| Что нужно | Откуда взять |
|---|---|
| Код AI-агента (Python, LangChain/LlamaIndex и т.д.) | Репозиторий команды |
| Существующие тесты (если есть) | tests/ в репозитории |
| Описание сценариев, которые агент должен выполнять | Документация, user stories |
| Среда для запуска (Docker, conda env) | Dockerfile / requirements.txt |
| CI-система | GitHub Actions (или GitLab CI / Jenkins) |
| Доступ к LLM API (если агент их использует) | API-ключи в secrets CI |
Если нет готового агента — симулируем:
- Возьмите любой open-source проект на LangChain (например,
langchain-chatbotилиagent-qa). - Разверните его локально.
- Создайте 100 типовых запросов/команд на основе документации.
3. Технологический стек
| Компонент | Инструменты | Назначение |
|---|---|---|
| Тестовый фреймворк | pytest + pytest-xdist (для параллельного запуска) | Написание и выполнение тестов |
| Язык программирования | Python 3.11+ | Реализация тестов |
| Пакет для golden-тестов | pytest-custom-exit-code / собственный враппер | Управление ожидаемыми результатами |
| Оценка ответов | llm-as-judge (через pytest-langchain) или fuzzy matching | Проверка недетерминированных ответов |
| CI | GitHub Actions | Автоматический запуск на PR |
| Контейнеризация | Docker | Изолированное окружение |
| Отчётность | Allure / pytest-html / GitHub Actions Summary | Визуализация результатов |
4. Этапы выполнения
Этап 1: Сбор и формализация 100 golden кейсов (3–4 часа)
Действия
-
Составьте чек-лист типов сценариев
-
Для каждого кейса создайте запись в формате YAML или JSON:
golden_case: id: "GC-001" input: "Какая столица Франции?" expected_output: "Париж" check_type: exact # exact | contains | llm_judge | regex category: "qa" -
Сгруппируйте кейсы в файл golden_cases.yaml (или Excel / Google Sheets → конвертируйте).
Ожидаемый результат этапа Файл golden_cases.yaml (или golden_cases.json) со 100 структурированными записями.
Этап 2: Создание тестового фреймворка (4–6 часов)
Действия
-
Структурируйте директорию тестов
tests/ regression/ conftest.py test_golden_cases.py golden_cases.yaml evaluators.py # логика проверки utils.py # запуск агента, логирование -
Реализуйте в conftest.py фикстуру для запуска агента:
import pytest from src.agent import Agent # ваш агент @pytest.fixture(scope="session") def agent(): return Agent.from_config("config.yaml") # Вспомогательная функция для загрузки golden cases def load_golden_cases(path): with open(path, "r") as f: return yaml.safe_load(f)["golden_case"] -
Напишите
test_golden_cases.pyс параметризованным тестомfrom .conftest import load_golden_cases from .evaluators import check_result import pytest @pytest.mark.parametrize("case", load_golden_cases("golden_cases.yaml"), ids=lambda c: c["id"]) def test_golden_case(agent, case): result = agent.run(case["input"]) assert check_result(result, case) == True, \ f"Case {case['id']}: ожидал {case['expected_output']}, получил {result}" -
Реализуйте
evaluators.pyс разными типами проверки:def exact_match(result, expected): return result.strip() == expected.strip() def contains(result, expected): return expected in result def llm_judge(result, expected): # Используйте отдельную LLM (например, GPT-4-mini) для оценки prompt = f"Ответ: {result}\nОжидалось: {expected}\nВерно? (да/нет)" verdict = judge_llm.invoke(prompt) return "да" in verdict.lower()
Ожидаемый результат этапа Работающий набор тестов, который можно запустить локально командой pytest tests/regression/ -v.
Этап 3: Настройка CI для запуска на PR (1–2 часа)
Действия
-
Создайте файл
.github/workflows/regression.ymlname: Regression Tests on: pull_request: types: [opened, synchronize, reopened] jobs: test: 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 pip install pytest - name: Run regression tests run: pytest tests/regression/ --junitxml=report.xml - name: Publish test report if: always() uses: dorny/test-reporter@v1 with: name: Regression Results path: report.xml reporter: java-junit -
Настройте блокировку PR при падении стандартное поведение GitHub Actions — если шаг завершился с ошибкой, PR не может быть слит. Дополнительно можно добавить required checks в настройки веток.
-
Проверьте, что secrets (API-ключи) доступны в окружении CI.
Ожидаемый результат этапа При создании PR автоматически запускается pipeline, результаты отображаются в PR.
Этап 4: Обработка недетерминированных ответов и flaky-тестов (2–3 часа)
Действия
-
Добавьте retry-механизм для LLM-запросов
@pytest.mark.flaky(reruns=2) def test_golden_case(...)Или используйте pytest-rerunfailures.
-
Для llm_judge-проверок установите порог уверенности и логируйте неудачные кейсы.
-
Внедрите логирование всех ответов в CI-артефакты для пост-анализа.
Ожидаемый результат этапа Flaky-тесты сведены к минимуму, повторные прогоны автоматизированы.
Этап 5: Документирование и демонстрация (1 час)
Действия
- Напишите README с инструкцией
- Как добавить новый golden кейс
- Как запустить тесты локально
- Как интерпретировать отчеты
- Проведите демо для команды (или запишите видео).
Ожидаемый результат этапа README.md в корне тестовой директории, команда осведомлена о процессе.
5. Критерии приемки (Definition of Done)
- Файл golden_cases.yaml содержит ровно 100 тестовых кейсов с идентификаторами
GC-001…GC-100. - Все тесты можно запустить локально одной командой pytest tests/regression/.
- В репозитории настроен GitHub Actions workflow, запускающий тесты на каждый PR.
- После завершения прогона в PR отображается отчёт (Allure или JUnit).
- PR блокируется для слияния, если хотя бы один тест упал (требуется required check).
- Для LLM-зависимых кейсов используется метод
llm_judge, а не строгое сравнение. - Тесты не требуют ручного ввода ключей — все secrets передаются через CI-переменные.
- README с инструкциями по добавлению кейсов и локальному запуску опубликован.
6. Ожидаемый результат
Основной артефакт Расширенный репозиторий с тестовой инфраструктурой.
Детальное содержание:
tests/regression/— директория с тестами- golden_cases.yaml — 100 кейсов
- conftest.py — фикстуры и загрузка
test_golden_cases.py— параметризованный тестevaluators.py— модуль проверокutils.py— вспомогательные функции
.github/workflows/regression.yml— CI pipeline- README.md с документацией
- Пример отчёта (скриншот или ссылка на успешный прогон)
Дополнительно (опционально):
- Интеграция с Slack/Telegram для уведомлений о падении.
7. Возможные сложности и их решение
| Сложность | Решение |
|---|---|
| Недетерминированность ответов LLM (одна и та же реплика может отличаться) | Использовать llm_judge — отдельную LLM для оценки адекватности ответа; задать порог уверенности > 80%. |
| Flaky тесты из-за тайм-аутов или сбоев API | Добавить retry (2–3 попытки) через pytest-rerunfailures; логировать каждый неудачный запрос. |
| Большое количество кейсов (100) замедляет CI | Распараллелить тесты с pytest-xdist -n auto; разбить на группы (QA, tools, edge) и запускать в отдельных jobs. |
| Зависимость от API-ключей в CI | Использовать GitHub Actions secrets; предусмотреть fallback (local mock) для pull request в форк. |
| Сложность поддержки golden кейсов (устаревают) | Ввести регулярный аудит раз в месяц; при каждом изменении агента обновлять ожидаемые результаты через полуавтоматический бенчмарк. |
8. Бюджет времени (оценка)
| Этап | Время |
|---|---|
| Этап 1: Сбор и формализация 100 golden кейсов | 3–4 ч |
| Этап 2: Создание тестового фреймворка | 4–6 ч |
| Этап 3: Настройка CI для запуска на PR | 1–2 ч |
| Этап 4: Обработка недетерминированных ответов и flaky | 2–3 ч |
| Этап 5: Документирование и демонстрация | 1 ч |
| Итого | 11–16 ч |
Примечание для первого раза может потребоваться дополнительное время на отладку pipeline и настройку секретов (≈2 ч). Предусмотрите буфер.
9. Связанные вопросы из базы знаний
| Вопрос | Тема |
|---|---|
| 42 | Как организовать CI/CD для ML-проектов? |
| 103 | Pytest-параметризация тестовых наборов данных |
| 204 | Использование LLM как judge для оценки ответов |
| 315 | Flaky-тесты в AI-системах: причины и борьба |
| 418 | Работа с секретами в GitHub Actions |
| 521 | Allure-отчёты для pytest |
| 627 | Стратегии регрессионного тестирования генеративных моделей |
| 733 | YAML-формат для конфигурации тестов |
| 840 | Docker-контейнеризация для воспроизводимости тестовой среды |
| 899 | Метрики покрытия для функциональных тестов агентов |
10. Чек-лист самопроверки
- Я создал и проверил файл golden_cases.yaml со 100 кейсами (все ID уникальны).
- Я запустил pytest tests/regression/ локально и убедился, что все тесты проходят (или я понимаю, почему падающие — это ожидаемо).
- Я настроил GitHub Actions workflow и увидел, что при открытии PR тесты запускаются.
- Я добавил необходимые secrets в репозиторий (API keys, если требуются).
- Я написал README и удостоверился, что другой разработчик может добавить новый кейс за 5 минут.