如何设计一个高质量Skill
目录
如何设计一个高质量Skill
三个段位:先写对,再写强,最后写活。外加一个 benchmark 闭环。
我在实际项目里写了不少 Skill,踩的坑比写的 Skill 还多 😅
回头一看,大部分问题不是"搞不懂语法怎么写",是从一开始就没把 Skill 当回事。你当它是一段 prompt,它就照着 prompt 的水平交差。你当它是个小系统来搭,它就能扛住复杂场景。
⚠️ 免责声明:下面全是我个人经验,信则有,不信则……也正常 😅
一、先写对
这一个段位只解决一件事:你写的指令,AI 能不能不走样地执行。
听起来不难,但我看过的 Skill 文件里,起码一半倒在这关 🤷
指令不是解释
SKILL.md 是操作指令集,不是知识库文档。解释只在"框定行为边界"时才有意义。
还是先说说为什么要区分这个。给人看的结构要铺垫背景、解释动机、讲设计思路。但 AI 不搞这套——你给它塞背景故事,它不会"理解得更深刻",只会被无关信息分散注意力。
那解释性的内容是不是完全不能写?不是。只留一种:框定行为范围的。比如"这个字段只在文档来源是 wiki 时生效"——这是在圈条件,必须留。但"为什么设计这个步骤"那种说明——你删掉试试,AI 行为没变的话,就该砍。
标准就一句话:删了这段,AI 会在某个场景不知道该怎么做吗?不会?那就删。
重点优先
每条指令
**关键词/动作名**:浓缩描述,AI 一眼定位关键信息。
理由是:AI 读文件跟人不一样。人扫一眼整页能自己归纳重点,AI 更依赖显式的格式信号——加粗、开头、列表项,这些才是它抓取信息的路标。你让它在普通段落里自己找关键信息,它就容易找偏或者找漏。
对比两种写法就清楚了。不好的写法:
“在处理飞书文档的时候,请注意,如果你需要读取文档内容的话,是不能直接去读取全文的,你需要先通过文档链接来获取一个叫做 block 树的…”
好的写法:
文档读取:先调 block 树接口,递归解析内容,禁止直接请求全文
Block 解析:按类型分流——text/header/list 走文本提取,table 走表格解析器
容量限制:单次最多拉取 500 个 block,超出需分页
前一种 AI 得自己归纳"哦意思是先拿 block 树",归纳这一步就可能歪。后一种 AI 扫一遍就定位到自己要的信息。
每条指令保持同样的结构:加粗是锚点,冒号后面是动作和约束。AI 养成习惯,看到加粗就知道这是要执行的事。
结构化表述
指令按角色边界、主流程、约束、异常四层排列。信息位置决定 AI 理解优先级。
指令在文件里的排列顺序,决定了 AI 理解的优先级。
位置就是权重。禁止项埋在第三层第六段里,AI 大概率忽略。约束直接放在显眼位置,AI 先记住边界再开始干活。
我是这么分层的:
| 层级 | 内容 | AI 怎么看 |
|---|---|---|
| ① | 角色和边界:我管什么、不管什么 | 先建框架 |
| ② | 主流程:正常路径怎么走 | 再认路 |
| ③ | 约束和禁止:什么不能碰 | 再记红线 |
| ④ | 异常处理:走不通了怎么办 | 最后记兜底 |
而且同一层内部也要有优先级。同一种类型的约束归到一起,不要分散在各个段落里。举例——容量限制、授权校验、超时处理,这三条属于同一个约束层就该放在一起写:
容量限制:单次最多拉取 500 个 block,超出需分页
授权校验:只处理当前用户有权限的文档,无权限的返回 E002
超时处理:单次操作超过 30 秒视为失败,返回 E003并重试
放在一起 AI 才知道"哦这些都是约束类规则",而不是在某个段落里零散出现一条。
Mermaid 优先
条件分支逻辑直接画图,不拿文字绕。一句话能讲清的除外。
文字来描述"如果 A 则 B,否则如果 C 则 D"这种分支逻辑,存在三个硬伤:嵌套深了必然产生歧义、边界情况容易遗漏、AI 对自然语言的条件推理不稳定。
Mermaid 的优势是:它没有歧义空间。三行图能画清楚的事情,文字绕半天还可能出错。
这条规则同样适用于"一个条件引出多个分支"和"循环/回退"这类逻辑。判断标准就一条:如果用文字描述要超过三句话才能讲清楚的分支,就放 Mermaid。
材料格式干净了,AI 才不容易跑偏。
二、再写强
写对之后下一个坎:任务一复杂、指令一多,AI 自己也乱。
这时候在一个文件里死堆指令没有用。得上架构。
编排器
复杂 Skill 里,SKILL.md 只做调度。阶段定义、I/O 契约、门禁声明,细节下沉。
简单 Skill,比如一个翻译补全,几十行全在一个文件里管够。但复杂 Skill——"会议纪要整理"包含查询、提取、结构化、生成、发送五个环节——全塞一个文件里,AI 读到后面忘了前面,执行质量反而下降。
编排器只管四件事:
- 流程有几个阶段、顺序怎么排
- 每个阶段的输入输出
- 硬约束和门禁卡在哪
- 但不把每阶段的细节全背自己身上
细节下沉到子文件或脚本。编排器保持 300 行左右是个经验值——拆少了说明阶段分得不够细,太多了说明编排器自己背了太多不该背的细节。
mini-loop
每个关键步骤内部自循环验收,而不是一条线走到底。做一步、验一步、过了才往下。
一次 Workflow 如果是一条 A → B → C → 完的直线,中间任何一步出问题都会导致整条链断裂或往下游传递脏数据。更好的做法是每一步自己绕回验收。
全局流程
├─ 收集阶段
│ └─ 小循环:拉数据 → 查完整性 → 缺了补 → 再查 → 过了往下
├─ 处理阶段
│ └─ 小循环:处理 → 格式校验 → 不对修 → 再验 → 过了往下
└─ 输出阶段
└─ 小循环:输出 → 质量判断 → 不够好优化 → 再判 → 过了交
全局循环是整个任务失败了大步重来。小循环是这一步没做好就在这一步里搞定,不把脏东西传给下一步。
小循环设计要盯三个点。一是验收条件能判定:不能是"质量好"这种说不清的标准,得是格式对不对、字段全不全、数量对不对这种能查的条件。二是回头次数有上限:一般三轮修不过就降级或者抛给编排器。三是修不了要有出路:哪一步扛不住了,编排器怎么接手,要提前想好。
软硬分层
确定性行为→脚本固化,灵活判断→指令引导。脚本兜底,指令提上限。
如果仔细看 Skill 要干的事,其实分两种工作。
一种是确定性的活:拼 URL、算日期、校验格式。没有歧义,谁做结果都一样。这种不应该让 AI 去推理——用 AI 的脑子算一个固定格式的日期,既浪费 token 又有概率算错。
一种是不确定的活:判断文本类型、异常选哪个策略、结果风格怎么调。没标准答案,要靠上下文灵活决定。这种才应该留给 AI,指令告诉它原则和优先级,让它现场判断。
拿飞书文档操作举例。block 树的解析逻辑是死的——一个 50 行脚本封掉,AI 不用推导,直接调。但遇到乱格式的嵌套表格该怎么布局?AI 现场判断,指令给出原则就行。
确定性的事脚本锚住,下限崩不了。不确定的事指令给判断空间,上限才出得来。
HARD 门禁
入口、步骤间、出口、安全四类位置设硬卡,过不去就停,不是提醒一下继续。
指令里写"禁止""必须"属于软约束。大部分时候管用,但高压场景下 AI 可能被上下文带偏,还是踩了红线。
HARD 门禁的意思是:过不去就是过不去。不是提醒,是停。
四类位置必须卡:
| 位置 | 干什么 | 例子 |
|---|---|---|
| 入口 | 前置条件不满足→打回,告诉原因 | 文档链接必须以 https:// 开头,否则阻断返回 E001 |
| 步骤间 | 上一步产出不合格→拦在边界 | block 解析为空→不进入内容提取,返回’文档无内容’ |
| 出口 | 最终结果不达标→拦着不输出 | 提取的文本缺一级标题→回写修正,不直接输出 |
| 安全 | 敏感操作→二次确认 | 删除操作→必须用户确认 |
每条门禁写成可判定条件——不是"看起来质量不错",是具体的检查逻辑。触发之后不是"提醒一下继续",只有三条路:退回去重来、降级走备选、直接阻断返回原因。
第二段位说到底:单文件指令是"把这件事做好了";上了编排器、小循环、脚本分层、门禁之后,是"不管多复杂也做不坏"。加的每一层都有明确分工——治前一层扛不住的事。
三、最后写活
前面两个段位都在预设好的框里做事。任务边界已知,流程提前定好。
但有一类场景:AI 上手的时候信息是不全的。得自己找,走一步看一步,根据中间结果调策略 🤔
这时候靠的不再是一两个脚本,而是一族按需定义、各司其职的脚本。
按需定义
脚本用英文动词命名,见名知义。validate 是底线,其余的按需求来。
命名直接反映脚本干什么。你的 Skill 需要什么就写什么,要求只有一个:模型看到名字就知道什么时候该调它。
每类脚本都有自己的定位,以常用的几种来说明:
validate:检查上一步产出的正确性。拿产出件按预设条件逐条查,返回通过/不通过,不通过带具体原因。不管 Skill 多简单多复杂,validate 都应该有——它是底线。这是前面 HARD 门禁的可执行版本:门禁写在编排器里是纸面规定,写在 validate 脚本里就是自动化关卡。
search:查 Skill自己内部的信息。内部有索引好的数据、缓存的结果、预设的知识条目。模型调 search 在自己的数据池里找,跟外部没关系。
research:查外部信息。数据不在 Skill 内部,得调外部 API、查数据库、拉实时数据。和 search 的本质区别:search 翻自己抽屉,research 去别人家敲门。
audit:记日志。记录每一步走了什么脚本、输入输出是什么。出事了不用翻几十页对话日志,audit 把关键节点串成了时间线。
grade:打分。validate 是"过没过"(二值判定),grade 是"多好"(等级判定),两个概念。
flow:管下一步往哪走。编排器定义好关键分支节点,flow 脚本是导航——调它,返回当前状态下可以走的方向。不替模型选,但保证模型不会自己发明一条不存在的路。
需要什么加什么,不用凑数。但 validate 是基本盘。
穿梭交互
脚本组合之后,模型不再"读完指令闷头干",而是在脚本之间反复穿梭。
具体来说,执行链路变成了这样:
每一步被对应脚本兜着。模型先翻自己抽屉,不够了出去找,做、验、记、评、走——每一步有确定性保障,每一步决策权又还给模型。
这和前面小循环的关系:小循环是单步内自修正,脚本家族是多步间自适应。一里一外套着。
双约束
脚本越多偏离风险越大。流程约束管方向,验收约束管质量,两根同时拽着。
但光有脚本还不够。脚本给模型提供了操作空间——但操作空间越大,偏离的风险也越大。
两根约束缺一不可。
流程约束靠 flow 脚本和编排器状态机:你可以自由走,但只能走画好的路。
验收约束靠 validate 脚本:每一步过了硬标准才能继续。
Clark 等人的研究也在指向同一个结论:给 Agent 更大信息获取自由度的同时,必须用结构化的流程契约约束边界1。自由和约束的平衡点,就是你设计质量的刻度。
第三段位到头来就一句话:Skill 不是一个文件在指挥 AI。编排器调度,脚本兜底,模型在中间主动穿来穿去。一个交互系统。
做完和做对之间,差一步 benchmark
Skill 写完了,怎么确认它不是"自己觉得好"?
用 benchmark 数据说话,而不是凭感觉。
skill-creator 自带 benchmark 能力。准备一组典型场景的测试输入,跑一轮,盯几个核心指标:触发准不准、任务完成率高不高、异常路径兜没兜住。数据出来了,哪里掉分调哪里。改完再跑,跟前一次对比——变好变差,数字说。
这跟写代码跑单测是一个道理。没跑过测试的代码谁敢上线?没跑过 benchmark 的 Skill 也别急着说写完了。
拿到数据之后,回头看三个段位漏没漏东西。触发率低→回第一段位看 description 写清楚没有。某个阶段完成率崩→回第二段位查那个阶段的 mini-loop 和门禁。边界场景大面积翻车→回第三段位检查脚本家族覆盖够不够。
整个闭环:
Benchmark 不是走个过场,是让循环转起来的发动机。没有它,你对质量的判断全凭感觉。有它,数据替你说话。
总结
| 段位 | 具体手段 | 治了什么 | 什么时候够用 |
|---|---|---|---|
| 简单指令 | 一个文件直接写 | — | 小任务,边界清楚 |
| 结构化指令 | 重点优先 + 加粗前缀、信息分层、Mermaid 画流程 | AI 理解不走偏,不乱归纳 | 规则多但流程直 |
| 编排器 + Workflow | 阶段拆分、mini-loop 自校正 | 任务复杂了执行不乱 | 多步骤有先后依赖 |
| 软硬分层 + 门禁 | 脚本固化确定性、指令保灵活、HARD 门禁卡边界 | 下限不崩,边界不被踩 | 有大量确定性操作 |
| 轻量 Agent | 按需定义脚本家族(validate 兜底,search/research/audit/grade/flow 按需加),模型在脚本间穿梭交互 | 预设不够用时自主查/验/记/评/走 | 信息不确定,得边做边判断 |
三段是新叠旧,不是新替旧。每层加上去,治的是前一层"能用但不够稳"的毛病。
第一段治 AI 理解偏差,第二段治复杂就崩,第三段治预设不够用。
重要的不是做到哪一段。是你清楚自己为什么停这儿、什么时候该往前走。
-
Clark et al. arxiv 2605.19604v1 ↩︎
更多推荐

所有评论(0)