Agent 框架评测实验室系列:如何测出企业场景中的真实强弱
“LangGraph、OpenAI Agents、PydanticAI、Google ADK,到底哪个更强?”
这句话听起来像一个排行榜问题,实际上至少藏着六个不同问题:谁更容易写出第一个 demo,谁在同一模型下更省 token,谁能安全暂停审批,谁能在进程崩溃后恢复,谁的原生抽象更适合复杂工作流,谁的运行证据足以通过企业审计。
如果不先限定业务场景和风险边界,“最强框架”没有可验证的含义。
我在开发 Agent Framework Lab 的过程中,逐步把框架测验从“同一个 prompt 跑一遍”改造成一条证据链:冻结任务、提示词、工具、模型和价格;交错重复执行;注入审批、取消、工具故障、worker 崩溃和进程重启;保存不可变原始结果;最后才按自定义权重生成比较结果。
这个系列整理 Lab 的核心理念、方法、代码、失败经验和阶段记录。它既是项目复盘,也是未来开发其他 Agent 测验项目时可以复用的设计手册。
系列文章
- 别急着问哪个 Agent 框架最好:先把比较问题定义对
- 把企业需求写成可执行的 Agent 评测契约
- 不注入故障,就测不出 Agent 框架的生产能力
- 从原始运行到排行榜:硬门、权重与统计陷阱
- Agent Framework Lab 开发实录:从比较 demo 到企业就绪 Alpha
此前发布的《Agent 框架开发与评测踩坑实录》是本系列的代码型伴读,集中记录事件账本、审批绑定、幂等键、价格表和 ground truth 等十二类工程坑。
一张图理解 Lab
场景 / Prompt / 工具 / 模型 / 价格 / 限额
│ 冻结并版本化
▼
Framework Adapter Matrix
┌──────────┴──────────┐
│ 公平公共赛道 │ 原生上限赛道
│ 同输入、同工具 │ 原生图、handoff、checkpoint
└──────────┬──────────┘
▼
正常运行 + 固定故障注入
▼
Raw Result / Events / Artifacts
▼
硬性 No-Go → 加权能力画像
▼
Go / Conditional-Go / No-Go
这套方法最重要的变化,是不再把框架看成一个只负责“调用模型”的 SDK。企业应用真正关心的是一整组能力:任务质量、安全治理、故障恢复、审计、成本、延迟、可运维性、开发体验和迁移成本。
别急着问哪个 Agent 框架最好:先把比较问题定义对
这是 Agent 框架评测实验室系列第一篇。
“框架强弱”不是一个单变量
比较两个 Agent 框架时,最容易犯的错误是:给它们各写一套最顺手的 prompt 和工具包装,跑一次,然后按最终答案打分。这样同时改变了框架、提示词、工具协议、错误恢复和输出解析,最后根本不知道分数差异来自哪里。
真正可回答的问题应该写成:
在指定企业任务、风险策略、运行环境、模型、工具和成本口径下,哪个框架更适合,弱点在哪里,证据是什么?
每轮实验只能有一个主要变量。测框架,就冻结任务、prompt、工具、模型、provider、temperature、token limit、价格、执行顺序和评分策略;测模型,就冻结框架;测 prompt,也不要同时升级工具。
公平与原生能力之间的矛盾
统一输入可以保证公平,但统一适配层也可能抹掉框架特长。例如把所有框架都压成一个普通 ReAct 循环,就测不出 LangGraph 的图状态与恢复,也测不出 OpenAI Agents 的 handoff 和原生 lifecycle。
Lab 因此采用两条赛道。
受控公共赛道
每个框架拿到同一份版本化任务、prompt、工具、模型和输出契约。它测的是:
- 工具协议是否稳定;
- 最终任务是否完成;
- token、延迟和调用次数;
- 是否越权或违反输出协议;
- 同样输入下的失败率。
它回答“相同条件下谁执行得更好”,但不代表框架能力上限。
原生上限赛道
允许框架使用推荐的 graph、handoff、checkpoint、memory、审批和恢复能力,但业务结果与治理门槛仍相同。新增的代码、依赖、配置和运维复杂度都要记录。
它回答“按框架原生方式开发,谁更适合这个企业结果”。
两条赛道不能不加说明地合并成一个榜单。一个框架可能公共赛道非常轻巧,原生赛道缺少持久恢复;另一个可能代码更多,但长流程恢复明显更强。这不是矛盾,而是能力画像。
先画能力向量,再算总分
企业框架至少要从这些维度观察:
| 维度 | 典型证据 |
|---|---|
| 任务效果 | 完成率、rubric 分、结构化协议 |
| 安全治理 | 工具授权、审批绑定、数据边界 |
| 可靠恢复 | 工具失败、取消、崩溃、重启、幂等 |
| 可审计性 | 事件无缺口、trace、工件哈希、lineage |
| 效率 | token、成本、模型/工具调用数、p50/p95 延迟 |
| 可运维性 | 安装、诊断、升级、依赖足迹 |
| 开发体验 | 类型安全、测试难度、适配器代码量 |
| 可迁移性 | 对模型、provider、工具协议的耦合 |
前五项可以主要由运行证据产生;可运维性和开发体验通常需要版本化人工 rubric。二者必须分开标注,不能把主观评分伪装成遥测数据。
公平执行还要处理时间偏差
如果先把框架 A 的 30 次全部跑完,再跑框架 B,模型网关的负载、限流和模型版本可能已经变化。正确顺序是交错:
Agent 框架开发与评测踩坑实录:从能跑到可审计、可比较
很多 Agent demo 的成功标准是:“模型能调用工具,最后返回一个答案。”
本文现作为《Agent 框架评测实验室系列》的代码型伴读;系列正文进一步讨论公平赛道、企业场景、故障证据、评分统计和项目演进。
但只要把它放进真实系统,问题马上变成另一组问题:任务执行到一半进程崩了怎么办?审批通过的到底是哪一次工具调用?工具重试会不会重复扣款?两个框架比较时,是否真的使用了同一份提示词和工具?模型价格变化后,旧实验的排名还能不能复算?
我在 Agent Framework Lab V2 RC 中把这些问题做成了一个可以运行、恢复、审计和比较的实验台。本文不讲“Agent 很有前景”,只记录实现过程中最容易被低估的坑、最终采用的设计,以及可以直接复制的代码片段。
先给结论:Agent 评测是一条证据链
可信的评测结果必须能回答:这次运行用了哪个框架、模型、provider、提示词和工具?模型调用、工具调用、审批、checkpoint 的顺序是什么?崩溃或重启后哪些动作被恢复,哪些动作绝不能重放?结果怎么评分?换一组权重后能否只重算排名?排名是否因为 ground truth 写错了?
因此数据流不是:
prompt -> model -> score
而是:
任务契约 + 模型契约 + 工具契约
↓
append-only 运行事件
↓
不可变 RunResult 原始证据
↓
可重算的 ScoreProfile
↓
排名、图表和审计报告
坑一:把“任务成功”和“评分高”混成一件事
一次运行可能在运行时层面成功完成,但答案质量只有 60 分;反过来,一个答案看起来不错,也不能掩盖未授权工具调用、预算超限或事件账本损坏。
Lab 将两者拆开:
class RunResult(BaseModel):
run_id: str
matrix_id: str
framework: str
case_id: str
status: Literal["completed", "failed", "blocked_gateway_contract", "unavailable"]
final_output: str = ""
tool_calls: list[ToolCallRecord] = []
model_calls: list[ModelCallRecord] = []
usage: Usage = Usage()
score: Score | None = None
trace_id: str | None = None
metadata: dict[str, Any] = {}
status == completed 只表示执行器完成生命周期;score.total 是评测器对结果的判断。模型返回错误 JSON 时,运行可以成功但结构化输出为 0;预算结算失败时,即使模型输出正确,也必须判为运行时失败;评分规则改变时,可以重算分数,但不能重写原始执行状态。
DeepSeek Harness 解读(四):minimal 真的是最小 Agent 吗?
这是 DSH 系列的最后一篇。我们之前问过:minimal preset 只有两个工具,它是否已经是最小化 Agent?答案是:对模型可见能力来说接近最小,对真实运行时来说并不是。
DSH 的四种 preset 不是四个产品
DSH 当前把 Agent 能力组合成几类 preset:
standard 完整 Coding Agent
ptc TypeScript Code Mode / PTC
minimal persistent bash + str_replace_editor
creator 运行时检查和插件实验
它们不是四个独立程序,而是同一个 Cordis Runtime 上的不同能力组合。
这一区分很重要:preset 决定的是某个 Agent Scope 可以看到和使用哪些能力,而不是重新启动一套完全不同的 Agent 实现。
minimal 为什么看起来很小
DSH 的 minimal 配置对模型暴露的主要能力只有:
1. persistent bash
2. str_replace_editor
同时它关闭或抑制了很多额外上下文:
- 不加载完整 Coding Agent 的复杂工具集;
- 不注入运行时上下文;
- 不使用默认的复杂压缩能力;
- 使用固定、短的系统提示;
- 让 Bash 在多个 step 之间保持状态。
相关实现可以直接看 minimal agent preset 和 minimal runtime 设计记录。