它是否具备足够的代理能力?使用你自己的工具对开放模型进行基准测试
摘要
这篇博客文章介绍了一种基准测试方法,用于评估开放模型在代理编程任务上的表现,不仅关注准确性,还关注代理过程的效率。它提供了一个使用 pi coding agent 的可定制工具框架,并在不同模型和库版本上进行测试。
查看缓存全文
缓存时间: 2026/06/18 17:40
它够“智能体化”吗?用你自己的工具对开放模型进行基准测试
来源:https://huggingface.co/blog/is-it-agentic-enough
返回文章列表 (https://huggingface.co/blog)
在不同指标上对 transformers 修订版进行基准测试
(https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/is-it-agentic-enough/img_6.png)
对不同指标上的 transformers 修订版进行基准测试
这是一篇由人撰写、聚焦智能体的博文。
编码智能体越来越多地代替我们使用软件:描述一个任务,智能体就自动挑选库、编写调用、运行并调试自己的错误。当库本身造成障碍时,它会乐意绕过它,从头重写逻辑。这给库开发带来了一个新概念:代码不仅要正确、高效,还要设计得让智能体能有效驱动它。一个笨拙的 API 或过时的文档会烦扰我们人类开发者,但现在也会让智能体走上一条更长、更昂贵的路径。
大多数基准测试只关注最终答案。而我们想要的是整个过程:不仅看智能体是否做对了,还要看它花了多少功夫才达到目标,以及这些指标在不同模型、库版本和任务之间的变化。我们以 transformers 作为案例,精确测量了这一点。
在这里,我们将介绍一个面向工具的特定基准测试,重点聚焦答案是如何找到的;并提供一个简单实现,完全运行在由 pi (https://www.npmjs.com/package/@mariozechner/pi-coding-agent) 编码智能体驱动的开放模型上,将完整模型 × 版本 × 任务的组合铺开到 Hugging Face Jobs (https://huggingface.co/docs/huggingface_hub/guides/jobs) 上,这样每次运行都能在完全相同的硬件上执行。
但是,如何为智能体优化软件呢?
我们坚信以下两条软件原则:
- 未经测试,等于无法工作
- 没有文档,等于不存在
在智能体优化的工具领域,这一点同样成立,而且这一次,两者直接相互关联。
你希望你的工具对智能体而言存在:它必须是可发现的。API 需要清晰,文档需要详尽。它们需要以智能体能快速访问到有用文件和示例的方式进行组织。如果你希望你的工具对智能体有效,那么你就应该为智能体使用而测试它。
为智能体使用测试软件
我们将以 transformers 作为贯穿本博文的例子:智能体使用它来解决机器学习任务(文本分类、图像描述、音频转录),而不是向其贡献代码;不过,这个测试框架的设计目标是能与任何可从命令行操作的工具配合使用。
我们对 transformers 的直觉是:通过几个改动——一个 CLI、一个 Skill 以及自包含的、面向任务的示例——可以大幅简化使用方式。这与最近应用于 hf CLI(已重新设计为智能体优化) (https://huggingface.co/blog/hf-cli-for-agents) 的方法相同,当时智能体的 token 用量减少了 1.3–1.8 倍(最高达 6 倍)。我们想知道这种收益是否具有普遍性,以及是否也能适用于 transformers。
直觉是强大的工具,但在我们向 transformers 这样一个广泛使用的代码库提交增加几千行代码的 PR 之前,我们需要更多证据。我们开始衡量成功究竟是什么样子。
并非所有成功都等同
两个智能体都能正确输出情感分类任务的标签,但其中一个:
- 编写一个 40 行的 Python 脚本,导入
transformers,调试一个形状错误,重新运行两次,最后打印答案;
而另一个:
- 输入
transformers classify --model ... --text "...",一个调用就完成了。
两者都得到 POSITIVE (0.9999),以下是智能体在此任务上实际走的两条路径:
# 任务:对 "I absolutely loved the movie, it was fantastic!" 进行情感分类
- # 智能体一:将脚本通过管道传给 python 并解析输出
- python - <<'PY'
- from transformers import AutoTokenizer, AutoModelForSequenceClassification
- import torch
- import torch.nn.functional as F
-
- model = AutoModelForSequenceClassification.from_pretrained("distilbert/distilbert-base-uncased-finetuned-sst-2-english")
- tokenizer = AutoTokenizer.from_pretrained("distilbert/distilbert-base-uncased-finetuned-sst-2-english")
- inputs = tokenizer("I absolutely loved the movie, it was fantastic!", return_tensors="pt")
- with torch.no_grad():
- logits = model(**inputs).logits
- probs = F.softmax(logits, dim=1)
- idx = torch.argmax(probs, dim=1).item()
- print(model.config.id2label[idx], probs[0][idx].item())
- PY
+ # 智能体二:一条命令
+ transformers classify \
+ --model distilbert/distilbert-base-uncased-finetuned-sst-2-english \
+ --text "I absolutely loved the movie, it was fantastic!"
两种方法都得到了相同的结果。但它们在成本、延迟、token 用量和失败情况上有着完全不同的表现。
如果你的评估只检查最终字符串,那么你就看不到这些差异,也不知道你推送到库中的改动(CLI 改进、更好的错误消息、一个 Skill)是否真的帮助了智能体。
我们设计这个测试框架的目标是评估一个智能体在完成给定任务时需要付出多少工作,以及对库的改动是否能提升性能。
我们如何进行评估?
简单说一下我们将如何评估智能体。
我们以三种变体(或称“级别”)运行每个任务;这是智能体面对 transformers 时可以采取的三种不同方式:
bare 仅 pip install transformers,没有其他内容
clone 完整的 transformers 源码,在工作目录中签出
skill 一个打包好的 Skill:CLI 的文档 + 任务示例,加载到上下文中
这些级别不是嵌套的:skill 不包含 clone(它提供的是精选文档,而非源码树),两者也不互斥,每个级别给智能体提供不同种类的帮助。我们将会看到,一个模型在 clone 级别上有时会比 skill 级别做得更好。
还有一些选择:
- 目前我们只关注那些能提供精确匹配的确定性任务,因为它们提供了极好的实验基础。模型作为评判者以及其他方案是其他任务下一步的明显方向。
- 每次运行都是一个独立的 Hugging Face Job:每个(模型 × 版本 × 任务)对应一个 job,因此整个组合可以在相同硬件上并行运行,确保大规模比较的公平性。
- 结果和跟踪放入 Hugging Face Bucket:速度快,不需要版本控制,且能处理非常高的写入并发。
以哪些模型作为基准对照?
并非所有驱动智能体的模型都同等,它们之间的差异会改变你在运行时应关注的内容。
大型开放模型
一方面,你拥有最大、能力最强的开放模型。对于相当常见的任务,它们最终应该能得到正确答案。对它们来说,任务完成率接近 100%,无法再提供关于你的工具的有用信息;一个更相关的基准是智能体完成任务的努力程度:它花费了多少轮、多少 token 和多少秒,以及它们是走了一条干净的路径还是使用了弃用的 API。
本地模型
本地模型的大小差异很大,它们的能力也各不相同。与大型模型相比,诸如**“匹配率 %”**等指标更为相关,因为你可以看到模型大小/能力如何影响在特定工具上的结果。
这个测试框架不仅为库维护者提供了如何改进仓库以适配智能体交互的指导,还能帮助评估不同的智能体和模型在用户关心的任务上的表现。
该框架从多个维度对每次运行进行评分,让你可以根据每类模型的实际需求进行提问:
- 匹配率 %:最终答案是否包含预期结果(按任务可以是大小写不敏感的子串/正则/精确匹配,所有内容在报告中明确列出);
- 中位时间和中位 token 数(新增 vs. 缓存 vs. 生成);
- 运行错误率 %:包括一个保护机制,标记那些产生了“无输出”的运行(0 个输出 token,没有工具调用,没有答案),以免静默失败伪装成“0”;
- 标记采用率:工具定义的行为标记;下面会解释这是什么。
所有内容汇总到一个你可以直接检查的报告中:
实时报告:概览、覆盖率与结果,全部在客户端运行。
由于它会捕获每次运行的原生智能体跟踪记录,数字只是开始:你可以逐条命令地阅读智能体做了什么。跟踪记录可通过 Hub 的智能体跟踪查看器 (https://huggingface.co/docs/hub/agent-traces) 共享:
在 Hub 的智能体-跟踪查看器中渲染的运行:MiniMax-M2.7 在 answer-question 任务上
在 Hub 的智能体-跟踪查看器中渲染的运行:MiniMax-M2.7 在 answer-question 任务上。
在 Hub 上打开此跟踪 ↗ (https://huggingface.co/buckets/lysandre/transformers-agentic-use/tree/traces/22404f7951/pi/MiniMaxAI–MiniMax-M2.7/bare__answer-question__run1.jsonl)
在结果之前,先快速回顾一下设置。每次运行变化四个要素:驱动智能体的模型、它运行的 transformers版本、任务以及级别(bare/clone/skill)。如之前讨论,对两类模型我们会关注不同的指标。
大型开放模型:固定模型,变化版本
由于大型开放模型通常能得出正确结果,你实际测量的是它为此付出的努力。它花了十轮还是一轮?它是否因为你弃用了某个 API 路径而因为信任过时的文档就用了它?它是否遇到了你未曾预见的错误?
自然的实验是固定一个强模型,变化工具的版本:我们测试的 transformers 的连续 git 版本,从 v5.8.0 和 v5.9.0 等已发布标签,到引入 CLI 和 Skill 的特定提交。我们想观察它对智能体施加的负载是上升还是下降。我们在 transformers 上使用该框架来检查添加专门的 CLI 和 Skill 是否确实减轻了智能体的工作量。
对于我们在测试中使用的三个大型模型,在所有任务上花费的平均时间表明,Skill 提交使得任务处理时间更短:
按版本和级别划分的中位时间
按版本和级别划分的中位时间:Skill 提交(绿点)是最快的。
另一方面,在克隆仓库的实验中,我们可以看到由于引入 CLI 和示例的提交,token 消耗显著增加,稍后会看到这一点。
按版本和级别划分的中位新 token 数
按版本和级别划分的中位新 token 数:一旦 CLI 进入仓库,clone 变体的 token 消耗就会跃升。
阅读 clone 变体的跟踪记录就能解释原因。该提交添加了一个命令,但它同时也将 CLI 的实现和一组 cli/agentic/*.py 使用示例直接发布到仓库中。
在 clone 变体下,智能体会面对一个完整的 transformers 检查点,大约三分之一的运行会先去阅读新的表面(/cli/ 树和示例脚本)来学习接口,然后才调用它。这使得中位输入 token 数从大约 4k 上升到大约 6.4k。
这两张图代表了一个权衡的两个方面:该提交为大型模型节省了时间(它们直接使用 CLI 而不是调试 Python 代码),代价是增加了 token 消耗(它们读取了教会它们使用 CLI 的代码)。在合并 PR 之前了解这个权衡是值得的。
不过,有一个权衡对 CLI 有利,但尚未纳入基准测试:读取成本的收益会在后续运行中摊销。我们的设置是为一次性实验构建的。每次运行都是一个全新的智能体,需要从头重新发现 CLI,所以每次都要付出发现成本。在实际使用中,智能体只需要学习一次接口,然后在同一个会话中一个接一个地解决问题,将成本分摊到多次请求中。我们这里测量的 token 增加更接近最坏情况,而不是用户日常会看到的情况。
小型模型:固定版本,变化模型
开放模型让我们对这里最重要的变量拥有精细的控制:大小、配置、量化、提供方、训练以及任何模型间可能不同的因素。它们也是优秀的工具表面最重要的地方:一个在 bare 环境下被要求“使用 transformers 做 X”的小模型可能会猜测一个几个版本前已经改变的 API,可能进行不必要的工具调用,并可能得到错误答案。
因此,这里的实验与上面相反:固定版本,改变模型。这有助于观察哪些模型确实能处理好任务,不仅仅是通过 token 数量和时间,而是深入到哪些模型无法可靠地处理工具调用。我们的直觉是,模型越小,工具使用和任务都越困难;为了验证这一点,我们在一系列模型大小上运行了框架:
按模型和级别划分的匹配率 %
按模型和级别划分的匹配率 %:skill 级别提升了较大模型的表现,但导致较小模型表现下降。
这似乎也与摄入的 token 数量相关:
按模型和级别划分的中位新 token 数
按模型和级别划分的中位新 token 数。
关于公平比较的说明:当覆盖率不均匀时(一个只完成了简单任务的模型看起来很快),简单地对所有任务取平均值会产生误导。报告包含一个**“仅共享任务”切换开关(跨模型和/或版本),以便你进行同质比较;还有一个覆盖率**热力图,让你精确看到哪些任务 × 版本 × 模型单元实际运行了。
调整工具:标记与结果
这里有两件事汇聚在一起:如何超越智能体是否成功,深入观察它做了什么以及如何做的;以及我们从框架中提取的初步结果。
什么是标记?
匹配率、token 数和时间告诉你一次运行的成本,但并不能告诉你太多关于底层发生了什么的信息。
这就是为什么我们引入了…(原文内容被截断,但根据上下文,应该是继续解释标记的概念。由于原文在此处戛然而止,我假设这是博客的剩余部分。但根据指令,我们需要完整翻译提供的markdown内容。我们看到原文最后是“这就是为什么我们引入了…”,但实际上原文的Markdown在此处结束?检查原文:原文在“Tweaking the tool: markers and results”小节下的“What’s a marker?”子节中,最后一句是“This is why we’ve i……”——显然被截断了。但作为翻译任务,我们只能翻译已知内容。所以翻译到此处结束,包括被截断的部分。)
这就是为什么我们引入了…(原文未完整提供)
相似文章
我用4B参数模型构建的编码智能体在基准测试中达到87%,诀窍如下
作者构建了SmallCode,一个针对小型本地模型优化的编码智能体,通过复合工具、改进循环和令牌预算等技术,在4B参数模型上实现了87%的基准测试成功率。
合并你PR的智能体,尚无基准可循。
Artificial Analysis 推出了一个编码智能体指数,该指数分别测试框架与模型的组合,强调基准测试任务与实际生产需求不同。文章认为,团队应基于自身的代码库和工作流来评估智能体配置,而非仅依赖标准化基准。
利用智能体编写高效的工具——借助智能体本身
Anthropic 分享了为 AI 智能体设计、评估和优化工具的工程最佳实践,特别介绍了如何利用模型上下文协议(MCP)和 Claude Code 来提升智能体的性能。
@Ali_TongyiLab: https://x.com/Ali_TongyiLab/status/2067158015615041755
AgentScope团队推出了PawBench,这是一个用于评估模型与代理框架综合性能的基准测试。通过对4,050个测试单元的分析,结果表明框架选择的影响堪比模型升级。
AA 推出 Coding Agent Index —— 模型与 Harness 组合的性能对比
Artificial Analysis 推出了 Coding Agent Index,这是一套新的基准测试套件,结合了 SWE-Bench-Pro-Hard-AA、Terminal-Bench v2 和 SWE-Atlas-QnA,旨在评估 AI 编程代理在多样化任务中的表现。