外部 Agent Skill 书写指南

📅 2026/7/31 8:04:52 👁️ 阅读次数 📝 编程学习
外部 Agent Skill 书写指南

外部 Agent Skill 书写指南

一、什么是 Skill

Skill 是一份给其他 Agent 使用的「说明书」,告诉它:

  • 什么时候该调用(触发场景)

  • 怎么调用(执行方式)

  • 预期产出(输出格式)

Skill 不是给人类用户的教程,也不是 Agent 的内部提示词,而是Agent 与 Agent 之间的接口契约


二、Skill 的标准结构

skill-name/ ├── SKILL.md ← 唯一必需文件(说明书) └── scripts/ ← 可选:脚本实现目录 └── main.py

命名规则

  • skill 目录名(同时也是 frontmattername字段)必须匹配^[a-z0-9][a-z0-9-]{0,62}$

- 仅小写字母 + 数字 + 连字符

- 必须以字母或数字开头

- 不以连字符开头/结尾

- 长度 ≤ 63 字符

- 这是 Trae / Claude / Qoder 等主流平台共用的安全约束

  • 示例:invoice-extractorskill-reviewerpdf-merger

SKILL.md 由两部分组成

| 部分 | 位置 | 作用 |

|—|—|—|

|Frontmatter(YAML) | 文件头部---块内 | 触发元数据,Agent 据此判断要不要加载正文 |

|正文(Markdown) | Frontmatter 之后 | 详细的输出列、依赖、运行方式、注意事项 |

脚本放在哪里

推荐放scripts/目录,与 SKILL.md 同级

invoice-extractor/ ├── SKILL.md └── scripts/ └── invoice_to_excel.py

不要把完整脚本内嵌在 SKILL.md 的代码块里。原因:

  • SKILL.md 会变得臃肿(一个中等脚本 10 KB+,Agent 加载慢)

  • 同一份代码在两处维护容易不同步

  • 别人拿到 SKILL.md + scripts/ 目录即可直接使用,无需先复制代码


三、Frontmatter 怎么写

---name:"skill-name"description:"功能描述(一句话)+ 触发场景(什么情况下调用)。要短,控制在 200 字以内。"version:"1.0.0"---

字段说明

| 字段 | 必填 | 说明 |

|—|—|—|

|name| ✅ | 见上文命名规则;同时也用作目录名 |

|description| ✅ | 触发关键词描述,< 200 字 |

|version| 推荐 | Semver 格式(MAJOR.MINOR.PATCH),便于版本管理与升级判断 |

|dependencies| 可选 | 显式声明依赖包及版本(如pypdf>=3.0,<6.0),避免环境差异导致失败 |

description 怎么写

关键点

  • description是 Agent 唯一会扫到的元数据,必须同时回答"做什么"和"何时用"。

  • 不要写长句子解释工作原理,Agent 只看它来判断要不要加载正文。

正面例子

description: "从电子发票 PDF 提取字段并导出 Excel。当用户提供 PDF 路径或含电子发票的目录,并要求报销登记时调用。"

反面例子

description: "这是一个发票处理工具" ← 没说明何时用 description: "用 Python 解析 PDF 然后写入 Excel" ← 太技术

version 怎么用

调用 Agent 拿到 skill 后可通过version判断是否需要更新:

  • 破坏性变更 → 升级 MAJOR

  • 新增功能/字段 → 升级 MINOR

  • Bug 修复 → 升级 PATCH

示例:

  • 1.0.0:首个稳定版

  • 1.1.0:新增"行程单合并"功能

  • 1.1.1:修复某发票版式解析失败


四、正文怎么写

核心原则:让 Agent 直接照做,不要让 Agent 再去拼脚本

Agent 拿到 Skill 后的预期行为是"照着 SKILL.md 的命令直接执行",不是"读完后去研究 PDF、再写代码、再调试"。

要做到这一点,正文里指向 scripts/ 下的脚本即可,不必把代码贴出来。

推荐章节顺序

  1. 概述 — 一句话讲功能

  2. 项目结构 — 列出目录、说明文件作用

  3. 运行 — 一两条命令示例(同时给 PowerShell 和 bash)

  4. 输出列 / 输出格式 — 让 Agent 知道结果长什么样

  5. 依赖 — 安装命令

  6. 注意事项 — 容错 / 边界情况 / 幂等性

  7. 触发关键词 — 帮助 Agent 判断场景(可选)

"运行"章节写法

## 运行 PowerShell(Windows): ```powershell # 安装依赖(首次需要) pip install pypdf openpyxl # 跑脚本(路径相对于本 SKILL.md 所在目录) python scripts/invoice_to_excel.py "D:\公司相关\发票" ``` bash(macOS / Linux): ```bash pip install pypdf openpyxl python3 scripts/invoice_to_excel.py "/Users/me/invoices" ``` 可选第二参数指定输出路径: ```bash python3 scripts/invoice_to_excel.py "<in_dir>" "<out.xlsx>" ```

要点:

  • 路径使用相对scripts/xxx.py,让调用者无需知道机器特定目录

  • 给一两条最简命令即可,不要列一堆调用方式

  • 路径示例用绝对路径方便理解,但说明"相对于 SKILL.md 目录"

  • 同时给 PowerShell 和 bash避免跨平台失败


五、避免的写法

| ❌ 错误写法 | 为什么错 |

|—|—|

| 把完整脚本内嵌到 SKILL.md 代码块 | 让 SKILL.md 臃肿、难维护、同步风险 |

| 让 Agent “先读 PDF,再写脚本” | 把 Skill 当教程用,Agent 不会复用你的代码 |

| 详细写"如何一步步操作" | Agent 已经有推理能力,不需要你教它步骤 |

| 中英混杂 | 浪费 token,统一一种语言 |

| 重复的标题/段落 | 同一信息只写一次 |

| 把 SKILL.md 写成 README | README 是给人看的,SKILL.md 是给 Agent 看的 |

| description 长篇大论 | description 只用来判断要不要加载正文,要短 |

| 用机器特定路径 | 让别的机器跑不了,要相对路径 |


六、自检清单

写完一个 Skill 后,逐条验证:

  • 独立可运行:解压 zip 后能否直接python scripts/xxx.py跑起来?

  • 依赖最小化:是否只依赖少数常见包?是否在文档里给了pip install

  • 依赖版本明确:依赖是否锁定了已验证的版本范围(如pypdf>=3.0,<6.0)?或提供requirements.txt

  • description 简洁:200 字内说明功能 + 触发场景?

  • 路径相对化:脚本路径是否相对 SKILL.md 所在目录(如scripts/xxx.py)?不要绑定机器特定路径。

  • SKILL.md 不臃肿:正文是否保持简短(< 5 KB 为佳)?脚本是否独立放在scripts/

  • 命名合规:目录名与name字段匹配^[a-z0-9][a-z0-9-]{0,62}$

  • 输出格式明确:是否清楚说明输出列/字段含义?

  • 退出码与输出约定:脚本成功时返回 0、失败非 0,错误信息输出到 stderr,关键结果(如输出文件路径)输出到 stdout?

  • 幂等性已声明:重复运行同一输入会覆盖、跳过还是报错?是否在"注意事项"里写明?

  • 跨平台示例:运行命令是否同时给了 PowerShell 与 bash 两种?

  • 附测试样本:是否提供一两个脱敏的小型测试样本?调用者解压后能立刻跑通验证。

  • 失败可恢复:脚本出错时是否会给出可读提示?是否需要清理 Excel 占用?

  • 重复内容已删除:同一信息没在多处复述?

  • 中英文统一:全文一种语言?

  • 语言匹配场景:中文业务场景用中文 skill(如"电子发票"“报销登记”),英文业务场景用英文 skill。中英文混杂会降低触发关键词匹配精度。


七、关于语言与 token

  • 英文 token 数通常比中文少:英文单词约 1 token/词,中文约 1.5-2 token/字。

  • 但 skill 是按"场景"匹配的,不是按"省 token"优化:中文业务场景里 description 写electronic invoice,Agent 触发识别会变差。

  • 取舍原则

- 中文业务 → 用中文,token 多花一些但触发精准

- 英文业务 → 用英文,省 token 也更地道

- 中英文混杂 → 避免(既不省 token 又损语义)

  • Frontmatter 用于触发判断;触发后正文完整加载(不同平台实现略有差异,但通常不会"前几次只读 frontmatter")。

八、脚本接口约定

调用 Agent 需要明确的成功/失败信号才能继续动作。建议遵循下列约定:

| 通道 | 内容 | 用途 |

|—|—|—|

|stdout| 关键结果(如"已生成: D:…\发票信息.xlsx") | Agent 据此获取输出位置 |

|stderr| 错误信息(人类可读) | Agent 据此告知用户失败原因 |

|exit code|0= 成功;非0= 失败 | Agent 据此判断是否继续 |

幂等性约定

  • 同一输入重复运行,应默认覆盖输出文件,而非追加或报错

  • 如行为不同(例:仅追加不覆盖),必须在"注意事项"中明确说明

  • invoice-extractor 即是覆盖行为:每次运行会覆盖发票信息.xlsx

错误处理建议

  • 输入路径不存在 → 退出码 1,stderr 提示

  • 依赖缺失 → 启动时检查,缺失时打印明确提示并退出

  • 部分字段解析失败 → 不退出,把空值写入 Excel,最后告知用户哪些字段需人工补


九、依赖管理

# 方式一:直接装最新版(不推荐用于生产)pipinstallpypdf openpyxl# 方式二:锁版本(推荐)pipinstall'pypdf>=3.0,<6.0''openpyxl>=3.0,<4.0'# 方式三:提供 requirements.txt# requirements.txt 内容:# pypdf>=3.0,<6.0# openpyxl>=3.0,<4.0pipinstall-rrequirements.txt

SKILL.md 中应写明已验证的版本范围。半年后某个包 breaking change 不会因为锁了版本而崩。


十、测试样本

建议:随 skill 附带一两个脱敏的小型测试样本。

目录约定:

invoice-extractor/ ├── SKILL.md ├── scripts/ │ └── invoice_to_excel.py └── tests/ ← 建议 ├── sample1.pdf ← 脱敏的测试 PDF ├── sample2.pdf └── README.md ← 说明预期输出

调用者拿到后:

python3 scripts/invoice_to_excel.py tests/

应该立即得到正确结果。如果失败,说明环境/依赖有问题。

样本要求:

  • 文件名不包含真实公司名、税号、金额

  • 覆盖至少 2 种版式(普通发票 + 增值税专票 / 发票 + 行程单 等)

  • 体积小(< 200 KB),便于分发


十一、发布方式

1. 单独 SKILL.md

直接放到目标 IDE 的 skills 目录,路径因平台而异:

| 平台 | 路径 |

|—|—|

| Trae |<skills-dir>/<name>/SKILL.md|

| Claude |<skills-dir>/<name>/SKILL.md|

| Qoder |<skills-dir>/<name>/SKILL.md|

| 其他 | 查阅各自 IDE 文档 |

通用形式:把SKILL.md放进<skills-dir>/<name>/SKILL.mdscripts/SKILL.md同级。

2. 打成 zip 分发

打包时排除调试文件、缓存、临时文件:

importzipfile,osfrompathlibimportPath src=Path('invoice-extractor')# skill 根目录out=Path('invoice-extractor.zip')SKIP_DIRS={'__pycache__','.git','_debug','tests'}# 视情况保留 testswithzipfile.ZipFile(out,'w',zipfile.ZIP_DEFLATED)asz:forroot,dirs,filesinos.walk(src):dirs[:]=[dfordindirsifdnotinSKIP_DIRS]forfinfiles:full=Path(root)/fiffull.suffixin{'.pyc','.pyo'}:continuez.write(full,arcname=full.relative_to(src).as_posix())

3. 维护策略

  • 脚本与 SKILL.md 解耦后,只用维护scripts/下的源文件

  • SKILL.md 只引用路径与版本号,不会因脚本细节变动而过期

  • 每次发布新版本时同步更新version字段


十二、本项目(invoice-extractor)示例

invoice_extractor/ ← 仓库根目录 ├── README.md ├── skills/ │ ├── invoice-extractor/ ← Skill 1 │ │ ├── SKILL.md │ │ └── scripts/ │ │ └── invoice_to_excel.py │ └── skill-reviewer/ ← Skill 2:审查其他 Skill │ ├── SKILL.md │ └── scripts/ │ └── review_skill.py ├── docs/ │ └── Skill写作指南.md ├── dist/ ← 分发包 │ ├── invoice-extractor.zip │ └── skill-reviewer.zip └── dev/ ← 开发调试(按 skill 分目录) ├── _pack.py ├── invoice-extractor/ │ ├── scripts/ │ └── output/ └── skill-reviewer/ └── scripts/

对照检查:

  • ✅ SKILL.md 精简到 ~2.6 KB(不内嵌脚本)

  • ✅ 项目结构:SKILL.md+scripts/invoice_to_excel.py,职责分离

  • ✅ description 一句话讲清功能 + 触发场景(77 字符)

  • ✅ 依赖明确:pip install pypdf openpyxl

  • ✅ 运行命令相对路径:python scripts/invoice_to_excel.py "<dir>"

  • ✅ 输出列表格化,Agent 容易解析

  • ✅ 退出码:成功 0、失败非 0

  • ✅ 幂等:每次覆盖发票信息.xlsx

  • ✅ 注意事项:Excel 占用、未解析字段留空等边界情况

  • ✅ 触发关键词清单