SOTA Sync
全部文章
工具与行动2026-04-14

编写Agent Skills的8条经验

Skill是Agent最灵活的扩展点。Phil Schmid总结了编写好Skill的核心原则:描述要精确触发时机,给目标而非步骤,在层叠文件结构里节省上下文,以及完整的eval流程。

Philipp Schmid 长期使用 Skills,总结了 8 条经验。

#Skill 的三层结构

一个 Skill 由三部分组成:

  • Frontmatter :name 和 description,每个 prompt 都会注入,告诉 Agent 什么时候激活这个 Skill
  • SKILL.md body :Markdown 指令,告诉 Agent 怎么执行任务(在 Skill 触发后才加载)
  • Assets(可选)scripts/references/assets/ 文件夹

#两类 Skill

Capability Skills :帮助 Agent 完成基础模型做不到的事情(比如 PDF 表单填写)。这类 Skill 会随模型能力提升而变得不必要,eval 会告诉你什么时候可以退休。

Preference Skills :编码你特定的工作流(比如团队代码审查步骤)。这类是持久化的,但需要和实际流程保持同步。

#描述是触发机制

描述写得好不好决定了 Skill 什么时候激活、什么时候静默。

  • 太模糊:"Helps with documents" → Agent 不知道什么时候用
  • 太宽泛:每个请求都触发
  • ✅ 精确:"Create, edit, and analyze .docx files, use for tracked changes, comments, formatting, or text extraction"

一条经验:改善描述就能带来 50% 的改进。

#Agent 很聪明,你的职责是告诉它不知道什么

研究表明,更长、更全面的上下文实际上会损害性能。最佳实践:

  • 用指令而非信息 :"Always use interactions.create()" 而不是说"The Interactions API is recommended"。前者是 Agent 会执行的指令,后者是它不会行动的信息。
  • 用示例领先 :5 行代码片段比 5 段文字解释更强。
  • 解释为什么 :当一条规则重要时,说出原因。"Use model X, model Y is deprecated and will return errors" 帮助 Agent 泛化,不只是记住测试案例。
  • 不要过拟合 :避免只在你的三个测试 prompt 上通过的"脆弱"改动。写要在百万次调用中都能工作的 Skill。

#层叠加载节省上下文

Agent 按层级加载信息:

  1. 始终加载 :SKILL.md 的 frontmatter(name + description)
  2. 触发时加载 :SKILL.md body(保持在 500 行以内)
  3. 按需加载 :reference 文件、scripts、assets

如果一个 Skill 覆盖多个主题(比如 AWS vs GCP),拆成独立的 reference 文件。Agent 只读它需要的那一个,节省上下文给实际任务。

如果 reference 文件超过 500 行,在顶部加一个目录和"行提示",让 Agent 能快速定位。

#描述目标,不是路径

把 Skill 写成"第 1 步读文件,第 2 步解析 JSON..."是最常见的错误。这样做夺走了 Agent 适应、恢复错误、找到更好方法的能力。

告诉 Agent 要达成什么,而不是怎么到达:

  • ❌ "Step 1: Read the config file. Step 2: Find the database URL. Step 3: Update the port number. Step 4: Write the file back."
  • ✅ "Update the database port in the config file to the value specified by the user."

给约束,不给程序:

  • ❌ "Step 1: Create a branch. Step 2: Make the change. Step 3: Run tests. Step 4: Open a PR."
  • ✅ "Always run tests before opening a PR. Never push directly to main."

如果精确步骤很重要,写成脚本。如果任务脆弱到"第 3 步在第 2 步之前执行会毁掉一切",那不是 Skill 问题,是脚本问题。

#思考什么时候不该触发

"Use for any coding task"这样的描述会劫持每个请求。

正确的做法是明确边界:"Use when working with PDF files. Do NOT use for general document editing, spreadsheets, or plain text files."

测试"应该触发"和"不应该触发"两种情况都必要。不然你只会在一个方向上优化。

#Eval 是必须的

不要在没有评估的情况下发布 Skill。

  1. 手动跑几次 ,看哪里会坏。是不是假设了某个依赖存在?是不是跳过了步骤?
  2. 写下"成功"的量化标准 。输出能编译吗?用的是对的 API 吗?评估结果,不是路径。
  3. 尝试 10-20 个测试 prompt 。混合 Skill 应该处理的、应该忽略的、以及棘手的边界情况。
  4. 跑多次试验 。Agent 输出是非确定性的。每个 prompt 跑 3-5 次,看分布,不看单次通过/失败。
  5. 隔离每次运行 。每次测试用干净的环境。上一次运行的上下文残留会掩盖真实失败。
  6. 先修描述 。大多数问题出在触发层,不在指令层。

#退休 Skill 的时机

不带 Skill 跑 eval。如果通过了,说明模型已经吸收了这个 Skill 的价值,Skill 不再必要。这对 Capability Skills 尤其重要——模型能力在提升,两者差距在缩小。