中文翻译暂不可用,显示俄语原文。
Настроить regression testing промптов
ТЕХНИЧЕСКОЕ ЗАДАНИЕ: Настроить regression testing промптов
1. Цель задачи
Настроить автоматическое регрессионное тестирование для промптов, используемых в LLM-приложении. Создать golden set из 100 пар «запрос → эталонный ответ» и внедрить CI-пайплайн, который при каждом изменении промпта (или конфигурации модели) запускает тесты и гарантирует, что ответы LLM не изменились (или не деградировали) относительно эталона.
Ключевой результат При любом коммите, затрагивающем файлы с промптами или параметры генерации, в CI запускается набор тестов, который должен пройти с успешностью 100% — все ответы на golden set точно совпадают с эталонными (exact match или эквивалентность с заданным порогом). В случае несовпадения пайплайн падает, и команда получает уведомление.
2. Исходные данные
| Что нужно | Откуда взять |
|---|---|
| Рабочее LLM-приложение с промптами (Python, LangChain, OpenAI API, или кастомное) | Существующий проект / pet-проект |
| Список из 100 разнообразных запросов (представительный для домена) | Ручной сбор + аугментация / синтез |
| Эталонные ответы для каждого запроса (сгенерированы один раз и проверены вручную) | Однократная генерация при фиксированной модели и seed=0 |
| CI/CD-система (GitHub Actions, GitLab CI, Jenkins) | Репозиторий проекта |
| Python 3.10+ | Система разработки |
Если нет реального приложения — симулируем:
- Создаём простой Python-скрипт
prompt_engine.py, который принимает строку запроса и заданный шаблон промпта, вызывает LLM (openai / mock), возвращает ответ. - В качестве модели используем OpenAI GPT-4-mini (или любой доступный endpoint). Если нет ключа — используем симуляцию: возвращаем фиксированный ответ для каждого запроса из golden set (так регрессия станет абсолютной). Для учебных целей допускается mock.
- Разворачиваем репозиторий на GitHub, настраиваем Actions.
3. Технологический стек
| Компонент | Инструменты | Назначение |
|---|---|---|
| Тестовый фреймворк | pytest + pytest-json | Запуск тестов, сериализация результатов |
| Golden set | JSON-файл (100 записей: {"query": ..., "expected": ...}) | Хранение эталонных пар |
| CI-пайплайн | GitHub Actions / GitLab CI | Автоматический запуск тестов при каждом изменении |
| Сравнение ответов | difflib.SequenceMatcher или rouge-score (exact match при seed=0) | Детерминированное сравнение строк |
| Управление зависимостями | pip + requirements.txt или poetry | Фиксация версий библиотек |
| Линтер/форматтер | black, flake8 (опционально) | Единый стиль кода |
4. Этапы выполнения
Этап 1: Формирование golden set (2–3 часа)
Действия
- Составить 100 запросов, покрывающих все типичные сценарии: короткие/длинные, простые/сложные, краевые случаи (пустой запрос, очень длинный контекст, нецензурная лексика, переключение языка и т.д.). Записать в файл
golden_set_inputs.txt(по одному запросу на строку). - Сгенерировать эталонные ответы — запустить текущий
prompt_engine.pyсо всеми запросами при температура=0, seed=42, фиксированном системном сообщении. Ответы сохранить вgolden_set_expected.txt. - Валидировать ответы вручную (выборочно 5–10 штук) — убедиться, что они осмысленны и соответствуют ожиданиям. При необходимости подкорректировать запросы или ответы.
- Сформировать итоговый JSON-файл
golden_set.json:
[
{
"id": 1,
"query": "What is the capital of France?",
"expected": "The capital of France is Paris."
},
...
]
Ожидаемый результат этапа Файл golden_set.json из 100 записей, готовых к использованию в тестах.
Этап 2: Разработка тестового фреймворка (2–3 часа)
Действия
- Создать структуру репозитория
tests/ conftest.py test_regression.py golden_set.json requirements.txt .github/workflows/regression.yml prompt_engine.py - Написать conftest.py — фикстуру, загружающую golden_set.json и возвращающую список тестовых случаев.
- Написать test_regression.py:
import json
import pytest
from prompt_engine import generate_answer # функция, которая принимает query, возвращает ответ
def load_golden_set():
with open("golden_set.json", "r") as f:
return json.load(f)
@pytest.mark.parametrize("case", load_golden_set(), ids=lambda c: c["id"])
def test_regression(case):
actual = generate_answer(case["query"], temperature=0, seed=42)
assert actual == case["expected"], f"Query {case['id']}: expected '{case['expected']}', got '{actual}'"
- Убедиться, что
generate_answerиспользует фиксированные параметры (seed, temperature) и ту же версию модели, что и при создании golden set. Если модель меняется, golden set должен обновляться отдельным процессом. - Запустить тесты локально —
pytest tests/ -v— все 100 должны пройти.
Ожидаемый результат этапа Набор тестов, успешно проходящий локально.
Этап 3: Интеграция в CI (1–2 часа)
Действия
- Создать файл GitHub Actions
.github/workflows/regression.yml:
name: Prompt Regression Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.10'
- name: Install dependencies
run: pip install -r requirements.txt
- name: Run regression tests
run: pytest tests/ -v --junitxml=report.xml
- name: Upload test report
if: failure()
uses: actions/upload-artifact@v3
with:
name: test-report
path: report.xml
- Добавить секреты (например,
OPENAI_API_KEY) в настройках репозитория. - Сделать коммит с изменением промпта (например, добавить слово "please" в системное сообщение) — CI должен упасть.
- Проверить, что лог ошибки показывает, на каком запросе произошло расхождение.
- Добавить отправку уведомлений (Slack / email) при падении тестов (опционально, можно в следующей итерации).
Ожидаемый результат этапа Рабочий CI-пайплайн, который запускается на каждый коммит и падает при изменении ответов относительно golden set.
Этап 4: Документирование и мониторинг (1 час)
Действия
- Написать README.md с описанием:
- Как обновить golden set (процедура:
python scripts/update_golden_set.py, ручная проверка). - Как добавить новый запрос (добавить в JSON, сгенерировать ответ, запустить тесты).
- Как интерпретировать отчёт CI.
- Как обновить golden set (процедура:
- Добавить скрипт обновления
update_golden_set.py, который генерирует новые эталонные ответы при смене модели или крупном изменении промпта. - Настроить дашборд (если есть Grafana / Prometheus) или хотя бы простой лог-файл с историей прогонов.
Ожидаемый результат этапа Полная документация и повторяемый процесс ведения golden set.
5. Критерии приемки (Definition of Done)
- Golden set содержит ровно 100 пар «запрос → эталонный ответ» в формате JSON.
- Все тесты запускаются одной командой
pytest tests/(локально) и проходят при неизменённых промптах. - В репозитории корректно настроен CI (GitHub Actions или аналог), который запускает тесты на каждый push в любую ветку.
- При изменении промпта (например, добавление одного слова в системную инструкцию) CI падает с четким указанием, какой тест не пройден (номер запроса, ожидаемый и фактический ответ).
- При удалении или изменении golden set CI также падает (если нарушен формат или количество записей).
- Процесс обновления golden set описан в README и воспроизводится по шагам.
- Тесты используют фиксированные параметры генерации (temperature=0, seed=42) — воспроизводимость.
- Длительность выполнения тестов в CI не превышает 10 минут (с учётом вызовов LLM). При использовании mock — менее 30 секунд.
6. Ожидаемый результат
Главный артефакт Репозиторий (или выделенная директория в проекте) со следующей структурой:
golden_set.json— 100 пар запрос-ответ.tests/test_regression.py— параметризованный тест.tests/conftest.py— фикстуры..github/workflows/regression.yml— CI-пайплайн.requirements.txt— зависимости (pytest, openai и т.д.).README.md— документация по ведению golden set и интерпретации результатов.
Дополнительно (опционально):
- Скрипт
scripts/update_golden_set.pyдля автоматической перегенерации эталонов. - Интеграция с системой оповещений (Slack, email) при падении регрессии.
- JUnit-отчёт, загружаемый в артефакты CI.
7. Возможные сложности и их решение
| Сложность | Решение |
|---|---|
| Недетерминированность LLM — даже при temperature=0 и seed=42 ответы могут различаться на разных версиях модели или платформы. | Использовать точную фиксацию версии модели (например, gpt-4-0613) и кеширование эмбеддингов. Вместо exact match можно использовать семантическое сходство (rouge-L > 0.95) с порогом, но цель задачи — 100% совпадение, поэтому лучше изначально генерировать golden set на той же модели и с теми же параметрами. Если нестабильность сохраняется — использовать mock-объект, который возвращает фиксированный ответ. |
| Объём golden set — 100 пар много ручной работы. | Использовать синтетические запросы (генерация из ключевых слов) и проверять только 15–20% вручную. Остальные считать правильными, если они сгенерированы текущей стабильной версией. |
| Частое изменение промптов — каждый PR может требовать обновления golden set, что замедляет разработку. | Разделить золотой сет на две части: критический (10–20 запросов, которые обязаны совпадать) и опорный (80 запросов, которые разрешено менять при утверждении). CI настроить: критический — всегда exact match, опорный — допускает изменение, но уведомляет. |
| Зависимость от внешнего API — тесты могут падать из-за таймаутов или ошибок сети. | Добавить retry-механизм в фикстуру (максимум 3 попытки с паузой). Если API недоступен — тест не запускается (пропускается), но CI завершается успехом. Альтернатива — использовать локальную open-source модель (например, Llama.cpp) для полной детерминированности. |
| Забыли обновить golden set после изменения логики приложения — тесты проходят, но ответы перестали быть актуальными. | Ввести триггер: при изменении любого файла с промптами (.prompt, .jinja) или при изменении prompt_engine.py автоматически создавать issue/задачу на обновление golden set. Можно также добавить pre-commit hook, который напоминает. |
8. Бюджет времени (оценка)
| Этап | Время (часы) |
|---|---|
| 1. Формирование golden set | 2–3 |
| 2. Разработка тестового фреймворка | 2–3 |
| 3. Интеграция в CI | 1–2 |
| 4. Документирование и мониторинг | 1 |
| Итого | 6–9 |
Примечание для первого раза Если golden set создаётся вручную, этап 1 может занять до 5 часов. Использование автоматической генерации (LLM на тестовых запросах) сокращает время до 30–60 минут.
9. Связанные вопросы из базы знаний
| Вопрос | Тема |
|---|---|
| 15 | Основы тестирования в AI/ML |
| 21 | Настройка CI/CD для ML-проектов |
| 45 | Метрики качества ответов LLM (ROUGE, BLEU) |
| 67 | Работа с seed и воспроизводимостью генерации |
| 89 | Интеграционное тестирование LLM-приложений |
| 101 | Управление промптами в Git |
| 155 | Паттерн golden set для ML |
| 203 | Параметризованные тесты в pytest |
| 256 | Асинхронные вызовы LLM в тестах |
| 310 | Оповещения о сбоях в CI |
10. Чек-лист самопроверки
- Я проверил, что
golden_set.jsonсодержит 100 записей с корректными полями и валидным JSON. - Я запустил
pytest tests/локально — все тесты зелёные (пройдены). - Я изменил один из промптов (например, убрал точку в конце системного сообщения), закоммитил и убедился, что CI упал с сообщением о расхождении на конкретном запросе.
- Я снова вернул промпт и убедился, что CI зелёный.
- Я описал в README процедуру обновления golden set и ссылку на неё внёс в описание репозитория.
- Я проверил, что файл
requirements.txtсодержит все необходимые библиотеки с фиксированными версиями. - Я убедился, что секреты (API key) правильно настроены в GitHub Actions.
- Я посмотрел лог первого успешного прогона в CI — все тесты выполнены за разумное время (<5 мин).