🐸 青蛙编程网
首页 / AI / 技能 Skills / 4. 编写实战

4. 编写实战

这是什么:写技能其实是在给一段流程做分层封装——步骤进正文,脚本进 scripts/,长资料进 references/,模板进 assets/。

为什么用:一份技能写得好不好,不在文笔,在结构对不对。该给模型的步骤写成人话、该给脚本的活儿写成代码,两者的失败方式完全不同。

如何用:本章拿一个真实场景(发版)从零拆一遍,再总结常见反模式,告诉你哪种内容该放哪个目录。

4.1 从「一段话」到一个技能

假设你每次都要交代这段话:

「先把测试跑一遍,然后看 git log 确定版本号,再更新 CHANGELOG,最后打 tag 并推上去。如果发布失败了,用 git tag -d 删掉 tag 再回滚。」

直接塞进系统提示词,它就得每次都在上下文里,而且「跑测试」「看 log」这种确定性动作全靠模型现编,容易漏步骤。拆成技能:

release/
├── SKILL.md
├── scripts/
│   └── collect-changes.sh
├── references/
│   ├── versioning.md
│   └── rollback.md
└── assets/
    └── changelog-template.md

对应的 SKILL.md:

---
name: release
description: 按团队规范发版:跑测试、生成变更日志、打 tag 并推送。用户提到「发版」「发布新版本」「打 tag」时使用。
allowed-tools: Bash(git:*) Bash(npm:test:*) Read Write
---

发版流程:

1. 跑测试:`npm test`。失败就停下报告,不要继续。
2. 收集变更:跑 `scripts/collect-changes.sh`,它输出本次要写入 CHANGELOG 的条目。
3. 定版本号:按 `references/versioning.md` 的规则定。
4. 写变更日志:用 `assets/changelog-template.md` 的结构,内容来自第 2 步的输出。
5. 打 tag 并推送:`git tag -a v<版本> -m "..." && git push --tags`。
6. 推送后把 tag 地址回报给用户。

发布失败时:按 `references/rollback.md` 处理,不要自行决定重试。

模型拿到这段正文,就知道每一步该调哪个工具——而具体怎么收集变更、版本号怎么定,全部下沉到了附件里。

4.2 scripts/:把确定性动作交给脚本

判断标准很简单:这一步的结果能不能被唯一确定地算出来?

动作 放哪 理由
收集本周提交 ✅ scripts/ 结果确定,脚本比模型可靠且省 token
决定版本号 ⚠️ 半放 规则写进 references/,判断留给模型
写变更日志 ❌ 正文 需要结合上下文措辞,模型擅长
跑测试 ✅ 正文 + 工具 正文给命令,模型调用工具执行

脚本要自包含:要么不依赖任何东西,要么在文档里写清楚依赖。规范给的两条硬要求:

  • 脚本要能优雅处理边界情况,出错时给出有用的错误信息
  • 支持的语言取决于 Agent 实现,常见是 Python / Bash / JavaScript

写脚本的收益不光是「省 token」,更是一致性:模型每次跑出来的结果一样,不会今天漏一个文件明天多一个文件。

4.3 references/:长资料下沉

references/ 放需要时才查的东西,命名约定是:

文件 放什么
REFERENCE.md 详细技术参考
FORMS.md 表单模板或结构化数据格式
领域文件 finance.md、legal.md 这类

一条重要纪律:每个参考文件要聚焦。文件越小,Agent 真去读的时候越省上下文。这也是规范里「引用只做一层」的由来——references/ 里再套 references/,引用链就断了。

反例:

references/
└── guide/
    └── REFERENCE.md      # ❌ 别嵌套

正例:

references/
├── REFERENCE.md          # ✅ 平铺
└── release-notes.md      # ✅

4.4 assets/:模板与静态资源

assets/ 放Agent 会拿去填的模板和固定资源:

放什么 例子
文档模板 changelog-template.md、周报三段式骨架
配置模板 tsconfig.base.json、.env.example
图片 架构图、流程图
数据文件 查找表、schema

一个实用技巧:在正文里点名引用模板,模型就会去读那个模板再填空,而不是自己临场编格式。模板越具体,输出越稳。

4.5 参考型 vs 任务型:两种写法

前面提过技能分两种,写法完全不同:

参考型——补知识,让模型知道「这个仓库的规矩」:

---
name: api-conventions
description: 本仓库 API 的命名与错误格式约定。写或改 REST 接口、定义响应体时使用。
---

写接口时:

- 路径用 RESTful 风格,资源名用复数
- 列表接口统一返回 `{ items: [], total: n }`
- 错误统一 `{ error: { code, message } }`,`code` 用大写下划线
- 新接口必须在 `openapi.yaml` 里补一段

任务型——给 SOP,最好加上「只能我手动触发」:

---
name: release
description: 按团队规范发版。
disable-model-invocation: true
---

(后面的发版步骤)

disable-model-invocation: true 的作用是:模型不能自作主张去发版,只有你打 /release 才触发。凡是有副作用的动作——发版、删库、付钱——都该加上它。

这是 Claude Code 的扩展字段(见第 2.3 节)。用别的工具时,把这条意思直接写进 description 或正文第一步。

4.6 常见反模式

反模式 症状 改法
技能写成小百科 正文 800 行,每轮都在烧 token 细节拆进 references/
描述写成广告语 模型永远不主动用它 改成「做什么 + 何时用 + 关键词」
步骤写成散文 模型漏步骤、顺序错 编号列表,一条一步
什么都要自己写 正文里塞满命令和实现 确定性的挪进 scripts/
互相嵌套引用 Agent 顺着链子绕晕 引用只做一层
同名技能到处放 到底哪个生效说不清 一个技能只留一份,其余删掉

动手改

  1. 挑一个你每周都要交代 Agent 的流程,按第 4.1 节拆成 SKILL.md + scripts/ + references/ 三层
  2. 给你拆出来的技能加一个 references/,把正文里最啰嗦的两段挪进去,对比正文长度变化
  3. 写一个「有副作用」的技能(比如发版、删数据),给它加上禁止模型自动触发的设置,然后想想:换到一个不支持这个字段的工具里,你要怎么表达同样的意思

小结

  • 判断标准:结果确定的进脚本,需要判断的留正文,长资料进 references,要填的模板进 assets
  • SKILL.md 正文只留「做什么、什么顺序、产出什么」,细节全下沉
  • 参考型补知识,任务型给 SOP;有副作用的任务型要禁止模型自动触发
  • 脚本要自包含、处理好边界情况——它换来的是一致性
  • 引用一层深、不嵌套;常见反模式对照表随时翻

下一章:安装与加载,技能到底放哪、优先级怎么排、怎么校验 🐸

📥 下载本章代码

ZIP 内含本章全部代码文件与说明,解压即用,与教程内容同步生成。