我们原本以为,要让 AI 编码助手掌握特定框架的知识,Skills(技能)应该是标准答案。但在针对 Next.js 16 API 做了深度评测后,结果却让我们大跌眼镜。
说实话,我本来以为 Skills 这种"按需调用"的模式才是未来的标准答案。但数据直接打脸了:在 AGENTS.md 里嵌入一个只有 8KB 的压缩文档索引,居然拿到了 100% 的通过率。而 Skills 呢?即便我们明确告诉 AI 去用它,最高也才达到 79%。如果不给明确指令,Skills 的表现跟完全没文档几乎没区别。
这事儿挺反直觉的,但数据就是这么说的。下面聊聊我们踩过的坑、学到的教训,以及你怎么在自己的 Next.js 项目里复现这套方案。
我们到底在解决什么问题?
AI 编码助手最大的痛点就是训练数据过时。Next.js 16 引入了一堆新 API,比如use cache、connection()和forbidden(),这些东西在目前主流模型的"脑子"里根本不存在。当 AI 不知道这些新玩意儿时,它要么写出错误的代码,要么就退回到老掉牙的模式。
反过来也一样。如果你还在用老版本的 Next.js,模型却给你推荐了项目里根本还没支持的新 API,那也挺头大的。所以我们想解决的问题很简单:怎么让 AI 能够访问到版本匹配的文档。
教 AI 框架知识的两种姿势
在看结果之前,先简单科普下我们测试的两种方案。
第一种是 Skills。这是一种包装领域知识的开放标准。它把提示词、工具和文档打包在一起,让 AI 在需要的时候调用。理想情况下,AI 应该能意识到:"噢,我现在需要 Next.js 的专业知识了",然后去调用这个 Skill。
第二种是 AGENTS.md。这就是你项目根目录下的一个 Markdown 文件,给 AI 提供持久的上下文。不管 AI 这一轮想干啥,AGENTS.md 里的内容都会直接喂给它,不需要它自己决定要不要加载。Cursor 或 Claude Code 也有类似的机制。
我们分别搞了一套 Next.js 文档 Skill 和一套 AGENTS.md 文档索引,然后扔进评测集里硬碰硬。
刚开始,我们把宝都押在了 Skills 上
从架构上看,Skills 确实更优雅。你把框架文档打包,AI 干活时按需调用,既能保证代码正确,又不会让上下文太臃肿。而且 skills.sh 上还有越来越多现成的 Skill 可以直接用。
我们当时的预想是:AI 碰到 Next.js 的任务,调 Skill,读文档,写代码。一气呵成。结果一跑评测,心凉了半截。
Skills 根本调不动
在 56% 的测试案例里,AI 压根就没去碰那个 Skill。文档就在那儿,但它就是不用。
看到这个 0% 的提升了吗?说实话,我第一次看到这个结果的时候也愣了一下。AI 就像个明明手里有说明书却非要盲操的修理工。在一些细分的测试里,用了 Skill 的表现甚至比没用还差(测试通过率 58% vs 63%),我猜是因为环境里多出来的工具反而成了干扰项。
这不只是我们的问题。AI 没法稳定触发工具,这是目前所有大模型的通病。
明确指令有用,但语气很微妙
既然它不主动用,那我们就强迫它用。我们在 AGENTS.md 里加了明确指令,让它必须调用 Skill。这一招确实管用,触发率直接拉到了 95% 以上,通过率也涨到了 79%。
虽然提升很大,但我们发现了一个很诡异的现象:指令的措辞稍微变一点,AI 的行为就天差地别。
比如,如果你告诉它"你必须先调用 Skill",它会先读文档,然后死磕文档里的模式,结果往往忽略了项目本身的上下文。但如果你换成"先探索项目,再调用 Skill",它会先建立整体认知,把文档当参考,效果反而好得多。
同样的 Skill,同样的文档,就因为一两句话的差别,结果完全不同。在测试use cache指令时,"先调 Skill"的方案写对了page.tsx,但完全忘了改next.config.ts。而"先探索"的方案就两头都顾到了。这种脆弱性让我们很担心,如果生产环境里的表现全靠"调教"指令的语气,那这方案也太不稳了。
搞一套靠谱的评测集
在下结论之前,我们得确保评测集本身没问题。最开始的测试题出得比较模糊,有些甚至在考模型训练数据里已经有的 API,这根本测不出文档的作用。
所以我们把评测集重做了一遍,去掉了干扰项,把重点放在了 Next.js 16 那些模型还没见过的 API 上。这次评测覆盖了这些硬核 API:用于动态渲染的connection()、use cache指令、cacheTag()和cacheLife()、forbidden()和unauthorized()、用于 API 代理的proxy.ts、异步的headers()和cookies(),以及after()、updateTag()和refresh()。
接下来的所有数据,都来自这套强化后的评测集。
一个大胆的直觉
既然让 AI 做决定这么难,那干脆别让它选了。我们产生了一个想法:直接把文档索引塞进 AGENTS.md 里。不是把整本手册塞进去,而是一个索引,告诉 AI 去哪里找对应版本的文档文件。这样不管你是用最新版还是维护老项目,AI 都能按图索骥。
我们在 AGENTS.md 里加了一句关键的话:"处理 Next.js 任务时,请查阅文档,不要依赖可能过时的训练数据。"说白了,就是把"要不要看文档"这个选择题,变成了"文档就在这儿"的填空题。
结果出人意料
最终的通过率数据如下:
在 Build、Lint 和 Test 的细分项上,AGENTS.md 拿到了全满分。
这个结果挺反直觉的。这种看起来很"笨"的静态文件方案,居然打败了更高级的 Skill 检索模式,哪怕我们已经把 Skill 的触发指令调优到了极致。
为什么"被动上下文"能赢过"主动检索"?
我们复盘了一下,大概有三个原因。首先是去掉了决策点。用 AGENTS.md 时,AI 不需要纠结"我该不该查一下"。信息就在手边,它顺手就用了。
其次是可用性的稳定性。Skills 是异步加载的,只有被调用时才起作用。而 AGENTS.md 的内容是每一轮对话的系统提示词的一部分,存在感极强。最后是规避了顺序问题。Skills 会让 AI 纠结是先读文档还是先看代码,而被动上下文直接消解了这个矛盾。
担心上下文太臃肿?
把文档塞进 AGENTS.md 确实有让上下文"爆炸"的风险。所以我们做了压缩。最开始的文档内容有 40KB,我们把它压缩到了 8KB,缩减了 80%,但通过率依然是 100%。
我们用了一种特殊的管道符分隔结构,把索引压到了极致。比如caching|use-cache|...|指向文档文件的路径这种格式。这样 AI 知道去哪儿找文档,但不需要把整篇文档都塞进对话里。当它需要细节时,再去读.next-docs/目录下的具体文件就行了。
你也可以试试
想在你的 Next.js 项目里搞一套?一行命令就行:
npx @next/codemod@canary agents-md
这个功能已经集成到了官方的@next/codemod包里。它会自动检测你的 Next.js 版本,下载匹配的文档到.next-docs/,然后在你的 AGENTS.md 里注入压缩后的索引。只要你用的 AI 助手支持 AGENTS.md(比如 Cursor 等),这套方案就能原地起飞。
对框架作者的启示
这并不是说 Skills 没用了。AGENTS.md 这种方案更适合提供那种"横向"的、全局的框架知识。而 Skills 更适合处理那些"纵向"的、特定动作的工作流,比如"帮我升级 Next.js 版本"或者"把项目迁移到 App Router"。这两者其实是互补的。
但话说回来,如果你维护着一个框架,想让 AI 写出更靠谱的代码,目前最稳的办法就是给用户提供一段可以塞进 AGENTS.md 的配置。
我的几点建议:别死等 Skills 进化。虽然模型对工具的调用能力会变强,但现在的业务等不起。另外要狠命压缩,不需要把全量文档喂给 AI,给它一个能找着路的索引就够了。最后是用评测说话,针对那些训练数据里没有的 API 专门写测试用例,那才是文档真正发光发热的地方。
我们的目标是让 AI 从"凭记忆推理"转向"凭检索推理"。目前看来,AGENTS.md 是实现这一目标最靠谱的路径。
• • •