框架对比基准 — 三固定原则与「对账异常调查」任务规范
框架对比基准 — 三固定原则与「对账异常调查」任务规范
日期: 2026-08-10 阶段: Phase 2 - AI-native 参考架构 标签: #agent-framework #benchmark-methodology #vercel-ai-sdk-6 #fair-comparison
核心问题
W9 要做一件危险的事:横向对比四个 agent 框架(Vercel AI SDK 6 / Claude Agent SDK / OpenAI Agents SDK / LangGraph+Temporal)。危险在于——框架对比是技术博客最容易翻车的体裁:换了框架就换了模型、换了 prompt、换了任务、换了评分口径,最后那张「我们测了一圈,X 框架最好」的表,本质是把噪声当信号。架构师看这种文章第一反应是「你控制变量了吗」。
今天不写任何对比结论,只回答一个方法论问题:怎样让四个框架的对比在统计上可信? 答案是「三固定」——同任务、同 golden、同 eval。三者任一不固定,跨框架数字就不可比。今天把这条原则坐实成一份可执行的基准任务规范(对账异常调查 agent),并启动第一个框架实现(Vercel AI SDK 6,2025-12-22 发布)——选它打头是因为本仓 orchestrator 已经跑在 ai 包上(src/agent/orchestrator/orchestratorAgent.ts),迁移成本最低,能最快产出数据点#1 校验基准本身是否合理。
关键内容
A. 为什么必须「三固定」:框架对比的混杂变量陷阱
agent 框架对比的因变量是「质量/token/延迟」,自变量应该只有框架本身。但框架不是孤立的——每个框架都隐含了一套默认行为,若不固定,会引入三类混杂变量:
| 混杂源 | 不固定会怎样 | 固定方法 |
|---|---|---|
| 任务 | A 框架测「客服退款」、B 测「代码修复」,难度不同,数字无法对齐 | 同一个金融任务:对账异常调查 |
| 模型 | A 默认 claude-sonnet-4-6、B 默认 gpt-5,测的是模型差异不是框架差异 | 四框架全部锁 claude-sonnet-4-6(本仓 cost.ts 已登价) |
| golden | A 在 80 案上测、B 在 20 案上测,样本量与难度分布不同 | 同一份 golden(复用 P1 的 66/80 案 AML 金标子集) |
| eval 口径 | A 用「LLM 看着对」、B 用代码型断言,宽严不一 | 同一套 eval(复用 src/aml/evalChecks.ts + judge rubric) |
| prompt | A 用三句话系统提示、B 用两千字,质量差异来自 prompt 工程 | 同一份系统提示 + 同一组工具描述 |
反直觉洞察①(框架对比最大的谎言是「我们测了框架」,其实测的是默认配置):绝大多数「框架 X vs Y」博客的真实自变量是作者在每个框架上花的调优时间——作者更熟 X,就把 X 的 prompt 调得更好,于是 X「赢」了。要让对比可信,prompt/模型/工具描述必须逐字符相同,框架之间唯一允许不同的是「编排这堆工具调用的代码骨架」。本基准的纪律是:四份实现共享同一个
system.txt、同一个工具 schema 文件、同一个claude-sonnet-4-6模型 id;框架代码只负责「怎么把这些喂进 tool loop」。
控制变量后,跨框架数字才有因果解释力:质量差异 = 框架的 tool-loop 调度/重试/停止策略差异;token 差异 = 框架注入的脚手架 token(系统 wrapper、工具描述格式、中间步骤回灌)差异;延迟差异 = 框架的并发/串行 dispatch 与额外网络往返差异。
B. 基准任务规范:对账异常调查 agent
选「对账异常调查」而非通用任务,有三个理由:(1) 它是真实金融场景(10 年风控背景的差异化锚点);(2) 它天然是 multi-step + multi-tool(检索流水→匹配→定位差异→出结论),能压出框架的 tool-loop 能力;(3) 它能复用 AML 金标的交易数据结构(src/aml/types.ts 的 AmlCase.transactions),无需另造数据。
任务定义(冻结为 bench/reconciliation/spec.md):
输入:一个对账案件 = { 内部账本流水[], 外部对账单流水[], 期间 }
目标:agent 调用工具找出「内外不匹配的交易」并给出归因
工具集(四框架共享同一 schema):
- fetchLedger(period) → 内部流水(确定性 mock,读 golden 案件)
- fetchStatement(period) → 外部对账单流水
- matchByAmountAndDate(a, b) → 返回匹配/未匹配对
- classifyBreak(txPair) → 差异归因(时间差/金额差/缺失/重复)
- finalReport(breaks[]) → 结构化输出:异常清单 + 每条归因 + 置信度
终止条件:调用 finalReport 即停;或步数 ≥ 8(与 orchestrator stopWhen 对齐)
golden 构造:从 AML 金标抽 N=20 案,注入 4 类已知 break(人为埋点,确定性),每案标注「应被发现的 break 集合」作为答案键。这样 eval 可确定性判分:
break_recall = |agent 找到的 break ∩ 真实 break| / |真实 break|
break_precision= |agent 找到的 break ∩ 真实 break| / |agent 报告的 break|
hallucination = agent 报告了 golden 中不存在的 break 数(应为 0)
反直觉洞察②(基准任务要「确定性可判分」,不能用真实脏数据):直觉想用真实银行对账数据显得「实战」,但真实数据没有答案键——你无法确定性地说「agent 漏了哪笔」,只能再请人工标,又把人工一致率的不确定性叠进框架对比,噪声翻倍。框架对比基准必须用可判分的合成数据(埋点的 break = 答案键),把「评测的不确定性」压到零,才能让残差全部归因到框架。真实脏数据留给 P3 的 AML Copilot 端到端验收,不用于框架横评。
C. 评测维度表:四框架统一打分卡(CLASSIC 裁剪版)
框架对比要的不是单一「准确率」,而是一张多维卡。借 Aisera 的 CLASSIC 五维(Cost/Latency/Accuracy/Stability/Security,2026)裁剪——Security 维度并入 W8 已做的红队(不在框架横评重复),Stability 用「同一案件跑 k 次的结果方差」衡量。统一打分卡:
| 维度 | 指标 | 数据来源 | 判分方式 |
|---|---|---|---|
| Accuracy | break_recall / precision / hallucination | golden 答案键 | 确定性 |
| Cost | 单案 token(in/out 分列)× estimateCost | AI SDK usage / 各框架 usage 回调 | 确定性(cost.ts 登价) |
| Latency | 单案 wall-clock 中位数 + p95 | 包裹 agent 调用计时 | 确定性 |
| Stability | 同案 k=5 次的 recall 方差 / 输出 break 集合 Jaccard | 重复运行 | 确定性 |
| 工程性(额外) | LoC、类型安全、可观测接入难度 | 人工评分(标注主观) | 主观,单列 |
每框架对 20 案 × k=5 跑出 100 条 trace,token/latency 取中位数避免长尾污染。质量分用 evalChecks.ts 风格的确定性断言聚合(pass rate),不引入 LLM-judge——因为 break 集合可确定性比对,judge 在此是多余的不确定性源(呼应洞察②)。
D. Vercel AI SDK 6 实现启动:为什么它打头阵
AI SDK 6(2025-12-22 发布)把 Agent 提升为一等抽象——Agent 是接口,ToolLoopAgent 是生产级默认实现,处理完整 tool-loop。定义形态:
const reconAgent = new ToolLoopAgent({
model: 'anthropic/claude-sonnet-4.5', // 本基准锁 claude-sonnet-4-6
instructions: RECON_SYSTEM, // 四框架共享同一字符串
tools: { fetchLedger, fetchStatement, matchByAmountAndDate, classifyBreak, finalReport },
// stopWhen 默认 stepCountIs(20);本基准覆盖为 stepCountIs(8) 对齐 orchestrator
})
选它打头三个工程原因:(1) 本仓 orchestrator 已用 ai 包(generateText + tool() + stopWhen,见 orchestratorAgent.ts),AI SDK 6 的 ToolLoopAgent 本质是把现有 generateText({ tools, stopWhen }) 模式封装成可复用对象——迁移即「把散落的工具定义聚成一个 Agent 实例」,最低成本;(2) usage 回调直接喂本仓 estimateCost,token/cost 维度零额外代码;(3) AI SDK 6 的 @ai-sdk/mcp 已稳定 + rerank() 原生——为 W8 的 MCP server 与 hybridSearch 复用埋下接口。先用最熟的框架跑通基准,能在数据点#1 就暴露「基准规范本身是否有坑」(如工具 schema 描述歧义、终止条件不收敛),比在陌生框架上调试基准高效。
设计要点/决策表
| 要点 | 决策 | 理由 |
|---|---|---|
| 对比可信性 | 三固定:同任务/同 golden/同 eval | 不固定则数字测的是混杂变量不是框架 |
| 模型 | 四框架全锁 claude-sonnet-4-6 | 隔离框架变量,价已登在 cost.ts |
| prompt/工具 schema | 逐字符共享同一文件 | 防「作者熟谁谁赢」的隐性调优偏差 |
| 任务 | 对账异常调查(金融 + multi-tool) | 真实场景差异化 + 压 tool-loop 能力 |
| golden | 合成埋点 break = 确定性答案键 | 框架横评必须可判分,零评测不确定性 |
| eval | 确定性断言(recall/precision/halluc),不用 judge | break 可确定性比对,judge 是多余噪声源 |
| 打头框架 | Vercel AI SDK 6 | 本仓已用 ai 包,迁移成本最低 |
| 终止条件 | stopWhen=stepCountIs(8) | 对齐 orchestrator 现有 8 步上限 |
对本项目的落地
- 新建
bench/reconciliation/:spec.md(任务冻结规范,本笔记 B 节)、golden.ts(从getGoldenDataset()抽 20 案 + 埋 4 类 break + 答案键,内嵌常量,同retrievalGolden.ts模式)、tools.ts(五工具的共享 zod schema,四框架 import 同一份)、system.ts(RECON_SYSTEM单一字符串)。这四个文件是「固定层」,任何框架实现不得改它们——这是三固定的物理保证。 - 新建
bench/frameworks/aiSdk6/reconAgent.ts:用ToolLoopAgent(@ai-sdk/...v6)封装,model 锁claude-sonnet-4-6,instructions=RECON_SYSTEM,tools=tools.ts,覆盖stopWhen: stepCountIs(8);usage→estimateCost(复用src/agent/shared/cost.ts)。对照 orchestratorAgent.ts:现有 orchestrator 是generateText函数式写法,AI SDK 6 的ToolLoopAgent是其对象化封装——本实现验证「现有 orchestrator 能否平滑升级到 v6 Agent 抽象」,为作品①底座升级铺路。 - 评分器
bench/score.ts:对每框架的 trace 跑 C 节五维,输出统一 JSON(喂 agent-lab 跑分表);质量分复用evalChecks.ts的CheckResult结构(break 比对断言),token/cost 复用estimateCost,latency 用performance.now()包裹。 - 诚实标注:本日只冻结规范 + 启动 AI SDK 6 实现;四框架完整数据要到 Day 60 才齐。
spec.md头注明确「N=20、k=5 为 v1 规模,样本量小、结论仅在本金标分布内有效,禁止外推为框架普适排名」——与 day7「基线满分=口径一致非性能」同一诚实纪律。CI 不阻断 bench(bench 是研究产物非质量门),但 bench 跑通须过现有evalChecks不退化。
参考资料
- Vercel — AI SDK 6(vercel.com/blog/ai-sdk-6,2025-12-22 发布):Agent 一等抽象;
Agent接口 +ToolLoopAgent生产级实现;stopWhen默认stepCountIs(20);needsApproval工具审批;Output.object()结构化输出;@ai-sdk/mcp稳定(OAuth/resources/prompts/elicitation);rerank()原生(Cohere/Bedrock/Together)(2025-12) - Aisera — What is AI Agent Evaluation: A CLASSic Approach:CLASSIC 五维 Cost/Latency/Accuracy/Stability/Security;域内 agent 82.7% vs 通用 LLM 59-63%、成本低 4.4-10.8×(2026)
- Evaluation and Benchmarking of LLM Agents: A Survey(arXiv 2507.21504):agent 打破「固定题→金答案→确定性判分」的传统 benchmark 假设;系统指标 = 单任务 token / 延迟 / 工具调用频次 / 失败恢复(2025-07)
- InfoQ — Evaluating AI Agents in Practice:golden dataset 接 trace 防回归;trajectory benchmark(τ-bench/GAIA/OSWorld)vs 自建 golden(2026)
- 本仓物证:
src/agent/orchestrator/orchestratorAgent.ts(generateText+tool+stopWhen现状)、src/agent/shared/cost.ts(estimateCost/MODEL_PRICES)、src/aml/evalChecks.ts(CheckResult确定性断言)、src/aml/types.ts(AmlCase.transactions)、src/agent/eval/retrievalGolden.ts(内嵌 golden 模式)(2026-06)
SOTA 检查 (2026-08-10)
- Vercel AI SDK 6 是 TS 主栈生产首选(2025-12-22 GA,2026-08 仍当前大版本):Agent 一等抽象 + 稳定
@ai-sdk/mcp使其成为本仓(TS)最自然的框架升级路径;执行当周须npm view ai version确认 6.x 具体小版本(接口在 6.0 后可能微调,以官方 changelog 为准)。 - 「三固定」是框架对比的方法论底线,非本项目独创:arXiv 2507.21504 survey 明确 agent 打破传统 benchmark 的确定性假设,要求显式控制任务/数据/评分——本基准把它落成可执行的固定层文件,是对该共识的工程实现。
- CLASSIC 五维是 2026 企业 agent 评测主流框架之一:但「域内 82.7% vs 通用 59-63%」是 Aisera 自家口径,属厂商 benchmark,引用作维度框架可,引用作绝对数字须存疑(同 Day 60 将批判的 memory 厂商自报问题)——本基准只借其五维结构,不引其数字。
- 过时认知警示:(1) 不可用「LLM 看着对不对」做框架横评质量分——break 可确定性比对,judge 在此是多余噪声(洞察②);(2) 不可换框架时顺手换模型/prompt——那测的是混杂变量(洞察①)。
- 待跟踪:N=20/k=5 是小规模 v1,Day 58 跑出 AI SDK 6 数据点后复核「样本量是否足以让框架间差异显著」(若四框架质量分差 < 重复运行方差,则需扩 golden 或加任务难度);
ToolLoopAgent的stopWhen与本仓 orchestrator 的stopWhen: ({steps}) => steps.length >= 8语义是否完全等价,Day 58 实现时验证。