让 Agent 测试不止停在‘调用成功’:用 CATT 验证服务端真实结果
AI Agent 调用了 MCP 工具、返回了“预订成功”,测试就算通过了吗?未必。工具调用成功只说明请求走完了,不代表数据库里真的只有一笔订单,也不代表用户看到的答案没有夸大。Consumer Agent Testing Tool(CATT)把测试重点放到服务端的实际结果:让脚本或模型驱动的 Agent 执行场景,再检查服务状态、审批边界和最终回答。
CATT 是 MIT 许可的 Python 项目,面向 MCP 服务、MCP App、网站和 HTTP API。它以“替身宿主”模拟 Agent 使用服务的环境,而非复刻某个商业助手的私有实现。因此,测试通过不能当作与 Muse 或 Instinct 等托管产品兼容的认证;项目 README 对各行为的依据也区分 documented、unofficial、assumed 和 unknown。这个边界很重要:测试结论应与其模拟范围一起阅读。
从工具调用转向可观察的结果
以预订流程为例,场景可以规定 Agent 可用哪些工具、哪些操作要审批,以及哪些个人信息不能暴露给模型。CATT 运行后,不只记录工具返回值,还能核验服务端私有状态,例如是否只生成一笔确认订单、有没有重复扣款,并检查 Agent 的最终回答是否虚报结果、遗漏金额或确认信息。这样,“工具返回 200”与“业务结果正确”就不再被混为一谈。
仓库提供 connector lane、MCP Apps、浏览器和 HTTP API 等测试路径。各路径的成熟度与前置条件不同:例如浏览器场景使用 Chromium;部分 API 验证需要本地部署和私有控制适配器;Linux 上若干依赖 macOS Seatbelt 的离线能力并不支持。开始前应以 README 的能力表和对应文档为准,不要把实验性扩展当成稳定功能。
用内置 fixture 跑一个可重复案例
项目要求 Python 3.12 或更新版本及 uv。克隆仓库后,connector lane 的基础依赖可以通过 uv sync 安装。启动示例服务:
uv run python -m consumer_agent_testing_tool.connector_fixture --port 8765 --variant good --auth none
在另一终端,用仓库自带的场景与脚本执行测试:
uv run consumer-agent-testing-tool connector-run examples/connector/fixture-booking.yaml \ --driver scripted --script examples/connector/fixture-booking.calls.json
这是 scripted driver,不需要模型账户或付费推理。示例会执行房间查询、报价、预订并生成回答;测试主机随后检查 fixture 的私有 oracle、预订状态、审批与回答约束。成功运行会输出报告路径,且在所有必需检查通过时以退出码 0 结束。不要把报告目录直接公开:项目提示其中的 private/ 保存主机侧私有值;需要分享时使用工具提供的 export 流程。
需要测试自己的 MCP 服务时,可先用 scaffold 读取工具目录并生成场景骨架,再将其中的 TODO(scaffold) 全部补齐。该命令不会调用服务工具;生成的草稿不是已经验证过的测试。运行前要审查工具 allowlist、私有数据、审批条件和结果断言,尤其避免让 Agent 接触环境变量读取等不必要能力。
把证据纳入开发循环
CATT 的价值不在于“多跑几次 Agent”,而在于把测试断言落到 Agent 之外可观察的事实。一个实用流程是:先用 scripted 测试验证确定性边界;再按需加入模型驱动试验,比较不同运行的结果;将失败报告、场景版本和服务端 oracle 一起纳入 CI。模型驱动运行可能产生推理费用,项目的 doctor 默认不会发起模型请求,只有显式加 --model-preflight 才会发送两次短请求。
同时应把失败分类:服务状态不符、审批策略被绕过、最终回答虚构,分别指向不同修复层。若检查本身不可观察或运行受环境限制,应报告 blocked/unsupported,而不是把“无法判断”算作通过。这样的保守结论,比一条绿色的工具调用日志更能保护真实业务。
相关链接