当AI Agent的tool call从demo走向生产,测试 discipline 成为决定生死的关键变量。2026年,工具调用测试已从简单的pytest mock进化为六层栈式体系:Mock/Replay层用VCR磁带捕获回放、Simulation层用LLM驱动虚拟用户、Contract层检测Schema漂移、Golden Dataset层守住回归底线、Observability层全链路追踪、Chaos层注入故障验证韧性。本文实测evalcraft、LangWatch Scenario、AWS ToolSimulator、DriftGentic、agent-chaos等工具,拆解从第一次assert tool_called到生产级混沌工程的完整路径。
| 测试层 | 核心问题 | 代表工具/框架 | 上手成本 | 覆盖率 | 生产价值 |
|---|---|---|---|---|---|
| L1: Mock/Replay | 工具是否被正确调用? | evalcraft, pytest-mock, VCR | ★☆☆ | 工具签名级 | 确定性回归 |
| L2: Simulation | Agent面对模拟用户行为是否合理? | LangWatch Scenario, ToolSimulator | ★★☆ | 交互行为级 | 行为验证 |
| L3: Contract | 工具Schema和后端API是否还一致? | DriftGentic, Schemathesis | ★★☆ | 接口契约级 | 漂移检测 |
| L4: Golden Dataset | Agent整体行为是否回归? | Google ADK Eval, promptfoo | ★★★ | 端到端级 | CI/CD门禁 |
| L5: Observability | 生产环境工具调用发生了什么? | OTel+Langfuse, LangSmith | ★★☆ | 全链路级 | 线上诊断 |
| L6: Chaos | Agent在故障下是否依然安全? | agent-chaos, FIS | ★★★ | 韧性极限级 | 弹性保证 |
graph TB
subgraph "工具调用测试六栈"
L1["L1: Mock/Replay<br/>evalcraft / pytest-mock"]
L2["L2: Simulation<br/>LangWatch Scenario / ToolSimulator"]
L3["L3: Contract<br/>DriftGentic / Schema检测"]
L4["L4: Golden Dataset<br/>Google ADK Eval / CI门禁"]
L5["L5: Observability<br/>OTel + Langfuse/LangSmith"]
L6["L6: Chaos<br/>agent-chaos / 故障注入"]
end
L1 -->|"通过签名验证"| L2
L2 -->|"行为验证通过"| L3
L3 -->|"契约一致"| L4
L4 -->|"回归门禁通过"| L5
L5 -->|"上线后监控"| L6
L6 -->|"发现脆弱点<br/>反馈修复"| L1
style L1 fill:#e3f2fd
style L2 fill:#f3e5f5
style L3 fill:#fff3e0
style L4 fill:#e8f5e9
style L5 fill:#fce4ec
style L6 fill:#efebe9
工具调用的第一个测试问题是:"Agent在给定输入下,是否选择了正确的工具并传入了正确的参数?"这个问题的答案必须是确定性的——同一个测试跑100次应该得到相同的结果。2026年,这个领域的突破来自evalcraft,它自称"AI Agent的pytest"。
evalcraft的核心机制是Cassette(磁带)模式——借鉴了Ruby VCR库的经典设计。当Agent首次执行时,evalcraft记录完整的LLM请求/响应对,包括tool call的参数和返回值,存为JSON磁带文件。后续测试直接回放磁带,零API调用、零成本、完全确定性。
# evalcraft磁带回放模式测试
from evalcraft import AgentTest, cassette
class TestWeatherAgent(AgentTest):
agent = WeatherAgent()
@cassette("weather_nyc_sunny")
def test_calls_weather_tool_with_city(self):
result = self.agent.run("纽约今天天气如何?")
# 验证调用了正确的工具
self.assert_tool_called("get_weather")
# 验证参数正确
self.assert_tool_args("get_weather", {"city": "New York"})
# 验证最终回复包含天气信息
self.assert_response_contains("晴")
@cassette("multi_tool_forecast")
def test_parallel_tool_calls(self):
result = self.agent.run("对比东京和伦敦的天气")
# 验证并发调用了两次天气工具
self.assert_tool_call_count("get_weather", 2)
self.assert_tool_args_at(0, "get_weather", {"city": "Tokyo"})
self.assert_tool_args_at(1, "get_weather", {"city": "London"})
evalcraft的优势是零学习成本——任何会写pytest的工程师都能在10分钟内上手。磁带文件可以提交到Git,团队成员共享测试数据。CI中运行速度极快,100个测试用例可在5秒内完成。
但Mock层的天花板也很明显:它只能验证已见过的行为。磁带是上一次成功运行的快照,如果LLM模型升级导致工具选择策略变化,磁带要么过时报错,要么需要重新录制。这就是为什么Mock层只是起点,不是终点。
变现评估:evalcraft是开源的(Apache 2.0),但围绕"Agent测试训练营"有明确的商业空间——将pytest基础、磁带录制、CI集成打包成48小时速成课程,单价¥999,目标人群是正在从传统后端转向AI Agent开发的中高级工程师。
Mock层验证的是"Agent是否按预期调用工具",但跳过了一个关键问题:"Agent在面对真实用户的多轮交互时,工具调用策略是否合理?"Simulation层用LLM扮演虚拟用户,对Agent进行多轮压力测试。
2026年这个领域有两个重量级选手:LangWatch Scenario(开源,TypeScript/Python双语言)和AWS ToolSimulator(Strands Evals内置)。
LangWatch Scenario的设计哲学是"用LLM测试LLM":一个LLM扮演用户模拟器(User Simulator),生成多轮对话;另一个LLM扮演评判者(Judge),评估Agent的工具调用是否合理。这种三方博弈结构能暴露Mock层无法触及的边界情况。
// LangWatch Scenario: 多轮工具调用模拟测试
import { Scenario } from "langwatch-scenario";
const agentUnderTest = new BookingAgent();
const result = await Scenario.create()
.agent(agentUnderTest) // 被测Agent
.simulator("openai:gpt-4.1") // LLM扮演用户
.judge("anthropic:claude-sonnet-4-20250514") // LLM评判结果
.instruction(
"你是一个挑剔的商务旅客,试图改签航班。" +
"尝试以下边界情况:改签到已满航班、用过期里程兑换、同时改签两个航段"
)
.successCriteria([
"Agent必须调用search_flights工具查询可用航班",
"当航班满员时,Agent不应直接调用book_flight",
"Agent应主动询问替代日期而非直接失败",
"里程不足时,Agent应提示付费选项"
])
.maxTurns(8)
.run();
// 输出:通过率、工具调用序列、失败回合详情
console.log(`通过率: ${result.passRate}%`);
console.log(`工具调用序列: ${result.toolCallTrace}`);
AWS走的路线更务实——不模拟用户,而是模拟工具本身。ToolSimulator用LLM生成工具返回值,让测试者不需要搭建真实的外部服务。这在以下场景特别有价值:
# AWS ToolSimulator: 模拟工具返回值
from strands_agents.eval import ToolSimulator
simulator = ToolSimulator()
# 注册工具并配置模拟场景
@simulator.register("database_query")
def simulate_db(tool_name, args, state):
if state.get("db_down"):
return {"error": "Connection refused", "status": 500}
if "SELECT * FROM users" in args["sql"]:
return {"rows": [{"id": 1, "name": "test_user"}]}
return {"rows": []}
# 运行模拟评估
result = simulator.evaluate(
agent=my_agent,
scenarios=[
{"input": "查询所有用户", "state": {"db_down": False}},
{"input": "查询所有用户", "state": {"db_down": True}}, # 故障场景
]
)
变现评估:Simulation层是目前Agent测试领域最热的赛道。LangWatch已获得种子轮融资,其Scenario框架的开源策略明显是在建立生态壁垒。训练营方向——"7天从Mock到Simulation"——可以定价¥2499,因为涉及LLM-as-Judge的调优技巧,门槛明显高于单纯的pytest。
这是2026年最被低估的测试层。问题看似简单:"Agent持有的工具Schema描述,和后端API的实际行为,是否还一致?"
答案是:在大多数生产环境中,它们已经不一致了,只是你不知道。
后端团队改了API的字段名、增加了必填参数、调整了枚举值范围——这些变更在传统微服务中通过Swagger/Pact contract test捕获。但在Agent系统中,工具Schema是写在prompt或JSON配置中的静态描述,和后端代码没有任何编译期绑定。Schema漂移是静默发生的,Agent不会报错,只会产生越来越离谱的工具调用参数。
DriftGentic是2026年新出现的专治这个问题的工具,核心理念是"在Agent和工具之间插入契约验证层":
# DriftGentic: 工具调用契约验证
from driftgentic import ContractGuard, ToolContract
# 定义工具契约
weather_contract = ToolContract(
name="get_weather",
input_schema={
"type": "object",
"properties": {
"city": {"type": "string", "minLength": 1},
"units": {"type": "string", "enum": ["celsius", "fahrenheit"]}
},
"required": ["city"]
},
output_schema={
"type": "object",
"properties": {
"temperature": {"type": "number"},
"condition": {"type": "string"}
},
"required": ["temperature", "condition"]
},
# 后端API的OpenAPI spec URL,用于自动漂移检测
backend_spec_url="https://api.weather.com/openapi.json",
drift_detection="auto" # 自动对比Schema差异
)
# 在Agent中注册契约守卫
guard = ContractGuard(contracts=[weather_contract])
# Agent每次工具调用都会经过验证
agent = MyAgent(middleware=[guard])
DriftGentic的工作流程分三个阶段:
Zylos在2026年4月的研究中提出了Agent工具契约的四个层次,比传统的Pact契约更细粒度:
| 契约层次 | 验证内容 | 示例 |
|---|---|---|
| Schema契约 | 参数类型和结构 | city必须是string,非空 |
| 语义契约 | 参数含义和取值范围 | city必须是真实城市名 |
| 行为契约 | 工具调用的副作用 | delete_user必须先调用confirm |
| 时序契约 | 工具调用的先后顺序 | 必须先search再book |
变现评估:Contract层是目前商业化空间最大的测试层。DriftGentic已采用SaaS模式(免费层+按调用量计费)。对于企业客户,"API漂移检测Agent工具调用"是一个可以直接卖钱的能力——尤其是金融、医疗等强监管行业,工具调用参数错误可能导致合规事故。训练营方向:"Schema First Agent开发"——教工程师从契约出发设计Agent工具,定价¥1999。
"改了prompt之后,Agent的工具调用行为是不是退步了?"这是每个Agent开发者在凌晨2点面对的问题。Golden Dataset层的答案是:用一组经过人工审核的标准测试用例,作为CI/CD的门禁。
Google ADK(Agent Development Kit)在2026年内置了最完整的Golden Dataset方案。核心流程是:
.test.json文件,成为Golden Dataset# Google ADK: Golden Dataset回归测试
from google.adk.evaluation import AgentEvaluator
evaluator = AgentEvaluator(
agent=my_agent,
test_files=["tests/golden/booking.test.json"],
metrics=[
"tool_selection_accuracy", # 工具选择正确率
"tool_args_match_rate", # 参数匹配率
"trajectory_similarity", # 轨迹相似度(非精确匹配)
"final_response_quality" # 最终回复质量
],
# 设置通过阈值
thresholds={
"tool_selection_accuracy": 0.95,
"tool_args_match_rate": 0.90,
"trajectory_similarity": 0.85
}
)
# 运行评估——可作为pytest用例
results = evaluator.evaluate()
# 如果任何指标低于阈值,返回非零退出码,CI失败
assert results.all_passed, f"回归测试失败: {results.failures}"
这里最值得注意的是trajectory_similarity——它不要求Agent每次走完全相同的工具调用路径,而是用语义相似度评估。这解决了一个核心矛盾:
Agent的不确定性意味着同一问题可能有多条合理的工具调用路径。例如"订一张北京到上海的机票",Agent可能先查航班再订票,也可能先查余额再查航班再订票。两条路径都是正确的,但精确匹配只会通过其中一条。
ADK使用embedding相似度评估轨迹的语义等价性,阈值为0.85时能过滤掉真正的回归(比如忘了调用支付工具),同时容忍合理的路径变化。
promptfoo(原promptfoo,2026年已获A轮融资)走的是框架无关路线——不绑定任何Agent框架,通过配置文件定义Golden Dataset:
# promptfoo: 工具调用回归测试配置
tests:
- description: "天气查询应该调用get_weather工具"
vars:
query: "北京明天天气"
assert:
- type: tool-call
tool: get_weather
args:
city: "北京" # 支持模糊匹配
- type: contains
value: "温度"
- description: "航班预订应先搜索再预订"
vars:
query: "帮我订明天北京到上海的机票"
assert:
- type: tool-call-sequence
sequence: [search_flights, book_flight]
- type: latency
threshold: 5000 # 响应时间不超过5秒
变现评估:Golden Dataset层的变现路径最清晰——它是企业Agent上线前的必经关卡。ADK内置了但只支持Google生态,promptfoo跨框架但需要付费版才有CI集成和团队协作。训练营方向:"Agent QA工程师认证"——涵盖Golden Dataset设计、阈值调优、CI/CD集成,可以定价¥3499。
前四层都是在部署前验证,但工具调用的问题有一半以上发生在部署后——API突然变慢、第三方服务改了返回格式、并发量上来后超时。你无法修复你看不见的问题。
2026年,Agent工具调用的可观测性已经收敛到OpenTelemetry(OTel)标准。所有主流框架——LangChain、CrewAI、OpenAI Agents SDK、Claude Agent SDK——都支持通过OTel导出trace数据。这意味着你不再需要为每个框架学一套调试工具。
graph LR
A["Agent Run Span<br/>trace_id: abc123"] --> B["LLM Call Span<br/>model: gpt-4.1"]
A --> C["Tool Call Span<br/>tool: get_weather"]
C --> D["HTTP Request Span<br/>api.weather.com"]
C --> E["Tool Response Span<br/>status: 200"]
A --> F["LLM Call Span<br/>model: gpt-4.1"]
F --> G["Tool Call Span<br/>tool: book_flight"]
style C fill:#fff3e0
style G fill:#fff3e0
style D fill:#e8f5e9
style E fill:#e8f5e9
在这个标准结构中,每次工具调用都是一个Span,包含:
- tool.name:工具名称
- tool.args:调用参数(可脱敏)
- tool.result:返回值摘要
- tool.duration_ms:执行耗时
- tool.status:成功/失败/超时
- llm.tokens.used:本次调用消耗的Token数
Langfuse v3(2026年最新版本)是目前OTel生态中Agent调试体验最好的平台。它提供了工具调用瀑布图——可视化展示Agent的每一步工具调用,包括耗时、参数、返回值,以及LLM的决策推理过程。
关键功能包括: - 工具调用热力图:一眼看出哪些工具调用最慢、失败率最高 - Token归因:精确到每个工具调用的Token消耗 - 对比视图:并排对比两次Agent运行的工具调用差异 - 回放功能:重放历史工具调用序列,定位问题根因
| 平台 | 核心优势 | 工具调用调试特色 | 定价 |
|---|---|---|---|
| Langfuse | 开源、OTel原生 | 工具调用瀑布图、对比视图 | 免费(自托管)/ 按量 |
| LangSmith | LangChain生态深度集成 | 与LangGraph工具节点自动关联 | 按Trace量计费 |
| Arize Phoenix | 本地优先、零外部依赖 | 嵌入式notebook调试体验 | 免费(本地)/ 按量 |
变现评估:Observability层的商业化已相当成熟,Langfuse和LangSmith都有清晰的SaaS模式。训练营方向——"Agent可观测性实战"——教工程师从OTel instrumentation到Langfuse仪表盘搭建,定价¥1999。
前五层都假设世界是正常的。但生产环境不是——LLM API会失败(1-5%的错误率),第三方工具会超时,数据库会宕机。Agent在工具调用失败时的行为,决定了它是玩具还是产品。
2026年,Agent混沌工程出现了专用工具:agent-chaos(REAATech开源)和Microsoft Agent Governance Toolkit内置的混沌测试模块。
agent-chaos的设计非常优雅——它作为中间件插入Agent和工具之间,不需要修改Agent代码:
# agent-chaos: 工具调用故障注入
from agent_chaos import ChaosMiddleware, FaultConfig
chaos = ChaosMiddleware(
faults=[
# 10%概率让天气API超时
FaultConfig(
tool_name="get_weather",
fault_type="timeout",
fault_rate=0.10,
delay_ms=30000 # 30秒超时
),
# 5%概率让支付API返回500错误
FaultConfig(
tool_name="process_payment",
fault_type="error",
fault_rate=0.05,
error_code=500,
error_message="Internal Server Error"
),
# 3%概率让搜索API返回空结果
FaultConfig(
tool_name="search_flights",
fault_type="empty_response",
fault_rate=0.03
),
],
# 安全限制
blast_radius="single_tool", # 只影响单个工具
auto_rollback=True, # 异常时自动回滚
max_concurrent_faults=1 # 最多同时注入1个故障
)
# 包装Agent
agent = BookingAgent(middleware=[chaos])
result = agent.run("帮我订一张北京到上海的机票")
# 检查Agent是否正确处理了故障
print(chaos.report())
# 输出:故障注入次数、Agent重试次数、降级行为统计
Zylos Research在2026年4月的报告中提出了Agent混沌测试的三个核心指标:
故障恢复率(Recovery Rate):工具调用失败后,Agent能否通过重试、降级或替代路径完成任务。生产级Agent应达到80%以上。
级联失败率(Cascade Failure Rate):一个工具的失败是否会触发连锁反应导致整个任务失败。这是Agent架构健康度的核心指标。
优雅降级评分(Graceful Degradation Score):Agent在部分工具不可用时,能否给用户一个有意义的回复(而非报错堆栈)。
graph TD
subgraph "混沌工程四阶段"
A["1. 基线测量<br/>正常状态下工具调用成功率"] --> B["2. 故障注入<br/>超时/错误/空结果"]
B --> C["3. 行为观测<br/>Agent是否重试/降级/报错"]
C --> D["4. 韧性评分<br/>Recovery Rate / Cascade / Graceful"]
end
D -->|"不达标"| E["修复Agent重试/降级逻辑"]
E --> A
D -->|"达标"| F["进入下一轮更强故障"]
F --> B
style A fill:#e3f2fd
style B fill:#fff3e0
style C fill:#f3e5f5
style D fill:#e8f5e9
变现评估:Chaos层是所有测试层中门槛最高的,也是商业价值最大的。企业Agent上线前必须经过韧性验证——尤其是金融、医疗等高可用场景。agent-chaos是开源的,但围绕它的咨询服务("我们帮你做Agent混沌工程审计")可以定价¥5万-20万/次。训练营方向受限,因为需要生产环境才能练手。
不是所有团队都需要六栈全上。根据团队规模和Agent复杂度,推荐以下路径:
| 阶段 | 团队规模 | 推荐栈组合 | 预计投入 |
|---|---|---|---|
| 起步期 | 1-3人 | L1(Mock) + L5(OTel) | 1周 |
| 成长期 | 3-10人 | L1 + L2(Simulation) + L4(Golden) + L5 | 2-3周 |
| 成熟期 | 10+人 | L1-L5全上 + L6(Chaos)按需 | 1-2月 |
| 企业级 | 50+人 | 六栈全上 + 专职QA团队 | 持续投入 |
# GitHub Actions: Agent工具调用测试Pipeline
name: Agent Tool Call Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
# L1: Mock/Replay测试(最快,必须通过)
- name: Unit Mock Tests
run: pytest tests/unit/ --with-evalcraft
# L3: Contract验证
- name: Schema Drift Detection
run: driftgentic check --contracts ./contracts/
# L4: Golden Dataset回归
- name: Golden Dataset Regression
run: |
adk evaluate --test-dir tests/golden/ \
--threshold tool_selection_accuracy=0.95 \
--threshold trajectory_similarity=0.85
# L2: Simulation测试(可选,PR时触发)
- name: Simulation Tests
if: github.event_name == 'pull_request'
run: scenario run --simulator gpt-4.1 --judge claude-sonnet-4-20250514
# L6: Chaos测试(仅main分支,夜间运行)
- name: Chaos Engineering
if: github.ref == 'refs/heads/main'
run: agent-chaos run --config chaos-config.yaml --report chaos-report.json
一个容易被忽视的问题是六栈之间的数据格式不统一。evalcraft用JSON磁带、Scenario用自定义trace格式、DriftGentic用JSON Schema、ADK用.test.json、OTel用protobuf、agent-chaos用自己的report格式。六栈之间的数据不能互操作。
2026年下半年可能的收敛方向是OTel成为统一基础——所有测试层都输出OTel格式的trace数据,这样一次测试运行的数据可以同时被六栈的所有工具消费。Langfuse已经在向这个方向演进,其v3版本可以直接消费evalcraft和Scenario的输出。
测试不是成本,是杠杆。 在工具调用领域,没有测试的Agent等于没有刹车的汽车。六栈体系的价值不在于每层都多完善,而在于找到你的Agent当前最脆弱的那个环节,用对应的测试层加固它。
对于大多数团队,起步的最佳组合是L1(Mock) + L5(Observability)——前者确保开发期质量,后者确保运行期可见。当Agent进入生产环境后,按需加入L3(Contract)防止Schema漂移、L4(Golden)守住回归底线。L2(Simulation)和L6(Chaos)是锦上添花,适合有专职QA团队的组织。
2026年最值得关注的趋势是OTel统一六栈数据格式和DriftGentic这类契约工具的商业化。前者降低集成成本,后者解决了一个真实且紧迫的痛点——你的Agent正在用过期的Schema调用已经变了的后端API。
[!tip] 51学通信知识星球 星主:爱卫生(微信:gprshome201101)——公众号「51学通信」创办者,19 年通信行业运维与讲师经验,著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书(各大电商平台有售)。 星球定位:深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域,主打运维岗位与信令分析。 当前规模:5200 篇主题 / 990 个回答,198 元/年。 加入福利:加入星球后请加爱卫生微信,拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题,另有群内分享。 AI 加持:51学通信知识星球已作为 skill 接入 WorkBuddy,使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例,做总结、找文档和 PPT 等场景全覆盖。
