从 Prompt 到 Agent Skill:把专家经验封装成可复用能力
团队里总有一些“效果特别好的 Prompt”。
它可能躺在某位专家的聊天记录里,长达两页,包含十几条要求:先看哪些文件、按什么顺序检查、哪些情况必须停止、输出用什么表格、最后运行哪些命令。
第一次复制,结果很好。第二个人补了一句自己的要求。第三个人删掉了“看起来没用”的限制。两个月后,团队手里已经有五个版本,谁也说不清哪一个才是标准。
问题不在于 Prompt 不够长,而在于它仍然只是一次对话中的文本:
- 什么时候该使用它,依靠人记得;
- 输入缺什么,往往执行到一半才发现;
- 详细资料全部塞在正文里,挤占任务上下文;
- 关键脚本每次临时重写;
- 输出好不好,没有稳定测试;
- 专家修正一次,下一个人仍可能复制旧版本。
Agent Skill 解决的正是这类问题。它不是“更长的 Prompt”,而是一个可以被 Agent 发现、按需加载、执行和验证的工作流包。
这篇文章会用一个真实例子贯穿全过程:把团队反复使用的“生成发布说明”Prompt,升级成 write-release-notes Skill。
完成后,你将能够:
- 判断一段经验应该留在 Prompt、写进
AGENTS.md,还是升级为 Skill; - 写出能够正确触发、也能避免误触发的
description; - 把流程、参考资料、模板和确定性脚本分层组织;
- 用正例、反例、缺失输入和边界案例测试 Skill;
- 把 Skill 当作代码资产持续版本化,而不是写完就忘。
一、Skill 到底是什么?
OpenAI 将 Skill 定义为面向特定任务的可复用能力:它把说明、资源和可选脚本放在一个目录中,让 ChatGPT 或 Codex 能够可靠地遵循同一工作流。Agent Skills 同时也是一种开放格式,最小结构只有一个 SKILL.md:
write-release-notes/
├── SKILL.md # 必需:触发元数据 + 核心工作流
├── agents/
│ └── openai.yaml # 推荐:界面名称、默认提示词、依赖
├── references/ # 可选:规范、领域知识、详细示例
├── scripts/ # 可选:需要确定性的可执行程序
└── assets/ # 可选:输出模板、图标、样板文件最关键的是:Skill 不会永远把全部内容塞进对话。
Agent 会先看到所有 Skill 的 name 和 description;当用户目标匹配,才读取完整 SKILL.md;执行到具体分支时,再按说明加载 references/、运行 scripts/ 或使用 assets/。这叫渐进式加载。
这套机制带来两个直接收益:
- 可以安装许多 Skill,而不用在每次任务里支付全部上下文成本;
- 专家知识可以按任务分支加载,Agent 不必从一大堆无关材料中寻找规则。
二、先别急着写 Skill:把经验放在正确位置
并不是所有好 Prompt 都应该变成 Skill。
| 承载面 | 适合放什么 | 典型例子 | 不适合放什么 |
|---|---|---|---|
| Prompt | 只对本次任务有效的目标、输入、范围和验收 | “修复订单页白屏,只改前端” | 每周都要重复的完整流程 |
AGENTS.md | 这个仓库里所有任务都要遵守的约定 | 构建命令、目录规则、Review 要求 | 仅生成发布说明时才需要的步骤 |
| Skill | 围绕一个明确用户目标的可复用工作流 | 发布说明、迁移审查、PDF 红线修订 | 永远适用的项目规则 |
| MCP / Connector | 实时外部数据、认证和受控动作 | 读取 GitHub PR、查询 CRM、创建工单 | 单纯的写作步骤和判断规则 |
| Plugin | 需要安装和分发的一组 Skill、连接器、工具与资产 | GitHub 协作能力包 | 团队内部的一个小工作流初稿 |
一个实用判断是:
Prompt 描述这一次要什么;
AGENTS.md规定这个项目永远怎么做;Skill 教 Agent 在某类任务中如何做;MCP 提供实时能力;Plugin 负责组合与分发。
混合需求要拆开。例如:
- “所有代码都使用 pnpm”放进
AGENTS.md; - “本次发布范围是
v2.4.0..v2.5.0”放进 Prompt; - “如何收集提交、分类变更、识别破坏性变更并生成发布说明”放进 Skill;
- “读取 GitHub Release 和 PR 的实时数据”交给 GitHub Connector 或 MCP。
三、什么经验值得封装?用五个问题筛选
一段经验同时满足越多条件,越值得升级为 Skill:
1. 是否重复发生?
同一类任务每周、每个版本或每个项目都会出现,而不是一次性的特殊事故。
2. 质量是否依赖隐性判断?
专家不仅“执行步骤”,还会判断:哪些改动面向用户、什么算 Breaking Change、何时必须停下来询问。
3. 输入和输出能否说清?
如果连开始需要什么、完成长什么样都无法描述,先梳理流程,不要急着封装。
4. 是否能独立验收?
能够用结构、字段、命令、示例或人工 Rubric 判断结果,而不是只说“感觉专业”。
5. 错误代价是否值得加护栏?
频繁遗漏、错误发布、泄露信息或不一致输出,会让固化流程产生明显收益。
下面三类通常不值得:
- 只用一次、上下文高度独特的任务;
- “写得更好看”这类边界模糊、没有稳定输入输出的愿望;
- 模型本来就能可靠完成、没有组织特有知识或流程的简单操作。
四、案例:那个越来越长的发布说明 Prompt
团队最初这样问:
请根据最近的代码提交写一份发布说明,按新功能、优化和修复分类,
语言通俗一些,不要写内部重构,要标记 Breaking Change,最后给升级建议。后来不断追加:
还要读取 PR,不要把 issue 标题当事实;没有证据的用户影响不能猜;
同一改动不要重复分类;安全修复未公开前不要披露利用细节;
必须写版本范围和比较链接;有数据库迁移时单独提示;
中文术语按照团队词表;最后检查每条都能追溯到 commit 或 PR……它已经不是普通写作指令,而是一个工作流:
确认版本范围
→ 收集提交与 PR 证据
→ 过滤内部噪声
→ 判断用户影响与风险
→ 分类并去重
→ 套用发布模板
→ 做可追溯性与安全检查这就是适合封装的信号。
五、第 1 步:先写“用例清单”,不要先写 SKILL.md
Skill 的触发与验证都来自真实用例。至少准备四组:
应该触发
请为 v2.4.0 到 v2.5.0 生成面向客户的发布说明。
整理本周已经合并的 PR,生成 Release Notes。间接表达但仍应触发
我们明天发版,帮我把这批用户可见的变化整理成公告。输入不完整,应追问
帮我写发布说明。此时至少缺少版本范围、目标读者或证据来源。Skill 应追问,而不是擅自选择最近十条提交。
不应该触发
给这个 PR 写 Review 意见。
把 README 中的安装步骤翻译成英文。如果一个 Skill 只有正例,没有反例,它很可能会过度触发。
六、第 2 步:命名与 description 决定 Skill 能否被发现
Skill 名称使用小写字母、数字和连字符,目录名与 name 保持一致。优先使用动作导向的短名称:
write-release-notes ✅
release-notes-helper 勉强可用,但目标不如动词清楚
ReleaseNotesExpert ❌ 大写且不像用户目标
general-dev-tool ❌ 范围过宽description 是最重要的触发入口。Agent 在尚未激活 Skill 时只能看到它和名称,所以“什么时候使用”必须写在 description 里,不能藏在正文的“适用场景”章节。
差的写法:
description: 帮助生成高质量发布说明。它没有说明输入、读者、触发词和边界。
更好的写法:
description: >-
Generate customer-facing release notes from a Git commit range, merged pull
requests, or a release diff. Use when the user asks for release notes,
changelogs, launch announcements, or a summary of user-visible changes.
Do not use for code review, commit-message writing, or internal sprint reports.一个可用 description 通常包含:
- 做什么:生成面向客户的发布说明;
- 输入是什么:commit range、PR 或 release diff;
- 用户会怎么说:release notes、changelog、发版公告;
- 何时不要用:代码审查、提交信息、内部周报。
不要把步骤写进 description。元数据负责路由,正文才负责执行。
七、第 3 步:用 Skill Creator 初始化骨架
在 Codex 中可以直接调用:
$skill-creator
创建一个 write-release-notes Skill:根据 Git 版本范围或已合并 PR,
生成面向客户的发布说明。需要识别用户可见变化、Breaking Change、
迁移步骤和安全披露边界;缺少版本范围时必须追问;不要用于代码审查。如果你手工创建,仓库级 Skill 建议放在:
.agents/skills/write-release-notes/个人跨项目复用可以放在:
$HOME/.agents/skills/write-release-notes/仓库级 Skill 可以和代码一起提交、Review 和版本化,更适合团队流程。个人级 Skill 适合仍在探索的工作方式。
最小文件:
---
name: write-release-notes
description: Generate customer-facing release notes from a Git commit range or merged PRs. Use for release notes, changelogs, and launch announcements. Do not use for code review or internal sprint reports.
---
# Write release notes
1. Confirm the version range and target audience.
2. Collect traceable change evidence.
3. Keep only user-visible changes.
4. Classify, deduplicate, and identify upgrade risks.
5. Render the required template.
6. Verify every claim against a commit or PR.这已经是一个 Skill,但还没有承载真正的专家经验。
八、第 4 步:把专家判断写成“输入—决策—动作—输出”
不要写“认真分析”“保证高质量”这类无法执行的口号。每条经验都尽量落到四类信息:
| 类型 | 要回答的问题 | 发布说明示例 |
|---|---|---|
| 输入契约 | 开始前必须拿到什么? | 起止版本、目标读者、提交或 PR 证据 |
| 决策规则 | 如何判断和分支? | 只有用户可观察变化进入正文 |
| 动作步骤 | 按什么顺序做? | 先收集,再分类,最后写作与验证 |
| 输出契约 | 结果必须长什么样? | 摘要、分类变化、Breaking Changes、升级步骤、来源 |
下面是一份更完整的 SKILL.md 核心:
---
name: write-release-notes
description: >-
Generate customer-facing release notes from a Git commit range, merged pull
requests, or a release diff. Use for release notes, changelogs, launch
announcements, and summaries of user-visible changes. Do not use for code
review, commit-message writing, or internal sprint reports.
---
# Write release notes
## Inputs
Require:
- a Git range, release diff, or explicit PR list;
- the target audience;
- output language.
If the change range is missing or ambiguous, ask for it before collecting data.
Do not silently choose a time window.
## Workflow
1. Inspect the repository guidance and current working tree without modifying it.
2. Collect commits and merged PR evidence for the confirmed range.
3. Exclude changes that are purely internal unless they alter performance,
compatibility, security, or operator behavior.
4. Classify each remaining item as Added, Improved, Fixed, Deprecated,
Security, or Breaking.
5. Merge duplicate entries that refer to the same user-visible outcome.
6. For Breaking items, identify affected users, required migration, and the
first incompatible version. If evidence is missing, mark it Unknown.
7. Render `assets/release-notes-template.md`.
8. Verify that every factual claim maps to at least one commit or PR.
## Safety and evidence
- Never infer customer impact from a ticket title alone.
- Never expose exploit details for an embargoed security fix.
- Never invent migration steps. Mark missing evidence and request review.
- Do not modify tags, releases, branches, or repository files.
## Resources
- Read `references/product-language.md` when writing customer-facing names.
- Read `references/security-disclosure.md` when any change is security-related.
- Run `scripts/collect-changes.sh <from> <to>` when a local Git range is provided.
- Use `assets/release-notes-template.md` for the final structure.
## Output
Return:
1. release title and one-paragraph summary;
2. grouped user-visible changes;
3. Breaking Changes and migration steps, even when empty;
4. evidence links or commit hashes;
5. an `Unknown / Needs review` list for unsupported claims.注意它没有规定每一句文案,而是固定了不应该被自由发挥的部分。
九、第 5 步:按风险设置 Agent 的自由度
Skill 不是越严格越好。合适的约束程度取决于任务的脆弱性:
高自由度:多种答案都合理
适合文案语气、摘要角度、解释方式。写原则和示例,不要锁死每句话。
中自由度:有首选模式,但允许变体
适合分类规则、输出结构、框架选择。用清楚的决策表、伪代码或带参数模板。
低自由度:步骤错一次就有明显风险
适合版本计算、文件转换、数据校验、发布命令。优先使用经过测试的脚本,让 Agent 传入少量参数。
例如,不要让 Agent 每次重新发明“如何列出两个 Tag 之间的提交”。把确定性部分放进脚本:
#!/usr/bin/env bash
set -euo pipefail
from_ref=${1:?"missing from ref"}
to_ref=${2:?"missing to ref"}
git rev-parse --verify "$from_ref^{commit}" >/dev/null
git rev-parse --verify "$to_ref^{commit}" >/dev/null
git log --no-merges --format='%H%x09%s' "$from_ref..$to_ref"脚本负责“准确列出”,模型负责“理解和表达”。这是 Skill 中非常重要的人机分工。
任何加入 scripts/ 的程序都必须实际运行测试。脚本出错会让错误稳定复现,比一次 Prompt 写错更危险。
十、第 6 步:用渐进式加载控制上下文
把所有材料都写进 SKILL.md,只是把超级 Prompt 换了文件名。
合理拆分:
write-release-notes/
├── SKILL.md
├── references/
│ ├── product-language.md
│ └── security-disclosure.md
├── scripts/
│ └── collect-changes.sh
└── assets/
└── release-notes-template.md拆分原则:
SKILL.md只保留每次执行都需要的核心工作流;references/放详细规范、领域词表、API Schema 和少见分支;scripts/放需要确定性、经常被重写的程序;assets/放最终产物要复制或改写的模板、图标和样板。
仅仅把文件放进去还不够。SKILL.md 必须说明什么时候读取或运行:
Read references/security-disclosure.md when a change is security-related.比下面这句有效得多:
See references/ for more information.后者没有路由条件,Agent 不知道该读哪个文件,也不知道是否需要读。
官方 Agent Skills 规范建议把 SKILL.md 控制在 500 行、约 5,000 Token 以内,并避免多层引用链。重点不是机械追求数字,而是确保激活后加载的每一段内容都与核心工作流有关。
十一、第 7 步:验证“会不会触发”和“做得对不对”
Skill 有两类完全不同的质量:
激活质量
- 应该触发时是否加载?
- 不应该触发时是否保持沉默?
- 间接表达能否识别?
- description 被缩短时,最关键触发词是否还在前面?
执行质量
- 输入缺失时是否追问?
- 是否遵守步骤和禁止事项?
- 是否读取了正确参考文件?
- 脚本是否用正确参数运行?
- 输出能否追溯和验收?
建立一个最小测试矩阵:
| 类型 | 测试请求 | 期望行为 |
|---|---|---|
| 直接正例 | “为 v2.4.0..v2.5.0 写 Release Notes” | 激活并执行完整流程 |
| 间接正例 | “明天发版,整理客户可见变化” | 激活;确认版本范围 |
| 缺失输入 | “写个发布说明” | 追问范围和目标读者 |
| 明确反例 | “Review 这个 PR” | 不激活 |
| 边界案例 | 只有内部重构 | 输出无用户可见变化,不编造亮点 |
| 安全案例 | 含未公开漏洞修复 | 加载披露规范,不泄露利用细节 |
测试时保存原始请求、实际输出、调用的文件或脚本以及失败原因。不要只让作者自己“读一遍觉得没问题”。复杂 Skill 最好用新的任务或独立 Agent 做前向测试,避免测试者从创作上下文中提前知道标准答案。
如果触发错了,先改 description;如果触发正确但流程漂移,再改正文或资源。不要用增加正文规则解决路由问题。
十二、第 8 步:安装、调用与验证目录
Codex 支持显式和隐式两种激活:
- 显式:在 Codex CLI 或 IDE 中输入
$write-release-notes,或通过/skills选择; - 隐式:用户请求与
description匹配时,由 Codex 自动选择。
第一次测试建议显式调用,这样先验证执行质量;之后去掉 $ 测试隐式触发。
仓库级 Skill 放进 .agents/skills/ 后,Codex 会从当前工作目录向仓库根目录扫描可用 Skill。修改通常能自动发现;如果没有出现,重启 Codex。
可以用 Skill Creator 自带验证脚本检查目录与 front matter:
python /path/to/skill-creator/scripts/quick_validate.py \
.agents/skills/write-release-notes开放 Agent Skills 生态也提供 skills-ref validate。语法验证只能发现命名、YAML 和结构错误,不能替代真实触发与输出测试。
十三、七个最常见的失败模式
1. 把 Skill 写成百科全书
正文塞进所有背景知识、所有工具说明和所有例子。激活以后,上下文立即被无关信息占满。
修复:保留核心工作流,细节按条件拆到 references。
2. description 写得很漂亮,但无法路由
“赋能团队高质量交付”没有用户目标、输入词和边界。
修复:使用用户真实会说的词,写清做什么、何时用、何时不用。
3. 一个 Skill 承包整个研发流程
同时做需求分析、编码、测试、发布和运营复盘。不同任务拥有不同触发、输入和成功标准,应该拆开。
4. 把常识写得很长,把关键边界写得很短
反复解释 Git 是什么,却只用一句“注意安全”。
修复:假设 Agent 已经聪明;只写它无法从通用知识得出的组织规则、顺序和禁止事项。
5. 用自然语言执行必须确定的计算
让模型手工计算版本、转换文件或聚合数字。
修复:稳定计算进入脚本,模型负责选择参数与解释结果。
6. 只有 Happy Path
没有测试缺失输入、误触发、安全边界和空结果。
修复:至少覆盖直接、间接、缺失、反例和风险五类测试。
7. 发布后没有负责人
流程变化了,Skill 仍在教旧方法。
修复:像代码一样指定 Owner、Review、版本和退役机制。
十四、Skill 也需要工程化维护
一个进入团队使用的 Skill,至少应该记录:
- Owner:谁负责业务正确性;
- 适用范围:哪些仓库、团队和任务;
- 依赖:工具、脚本、MCP、系统命令和权限;
- 测试集:正例、反例和边界案例;
- 变更记录:由 Git 历史与 PR 承担,不要另造无用文档;
- 失效信号:流程、工具或政策变化时谁来更新;
- 退役条件:何时由新 Skill、Plugin 或产品能力替代。
评估可以从四类指标开始:
| 指标 | 示例 |
|---|---|
| 触发准确率 | 应触发请求中成功激活的比例;反例误触发率 |
| 流程遵循率 | 必需步骤、停止条件、资源加载是否完成 |
| 输出合格率 | 模板字段、证据、人工 Rubric 的通过率 |
| 效率 | 平均返工次数、上下文用量、完成时间 |
不要只看“用户有没有调用”。一个被频繁误触发、输出还需要大量返工的 Skill,不是成功资产。
十五、从个人 Skill 到团队 Plugin
Skill 是工作流本身。当它需要更广泛分发或与外部能力组合时,再升级为 Plugin:
一个稳定 Skill
→ 多个相关 Skills
→ 加入 GitHub / CRM 等 Connector 或 MCP
→ 配置界面元数据与依赖
→ 打包为可安装 Plugin边界仍然要清楚:
- Skill 告诉 Agent 什么时候、按什么顺序、如何判断、输出什么;
- MCP 提供 实时数据、认证、授权和受控动作;
- Plugin 把 Skills、连接器、MCP 配置和资产组合成可安装能力包。
不要因为最终可能做成 Plugin,就在第一版 Skill 中提前引入服务器、认证和发布流程。先证明工作流本身有价值。
十六、一份可直接使用的 Skill 设计卡
创建前先填完这张卡:
Skill 名称:
一句话用户目标:
应该触发的 3 个真实请求:
1.
2.
3.
不应该触发的 3 个请求:
1.
2.
3.
必需输入:
输入缺失时:追问 / 使用默认值 / 停止
核心决策:
1.
2.
3.
确定性动作(考虑脚本):
按需知识(考虑 references):
输出模板(考虑 assets):
禁止推断或执行:
完成标准:
测试集位置:
Owner:如果这张卡填不完,说明专家经验仍停留在直觉层面。先观察几次真实执行,把决策说清,再创建 Skill。
结语:把“我会做”变成“团队和 Agent 都能稳定做”
Prompt 的价值是快速探索。不要在一开始就把每个想法工程化。
当一个 Prompt 被反复复制、不断追加边界、依赖固定资料或脚本,并且结果已经有稳定验收标准时,它就跨过了一条线:从一次性对话,变成了值得维护的能力。
真正优秀的 Skill 不会试图替代 Agent 的智能。它只固化那些不能靠猜的部分:
何时触发、需要什么、按什么顺序、哪里必须停、哪些事实不能编、结果如何验收。
专家经验完成封装的标志,不是 SKILL.md 写得多长,而是另一位同事、另一个项目、另一次会话在没有作者现场指导时,仍能稳定得到合格结果。