Ідея за 30 секунд
Regression testing для AI-агентів порівнює candidate з baseline на тих самих кейсах і в тих самих умовах.
Його головна цінність у тому, що він показує, де саме змінилася поведінка системи після змін у моделі, промптах, інструментах або runtime.
Проблема
Без regression testing команда часто бачить лише загальне "краще/гірше", але не розуміє, що саме зламалося.
Типові наслідки такого підходу:
- непомітні регресії потрапляють у реліз;
- критичні сценарії просідають, хоча середній результат виглядає нормальним;
- важко пояснити, чи причина у змінах коду, моделі, промпту або умов прогону.
У підсумку реліз виглядає безпечним, але у production-середовищі з'являються повторні інциденти.
Коли використовувати
Regression testing потрібен кожного разу, коли зміни можуть вплинути на поведінку агента:
- оновили версію моделі;
- змінили промпт або policy-правила;
- додали або переробили інструменти;
- змінили runtime-налаштування (таймаути, retries, ліміти).
Regression testing відповідає на одне питання: що змінилося між версіями системи.
Також його варто запускати після інцидентів: щоб перевірити, що виправлення не зламало суміжні сценарії.
Реалізація
На практиці regression testing тримається на одному правилі: ті самі кейси і ті самі умови прогону, плюс порівняння з зафіксованим baseline. Приклади нижче схематичні і не прив'язані до конкретного фреймворку.
Як це працює в одному прогоні
Regression-прогін зазвичай запускає той самий eval harness, але з порівнянням результатів проти baseline.
Короткий цикл regression-прогону
- Dataset version — фіксуємо одну версію кейсів для обох запусків.
- Baseline report — беремо еталонний звіт як точку порівняння.
- Candidate run — запускаємо нову версію агента в тих самих умовах.
- Diff compare — рахуємо різницю по кейсах і ключових метриках.
- CI gate — блокуємо або пропускаємо реліз за порогами.
1. Зафіксуйте baseline і версію dataset
regression_context = {
"dataset_version": "golden-v1.4",
"baseline_report": "reports/baseline-golden-v1.4.json",
"model_version": "gpt-4o-2024-08-06",
}
baseline має бути прив'язаний до конкретної версії dataset, моделі та умов прогону.
2. Запускайте candidate в тих самих умовах
def run_candidate(agent, dataset, runtime_config):
return run_eval_suite(
agent=agent,
dataset=dataset,
timeout_sec=runtime_config["timeout_sec"],
max_steps=runtime_config["max_steps"],
tool_mocks=runtime_config["tool_mocks"],
)
Без однакових умов diff швидко стає шумним і втрачає діагностичну цінність.
3. Рахуйте diff за порогами ризику
def compare_summary(candidate, baseline):
deltas = {
"task_success_drop": baseline["task_success_rate"] - candidate["task_success_rate"],
"latency_growth": candidate["p95_latency"] - baseline["p95_latency"],
"cost_growth": candidate["avg_token_cost"] - baseline["avg_token_cost"],
}
return deltas
Пороги потрібно задавати явно, щоб рішення про реліз було детермінованим.
4. Дивіться не лише summary, а й кейси
def critical_case_regressions(case_diffs):
bad = []
for diff in case_diffs:
if diff["status"] == "regressed" and "critical" in diff["tags"]:
bad.append(diff["case_id"])
return bad
Навіть якщо summary виглядає нормальним, падіння в критичних кейсах має блокувати реліз.
5. Додавайте regression gate у CI
deltas = compare_summary(candidate_summary, baseline_summary)
critical_failures = critical_case_regressions(case_diffs)
if deltas["task_success_drop"] > 0.03:
fail("gate_failed:task_success_drop")
if deltas["latency_growth"] > 800: # ms
fail("gate_failed:latency_growth")
if critical_failures:
fail(f"gate_failed:critical_cases:{critical_failures}")
Regression gate має бути обов'язковим для змін, які впливають на модель, промпти, інструменти або runtime.
Нотатки для QA та автоматизації
QA-команди зазвичай запускають regression після оновлення моделі або промпту, щоб одразу побачити поведінковий diff проти baseline.
Практично це працює як обов'язковий CI-прогін для змін у model/prompt-конфігурації та регулярний повний regression suite для контролю повільних деградацій.
Типові помилки
Автоматичний перезапис baseline
Команда втрачає стабільну точку порівняння, і історія регресій стає нечіткою.
Типова причина: baseline оновлюють автоматично без окремого рішення.
Різні умови прогону для baseline і candidate
Запуски порівнюються, але з різними таймаутами, моделлю або mocks.
Типова причина: немає фіксованого runtime-конфігу для regression.
Порівняння тільки загальних метрик
Середній результат нормальний, але критичні кейси деградують.
Типова причина: у звіті немає case-level diff.
Немає чітких порогів для CI gate
Релізне рішення приймається "на око", і сигнал regression втрачається.
Типова причина: пороги не зафіксовані у правилах CI.
Нестабільні кейси в regression-наборі
Один і той самий кейс то проходить, то падає, і команда перестає довіряти звіту.
Типова причина: flaky-сценарії потрапили в основний regression-набір без стабілізації.
Коротко
- Regression testing порівнює
candidateіbaselineна тих самих кейсах. - Валідний
diffможливий лише за однакових dataset і runtime-умов. - Рішення про реліз має базуватись на порогах і критичних кейсах, а не на враженні від summary.
- Baseline треба версіонувати так само дисципліновано, як код і dataset.
FAQ
Q: Чим regression testing відрізняється від eval harness?
A: Eval harness запускає стандартизований прогін, а regression testing використовує цей прогін для порівняння candidate проти baseline.
Q: Коли оновлювати baseline?
A: Після підтвердженого релізу, коли команда свідомо приймає нову поведінку як еталон.
Q: Що найчастіше блокує реліз у regression gate?
A: Просідання критичних кейсів, падіння task_success_rate, різкий ріст latency або token cost.
Q: Чи достатньо synthetic кейсів для regression?
A: Для старту так, але стійкіший сигнал дає поєднання синтетичних кейсів і replay-сценаріїв із production.
Що далі
Після налаштування regression gate підключіть стабільні кейси через Golden Datasets і стандартизований прогін через Eval Harness. Для локальних перевірок логіки використовуйте Unit Testing, а інциденти розбирайте через Replay and Debugging.