Agent回归测试怎么配置:固定用例、基线结果和失败判定
Agent 每次修改提示词、工具或模型参数后,之前正常的行为可能被破坏,回归测试就是用来发现这类退化。
配置的关键不是写很多用例,而是把测试输入、基线输出和失败判定规则固定下来,让每次改动后能自动重跑并对比差异。
下面以 Python 的 pytest 为例,说明具体的配置步骤和避坑点。
先明确测什么和怎么判
Agent 的输出不是固定字符串,所以不能直接用 assert output == expected。
回归测试要拆成三层:
- 确定性部分:工具调用是否发生、调用了哪个工具、参数是什么、是否命中禁止操作。这部分可以精确断言。
- 半确定性部分:返回内容是否包含关键事实、是否包含指定字段、长度是否在范围内。用关键词或结构校验。
- 主观部分:语气、完整性等,适合人工抽检,不放进自动回归。
基线结果建议保存为 JSON 文件,而不是硬编码在测试文件里。
这样更新基线时有记录,也方便对比。
准备测试用例和基线文件
在项目根目录创建目录结构:
tests/
regression/
cases.json
baselines/
case_001.json
test_agent.py
cases.json 存放测试输入和判定规则,例如:
[
{
"id": "case_001",
"input": "查询北京今天天气",
"expect_tool": "weather_api",
"expect_keywords": ["北京", "天气"],
"forbidden_tool": ["file_write", "shell_exec"]
}
]
baselines/case_001.json 保存上一次通过时的工具调用和关键输出片段:
{
"tool_calls": [{"name": "weather_api", "args": {"city": "北京"}}],
"output_excerpt": "北京今天多云,气温 12 到 20 摄氏度"
}
基线不需要保存完整输出,只保存用于判定的字段即可。
编写 pytest 测试并固定判定规则
在 test_agent.py 中加载用例和基线,调用 Agent 后按规则断言:
import json
import pytest
from pathlib import Path
from my_agent import run_agent # 替换为实际入口
CASES = json.loads(Path("tests/regression/cases.json").read_text())
@pytest.mark.parametrize("case", CASES, ids=[c["id"] for c in CASES])
def test_regression(case):
result = run_agent(case["input"])
tool_names = [t["name"] for t in result.get("tool_calls", [])]
if case.get("expect_tool"):
assert case["expect_tool"] in tool_names, f"未调用预期工具 {case['expect_tool']}"
for bad in case.get("forbidden_tool", []):
assert bad not in tool_names, f"触发了禁止工具 {bad}"
output = result.get("output", "")
for kw in case.get("expect_keywords", []):
assert kw in output, f"输出缺少关键词 {kw}"
baseline_path = Path(f"tests/regression/baselines/{case['id']}.json")
if baseline_path.exists():
baseline = json.loads(baseline_path.read_text())
assert tool_names == [t["name"] for t in baseline["tool_calls"]], "工具调用与基线不一致"
这里只对工具调用序列做精确对比,输出内容用关键词校验。
如果 Agent 输出本身不稳定,可以进一步放宽为只校验工具调用和结构化字段。
接入 CI 并设置失败处理
在 CI 配置中增加一步运行回归测试,例如 GitHub Actions:
- name: Run agent regression
run: pytest tests/regression -q
失败时 CI 会直接报错,阻止合并。
建议同时保留失败用例的输出,方便排查:
def test_regression(case):
result = run_agent(case["input"])
# ... 断言 ...
在 pytest 配置中启用 --tb=short 和 -ra,失败摘要会更清晰。
如果 Agent 调用外部 API,注意在 CI 中设置超时和重试,避免偶发网络问题被误判为回归失败。
避坑与验证
- 基线不要自动覆盖:只有确认新行为正确后,才手动更新基线文件,否则回归测试会失去意义。
- 区分环境差异:模型版本、温度参数、外部 API 返回都可能影响结果,测试前固定这些变量,或在用例中标注环境要求。
- 失败用例单独重跑:偶发失败先重跑一次,确认是稳定失败还是环境抖动,再决定是否修改断言。
配置完成后,用 pytest tests/regression -q 跑一遍,确认全部通过;
然后故意改坏一个工具名,再跑一次,确认测试能报错。
这样才算验证了回归测试本身有效。
常见疑问
回归测试和单元测试有什么区别?
单元测试验证单个函数逻辑,回归测试验证 Agent 整体行为在改动后没有退化,通常依赖真实或录制的模型调用。
基线文件应该多久更新一次?
没有固定周期。每次确认新行为符合预期时更新,并在提交记录中说明原因。
Agent 输出每次都不一样怎么办?
优先把判定条件从完整文本对比改为工具调用、关键字段和禁止项校验,不要为了通过测试而放宽到没有意义。