Ідея за 30 секунд
Eval harness — це спосіб запускати один і той самий набір сценаріїв для агента, оцінювати результати за однаковими правилами і порівнювати candidate з baseline.
Проблема
Без eval harness команди часто тестують агентів вручну:
- запускають кілька запитів у чаті;
- дивляться на кілька прикладів відповіді;
- роблять висновок, що зміна виглядає безпечною.
Це не дає стабільної картини: зміна може виглядати нормально на випадкових прикладах, але ламати важливі production-сценарії.
Найчастіші наслідки:
- неможливо чесно порівняти
candidateіbaseline; - складно відтворити регресію;
- CI не має чіткої умови, коли блокувати реліз.
Основна концепція / модель
Eval harness — це не один тест, а конвеєр перевірки: зафіксований dataset, контрольовані умови прогону, оцінка, порівняння з baseline і звіт.
| Компонент | Що робить |
|---|---|
| Dataset | Зберігає стабільний набір сценаріїв і очікувань |
| Runner | Проганяє агента по кожному сценарію в однакових умовах і збирає результати прогону |
| Evaluators | Застосовують детерміновані перевірки, оцінку через LLM-as-a-judge і метрики якості |
| Baseline comparator | Порівнює candidate з baseline |
| Report + CI gate | Формує підсумок і вирішує pass/fail для релізу |
Чим стабільніші ці компоненти, тим менше шансів, що diff між candidate і baseline пояснюється умовами прогону, а не реальною зміною поведінки.
Як це працює
У практиці eval harness запускається як частина release pipeline. Кожна зміна проходить той самий набір сценаріїв.
Як проходить один прогін eval harness
- Dataset — береться зафіксований набір кейсів.
- Runner — агент запускається на кожному кейсі в однакових умовах.
- Evaluators — застосовуються детерміновані перевірки і, за потреби, оцінка через LLM-as-a-judge.
- Baseline comparison —
candidateпорівнюється зbaselineна тих самих кейсах. - Report — зберігається звіт по кейсах і загальний підсумок.
- Gate — CI пропускає або блокує реліз за порогами.
Eval harness не замінює unit-тести. Unit-тести перевіряють локальні компоненти, а harness — поведінку системи на завершених сценаріях.
Реалізація
На практиці eval harness тримається на кількох простих правилах. Приклади нижче схематичні і не прив'язані до конкретного фреймворку.
1. Структура сценарію (test case)
case = {
"id": "price_btc_basic",
"input": "What is the price of BTC?",
"expected_tool": "crypto_price_api",
"checks": ["tool_selection", "valid_output_schema"],
}
Чіткі кейси спрощують аналіз регресій і зменшують неоднозначність під час розбору прогонів.
2. Runner для прогону кейсів
def run_case(agent, case):
result = agent.run(case["input"])
return {
"case_id": case["id"],
"selected_tool": result.selected_tool,
"output": result.output,
"stop_reason": result.stop_reason,
}
Нову версію і baseline потрібно запускати в однакових умовах: з тими самими таймаутами, tool-mocks, лімітами і налаштуваннями середовища прогону.
3. Оцінка і порівняння з baseline
def evaluate_case(run_result, case):
checks = {
"tool_selection": run_result["selected_tool"] == case["expected_tool"],
"valid_output_schema": isinstance(run_result["output"], dict),
}
return {"passed": all(checks.values()), "checks": checks}
candidate = run_eval_suite(agent=candidate_agent, dataset=dataset)
baseline = load_baseline_report("reports/baseline.json")
diff = compare(candidate, baseline)
Для відкритих задач до детермінованих перевірок зазвичай додають LLM-as-a-judge, але як окремий шар оцінки.
Baseline теж варто версіонувати і прив'язувати до конкретної моделі, промпту та конфігурації runtime.
4. Звіт і CI gate
summary = build_summary(candidate, diff)
if summary["task_success_rate"] < 0.92:
fail("gate_failed:task_success_rate")
if summary["hallucination_rate"] > 0.03:
fail("gate_failed:hallucination_rate")
write_json("reports/eval-summary.json", summary)
Хороший eval harness завжди зберігає артефакти: результати по кейсах, причини fail, diff проти baseline і підсумковий звіт.
5. Release gate у загальній стратегії
Критерії блокування релізу і пороги для CI gate винесені окремо в Стратегію тестування, щоб не дублювати їх у кожній статті.
Нотатки для QA та автоматизації
Eval harness варто запускати у двох режимах: короткий обов'язковий прогін у CI для кожного PR і повний нічний прогін для ширшого dataset. Такий розподіл дає швидкий зворотний зв'язок під час розробки та окремо відстежує повільні регресії, які зазвичай видно лише на довгих тестових серіях.
Типові помилки
Нестабільний dataset
Сценарії постійно змінюються "по ходу", тому результати різних прогонів не можна чесно порівняти.
Типова причина: dataset не версіонується і не має фіксованих ID кейсів.
Нефіксована версія моделі
LLM-провайдери іноді оновлюють моделі без зміни загальної назви.
Якщо версія не зафіксована (наприклад, gpt-4o-2024-08-06), результати можуть змінюватися між прогонами.
Типова причина: використовується alias моделі (gpt-4o, sonnet) без version pinning.
У production системах зазвичай фіксують конкретну версію моделі або snapshot-версію.
Ручний запуск замість автоматизації
Harness запускають тільки коли "є час", а не на кожну суттєву зміну.
Типова причина: немає інтеграції в CI і зрозумілого pass/fail gate.
Немає порівняння з baseline
Команда дивиться лише на абсолютні метрики candidate і пропускає непомітні регресії.
Типова причина: звіт не містить diff між candidate і baseline.
Змішані детерміновані і недетерміновані перевірки
Детерміновані перевірки і LLM-as-a-judge змішані в один "загальний бал", тому складно зрозуміти, що саме зламалося.
Типова причина: немає окремих секцій оцінки для різних типів перевірок.
Відсутні артефакти прогону
Є тільки фінальний відсоток успіху без трейсів і перевірок по кейсах.
Типова причина: harness не зберігає детальні результати у файли звіту.
Нестабільні eval-прогони
Один і той самий кейс то проходить, то падає, тому звіту перестають довіряти.
Типова причина: нестабільне зовнішнє середовище, відсутність mocks, плаваючі таймаути або неоднакові умови прогону.
Коротко
- Eval harness робить тестування агентів повторюваним і порівнюваним.
- Рішення про реліз має спиратися на diff
candidatevsbaseline, а не на ручні приклади. - Важливі не лише підсумкові метрики, а й артефакти по кожному кейсу.
- Без CI gate eval harness перетворюється на "звіт заради звіту".
FAQ
Q: Eval harness — це просто набір тестів?
A: Ні. Це керований процес: dataset, runner, evaluators, порівняння з baseline і CI gate.
Q: Чи можна обійтись без LLM-as-a-judge?
A: Так, якщо задачі добре покриваються детермінованими перевірками. Для відкритих задач LLM-as-a-judge зазвичай додають як окремий шар оцінки.
Q: Як часто запускати eval harness?
A: Мінімум на кожну зміну, що може вплинути на поведінку агента: модель, промпти, інструменти, runtime-правила.
Q: Що найважливіше в першій версії harness?
A: Стабільний dataset, збережений baseline, чіткі pass/fail пороги і артефакти прогону.
Що далі
Для загальної картини почніть із Стратегії тестування. Далі покрийте критичну логіку через Unit Testing, потім зберіть стабільний Golden Datasets, а для змін між версіями підключіть Regression Testing.
Коли з’являться перші реальні інциденти, додайте Replay and Debugging і включіть ці кейси у dataset вашого eval harness.