找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

3400

积分

0

好友

454

主题
发表于 21 小时前 | 查看: 2| 回复: 0

大家都在构建复杂的 Agent 框架,甚至将简单的文档查询功能拆解为多个工具,并称之为“模块化”。但结果往往不如人意:Agent 要么不知道何时调用工具,要么无法理解返回结果,最终产生大量不准确的输出。

近期,Vercel 官方技术团队进行了一次对比评测,其结果对当前流行的复杂 Agent 架构提出了挑战。

评测原文地址:https://vercel.com/blog/agents-md-outperforms-skills-in-our-agent-evals

我们曾认为 Skills 是教会 AI 编程 Agent 掌握特定框架知识的终极方案。然而,在针对 Next.js 16 的 API 构建了一套评估测试后,我们得到了一个意想不到的结论。

一个直接嵌入到 AGENTS.md 文件中、仅 8KB 大小的压缩文档索引,实现了 100% 的测试通过率。相比之下,即便我们明确指令 Agent 使用 Skills,其准确率也仅停留在 79%。更糟糕的是,如果没有这些强制指令,Skills 的表现与完全无文档时一样差。

本文将分享我们的尝试、发现,以及如何在你的 Next.js 项目中复现这一高效配置。

我们试图解决的问题

AI 编程 Agent 高度依赖其训练数据,但这些数据往往存在滞后性。例如,Next.js 16 引入了诸如 'use cache'connection()forbidden() 等全新 API,而这些内容并未包含在当前主流模型的训练数据中。当 Agent 不了解这些 API 时,就会生成错误代码或退回到旧的模式。

反之亦然:当你在维护一个旧版本的 Next.js 项目时,模型可能会建议使用项目中尚不存在的新 API。我们的目标是通过赋予 Agent 与项目版本精确匹配的文档访问权限 来解决这一问题。

两种“教会” Agent 的方法

在深入结果之前,先快速了解我们测试的两种方法:

  • Skills:这是一种供编程 Agent 使用的、用于打包领域知识的开放标准。一个 Skill 捆绑了 Agent 可以按需调用的提示词(Prompts)、工具和文档。其核心理念是:Agent 能够自主识别何时需要特定框架的帮助,进而调用 Skill 并获取相关文档。
  • AGENTS.md:这是一个位于项目根目录的 Markdown 文件,用于为编程 Agent 提供持久的上下文支持。无论 Agent 是否决定加载它,你放入 AGENTS.md 的任何内容都会在每一轮对话中对 Agent 可见。Claude Code 使用的 CLAUDE.md 也是同样的原理。

我们构建了一个 Next.js 文档 Skill 和一个 AGENTS.md 文档索引,然后通过评估套件运行它们以比较性能。

起初,我们将赌注押在了 Skills 上

Skills 看起来是一个正确的抽象。你将框架文档打包成一个 Skill,Agent 在处理 Next.js 任务时调用它,然后生成正确代码。这种方式实现了关注点分离,上下文开销小,且 Agent 只在需要时加载内容。在 skills.sh 上甚至已经有了一个不断增长的可复用 Skills 目录。

我们预期的流程是:Agent 遇到 Next.js 任务 -> 调用 Skill -> 阅读版本匹配的文档 -> 生成正确代码。

然而,评估结果给了我们当头一棒。

Skills 的触发并不靠谱

在 56% 的评估案例中,Skill 从未被调用。Agent 明明拥有访问文档的权限,却选择了忽略。添加 Skill 后,结果与基准线相比没有任何提升:

配置 通过率 对比基准
基准 (无文档) 53%
Skill (默认行为) 53% +0pp

零提升。 Skill 就在那里,Agent 可以用,但它选择了不用。在详细的构建、Lint、测试细分数据中,Skill 在某些指标上的表现甚至比基准线还差(测试通过率为 58% vs 63%),这表明环境中一个未被使用的 Skill 反而可能引入噪音或干扰。

这并非特例。Agent 无法可靠地使用可用工具,是当前大模型的一个已知局限。

显式指令有帮助,但措辞极其脆弱

我们在 AGENTS.md 中尝试添加了显式指令,告诉 Agent 必须使用该 Skill。

Before writing code, first explore the project structure, then invoke the nextjs-doc skill for documentation.
(在编写代码之前,先探索项目结构,然后调用 nextjs-doc skill 获取文档。)

添加到 AGENTS.md 中用于触发 Skill 使用的示例指令。

这一改动将 Skill 的触发率提高到了 95% 以上,并将整体通过率提升至 79%。

配置 通过率 对比基准
基准 (无文档) 53%
Skill (默认行为) 53% +0pp
Skill (配合显式指令) 79% +26pp

这是一个显著的提升。但我们发现了一个关键问题:指令的措辞对 Agent 的行为影响巨大。

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

指令 行为 结果
“You MUST invoke the skill” (你必须调用 Skill) 首先阅读文档,死抠文档模式,忽略了项目上下文 结果较差
“Explore project first, then invoke skill” (先探索项目,再调用 Skill) 先建立对项目的心智模型,再将文档作为参考 结果更好

同一个 Skill,同一份文档,仅仅因为措辞的细微差别,最终结果天差地别。

在某次针对 'use cache' 指令的评估中,“先调用(invoke first)”的方法写出了正确的 page.tsx,但完全遗漏了必要的 next.config.ts 更改。而“先探索(explore first)”的方法则两者都正确完成了。

这种脆弱性令人担忧。如果微小的措辞调整会导致巨大的行为波动,那么这种方法在生产环境中就显得太不可靠了。这也反映了当前 Agent 在复杂决策上的不稳定性。

构建值得信赖的评估体系

在下结论之前,我们需要一套可靠的评估体系。我们最初的测试套件存在提示词语义模糊、测试验证的是实现细节而非可观察行为、以及过于关注模型训练数据中已有的 API 等问题。

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

我们核心评估套件中的 API 包括:

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

接下来的所有结果都来自这个经过强化的评估套件。每种配置都在相同的测试下进行评判,并进行多次重试以排除模型随机性的影响。

那个得到回报的直觉

如果完全消除“做决定”这个环节呢?与其寄希望于 Agent 主动调用 Skill,不如我们直接在 AGENTS.md 中嵌入一个文档索引。不是完整的文档,仅仅是一个索引,告诉 Agent 去哪里找到与你项目 Next.js 版本匹配的具体文档文件。

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

IMPORTANT: Prefer retrieval-led reasoning over pre-training-led reasoning for any Next.js tasks.
(重要提示:对于任何 Next.js 任务,优先使用基于检索的推理,而非基于预训练的推理。)

嵌入在文档索引中的关键指令。

这直接指示 Agent 去查阅文档,而不是依赖可能过时或错误的预训练数据。

结果让我们大吃一惊

我们在所有四种配置下运行了强化后的评估套件。

最终通过率:

配置 通过率 对比基准
基准 (无文档) 53%
Skill (默认行为) 53% +0pp
Skill (配合显式指令) 79% +26pp
AGENTS.md 文档索引 100% +47pp

在详细的细分数据中,AGENTS.md 在构建、Lint 和测试三个方面均获得了满分。

配置 Build Lint Test
基准 84% 95% 63%
Skill (默认行为) 84% 89% 58%
Skill (配合显式指令) 95% 100% 84%
AGENTS.md 100% 100% 100%

这完全出乎意料。“笨”办法(一个静态 Markdown 文件)竟然跑赢了更复杂的基于 Skill 的检索方案。

为什么“被动上下文”打败了“主动检索”?

我们的分析主要归结为三个因素:

  1. 没有决策点:使用 AGENTS.md,不存在 Agent 必须决定“我是否应该查一下这个?”的时刻。信息已经持续可见。
  2. 持续的可用性:Skills 是异步加载的,并且只在被调用时加载。而 AGENTS.md 的内容在每一轮对话的系统提示词中都存在。
  3. 没有顺序问题:Skills 带来了顺序决策难题(先读文档还是先探索项目?)。被动上下文完全避免了这个问题。

解决上下文臃肿的问题

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,...}

AGENTS.md 中的精简版文档索引示例。

Agent 知道去哪里找文档,而无需将全部内容塞入上下文。当它需要特定信息时,它会从 .next-docs/ 目录中读取相关文件。这种方式本质上是一种高效的 RAG(检索增强生成)实践。

亲手试一试

只需一条命令即可为你的 Next.js 项目完成此配置:

npx @next/codemod@canary agents-md

这个命令会做三件事:

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

如果你使用的是支持 AGENTS.md 的 AI 编程工具(如 Cursor 或其他兼容工具),这种方法同样有效。

这对框架作者意味着什么

Skills 并非毫无用处。AGENTS.md 方法为 Agent 处理 通用的、横向的 Next.js 任务提供了广泛改进。而 Skills 更适合用户显式触发的垂直、特定操作的工作流,例如“升级我的 Next.js 版本”或“迁移到 App Router”。这两种方法是互补的。

也就是说,对于通用的框架知识,被动上下文目前优于按需检索。如果你维护一个框架并希望编程 Agent 能为其生成正确的代码,请考虑提供一个 AGENTS.md 片段,供用户添加到他们的项目中。这对于 Next.js 这类迭代快速的前端框架尤其重要。

实用建议:

  • 不要等待 Skills 改进:随着模型在工具使用方面变得更好,差距可能会缩小,但眼下的结果才是最重要的。
  • 激进地压缩:你不需要在上下文中放入完整文档。一个指向本地可检索文件的精简索引同样有效。
  • 用 Evals 进行测试:构建针对训练数据中没有的 API 的测试。那才是文档访问权价值最大的地方。
  • 为检索而设计:结构化你的文档,以便 Agent 可以轻松查找和阅读特定文件,而不是一次性需要所有内容。

我们的核心目标是将 Agent 从基于预训练的推理转变为基于检索的推理。事实证明,一个精心设计的 AGENTS.md 文档索引是目前实现这一目标最可靠、最有效的方式。这项技术的实践和讨论,也可以在 云栈社区 这样的开发者社区中找到更多共鸣和延伸。

研究与评估由 Jude Gao 完成。CLI 工具可通过 npx @next/codemod@canary agents-md 获取。




上一篇:小市值策略动态择时:用“四大搅屎棍”与日历效应双维度控制回撤
下一篇:CVE-2025-55182漏洞实战:解析React RSC原理与Next.js安全升级指南
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-2-28 23:47 , Processed in 0.385075 second(s), 43 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表