翻译自 Vercel 博客文章:AGENTS.md outperforms skills in our agent evals

我们原本期望技能是教授编码智能体框架特定知识的解决方案。在构建专注于 Next.js 16 API 的评估后,我们发现了意想不到的结果。

直接嵌入在 AGENTS.md 中的压缩版 8KB 文档索引实现了 100% 的通过率,而技能即使在明确指示智能体使用它们的情况下,最高也只能达到 79%。如果没有这些指示,技能的表现与完全没有文档时没有区别。

以下是我们尝试的方法、我们学到的经验,以及如何在自己的 Next.js 项目中设置这一功能。

我们试图解决的问题

AI 编码智能体依赖于会过时的训练数据。Next.js 16 引入了 'use cache'connection()forbidden() 等 API,这些 API 并不在当前模型的训练数据中。当智能体不了解这些 API 时,它们会生成不正确的代码或回退到旧的模式。

反之也可能发生——你运行的是较旧版本的 Next.js,而模型建议了你的项目中尚不存在的新 API。我们希望通过向智能体提供版本匹配的文档来解决这个问题。

教授智能体框架知识的两种方法

在深入探讨结果之前,先简要介绍一下我们测试的两种方法:

  • 技能是一种开放标准,用于封装编码智能体可以使用的领域知识。一个技能将智能体可以按需调用的提示、工具和文档捆绑在一起。其理念是智能体在意识到需要特定框架的帮助时调用该技能,并获取相关文档。
  • AGENTS.md 是项目根目录中的一个 Markdown 文件,为编码智能体提供持久上下文。无论你在 AGENTS.md 中放入什么内容,智能体在每个回合都可以使用,而无需智能体决定加载它。Claude Code 使用 CLAUDE.md 来达到相同的目的。

我们构建了一个 Next.js 文档技能和一个 AGENTS.md 文档索引,然后将它们通过我们的评估套件,看看哪种表现更好。

我们最初押注于技能

技能似乎是正确的抽象。你将框架文档打包成一个技能,智能体在处理 Next.js 任务时调用它,然后你就能得到正确的代码。职责分离清晰,上下文开销最小,智能体只加载它需要的内容。甚至在 skills.sh 上还有一个不断增长的现成技能目录。

我们期望智能体遇到 Next.js 任务,调用技能,阅读版本匹配的文档,然后生成正确的代码。

然后我们运行了评估。

技能没有被可靠地触发

在 56% 的评估案例中,技能从未被调用。智能体可以访问文档但没有使用它。添加技能相比基线没有产生任何改进:

配置 通过率 相比基线
基线(无文档) 53%
技能(默认行为) 53% +0pp

零改进。技能存在,智能体可以使用它,但智能体选择不使用。在详细的构建/Lint/测试细分中,技能在某些指标上实际上表现比基线更差(测试方面为 58% vs 63%),这表明环境中未使用的技能可能会引入噪声或干扰。

这并非我们设置所独有。智能体不能可靠地使用可用工具是当前模型的一个已知局限性。

明确指令有帮助,但措辞很脆弱

我们尝试在 AGENTS.md 中添加明确指示,告诉智能体使用该技能。

Before writing code, first explore the project structure,
then invoke the nextjs-doc skill for documentation.

这提高了触发率到 95% 以上,并将通过率提升到 79%。

配置 通过率 相比基线
基线(无文档) 53%
技能(默认行为) 53% +0pp
带明确指令的技能 79% +26pp

一个实质性的改进。但我们发现指令措辞影响智能体行为的方式有些出乎意料。

不同的措辞产生了截然不同的结果:

指令 行为 结果
"你必须调用技能" 先阅读文档,以文档模式为锚点 错过项目上下文
"先探索项目,再调用技能" 先构建心理模型,使用文档作为参考 更好的结果

相同的技能。相同的文档。基于微小的措辞变化产生不同的结果。

在一个评估('use cache' 指令测试)中,"先调用"的方法编写了正确的 page.tsx,但完全错过了所需的 next.config.ts 更改。"先探索"的方法两者都得到了。

这种脆弱性让我们担心。如果微小的措辞调整会导致巨大的行为变化,这种方法在生产环境中感觉会很脆弱。

构建我们可以信任的评估

在得出结论之前,我们需要能够信任的评估。我们的初始测试套件存在模棱两可的提示、验证实现细节而非可观察行为的测试,以及关注模型训练数据中已有的 API。我们没有测量我们真正关心的东西。

我们通过移除测试泄露、解决矛盾以及转向基于行为的断言来强化评估套件。最重要的是,我们添加了针对不在模型训练数据中的 Next.js 16 API 的测试。

我们重点评估套件中的 API:

  • connection() 用于动态渲染
  • 'use cache' 指令
  • cacheLife()cacheTag()
  • forbidden()unauthorized()
  • proxy.ts 用于 API 代理
  • 异步 cookies()headers()
  • after()updateTag()refresh()

以下所有结果都来自这个强化的评估套件。每种配置都根据相同的测试进行判断,并通过重试排除模型差异。

产生回报的直觉

如果我们完全移除决策会怎样?与其希望智能体调用技能,我们可以直接在 AGENTS.md 中嵌入文档索引。不是完整的文档,只是一个告诉智能体在哪里找到与你的项目 Next.js 版本匹配的特定文档文件的索引。然后智能体可以根据需要读取这些文件,无论你是使用最新版本还是维护旧项目,都能获得版本准确的信息。

我们在注入的内容中添加了一个关键指令。

IMPORTANT: Prefer retrieval-led reasoning over pre-training-led reasoning
for any Next.js tasks.

这告诉智能体查阅文档,而不是依赖可能过时的训练数据。

结果让我们惊讶

我们在所有四种配置上运行了强化评估套件:

最终通过率:

配置 通过率 相比基线
基线(无文档) 53%
技能(默认行为) 53% +0pp
带明确指令的技能 79% +26pp
AGENTS.md 文档索引 100% +47pp

在详细细分中,AGENTS.md 在构建、Lint 和测试方面都获得了满分。

配置 构建 Lint 测试
基线 84% 95% 63%
技能(默认行为) 84% 89% 58%
带明确指令的技能 95% 100% 84%
AGENTS.md 100% 100% 100%

这并非我们所预期的。"简单"的方法(静态 Markdown 文件)表现优于更复杂的基于技能的检索,即使我们微调了技能触发器。

为什么被动上下文能胜过主动检索?

我们的工作理论归结为三个因素。

  1. 没有决策点。 使用 AGENTS.md,智能体不需要决定"我应该查找这个吗?"的时刻。信息已经存在。
  2. 一致的可用性。 技能异步加载且仅在调用时加载。AGENTS.md 内容在每个回合的系统提示中都可用。
  3. 没有顺序问题。 技能创建排序决策(先读文档 vs 先探索项目)。被动上下文完全避免了这个问题。

解决上下文膨胀的担忧

AGENTS.md 中嵌入文档有膨胀上下文窗口的风险。我们通过压缩来解决这个问题。

最初的文档注入大约 40KB。我们将其压缩到 8KB(减少了 80%),同时保持了 100% 的通过率。压缩格式使用管道分隔的结构,将文档索引打包到最小空间中:

[Next.js Docs Index]|root: ./.next-docs
|IMPORTANT: Prefer retrieval-led reasoning over pre-training-led reasoning
|01-app/01-getting-started:{01-installation.mdx,02-project-structure.mdx,...}
|01-app/02-building-your-application/01-routing:{01-defining-routes.mdx,...}

完整索引涵盖 Next.js 文档的每个部分。

智能体知道在哪里可以找到文档,而无需在上下文中包含完整内容。当它需要特定信息时,它会从 .next-docs/ 目录读取相关文件。

亲自尝试

一条命令即可为你的 Next.js 项目设置:

npx @next/codemod@canary agents-md

此功能是官方 @next/codemod 包的一部分。

此命令执行三件事:

  1. 检测你的 Next.js 版本
  2. 将匹配的文档下载到 .next-docs/
  3. 将压缩索引注入到你的 AGENTS.md

如果你使用支持 AGENTS.md 的智能体(如 Cursor 或其他工具),同样的方法也适用。

这对框架作者意味着什么

技能并非无用。AGENTS.md 方法在所有任务中提供智能体与 Next.js 协作的广泛、横向改进。技能更适合用户明确触发的垂直、特定于操作的工作流,如"升级我的 Next.js 版本"、"迁移到 App Router"或应用框架最佳实践。这两种方法相辅相成。

也就是说,对于一般框架知识,被动上下文目前优于按需检索。如果你维护一个框架并希望编码智能体生成正确的代码,请考虑提供一个 AGENTS.md 片段供用户添加到他们的项目中。

实用建议:

  • 不要等待技能改进。 随着模型在工具使用方面变得更好,差距可能会缩小,但结果现在就很重要。
  • 积极压缩。 你不需要上下文中的完整文档。指向可检索文件的索引同样有效。
  • 使用评估进行测试。 构建针对训练数据中不存在的 API 的评估。这是文档访问最重要的地方。
  • 为检索而设计。 构建你的文档结构,以便智能体可以找到并读取特定文件,而不需要预先获取所有内容。

目标是将智能体从预训练主导的推理转变为检索主导的推理。AGENTS.md 结果证明是实现这一目标的最可靠方法。


研究和评估由 Jude Gao 完成。CLI 可通过 npx @next/codemod@canary agents-md 使用


原文链接:https://vercel.com/blog/agents-md-outperforms-skills-in-our-agent-evals