给智能体写"入职手册":技能文件到底该怎么组织

很多人给智能体做的第一份"技能",其实就是一个很长的提示词:把步骤一二三四写清楚,保存,然后期待它每次都能照做。
真正用起来往往会暴露两个问题:装多了记不住,写长了做不对。 一份 3000 字的技能文档塞进上下文,模型真正"看见"的往往只有开头几条;而当你把要求拆得足够细,它又会在长任务里逐渐跑偏。
问题不在模型,在结构。
主流做法(Anthropic 的 Agent Skills 已把它做成了开放标准)是把技能定义成一个目录,核心是 SKILL.md:
关键差别在于它不是一次性灌进上下文的,而是分三层加载:
| 层级 | 内容 | 何时加载 | 成本 |
|---|---|---|---|
| 第一层 | name + description(YAML frontmatter) |
启动时常驻 | 约 100 tokens/个 |
| 第二层 | SKILL.md 正文 |
判定相关时才读 | 建议 <5k tokens |
| 第三层 | 附加文件、脚本、参考资料 | 按需再读 | 读了才算 |
官方给过一个很贴切的比喻:给智能体写技能,就像给新员工写入职指南——不需要让他入职第一天就把公司所有文档背下来,只要他知道"遇到什么事该翻哪一份"。
这个设计解决的就是开头那两个问题:装 20 个技能,常驻成本也只有 20 份 name+description;而具体流程只在真正需要时才展开,上下文不会被无关内容稀释。
判断标准只有一条:这部分内容,是每次都要用的,还是只有特定场景才用?
第三类最容易被忽略,也最值得说:能用代码判定的事,就不要让模型去判断。
比如"这篇文章写完了没有",靠模型扫一眼很容易糊弄过去;但写成脚本就是五项硬检查——文件存在、首行是标题、字数达下限、文末有收尾标记、没有占位链接。任一项不过就退出码非零,流程必须停下。
把确定性操作交给脚本,还有个额外好处:脚本不占上下文。模型不需要读懂它的实现,只要看它的报错信息。
一份管用的 SKILL.md 正文,通常由三块组成:
1. 流程:分步骤,每步写清楚输入和输出,而不是写一段散文。
2. 硬规则:用"禁止 / 必须 / 不得",不要用"建议 / 尽量"。
"建议"这种词在长任务里基本等于没有。要么写成硬约束,要么干脆别写——写了又不管用,反而让模型以为这条重要度低。
3. 收尾自检:把纪律变成可执行的检查。
误区一:技能越长越全越好
三层加载的设计本身就决定了 SKILL.md 要瘦:常驻上下文的只有 name + description,正文只在判定相关时才读,且建议控制在 5k tokens 以内。把细节全塞进 SKILL.md,等于主动放弃了"按需加载"这个最大优势——模型每次都得把整份长文档读进上下文,真正重要的硬规则反而被稀释。
所以这条误区的后半句值得记住:多写没有收益,但一定更占上下文。一个实用的判断:写完后问自己,这份 SKILL.md 里有没有"只有特定场景才用"的内容——有就挪到独立文件。
原因很直白:内容越多,每条规则的权重越低。技能的价值密度比覆盖度重要。
误区二:把所有边界情况都写进去
正确的做法是写主流程 + 兜底路径,而不是穷举。遇到抓不到的情况,写清"抓不到时改用 A 方案,并在结果里注明用了兜底",比写十种异常处理管用。
误区三:把示例堆进正文
好的示例放单独文件(EXAMPLES.md),正文只留一行"样例见 EXAMPLES.md"。模型在需要时会去读,不需要时不会占用上下文。
写技能这件事,本质上是在做知识工程:把一个人脑子里的做事方法,拆成"什么时候用、怎么做、怎么判定做完了"。
它跟写代码的要求其实很像——单一职责、按需加载、把不确定的部分隔离出去、用测试(自检)兜底。想清楚这一点,就不会再写出那种三千字、看起来很全、实际一条都没执行的大提示词了。
#智能体 #AgentSkills #提示词工程 #AI工程 #技术实践