如何更好地写 Agent Skill:命中率、可执行性与持续优化指南

Skill 正在变成 Agent 工程里的一个关键抽象。它不像 prompt 那样只服务一次对话,也不像 plugin/tool 那样只暴露一个动作。一个好的 Skill 更像一份“可复用的工作手册”:它告诉 Agent 在什么情况下该加载它、应该遵循什么流程、可以使用哪些脚本或参考资料、怎样验证结果,以及哪些坑千万别踩。

但 Skill 写不好也很麻烦。它可能根本不触发;也可能过度触发,污染上下文;还可能写得太泛,让 Agent 读完仍然不知道怎么做;更糟的是,第三方 Skill 可能成为新的语义供应链风险。

本文结合 Agent Skills 官方规范、本地 Codex Skill 编写规范、上下文工程、技能评估和近期安全研究,总结一套更实用的写法。

1. 先理解 Skill 的本质

一个 Skill 通常是一个文件夹,核心是 SKILL.md,可选包含:

  • scripts/:可执行脚本,用于稳定、重复、容易出错的操作。
  • references/:较长的参考资料,如 API 文档、数据库 schema、公司规范。
  • assets/:模板、图片、示例文件、样式资源等产物素材。

Agent Skills 官方文档把 Skill 的加载过程称为 progressive disclosure,也就是渐进式披露:

  1. Discovery:Agent 启动或检索时只看到 namedescription
  2. Activation:用户任务匹配 description 后,Agent 才读取完整 SKILL.md
  3. Execution:Agent 按照正文说明执行,必要时再读取 references、运行 scripts 或使用 assets。

这意味着一个关键事实:

Skill 是否命中,几乎首先取决于 name + description;Skill 是否好用,才取决于正文。

所以写 Skill 不能只问“正文够不够详细”,还要问:

  • 它会不会在正确任务上触发?
  • 它会不会在相似但不该触发的任务上误触发?
  • 它加载后是否给 Agent 足够明确的行动路径?
  • 它是否把稳定、可验证的动作交给脚本,而不是靠模型自由发挥?
  • 它是否能通过真实任务评估证明有收益?

2. 好 Skill 解决的不是“知识”,而是“反复出错的过程”

很多 Skill 写坏,是因为作者把它当成知识库文章来写。结果里面塞满概念解释、背景材料、通用最佳实践,但缺少真正能改变 Agent 行为的东西。

更好的判断标准是:

这个 Skill 是否能让 Agent 在一类任务上少走弯路、少犯错、更稳定地产出结果?

适合写 Skill 的场景:

  • 有明确可复用流程,比如“处理某类 PDF 表单”“生成符合公司规范的周报”。
  • Agent 经常需要你反复提醒同样的约束。
  • 任务涉及特定工具、API、文件格式或业务规则。
  • 操作步骤脆弱,顺序错了就失败。
  • 有固定输出格式、模板或验收标准。
  • 需要跨项目或跨团队复用。

不适合写 Skill 的场景:

  • 一次性任务。
  • 模型本来就能稳定完成的常识性任务。
  • 只是一堆通用建议,如“写清楚代码”“注意错误处理”。
  • 可以用 lint、schema、脚本直接强制的机械规则。
  • 与某个项目强绑定但不具备复用价值的临时背景。

一句话:Skill 应该封装“非显然的可复用做法”,不是封装百科知识。

3. 写 Skill 的三个层次

3.1 第一层:命中

命中靠 namedescription

name 应该短、具体、动作导向:

  • 好:analyzing-csv-sales-data
  • 好:reviewing-security-sensitive-code
  • 好:creating-branded-presentations
  • 差:data-helper
  • 差:best-practices
  • 差:my-awesome-skill

description 是命中的核心。它应该回答:

当用户说了什么、遇到什么任务、出现什么症状时,Agent 应该加载这个 Skill?

一个好 description 通常具备这些特征:

  • Use when... 或类似触发句式开头。
  • 描述用户意图,不描述 Skill 内部实现。
  • 覆盖同义词、场景词、文件类型、工具名、常见错误。
  • 说明边界,避免过宽。
  • 简短,但不空泛。

坏例子:

description: Helps with data analysis.

问题:太泛,几乎所有数据任务都可能误触发。

更好:

description: Use when analyzing tabular sales, finance, or operations data from CSV/XLSX files, especially when the user asks for cleaning, aggregation, charts, anomaly detection, or a concise business summary.

再进一步,如果这个 Skill 不负责数据库 ETL,可以加边界:

description: Use when analyzing tabular sales, finance, or operations data from CSV/XLSX files for cleaning, aggregation, charts, anomaly detection, or summary reporting. Do not use for database migration, ingestion pipelines, or backend ETL implementation.

3.2 第二层:可执行

Skill 触发后,正文应该让 Agent 知道“下一步做什么”。正文不是写给人慢慢学习的文章,而是写给 Agent 当场执行的操作说明。

正文应该优先包含:

  • 任务边界。
  • 默认流程。
  • 关键决策点。
  • 输入输出格式。
  • 常见坑。
  • 验证步骤。
  • 可用脚本和参考资料。

少写:

  • 大段背景。
  • 已经是常识的技术解释。
  • 多个平级方案但不给默认选择。
  • 充满“适当处理”“遵循最佳实践”的空话。

好 Skill 的正文像“带验收标准的 runbook”,不是“主题作文”。

3.3 第三层:可演化

Skill 不是写完就结束。它应该像代码一样迭代:

  1. 收集真实任务。
  2. 记录 Agent 没用 Skill 时怎么失败。
  3. 写最小 Skill 修正失败。
  4. 用相同任务测试是否改善。
  5. 增加边界测试,避免误触发。
  6. 根据 traces、输出质量和人工反馈继续修改。

近期关于 SkillGen、SkillForge、SkillOpt 等方向的研究,都指向同一个趋势:Skill 会从“人工写的提示文档”变成“可评估、可优化、可版本化的外部能力状态”。

4. 提升命中率:写 description 的方法

Skill 命中率可以拆成两个指标:

  • 召回率:该触发时有没有触发。
  • 精确率:不该触发时有没有误触发。

很多人只追求召回率,把 description 写得很宽,结果 Skill 到处乱触发,污染上下文。真正好的 Skill 是二者平衡。

4.1 用“用户意图词”而不是“内部实现词”

用户不会说:“请调用我的 progressive disclosure 技能”。用户会说:

  • “帮我把这个 Excel 做成周报”
  • “这个 PR 帮我看一下有没有安全问题”
  • “把这些调研纪要整理成投资摘要”
  • “这个 PDF 里的表单能不能自动填好”

所以 description 要写用户可能表达的任务,而不是只写 Skill 内部机制。

差:

description: Use when executing the csv_parser.py script and generating dataframe summaries.

好:

description: Use when the user needs to inspect, clean, summarize, chart, or explain CSV data, including messy exports, sales reports, operational metrics, and ad hoc spreadsheet-style analysis.

4.2 覆盖同义词和近义场景

命中率差,经常是因为 description 太依赖一个词。

比如“表格分析”可以写:

  • CSV
  • XLSX
  • spreadsheet
  • tabular data
  • sales report
  • metrics export
  • revenue table
  • 数据清洗
  • 汇总
  • 透视
  • 图表
  • 异常值

不要机械堆关键词,而是把它们组织成自然句。Agent 读起来顺,检索也更容易匹配。

4.3 写进“隐式触发”

用户不一定知道你的 Skill 名字,也不一定知道任务属于哪个领域。

比如一个“品牌 PPT Skill”,不应该只在用户说“品牌规范”时触发,也应该在这些场景触发:

  • “帮我把这个 deck 美化一下”
  • “改成我们公司风格”
  • “给客户发的方案看起来专业点”
  • “把这份销售材料做成正式演示”

description 可以加:

description: Use when creating or revising presentations that must follow company branding, visual identity, executive-ready formatting, or client-facing deck standards, even if the user only says "make it look professional" or "use our style."

4.4 写进“反例边界”

如果 Skill 经常误触发,就加边界。

例如 CSV 分析 Skill 不负责写 ETL 后端:

description: Use when analyzing CSV/XLSX data for insights, charts, cleaning, or summaries. Do not use for building backend ingestion pipelines, database migrations, or generic file conversion unless analysis is also required.

边界不是越多越好,但对高频误触发很有效。

4.5 建一个 trigger eval 集

不要靠感觉调 description。官方优化指南建议准备大约 20 条查询:

  • 8-10 条应该触发。
  • 8-10 条不应该触发。
  • 每条跑多次,因为模型行为有随机性。

样例:

[
  {
    "query": "我有个 q4_sales.xlsx,帮我找出毛利率最低的 10 个客户并做个图",
    "should_trigger": true
  },
  {
    "query": "帮我写一个把 CSV 导入 Postgres 的后端接口",
    "should_trigger": false
  },
  {
    "query": "老板让我把这个销售数据整理成一页摘要,最好有趋势图",
    "should_trigger": true
  },
  {
    "query": "把这个 JSON 转成 YAML",
    "should_trigger": false
  }
]

测试时记录:

  • 触发次数。
  • 触发率。
  • 误触发率。
  • 没触发但本该触发的 query。
  • 触发后有没有真的改善结果。

命中率优化不是只改词,而是做“小型检索评估”。

5. Skill 正文怎么写

推荐结构:

---
name: your-skill-name
description: Use when ...
---

# Skill Title

## Core Principle
一句话说明这个 Skill 的核心判断。

## Workflow
1. 第一步
2. 第二步
3. 第三步

## Available Resources
- `scripts/validate.py`:验证输出结构
- `references/schema.md`:当任务涉及数据库字段时读取
- `assets/template.md`:生成报告时使用

## Decision Rules
- 如果 A,用 X
- 如果 B,用 Y
- 如果不确定,先检查 Z

## Gotchas
- 某个字段名容易混淆
- 某个 API 返回值有特殊含义
- 某个工具必须先初始化

## Validation
完成前运行或检查:
1. ...
2. ...

## Output Format
使用以下结构输出:
...

这不是唯一结构,但它符合 Agent 执行习惯:先看原则,再看流程,再看资源,再看坑,再验证。

6. 几个最值得优化的方向

6.1 从“建议”改成“流程”

弱:

生成报告时要注意结构清晰、重点突出、引用来源可靠。

强:

生成报告:
1. 先列出 3-5 个关键结论。
2. 每个结论必须关联一个来源或数据点。
3. 把不确定信息放入“待确认”小节。
4. 最后输出“下一步建议”,每条不超过 30 字。

Agent 对流程的遵循通常比对抽象建议更稳定。

6.2 从“多个选项”改成“默认路径 + 例外”

弱:

你可以使用 pandas、polars、csvkit、duckdb 或 sqlite 来分析 CSV。

强:

默认使用 pandas 分析 CSV。数据超过 500MB 或需要 SQL 聚合时,改用 duckdb。

太多平级选项会让 Agent 犹豫。给默认路径,保留逃生口。

6.3 把脆弱步骤下沉为脚本

如果 Agent 每次都要重写同样的解析、校验、转换、渲染逻辑,这部分就适合放进 scripts/

适合脚本化的内容:

  • 复杂格式解析。
  • 文件校验。
  • 图表生成。
  • 批量转换。
  • schema 检查。
  • 安全扫描。
  • 输出一致性验证。

脚本设计要对 Agent 友好:

  • 支持 --help
  • 参数明确。
  • 错误信息可修复。
  • 输出结构化 JSON 或清晰文本。
  • 不要交互式输入。
  • 依赖版本固定。

6.4 把长资料移动到 references

SKILL.md 不应变成 2000 行巨物。大资料应该放到 references/,并在正文里写清楚何时读取。

弱:

更多信息见 references/。

强:

当任务涉及 API 错误码时,读取 `references/api-errors.md`。
当任务涉及字段映射时,读取 `references/schema.md`。
当用户要求生成正式合同条款时,读取 `references/legal-style-guide.md`。

重点不是“有参考资料”,而是“Agent 知道什么时候该读哪份资料”。

6.5 写 Gotchas

Gotchas 是 Skill 里最值钱的部分之一,因为它记录的是模型最容易合理猜错的地方。

例子:

## Gotchas

- `customer_id` 在 CRM 里叫 `account_id`,在 billing API 里叫 `uid`。
- `/health` 只代表服务进程存活,不代表数据库可用;检查上线状态必须用 `/ready`。
- 生成日报时不要引用盘中传闻,除非来源中明确标记为已确认。

每当你纠正 Agent 一次,就问自己:这条纠正是否应该进入 Gotchas?

6.6 加验证闭环

没有验证步骤的 Skill,很容易变成“看起来遵守了”。更好的写法是:

## Validation

Before finalizing:
1. Run `python scripts/validate_output.py output.md`.
2. If validation fails, fix the reported issue and run it again.
3. Check that every key claim has a source.
4. Confirm the final file path exists.

对于不能脚本验证的任务,也可以用 checklist 验证。

6.7 记录“何时不要用”

如果两个 Skill 容易抢任务,应该写边界。

例如:

Do not use this skill when the user only wants a plain-language explanation and no file editing, charting, or data transformation is needed.

这能减少误触发和冲突。

7. Skill 类型与写法差异

7.1 流程型 Skill

适合:固定步骤、多阶段产物、反复执行。

重点:

  • 明确步骤。
  • 明确每步输入输出。
  • 有中间验证。
  • 最好有脚本或模板。

例子:生成市场简报、处理报销单、做代码发布检查。

7.2 规范型 Skill

适合:品牌规范、写作风格、代码审查标准、合规要求。

重点:

  • 写清楚优先级。
  • 给正反例。
  • 给输出模板。
  • 写常见违规点。

例子:公司品牌 PPT、法律合同审阅、PR Review 风格。

7.3 工具型 Skill

适合:某个 API、CLI、平台、SDK 的固定用法。

重点:

  • 告诉 Agent 用哪个工具。
  • 常用命令放正文。
  • 全量文档放 references。
  • 易错命令放 Gotchas。
  • 高风险命令加确认规则。

例子:GitHub PR 处理、Jira 工单更新、云平台部署。

7.4 领域知识型 Skill

适合:公司业务、金融指标、医学流程、行业术语。

重点:

  • 避免百科化。
  • 只放 Agent 容易不知道或容易误解的领域规则。
  • 把大知识库拆成 references。
  • 增加引用与来源要求。

例子:A 股资讯整理、保险理赔审核、B2B 销售线索评分。

7.5 纪律约束型 Skill

适合:TDD、验证后再宣称完成、安全审批、调试流程。

重点:

  • 明确硬门槛。
  • 写红旗信号。
  • 写常见借口和反驳。
  • 用压力场景测试是否还会遵守。

这种 Skill 最容易被 Agent “理性化绕过”,所以要比普通 Skill 更强硬。

8. 命中率优化的实战流程

可以把 Skill 优化当成一个小型产品迭代。

第一步:收集真实任务

至少收集 10-20 条用户可能说的话。不要只写标准问题,要包括:

  • 口语化表达。
  • 不完整表达。
  • 混合任务。
  • 文件路径。
  • 具体业务背景。
  • 同义词。
  • 拼写错误。

第二步:标注触发与不触发

每条 query 标记:

  • should_trigger: true
  • should_trigger: false

负样本要选“近似但不该触发”的任务,而不是天气、笑话这种明显无关的样本。

第三步:跑触发测试

每条跑 3 次左右,记录触发率。

关注四类问题:

  • 应触发但没触发:description 缺少意图词或场景词。
  • 不应触发但触发:description 太宽或缺少边界。
  • 触发了但没帮助:正文质量不足。
  • 触发后变差:Skill 与当前上下文冲突、过时或过度规定。

第四步:修改 description

修改时不要只加关键词,而要明确:

  • 哪些用户意图应该命中。
  • 哪些近似场景不应该命中。
  • 哪些隐式表达也要命中。

第五步:测试输出质量

命中只是第一步。还要比较:

  • 有 Skill 和无 Skill 的结果。
  • 新版本 Skill 和旧版本 Skill 的结果。
  • 成功率。
  • token 成本。
  • 执行时长。
  • 工具调用是否更准确。
  • 人工修改量是否减少。

第六步:版本化

把 Skill 当代码管理:

  • 修改原因写入 commit。
  • 保留评估样本。
  • 记录命中率和误触发率。
  • 重要变更做回归测试。

9. 常见问题与答案

Q1:Skill 越长越好吗?

不是。长 Skill 会占上下文,并且增加注意力噪音。官方最佳实践建议 SKILL.md 保持精炼,长资料用 progressive disclosure 拆到 references。

判断一句话该不该留下,可以问:

Agent 没有这句话,会不会更容易做错?

如果不会,删。

Q2:description 要不要写 Skill 的内部流程?

通常不要。description 的职责是触发,不是教学。它应该描述“何时使用”,而不是把完整流程塞进去。流程放正文。

Q3:Skill 和 prompt 模板有什么区别?

Prompt 模板偏一次性输入结构;Skill 是可复用能力包。Skill 可以包含流程、脚本、参考资料、模板、验证逻辑和触发条件。

Q4:Skill 和 tool 有什么区别?

Tool 是一个动作接口,例如 search_web(query)。Skill 是一套如何完成任务的过程知识,里面可以告诉 Agent 何时、如何、按什么顺序使用多个工具。

Q5:什么时候要放脚本?

当某个操作:

  • 经常重复;
  • 容易写错;
  • 需要确定性;
  • 需要验证;
  • 参数复杂;
  • 或者涉及文件格式细节;

就应该考虑脚本化。

Q6:怎么判断 Skill 真的有用?

做 A/B 测试:

  • 同一批任务,无 Skill 跑一次。
  • 同一批任务,有 Skill 跑一次。
  • 比较成功率、人工修改量、执行时间、token 成本、错误类型。

如果没有明显改善,Skill 可能太泛、太空、触发不准,或者这个任务本来不需要 Skill。

Q7:为什么我的 Skill 不触发?

常见原因:

  • description 太短或太抽象。
  • 只写了实现方式,没写用户意图。
  • 缺少文件类型、领域词、症状词。
  • 用户任务太简单,Agent 认为不需要额外能力。
  • Skill 名称和 description 与其他 Skill 冲突。
  • Skill 没安装到正确目录或没有被客户端发现。

Q8:为什么我的 Skill 老是乱触发?

常见原因:

  • description 过宽。
  • 写了太多泛化关键词。
  • 没有 near-miss 负样本。
  • 没写“不要用于哪些场景”。
  • Skill 试图覆盖多个不相关任务。

Q9:Skill 之间冲突怎么办?

先检查边界是否清楚。必要时:

  • 拆分过宽 Skill。
  • 合并高度重叠 Skill。
  • 给 description 加互斥条件。
  • 在正文里写优先级。
  • 用 router/总控 Skill 做选择。

Q10:Skill 会不会有安全风险?

会。SKILL.md 不是普通文档,而是 Agent 会读、会信、会执行的操作文本。近期研究指出,仅修改自然语言元数据和说明,就可能影响 Skill 的发现、选择和治理结果。

安全建议:

  • 不信任第三方 Skill。
  • 读完 SKILL.md 再启用。
  • 检查 scripts/ 是否有危险操作。
  • 高风险工具必须人工确认。
  • 不把密钥、token、内部路径写进 Skill。
  • 对可执行脚本做最小权限和沙箱。
  • 对 Marketplace/团队共享 Skill 做审核和签名。

10. 一个高命中 Skill 的模板

---
name: reviewing-payment-risk
description: Use when reviewing code, workflows, API changes, or operational procedures that affect payments, refunds, invoices, billing state, subscriptions, credits, or money movement. Use even if the user only mentions checkout, pricing, plan changes, or customer balance. Do not use for general UI copy or analytics-only changes.
---

# Reviewing Payment Risk

## Core Principle

Treat payment-related changes as state-changing, user-impacting, and audit-sensitive. Prefer explicit validation over assumption.

## Workflow

1. Identify the money-moving path: charge, refund, invoice, subscription, credit, or balance update.
2. Locate authorization checks and idempotency boundaries.
3. Check data consistency across internal database, payment provider, and user-visible state.
4. Verify failure handling: retries, partial success, duplicate webhook delivery, timeout.
5. Confirm observability: audit log, trace ID, customer support lookup path.
6. Before final response, list risks by severity and include concrete file/function references.

## Gotchas

- Payment webhooks may be delivered more than once. Every handler must be idempotent.
- A successful provider response does not guarantee local database commit succeeded.
- Refunds and credits are not the same thing; do not treat them interchangeably.

## Validation

Before finalizing:
1. Check that every high-risk operation has authorization.
2. Check idempotency for every external callback.
3. Check that user-visible billing state cannot diverge silently.
4. If tests exist, identify which tests cover duplicate events and partial failures.

## Output Format

Return:
- Summary
- High-risk findings
- Medium-risk findings
- Missing tests
- Open questions

这个模板的关键不在“写得多”,而在:

  • description 覆盖了显式和隐式触发词。
  • 写了不适用场景。
  • 正文给默认流程。
  • Gotchas 是领域特有的。
  • 验证项可执行。
  • 输出格式稳定。

11. 发散方向:未来 Skill 可以怎么优化

11.1 Skill as Code

把 Skill 当成代码资产管理:

  • PR 审查。
  • 单元测试。
  • 版本号。
  • changelog。
  • 回滚。
  • 自动校验 frontmatter。
  • 自动跑 trigger eval。

11.2 Skill Telemetry

记录 Skill 运行数据:

  • 哪些 query 触发了。
  • 哪些 query 没触发但后来人工指定了。
  • 触发后是否完成任务。
  • Agent 是否读取了 references。
  • 哪些脚本运行失败。
  • 用户是否要求重做。

这些数据能反向指导 description 和正文优化。

11.3 Skill Marketplace Governance

随着 Skill 生态扩大,治理会越来越重要:

  • 签名和来源验证。
  • 安全扫描。
  • 权限声明。
  • 依赖锁定。
  • 恶意指令检测。
  • 用户可见的风险标签。
  • 组织级 allowlist。

11.4 Skill Router

当 Skill 数量变多,单纯依赖每个 description 可能不够。可以增加一个轻量 router:

  • 先判断任务类型。
  • 再选择一个或多个 Skill。
  • 对冲突 Skill 做优先级决策。
  • 对不确定任务先询问用户。

11.5 Skill Distillation

从成功任务轨迹中自动提炼 Skill:

  • 提取成功步骤。
  • 提取失败原因。
  • 提取用户纠正。
  • 形成 Gotchas。
  • 生成评估用例。

这比凭空让模型“写一个 Skill”更可靠,因为它有真实任务 grounding。

11.6 Skill Regression Testing

每次改 Skill,都跑:

  • 命中率测试。
  • 输出质量测试。
  • 误触发测试。
  • 安全检查。
  • token 成本对比。

Skill 退化很隐蔽。一个看似更完整的版本,可能因为正文太长、规则冲突或 description 过宽而让 Agent 表现变差。

11.7 Skill Memory Loop

把用户每次纠正 Agent 的话沉淀成候选 Skill 更新:

  • “以后不要这么做”
  • “我们公司这里叫 XX”
  • “这个字段不能用”
  • “这个接口要先调 A 再调 B”

这些不是普通聊天记录,而是高价值组织知识。

结语

写 Skill 的核心不是“把提示词写长”,而是把经验变成可触发、可执行、可验证、可演化的过程知识。

一个高质量 Skill 应该满足四句话:

  1. 该出现时能出现:description 命中真实用户意图。
  2. 不该出现时能克制:边界清楚,减少误触发。
  3. 出现后真有用:正文给出流程、资源、坑和验证。
  4. 用久了会变好:有评估、trace、反馈和版本迭代。

如果说 prompt engineering 是写给模型的一次性请求,那么 skill engineering 更像是给 Agent 写长期使用的操作系统补丁。它不是越华丽越好,而是越能稳定改变行为越好。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐