
1. SKILL.md 到底解决什么问题Agent 的技能封装与提示词模板的边界先交代一个背景。最近不少做 Agent 开发的朋友都在聊SKILL.mdGitHub 上相关的技能仓库也越来越多Claude、PI Agent 这类偏 Autopilot 风格的 Agent 都开始用这套思路做能力扩展。很多人把它理解成“给 Agent 写一个更长的系统提示词”这个理解大方向没错但实际操作时完全不是一回事。我先说结论SKILL.md是 Agent 技能的结构化封装格式它不是一段提示词而是一个包含目录、入口指令、参考文档、示例甚至脚本的完整技能包。提示词模板解决的是“让模型按照某种格式回答”的问题而SKILL.md解决的是“让 Agent 在复杂任务中稳定调用一套完整方法”的问题。两者层级不同前者是话语层面的约束后者是能力层面的封装。我最初接触 SKILL.md 是在做一个自动化测试 Agent 的项目。当时的痛点是测试用例生成的prompt已经写了两千多字但Agent的行为依然不稳定。有时候它记得先做接口探测有时候直接跳过有时候按规范输出报告有时候又自由发挥。后来把测试方法论、接口探测流程、报告模板、常见风险清单全部拆进一个 skill 目录用 SKILL.md 做入口Agent 的行为一致性立刻上了一个台阶。这不是玄学而是因为技能包给 Agent 提供的不是“一段话”而是“一套可翻阅、可定位、可引用的完整资料操作规范”。所以这篇文章的适用人群很明确已经在做 Agent 开发发现纯提示词方案撑不起复杂任务的人或者是准备把自己的工作流封装成 Agent 技能但不知道从何下手的人。我会从设计思路、目录结构、实操写法、踩坑清单四个维度展开全程用我实际跑过的项目举例。2. 设计思路拆解为什么技能包不能只是“长提示词”2.1 提示词模板的工作方式与天花板传统提示词模板的工作方式是把所有约束塞进上下文。模型每次执行任务时都要连同这串长长的指令一起处理。这种方式有几个很难绕开的毛病。第一上下文的珍贵空间被占用。Agent 的任务通常需要多轮工具调用每轮调用都要把历史记录、工具返回值一并送进上下文。如果提示词本身就占了大量空间留给真正任务数据的空间就变少了。模型可用的“有效注意力”会被指令文字稀释任务稍复杂就容易丢三落四。第二行为控制是概率性的。提示词本质上是在“请求”模型按某种方式工作但模型并不具备真正的记忆和执行状态机。同一个任务把提示词放在不同的对话位置、不同的历史长度里表现都会有波动。这在大模型 API 的日常使用中尤其明显Azure OpenAI 和 Anthropic API 在不同温度、不同上下文长度下的指令遵循度变化非常大。第三不可复用、不可管理。写死的提示词只能依靠复制粘贴来复用。一旦需求变化要改动所有相关位置。更麻烦的是提示词没法做单元测试你只能在完整对话中去试错回归成本很高。2.2 SKILL.md 的封装逻辑能力、过程、资源三层分离SKILL.md 的核心思路是把一个“技能”拆成三层来封装。能力层描述这个技能是做什么的、适合什么场景、需要哪些前置条件。这一层让 Agent 能够判断“什么时候应该调用这个技能”。过程层描述完成技能任务的具体步骤、检查点、输出规范。这一层不是简单写“请按步骤执行”而是给出可执行的操作序列必要时配合脚本、命令等自动化手段。资源层是技能附带的参考文档、示例、模板、数据文件。Agent 在执行过程中遇到不确定情况时可以按需去查这些资源而不是被动等待开发者在提示词里把所有可能性穷举完。这三层分离最大的好处是让技能从“一次性指令”变成了“可维护的模块”。提示词是程序里的一段硬编码SKILL.md 则像是把能力打成了一个函数附带文档、单测和调用约定。另外还有一个容易被忽视的设计点SKILL.md 结构化的好处在于“可被外部工具处理”。比如 COST 框架Context Optimization Skills Toolkit可以扫描多个技能包自动生成优化后的技能描述合并相近能力、压缩上下文占用。这是纯提示词文本做不到的因为程序无法结构化地解析一段自然语言指令。2.3 什么场景值得做 SKILL.md什么场景别折腾以我自己的项目经历下面几类场景做 SKILL.md 收益最大。有固定流程、多步骤、可重复执行的任务。比如代码审查、数据清洗报告、竞品分析、SEO 审核、测试用例生成。这类任务每次执行逻辑相似只是输入数据不同非常适合封装。需要查阅外部资料的任务。比如写行业分析时需要看模板、看案例、查术语表。这些资料单独放在 reference 目录比全堆在提示词里更适合 Agent 按需检索。多人复用、需要标准化的技能。团队内不同人写提示词风格差异很大用 SKILL.md 统一后Agent 行为不再依赖每个人的表达能力。反过来如果只是做一次性的、简单的问答或文本改写SKILL.md 就是杀鸡用牛刀。它的设计初衷是“可复用、可迭代”单次任务用不上这些投入。3. 目录设计与参考文件配置一个生产级技能包的骨架3.1 标准目录结构SKILL.md、reference、scripts 的职责划分目前社区里比较流行的 SKILL.md 技能包结构大致长这样skill-name/ ├── SKILL.md # 技能主入口描述技能用途执行流程 ├── reference/ # 参考文档、模板、术语表按需加载 │ ├── template.md │ ├── checklist.md │ └── examples/ # 输入输出示例 ├── scripts/ # 可执行的辅助脚本Python、Shell 等 └── assets/ # 静态资源如 JSON schema、图片等我一般会在 reference 里再细分checklist、template、examples三类文件。因为 Agent 在技能执行过程中的“查阅行为”是分阶段的任务开始时读 SKILL.md 明确流程中途遇到不确定格式时读 template做完一部分对照 checklist 自查最后输出前参考 examples 校准格式。三个文件职责不同不能混在一起。3.2 SKILL.md 主体文件怎么写短小而高频拒绝长篇大论很多人在写 SKILL.md 时犯的最大错误是把它当成“系统提示词加强版”来写一口气写两三千字。结果 Agent 加载技能时指令本身就把上下文塞满了。有效写法是短小而高频用可执行指令代替大段描述。拿我写的“代码审查技能包”举例SKILL.md 核心部分是这样的--- name: python-code-reviewer description: 对 Python 代码进行系统性审查输出结构化审查报告。适用于 Pull Request 审查和代码质量评估。 version: 1.0.0 --- # Python 代码审查技能 在收到代码片段或 PR 信息后按以下步骤执行 1. 先读取 reference/checklist.md建立审查基线。 2. 按优先级逐项检查安全问题 正确的异常处理 资源泄漏 逻辑错误 代码风格。 3. 每发现一个问题在报告中标注严重级别blocker / major / minor和建议修复方案。 4. 输出报告时严格按照 reference/template.md 的格式不得自由发挥。 5. 如果遇到不明确的依赖或框架特定用法先查阅 reference/仍无法确认则标注“需人工确认”禁止臆断。 约束 - 只审查代码本身不涉及提交者个人行为。 - 不修改代码只输出报告。 - 发现紧急安全问题时在报告开头用 BLOCKER 标记突出显示。这段写的都是“动作”不是“建议”。每个动作都有明确的对象读取哪个文件、输出哪种格式、什么情况标记为什么级别Agent 执行时就不需要做太多价值判断只要按顺序执行即可。3.3 reference 模板文件怎么设计给 Agent 一个“抄作业”的基准reference 里的模板文件作用是给 Agent 提供“满分答案的基准格式”。写这个文件时有一个关键原则要给出格式示例而不是格式描述。比如代码审查报告的模板文件不应该写“报告应包含问题描述、严重级别、修复建议等”而应该直接给一个填好的例子## 审查报告 ### BLOCKER-1: SQL 注入风险 - 文件: user_api.py 第 42 行 - 问题: 直接使用 f-string 拼接 SQL 查询字符串 - 风险: 攻击者可通过构造参数逃逸查询条件读取未授权数据 - 建议: 使用参数化查询参考 psycopg2.sql 模块 ### MAJOR-1: 文件句柄未关闭 - 文件: report_generator.py 第 18 行 - 问题: 使用 open() 后未调用 close()也没有使用上下文管理器 - 风险: 长时间运行的服务可能耗尽文件句柄 - 建议: 改为 with open(...) as f: 写法Agent 在看到完整示例后输出格式基本不会再跑偏。这比任何文字描述都高效因为语言模型的模仿能力远强于指令遵循能力这是我们在实际项目中验证过的结论。3.4 一个容易被忽略的点SKILL.md 里的“何时不用”好的技能定义除了告诉 Agent“何时用”还必须明确“何时不用”。这个约束可以避免 Agent 在明显不合适的场景下强行套用技能。比如我的代码审查技能包里写了不适用场景 - 代码量少于 50 行的单函数直接给出简单评论即可无需完整报告。 - 不涉及业务逻辑纯配置文件的变更无需审查。 - 用户只需要解释某段代码含义时不得套用审查流程。加了这个约束之后Agent 的技能误用率明显下降。之前没有这个字段时经常出现用户只是问“这段代码什么意思”Agent 却一本正经跑完整套审查流程并输出报告——这不仅烦人还浪费了大量 token。4. 实操过程与复现细节从需求拆解到技能包落地4.1 场景说明做一个“AI 小说写作助手技能包”用“AI 写作辅助”这个场景来跑一遍完整实操。之所以选写作场景是因为它足够通用而且和纯提示词方案的区别非常明显——很多人觉得写作不就是给个 prompt 吗用 SKILL.md 做之后你会发现 Agent 对风格的把控稳定得多。需求拆解技能要支持世界观设定生成、人物小传、章节大纲、逐章写作四个子任务每种子任务都有不同的输入输出要求写作风格需要可配置通过参数切换必须保证跨章节的角色设定一致性这是纯提示词最难实现的点之一4.2 搭建技能包目录并编写核心文件mkdir -p ai-novel-writer/reference/examples cd ai-novel-writer touch SKILL.md touch reference/worldbuilding_template.md touch reference/character_sheet.md touch reference/chapter_template.mdSKILL.md 内容设计成四种子任务分流。关键是要用if...then式的逻辑让 Agent 先判断用户想干什么再加载对应流程--- name: ai-novel-writer description: AI 小说写作辅助技能支持世界观设定、人物小传、章节大纲、逐章写作与修改。 version: 1.1.0 --- # AI 小说写作技能 根据用户输入判断子任务类型执行对应流程。 ## 子任务世界观设定生成 1. 读取 reference/worldbuilding_template.md。 2. 按模板逐项生成时代背景、地理环境、社会结构、魔法/科技体系、冲突来源。 3. 每项生成后检查与已有设定的逻辑一致性如存在参阅 character_sheet.md。 4. 输出格式严格遵循模板不得自创栏目。 ## 子任务人物小传 1. 读取 reference/character_sheet.md。 2. 按模板生成基础信息、性格核心、动机、优缺点、关系网、成长弧光。 3. 人物动机必须与世界观设定中的冲突来源相呼应。 4. 输出时完整填写所有字段缺失信息标注“待补充”不得跳过。 ## 子任务章节大纲/逐章写作 1. 先确认是否存在世界观和人物设定文件没有则提示用户先完成前两个子任务。 2. 根据已有设定生成章节内容。 3. 检查章节内每个角色的行为是否符合 character_sheet 中的人格设定。 4. 风格参数如叙事视角、节奏在用户未指定时保持与上一章一致。注意这里的几个设计子任务分流让 Agent 有清晰的决策路径不会所有情况混用一套流程。文件依赖关系章节写作前要求先有世界观和人物设定这样就不用担心 Agent 写出和上下文不一致的内容。约束写进主文件不依赖模型“自觉”。比如“缺失信息标注待补充不得跳过”这类约束就是为了防止模型自由发挥。4.3 用 COST 工具做技能包压缩与优化写好的技能如果有多个或者用户使用的模型上下文窗较小建议用 COSTContext Optimization Skills Toolkit做一次优化。COST 的核心逻辑很简单读取技能包内的所有文本根据配置的 token 限制自动压缩描述同时保留关键操作性指令。安装和基础使用pip install skills-toolkit cost optimize ./ai-novel-writer --max-tokens 8000 --model claude-3-5-sonnet它做的事情包括合并重复的指令描述将冗长的描述性文本压缩为要点自动清理无效的参考引用输出优化后的技能包目录默认在dist/下我自己的一个技能包原本所有文件加起来约 12000 token经过 COST 压缩后降到 6000 token行为一致性测试通过率没有明显下降。这在长对话场景下很值因为保留了更多上下文空间给对话历史和工具返回结果。4.4 测试与迭代构建技能包的最小验证集技能包写完以后必须用最小验证集做回归测试。我第一次写 SKILL.md 时测试了十几个技能包后来发现不建立验证集就是在给自己埋雷。因为技能包改动后经常会引入一个隐性 bug某条约束和另一条约束冲突Agent 会无所适从。我的做法是给每个技能包维护tests/目录放 5-10 个标准输入和期望输出说明用自动化脚本跑一遍# 简易回归测试脚本 for input in tests/*.txt; do echo Testing $input claude --skill ./ai-novel-writer $input output_$(basename $input).md # 检查输出是否包含预期结构 done测试用例要覆盖正常输入、边界输入、故意误导输入三种情况。比如写作技能包正常输入是“写一个第一章”边界输入是“只写一段五百字的场景描写”误导输入是“给我讲讲你是什么模型”这种完全不相关的问题。最后一种用例很关键它验证的是 skills 的“护栏”够不够硬。4.5 实测对比同一任务提示词 vs SKILL.md为了直观说明差异我针对代码审查这个场景做了一组对比测试。同一段有五个问题的 Python 代码分别用长提示词方案和 SKILL.md 方案驱动 Agent 审查结果如下对比维度长提示词方案SKILL.md 技能包问题发现数量3 / 55 / 5报告格式一致性两次输出格式不一致完全一致严重级别标注是否合理有一处误判全部正确平均 token 消耗约 9500约 7600是否需要人工校正需要不需要这个结果不是个例我在其它技能报告生成、数据分析、竞品调研上也观察到了类似趋势。格式越复杂、步骤越多的任务SKILL.md 的稳定性优势越明显。5. 常见问题与排查技巧技能不生效时先查这五个地方5.1 Agent 完全不调用技能怎么办这个现象在刚切换到 SKILL.md 方案时最容易遇到。明明技能包里写得很详细Agent 却像没看见一样继续按照默认方式回答。优先检查以下三点第一技能入口描述是否足够“触发”。SKILL.md 的description字段是 Agent 判断“要不要用这个技能”的依据。如果你的描述写得太宽泛比如“AI 写作技能”Agent 很可能不觉得当前任务和它有直接关系。改成“生成小说世界观设定、人物小传、章节大纲、逐章写作”命中率会高很多。第二技能的适用场景是否写得太窄。如果描述里带了太多限定词比如“仅用于用户明确要求生成报告时”Agent 会把很多隐含需求挡在外面。第三运行环境是否正确加载了技能包目录。不同框架对 SKILL.md 的加载方式不同有的需要在配置里指定 skills 目录有的支持自动扫描。优先检查日志看启动时是否打印了技能加载成功的信息。5.2 技能包写得太“重”上下文爆炸怎么办如果 SKILL.md 加 reference 全部文件加起来超过 15000 token基本可以判定写得太重了。这时从上到下压缩主文件控制在 2000-3000 token 以内只保留分支判断、执行步骤、硬约束。reference 里的模板文件只保留“必要字段一个完整示例”不需要写解释性说明。所有文件去掉重复内容。比如主文件里写了“按模板输出”模板文件又在开头重复一遍同样的要求这属于无效消耗。用 COST 工具做自动压缩配合手动精简。另外还有一个思路把大型技能拆成多个小技能。比如把“AI 小说写作”拆成“世界观设定”“人物设计”“章节写作”三个独立技能每个技能只负责一件事Agent 在需要时按需调用而不是一口气加载全部内容。5.3 技能被误调用怎么收紧边界误调用和“不调用”是硬币的两面。不调用是触发不足误调用是护栏不够。收紧边界的方法是加强 SKILL.md 里的“不适用场景”描述并配合 description 的精确化。比如在代码审查技能里写成description: 对 Python 项目代码进行系统性安全与质量审查输出结构化报告。如果用户只是询问代码含义、要求解释某段逻辑、或需要代码优化建议请勿使用本技能。不要小看最后一句“请勿使用”这比任何规则都有效。模型对否定性指令的遵循度在技能包场景下表现非常好因为整个技能包结构让“不适用”变得可定位不像提示词里混着一大堆要求找不出重点。5.4 技能包升级后行为反而变差了这种情况通常发生在技能包体积变大以后。新增加的内容可能和旧内容产生语义冲突导致 Agent 在执行时不知道该听谁的。我的做法是每次升级技能包时只改一处逻辑跑完最小验证集再改下一处。不要一次性重构多个部分。而且升级后要保留旧版用版本号区分方便回滚。SKILL.md 的 frontmatter 里有个version字段这个字段不只是给人看的Agent 在对话中如果被问起“你用的是哪个版本的技能”它能准确报出来这对我排查问题帮助很大。5.5 排查清单速查表现象优先检查项常见修复Agent 不调用技能description 是否可触发、技能目录是否被正确加载重写 description检查运行日志技能被误调用不适用场景描述是否缺失、description 是否过于宽泛增加否定性描述收紧触发条件输出格式不稳定模板文件是否给出完整示例模板中填充真实示例而非字段说明上下文不够用技能包总 token 是否过大精简主文件、拆分技能、用 COST 压缩升级后行为变差是否一次性改了多个模块分次修改每次只动一个逻辑点跑回归测试写在最后的一点实战体会做 SKILL.md 技能开发到现在我最大的感受是它把 Agent 开发从“写提示词的艺术”变成了“设计技能包的工程”。提示词写得好不好依赖个人表达能力和对模型脾性的把握而技能包做得好不好靠的是结构化思维和维护纪律。如果你目前还在用几百上千行的提示词模板硬撑复杂任务我建议挑一个最稳定的任务场景花半天时间把它改造成 SKILL.md 技能包试试。不需要一上来就搞很多技能一个就够。等你跑通了这个转换过程后续的技能化改造就很顺了。最后分享一个我个人的习惯每次给技能包添加新技能时顺手把最小验证集的测试用例也补充进去。短期看是多花了时间但长期来看Agent 行为稳定性带来的收益远大于这些成本。