-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_golden_qa.py
More file actions
49 lines (36 loc) · 1.67 KB
/
Copy pathtest_golden_qa.py
File metadata and controls
49 lines (36 loc) · 1.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
"""Parametrised evaluation tests from the golden QA dataset.
Marked with ``@pytest.mark.eval`` so the default ``just check`` /
``pytest tests/`` invocations skip them. Run explicitly with::
uv run pytest eval/
Wire a real LLM-backed ``answer_fn`` by editing ``_answer_fn`` below or
constructing ``EvalRunner`` with your own callable. The default echoes the
question verbatim, which makes the trivial example case (``echo hello``
expects ``hello``) pass without any LLM credentials.
"""
from __future__ import annotations
import pytest
from src.eval.models import EvalCase
from src.eval.runner import EvalRunner, load_golden_dataset
# Load cases without initialising a runner (no side effects at import time)
golden = load_golden_dataset()
def _answer_fn(question: str) -> str:
"""Placeholder agent. Strips a leading ``echo `` so the example case
resolves to the expected answer; in real use this calls the agent
loop / LLM client wired by the project."""
return question.removeprefix("echo ").strip()
@pytest.fixture(scope="module")
def runner() -> EvalRunner:
"""Single runner shared across cases in this module."""
return EvalRunner(answer_fn=_answer_fn)
@pytest.mark.eval
@pytest.mark.parametrize("case", golden, ids=lambda c: c.id)
def test_golden_qa(case: EvalCase, runner: EvalRunner) -> None:
"""Evaluate a golden QA test case against the configured agent."""
result = runner.evaluate(case)
assert result.pass_result, (
f"[{case.id}] {case.category}/{case.difficulty}\n"
f"Q: {case.question}\n"
f"Expected: {case.expected_answer}\n"
f"Got: {result.actual_answer}\n"
f"Reason: {result.failure_reason}"
)