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

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

  1. Возьмите любой open-source проект на LangChain (например, langchain-chatbot или agent-qa).
  2. Разверните его локально.
  3. Создайте 100 типовых запросов/команд на основе документации.

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

КомпонентИнструментыНазначение
Тестовый фреймворкpytest + pytest-xdist (для параллельного запуска)Написание и выполнение тестов
Язык программированияPython 3.11+Реализация тестов
Пакет для golden-тестовpytest-custom-exit-code / собственный врапперУправление ожидаемыми результатами
Оценка ответовllm-as-judge (через pytest-langchain) или fuzzy matchingПроверка недетерминированных ответов
CIGitHub ActionsАвтоматический запуск на PR
КонтейнеризацияDockerИзолированное окружение
ОтчётностьAllure / pytest-html / GitHub Actions SummaryВизуализация результатов

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

Этап 1: Сбор и формализация 100 golden кейсов (3–4 часа)

Действия

  1. Составьте чек-лист типов сценариев

    • Простые вопрос-ответ (30 кейсов)
    • Многошаговые диалоги (20 кейсов)
    • Вызов инструментов (API, поиск, DB) (20 кейсов)
    • Краевые случаи (empty input, длинный контекст, ошибки LLM) (20 кейсов)
    • Сценарии с ожидаемым отказом (10 кейсов)
  2. Для каждого кейса создайте запись в формате YAML или JSON:

    golden_case:
      id: "GC-001"
      input: "Какая столица Франции?"
      expected_output: "Париж"
      check_type: exact  # exact | contains | llm_judge | regex
      category: "qa"
    
  3. Сгруппируйте кейсы в файл golden_cases.yaml (или Excel / Google Sheets → конвертируйте).

Ожидаемый результат этапа Файл golden_cases.yaml (или golden_cases.json) со 100 структурированными записями.


Этап 2: Создание тестового фреймворка (4–6 часов)

Действия

  1. Структурируйте директорию тестов

    tests/
      regression/
        conftest.py
        test_golden_cases.py
        golden_cases.yaml
        evaluators.py  # логика проверки
        utils.py       # запуск агента, логирование
    
  2. Реализуйте в 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"]
    
  3. Напишите 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}"
    
  4. Реализуйте 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 часа)

Действия

  1. Создайте файл .github/workflows/regression.yml

    name: 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
    
  2. Настройте блокировку PR при падении стандартное поведение GitHub Actions — если шаг завершился с ошибкой, PR не может быть слит. Дополнительно можно добавить required checks в настройки веток.

  3. Проверьте, что secrets (API-ключи) доступны в окружении CI.

Ожидаемый результат этапа При создании PR автоматически запускается pipeline, результаты отображаются в PR.


Этап 4: Обработка недетерминированных ответов и flaky-тестов (2–3 часа)

Действия

  1. Добавьте retry-механизм для LLM-запросов

    @pytest.mark.flaky(reruns=2)
    def test_golden_case(...)
    

    Или используйте pytest-rerunfailures.

  2. Для llm_judge-проверок установите порог уверенности и логируйте неудачные кейсы.

  3. Внедрите логирование всех ответов в CI-артефакты для пост-анализа.

Ожидаемый результат этапа Flaky-тесты сведены к минимуму, повторные прогоны автоматизированы.


Этап 5: Документирование и демонстрация (1 час)

Действия

  1. Напишите README с инструкцией
    • Как добавить новый golden кейс
    • Как запустить тесты локально
    • Как интерпретировать отчеты
  2. Проведите демо для команды (или запишите видео).

Ожидаемый результат этапа README.md в корне тестовой директории, команда осведомлена о процессе.


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

  • Файл golden_cases.yaml содержит ровно 100 тестовых кейсов с идентификаторами GC-001GC-100.
  • Все тесты можно запустить локально одной командой pytest tests/regression/.
  • В репозитории настроен GitHub Actions workflow, запускающий тесты на каждый PR.
  • После завершения прогона в PR отображается отчёт (Allure или JUnit).
  • PR блокируется для слияния, если хотя бы один тест упал (требуется required check).
  • Для LLM-зависимых кейсов используется метод llm_judge, а не строгое сравнение.
  • Тесты не требуют ручного ввода ключей — все secrets передаются через CI-переменные.
  • README с инструкциями по добавлению кейсов и локальному запуску опубликован.

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

Основной артефакт Расширенный репозиторий с тестовой инфраструктурой.

Детальное содержание:

  • tests/regression/ — директория с тестами
  • .github/workflows/regression.yml — CI pipeline
  • README.md с документацией
  • Пример отчёта (скриншот или ссылка на успешный прогон)

Дополнительно (опционально):


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 для запуска на PR1–2 ч
Этап 4: Обработка недетерминированных ответов и flaky2–3 ч
Этап 5: Документирование и демонстрация1 ч
Итого11–16 ч

Примечание для первого раза может потребоваться дополнительное время на отладку pipeline и настройку секретов (≈2 ч). Предусмотрите буфер.


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

ВопросТема
42Как организовать CI/CD для ML-проектов?
103Pytest-параметризация тестовых наборов данных
204Использование LLM как judge для оценки ответов
315Flaky-тесты в AI-системах: причины и борьба
418Работа с секретами в GitHub Actions
521Allure-отчёты для pytest
627Стратегии регрессионного тестирования генеративных моделей
733YAML-формат для конфигурации тестов
840Docker-контейнеризация для воспроизводимости тестовой среды
899Метрики покрытия для функциональных тестов агентов

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

  • Я создал и проверил файл golden_cases.yaml со 100 кейсами (все ID уникальны).
  • Я запустил pytest tests/regression/ локально и убедился, что все тесты проходят (или я понимаю, почему падающие — это ожидаемо).
  • Я настроил GitHub Actions workflow и увидел, что при открытии PR тесты запускаются.
  • Я добавил необходимые secrets в репозиторий (API keys, если требуются).
  • Я написал README и удостоверился, что другой разработчик может добавить новый кейс за 5 минут.