分析了 AI 编程代理如何发现、使用 SKILL.md 文件,以及这些技能定义对产品使用效果的实证影响。
Agent 技能在编程 Agent 与开发者产品之间引入了一个新的层级。与其让 Agent 从文档或其他线索中拼凑一切,不如让技能在相关时刻为其提供精准的指令、脚本和资源。技能超越了文档的范畴,帮助 Agent 发现、导航和使用你的产品。
当然,SKILL.md 的存在并不必然意味着 Agent 会找到它、使用它,或更有效地使用你的产品。早期的证据表明,技能可以改变 Agent 的行为,但并非总是朝好的方向改变。这引出了一组更有价值的问题:编程 Agent 如何发现和使用技能——首先从它们是否能找到技能开始。
在判断技能是否有帮助之前,Agent 必须知道它的存在。而这首先取决于一个看似平凡的问题:技能存放在哪里。
放在仓库某处的 SKILL.md 并非自动可发现。确切位置仍取决于 Agent 和运行时。例如,Claude Code 支持将项目技能放在 .claude/skills/skill-name/SKILL.md 下,而 OpenAI Codex 使用相同的基础技能格式,在 .agents/skills 中发现仓库技能,也可以加载打包在插件中的技能。测试技能时,首先要验证的是它已被安装在 Agent 设计用来发现它的位置。
技能可用之后,还有另一个步骤。OpenAI 和 Anthropic 都使用渐进式披露,而不是将每个已安装技能的全部指令一次性全部放入上下文。Agent 最初只看到轻量级的元数据,特别是技能的名称和描述,并使用这些信息来决定是否需要加载该技能。这使得技能描述变得尤为重要。OpenAI 和 Anthropic 都建议使用技能元数据来说明技能的作用以及 Agent 应该在何时使用它。
在不同特异性层级测试技能激活:
命名技能:测试 Agent 能否在明确指示下使用该技能。示例:"使用 Quantiles 技能运行一次评估。"
描述任务:测试 Agent 是否能从任务中识别出相关技能。示例:"为这个应用配置身份验证。"
描述目标:测试 Agent 是否能从开发者的目标中推断出技能的关联性。示例:"让这个服务连接上,这样我就可以开始评估 Agent 了。"
这更接近我们实际使用编程 Agent 的方式。我们告诉它们我们想完成什么,而不是指定使用哪个技能、MCP 服务器、文档页面或工具。OpenAI 建议测试这个范围,从显式和上下文相关的请求,到技能根本不应该激活的情况。
技能发现只是评估的一部分。你还需要知道技能是否改变了 Agent 成功使用你产品的能力。在 Agent、仓库、文档、工具和环境保持不变的情况下,比较使用技能和不使用技能执行相同任务的情况。这将技能隔离为主要实验变量,使 Agent 行为和结果的差异更容易解读。
那么我们如何知道技能是否真的有帮助?执行轨迹给了我们一些线索。观察这些信号可以展示技能如何改变了 Agent 的行为,以及它是否让工作流更高效——包括完成时间或更可靠。
技能对 Agent 性能的影响可能因任务类型而异。对于安装和身份验证,定义好的产品工作流可以减少歧义,帮助 Agent 避免错误的工具调用或不必要的步骤。从错误中恢复通常需要更大的灵活性,因为下一步适当的行动取决于错误本身和当前环境。高级工作流可能从关于产品约定和重要决策点的指导中获益更多,而不是详细的分步说明。
效果也可能因编程 Agent 而异。一个 Agent 可能已经能很好地导航你的文档,从额外指导中获益甚微,而另一个 Agent 则能从结构化指导中显著受益。随着模型的改进,这种情况也会发生变化。目标不是让技能改善一切,而是找到在哪些地方一点点额外的指导能产生有意义的差异,哪些地方 Agent 自己处理反而更好。
下表展示了技能可能在哪些地方有帮助或有害,以及如何通过正确水平的指导来减少不确定性,同时为 Agent 留出适应的空间。
你的产品及其依赖服务(包括 AI 模型)的变化,可能改变 Agent 使用它的体验。为你最重要的业务流程维护一组稳定的评估任务,并将其用作产品、文档或 SKILL.md 变化时的回归测试。当出现新的 Agent 失败时,将其转化为另一个评估任务,这样你就可以在未来对其进行测试。
编程 Agent 也在不断变化。今天有帮助的指导可能随着模型改进变得不再必要,而新的 Agent 行为可能暴露出你从未见过的问题。这使得 Agent 评估成为产品建设的持续部分。随着产品和使用它的 Agent 都在变化,持续测试重要的业务流程。有时这会让你更新 SKILL.md。有时更好的修复在文档、API、错误消息或产品本身。