最近做 AI Agent 的团队,可能都遇到过一个挺让人头疼的问题:
模型没换。
业务也没换。
就改了一版 System Prompt,调整了一下 Tool Schema,或者给 Coding Agent 增加了一个工具。
重新跑 Benchmark——
成功率掉了。
问题来了:
到底哪里坏了?
是模型突然不会推理了?
Tool选错了?
参数传错了?
还是Agent写完代码之后,压根忘了执行测试?
以前碰到这种问题,很多团队只能重新翻:
Prompt、Log、Trace、Tool Calling记录。
一点一点找。
而Google最近公开的一篇 Harness Engineering 技术文章,恰好把这个问题摆到了台面上。
Google给出的思路很值得测试工程师关注:
测试AI Agent,不能永远只盯着最终答案。
真正应该进入测试体系的,还有Agent执行过程中那些可以观察、可以断言、可以回归的行为。
这就是:
Behavioral Evaluation
而它背后,其实藏着一个正在发生的变化:
AI Agent越来越像一个需要被系统测试的软件,而不是一个只需要“做题打分”的大模型。
一、以前我们到底是怎么测Agent的?
现在很多AI团队做 Agent Evaluation,第一反应仍然是找Benchmark。
例如AI Coding领域常见的:
SWE-bench、Terminal-Bench,以及各种内部Evaluation Dataset。
基本逻辑都是:
给Agent一个任务
↓
Agent执行
↓
拿到最终结果
↓
执行测试
↓
PASS / FAIL
↓
统计成功率
比如100个Case:
Agent V1:82%
Agent V2:86%
看起来V2变强了。
但是Google指出了一个很现实的问题:
86%到底为什么比82%好?
反过来也一样。
如果:
Agent V3:79%
到底是哪次Harness修改把它搞坏了?
Google在9月9日发布的Harness Engineering文章中明确提到,端到端Benchmark适合观察总体表现,但当分数变化时,它往往不能直接告诉开发者:模型是不是对模糊Prompt过度自信、是不是忘记运行测试,或者是不是“幻觉”出了一个不存在的CLI参数。
这就很像我们以前做自动化测试。
你不能只有:
System Test
还得有:
Unit Test
Integration Test
Regression Test
Agent也一样。
二、Google提出了一个很像“Agent单元测试”的东西
Google把 Behavioral Evaluation 描述得很形象:
它有点像针对Agent Harness的Integration Test。
它不一定关心Agent最后说了什么漂亮的话。
而是检查:
Agent有没有做它本来应该做的事情?
Google举了几个很典型的例子。
比如:
用户需求描述不完整时:
Agent应该追问
还是:
自己猜一个答案?
修改Build文件之后:
Agent有没有运行Validator?
生成文档之后:
有没有引用正确的Repository?

这时候测试对象已经变了。
以前:
assert response == expected_answer
现在:
assert agent.called_tool("test_runner")
这一步很重要。
因为:
Outcome正确,不代表Behavior正确。
三、放到真实测试业务里,会更容易理解
假设我们现在做一个电商售后Agent。
用户说:
“刚买的耳机还没发货,不想要了,帮我退掉。”
Agent最后回答:
“好的,退款申请已经为您提交。”
看起来:
PASS
但是我们把Trace打开。
发现它实际上执行的是:
用户请求
↓
query_order
↓
refund_payment
↓
回复用户
少了一步:
check_refund_policy
甚至没有确认:
订单状态
支付状态
退款资格
最后业务结果可能碰巧是正确的。
但这个Agent能上线吗?
显然不能因为一次“碰巧正确”就判它通过。
四、我们可以给Agent增加Behavioral Evaluation
先定义测试Case:
case = {
"input": "订单还没有发货,帮我退款",
"must_call": [
"query_order",
"check_refund_policy"
],
"forbidden_before_validation": [
"refund_payment"
],
"max_steps": 8
}
执行Agent:
trace = agent.run(case["input"])
然后不要只拿Final Answer。
直接读取Agent执行轨迹:
def get_tool_calls(trace):
return [
event.tool
for event in trace
if event.type == "tool_call"
]
开始做Behavior Assertion:
def evaluate_behavior(trace, case):
tools = get_tool_calls(trace)
missing_tools = [
tool
for tool in case["must_call"]
if tool not in tools
]
return {
"missing_tools": missing_tools,
"steps": len(trace),
"passed": (
len(missing_tools) == 0
and len(trace) <= case["max_steps"]
)
}
这时候Evaluation报告可能变成:
Final Answer:PASS
Business Result:PASS
Tool Selection:PASS
Tool Sequence:FAIL
Required Validation:FAIL
Steps:5
Overall:FAIL
这就比:
成功率:86%
有价值多了。
五、为什么这件事和Harness有关?
这里需要把一个最近特别火的词讲明白:
Agent Harness
简单理解:
模型是大脑,Harness是让这个大脑真正干活的那套工程系统。
里面可能包含:
System Prompt
Context
Memory
Tool
MCP
Skills
Subagent
Retry
Planning
Session
Sandbox
Execution Loop
所以今天一个Agent最终表现怎么样,越来越不能简单写成:
Agent能力 = Model
更准确的是:
Agent能力
=
Model
×
Harness
×
Context
×
Tool
×
Runtime Configuration
这也是为什么最近半年:
Harness Engineering
越来越值得测试开发工程师关注。
因为Harness越复杂:
可测试对象就越多。
六、最麻烦的是:Agent存在随机性
传统自动化测试可以写:
assert result == expected
跑100次基本一样。
LLM Agent不一样。
同一个:
Model
Prompt
Tool
Temperature
重复执行,也可能产生不同Trajectory。
所以你不能因为一次:
FAIL
就直接把CI/CD卡死。
Google这次也特别强调了这一点。
对于具有随机性的复杂Agent任务,不应该过度依赖单次Eval,而应该通过批量Evaluation观察总体Pass Rate和趋势。([Google 开发者博客][1])
例如:
results = []
for _ in range(30):
trace = agent.run(test_case)
results.append(
evaluate_behavior(trace, test_case)
)
然后统计:
pass_rate = (
sum(r["passed"] for r in results)
/ len(results)
)
V1:
Behavior Pass Rate:96.7%
修改System Prompt以后:
V2:
Behavior Pass Rate:76.7%
这时候问题就非常清楚了。
Prompt Regression。
而不是:
“感觉新版Agent好像变笨了。”
七、这其实把Prompt Engineering变成了测试工程
再往前走一步,会出现一个很有意思的工作流。
比如我们发现:
Agent经常修改代码以后
忘记运行pytest
那就把这个线上Bad Case加入:
Evaluation Dataset
写成:
async def test_agent_runs_tests_after_code_change():
result = await agent.run(
"修复calculate_discount函数的边界问题"
)
tools = extract_tools(result.trace)
assert "edit_file" in tools
assert "pytest" in tools
现在开始改Prompt。
V1:
Pass Rate:71%
V2:
Pass Rate:89%
V3:
Pass Rate:97%
问题解决。
但事情还没结束。
必须重新执行原来的Evaluation Suite:
pytest evals/behavioral/
确认:
其他Behavior没有Regression。
Google甚至提到了利用这种测试体系自动迭代System Prompt:让模型修改Prompt,再通过Eval Suite验证新的修改有没有解决问题,同时有没有破坏原有行为。([Google 开发者博客][1])
你会发现:
以前大家讨论的是:
Prompt Engineering
现在慢慢变成了:
Harness Engineering
再往后其实就是:
AI Testing Engineering
八、这对传统测试开发工程师反而是个机会
看到这里你可能会发现:
这些东西并没有完全脱离我们以前做测试的知识体系。
以前我们做:
pytest
API Testing
UI Automation
Mock
Assertion
Test Dataset
Regression Testing
CI/CD
Performance Testing
Observability
现在只是测试对象变了。
变成:
Agent Evaluation
Behavioral Evaluation
Tool Calling Testing
MCP Testing
Evaluation Dataset
Trajectory Evaluation
Continuous Evaluation
Quality Gate
Agent Regression Testing
比如:
传统API测试:
assert response.status_code == 200
Agent Tool测试:
assert "query_order" in tool_calls
传统回归:
代码修改
→ Regression Suite
Agent回归:
Prompt / Model / Harness / Tool修改
→ Evaluation Suite
传统CI:
Test FAIL
→ PR BLOCK
Agent时代:
Evaluation Regression
→ PR BLOCK
这两套东西并不是割裂的。
恰恰相反。
很多测试开发工程师原来的能力可以直接迁移过去。
九、而且这个趋势已经开始进入真正的CI/CD
这不是我为了文章硬拔高度。
AWS在9月8日刚公开了一套 Automated Agent Evaluation + GitHub Actions 的完整实践。
流程是:
Agent修改
↓
部署测试环境
↓
运行Evaluation Dataset
↓
采集Agent Trace
↓
AgentCore Evaluations评分
↓
低于Threshold
↓
GitHub Actions FAIL
↓
阻止PR

AWS明确把它称作 CI/CD Quality Gate,而且案例里还包括了带角色权限控制的MCP Tool。
也就是说:
我们以前经常说的:
Continuous Testing
正在延伸成:
Continuous Evaluation
这两个东西以后很可能会融合。
而这恰恰是下一篇我们要继续聊的内容。
十、测试工程师现在真正值得补的,不是“会不会调一个大模型API”
如果只是:
response = client.chat(...)
这个门槛其实已经很低了。
真正能形成测试开发工程能力的是:
你能不能设计一个:
Evaluation Dataset
↓
Agent Runner
↓
Trace
↓
Behavior Assertion
↓
LLM Judge
↓
Regression
↓
Quality Gate
↓
CI/CD
再把:
正确率
Tool选择
业务规则
Trajectory
Latency
Token
Cost
Stability
全部变成可度量指标。
这时候做的就已经不是简单的:
“让AI帮我生成几个测试用例。”
而是真正开始进入:
AI测试开发。
写在最后
我觉得Google这次关于Harness Engineering的分享,真正值得测试工程师注意的并不是又多了一个新名词。
而是一个很明显的趋势:
AI Agent越往生产环境走,传统软件测试的方法反而越重要。
只不过我们以前测试的是:
接口
页面
服务
数据库
现在开始增加:
Agent
Harness
Tool
MCP
Context
Trajectory
最终还是那几个老问题:
它有没有按预期工作?
修改之后有没有退化?
异常情况下能不能恢复?
能不能在上线之前发现问题?
只是这一次,被测试的对象换了。