最近在折腾 Agent 相关的东西时我发现自己和不少同行都掉进了同一个坑里明明已经把 Prompt 写得很细了任务拆解也很清楚可模型一旦换了个场景表现就立刻变得不稳定。有一阵子我甚至怀疑是不是模型本身不行后来才发现问题出在“能力复用”这件事上——我把所有指令都堆在系统提示词里指令之间互相干扰场景一多就乱成一锅粥。直到我认真把所谓“Skills”这套机制吃透很多问题才迎刃而解。这篇文章就围绕“skills”这个主题展开聊聊我理解的 Agent Skills 到底是什么、和传统 Prompt / MCP 有什么区别、怎么设计一个高质量技能包以及我在实际调试中踩过的坑。无论你是刚开始接触 AI 应用开发还是在为现有工作流里的模型表现不稳定发愁这篇内容应该都能给你一些可以直接上手的参考。1. Skills 到底是什么解决了什么问题1.1 从一次反复“调教”经历说起先说个项目里的真实片段。当时我在做一个批量处理合同摘要的需求起初是直接在 Prompt 里写了一大段“你是一个资深法务请按以下步骤提取合同要素……”测了几轮下来单份合同的效果确实不错。可一旦换成另一类文书比如起诉状或者尽调报告同样的 Prompt 就开始“胡言乱语”。我一开始以为只是 Prompt 不够长于是继续堆描述、加 few-shot 示例结果系统提示词越来越长模型的行为反而越来越怪——它开始把适用于合同场景的规则错误地带到文书场景里还经常漏掉我新加的要求。回头复盘才发现我本质上是在同一个上下文里塞入了多套相互独立的“操作手册”模型根本分不清什么时候该按哪套手册执行。这就是 Skills 想要解决的核心问题把模型在特定任务下需要掌握的指令、背景知识、参考样例和可用工具封装成独立的技能模块让模型在需要的时候“按需加载”而不是一股脑地塞进全局上下文里。从工程角度理解Skills 可以看作是一份存放在项目目录下、带有固定格式的能力描述文件。它告诉模型“当遇到某类任务时你可以先读取我的技能说明再用我提供的模板和示例去完成任务。”这种做法比把规则埋在系统提示词里要干净得多也更接近人类员工“按项目手册办事”的直觉。1.2 Skills 与 MCP、Function Calling 的核心差异很多人第一次接触 Skills 时会把它和 MCP 混淆包括我自己刚开始也绕了弯。简单梳理一下三者的分工Skills解决“模型知道怎么做某件事”的问题。它提供的是知识、流程、模板和范例本质是增强模型的推理和执行能力不直接去调用外部系统。MCPModel Context Protocol解决“模型如何连接外部数据与工具”的问题。它负责打通 API、数据库、文件系统等外部资源让模型能够读写真实世界的数据。Function Calling解决“模型如何发起结构化调用”的问题。它定义了模型输出中的函数参数格式常见于单次请求中的即时函数调度是更底层的机制。用一句话概括Skills 强调的是把“经验”固化下来MCP 是把“连接”标准化Function Calling 则是“执行”的接口。这三者并不互斥实际场景里经常配合使用——技能负责告诉模型该怎么做MCP 负责把数据喂给模型Function Calling 负责触发具体的动作。我在设计技能包时会先画一张分工表明确哪些内容属于技能的“知识层”哪些需要依赖 MCP 的“工具层”避免把两者混在一个文件里。曾经我就犯过错误把数据库查询语句写进了技能说明里结果模型每次执行任务时都把查询当作固定模板原样输出并没有真正触发查询动作。后来把查询逻辑挪到 MCP 工具里技能里只描述“什么时候用哪个工具、期望得到什么结果”整个流程才顺畅起来。还有一个很直观的对比传统 Prompt 像是给一个临时工写了一份详细的临时任务说明任务结束就作废了Skills 则是给这个员工建立了一套可沉淀的岗位 SOP下次再遇到类似任务他可以直接翻出自己的 SOP 来执行。这种“可复用性”在长期项目里价值非常大。2. 技能包的结构与动手搭建2.1 一个最小可用技能包的组织结构先说结论一个规范的技能包本质上就是一个包含元信息与说明文档的文件夹。Claude 官方把这种技能称为 Agent Skills但它背后的思想完全可以用在其他支持类似机制的模型框架上。下面是我常用的一套最小目录结构my-skill/ ├── SKILL.md # 技能的主说明文件 ├── reference.md # 可选背景知识、规则补充 ├── examples/ │ └── sample_input.md # 可选输入示例 └── scripts/ └── run.py # 可选配套执行脚本其中SKILL.md是核心模型会优先读取这个文件来确定技能的作用和用法。它的文件名并不强制必须叫SKILL.md但如果你希望模型在特定条件下自动加载最好还是遵循主流的命名约定因为很多框架在扫描技能目录时会对特定文件名做优先识别。我们看一个简化版的SKILL.md示例--- name: contract-review description: 适用于合同/协议类文档的风险点审查与条款摘要 --- # 合同审查技能 ## 适用场景 - 用户提供合同全文或段落希望识别风险条款 - 用户要求对合同要点进行结构化摘要 ## 执行流程 1. 通读全文标记出涉及金额、期限、违约责任、保密、解约的条款 2. 对每个风险点输出风险等级高/中/低 3. 使用《审查结果模板》输出结果 ## 审查结果模板 | 条款位置 | 风险描述 | 风险等级 | 修改建议 | |---------|---------|---------|---------| | 第X条第X款 | ... | ... | ... |这个文件看起来很简单但里面每一步都有讲究name和description是模型判断“要不要加载这个技能”的依据执行流程部分不能只给步骤还要给判断标准和输出格式模板的作用是约束输出形态让模型每次产出的结果在结构上保持一致。我在实践中的体会是最容易被忽略的是“适用场景”这段。很多人写完技能的 description 就匆匆往下写执行步骤结果模型在不需要该技能的时候也强行触发或者在需要的时候反而没触发。后来我会刻意把“适用场景”写得更具体甚至会加“不适用场景”比如在合同技能里明确写上“本技能不适用于口头约定的非正式沟通内容”模型的触发准确率明显提升了。2.2 SKILL.md 的编写要点与 frontmatter 格式如果你用过 Jekyll 或 Hugo 写博客一定对两边用---包裹的 frontmatter 不陌生。Skill 文件同样借用了这种格式通过 YAML 元数据给模型提供“快速判断”所需的信息。这里有几个值得注意的地方name字段必须唯一最好见名知意。我踩过的坑是给两个技能分别命名为“excel-helper”和“excel-analyzer”结果模型经常分不清该调用哪一个后来改成“excel-format-tool”和“excel-data-analysis”问题立刻缓解。技能命名的核心原则是让模型在第一眼就能看出两个技能之间的边界。description字段是“触发信号源”它决定了模型是否会在某个任务上下文中主动拉取这个技能。千万不要只写一个笼统的概述应该包含“什么时候用”和“解决什么问题”两个维度。举个例子不推荐处理 Excel 文件推荐将二维表格数据清洗并转换为指定格式包含重复项删除、空值填充、列名标准化正文部分不要写长篇大论要控制在模型一次读取能消化的范围内。技能说明文件的核心目的是“指导行为”不是“展示知识”。如果一个技能说明超过了 500 行我建议先停下来想想是不是有部分内容可以挪到独立的参考文件中等模型需要时再按路径读取说到这里我常用的做法是在SKILL.md里引用外部文件当需要判断某条款是否涉及“格式条款无效”情形时参考 reference.md 中的判例要点。这样可以让主文件保持轻量需要深度知识时才去打开参考文件有效减少上下文占用。3. 设计三个实战技能既能用又能玩3.1 文本润色与风格迁移技能第一个案例是我的日常高频技能——文本润色。它不会让你一夜之间写出爆款文案但能保证你的文字风格保持一致特别是团队里多人维护同一份文档时这个技能可以充当“风格统一器”。技能目录大概长这样polish-writing/ ├── SKILL.md └── examples/ ├── before.md └── after.mdSKILL.md的关键内容--- name: polish-writing description: 将输入文本润色为正式书面风格纠正语法错误统一术语可用于技术文档或汇报材料改写 --- # 文本润色技能 ## 处理规则 1. 保留原文关键信息不允许增加虚构数据 2. 术语统一首次出现缩写时补充全称 3. 句子超过40个字时拆分为短句 4. 删除冗余的“非常”“十分”“一定”等程度副词 ## 输出格式 - 先输出润色后全文 - 再使用“改写说明”小节列出3-5条修改要点这里我觉得最有价值的不是“润色”本身而是**“改写说明”这个环节**。它让模型在输出时能“自我解释”方便我快速判断哪些修改是优化、哪些修改可能扭曲了原意。分享一个实际效果对比。原句是“目前这个功能在比较极端的情况下会导致系统反应速度变得比较慢我们需要尽快进行必要的性能优化。”模型按技能处理后的输出是“当前功能在极端场景下响应变慢需尽快优化性能。”改写说明中模型标出“删除了重复语义的‘比较’”。如果单靠系统提示词也能达到类似效果但每次都要重新写风格约束。有了这个技能后任何文档需要统一语言风格时我只需要告诉模型“使用 polish-writing 技能处理”它就会按照预设规则操作省去了反复“调教”的精力。3.2 技术方案评审技能第二个案例更偏向工程场景让模型扮演技术方案评审者。这个技能的价值在于它能帮你在评审会上少当几次“睁眼瞎”——当然它替代不了真正有经验的架构师但至少能把常见的设计漏洞提前暴露出来。技能目录tech-review/ ├── SKILL.md └── checklists/ ├── database.md ├── api-design.md └── security.mdSKILL.md里会让模型先识别方案涉及的技术栈然后按清单逐项检查最后输出一份结构化评审意见--- name: tech-design-review description: 针对技术设计方案或系统架构文档进行风险评审重点检查数据一致性、接口边界、安全防护、可扩展性 --- # 技术方案评审技能 ## 评审流程 1. 扫描文档提取“架构图/模块列表/核心流程/数据模型”四类信息 2. 根据文档类型加载对应 checklistsapi-design.md / database.md / security.md 3. 逐项核对标记“通过”“需修改”“严重风险”三档结论 ## 输出要求 每一条问题必须给出 - 问题定位涉及哪个模块或流程 - 风险说明为什么这是问题可能引发什么后果 - 修改建议给出可执行的方案我拿这个技能评审过一个内部工具的接口设计方案。方案里定义了回调接口但没注明超时和重试策略。技能在“api-design”清单中命中“接口幂等性缺失”这条给出了“需要增加 requestId 校验并以 2 秒超时、3 次重试为初始配置”的建议。这种具体建议单靠模型临时发挥很难稳定产出但有了清单模板后每次都能把关键项检查一遍。这种“清单即知识”的做法其实是把资深工程师的检查习惯拆解成了模型可执行的规则。我第一次试用时的感受是它不像是在和一个通用聊天机器人对话更像是在和一个“入职培训很到位的新同事”配合。3.3 让技能“自我进化”的小技巧技能并不是一次写完就固定不变的。我在实际维护中会保持一个“技能复盘”的习惯大概每个迭代周期做一次。具体做法是把技能投入运行的场景中收集模型输出的结果定期抽取一部分结果做对比分析找出那些“模型总是跑偏”的共性点再反过来修订技能说明。举一个真实的例子。我原来给“合同审查技能”写的执行流程是通读全文标记风险条款输出风险清单结果模型每次都能把风险条款找出来但经常搞混风险等级把“可协商”的条款标成“严重”把真正可能导致合同解除的条款标成“低风险”。我后来细看才明白问题出在我的等级定义太模糊。“中风险”我只写了“需要关注”没有给出判断阈值。于是我改成了这样风险等级判断标准 - 高风险可能导致合同违约、解除、重大经济损失或违反强制性法律规定 - 中风险可能导致履约争议、成本增加但不影响合同整体履行 - 低风险用词不规范、表述歧义可通过后续沟通澄清改完再测风险等级的标注准确率肉眼可见地提升。这种“用输出来反哺输入”的迭代方式是技能体系长期能保持活力的关键。我的经验是每隔一两周就花点时间翻看模型最近的真实输出从中找出规律性的问题然后去更新技能文件——而不是等出了问题再去改。4. 避坑指南与调用机制调优4.1 高频问题速查表我在搭建和使用 Skills 的过程中踩过不少坑整理成一张问题速查表方便你直接对照排查问题现象可能原因解决思路模型不触发技能description 太宽泛模型无法匹配精简 description加入触发关键词模型在错误场景触发技能name 和 description 边界不清在 SKILL.md 中显式增加“不适用场景”模型读取技能后仍然乱答执行流程不够具体增加判断条件、输出模板、示例段落技能说明太长启动变慢SKILL.md 过于臃肿将细节拆到 reference.md按需读取多个技能互相干扰技能职责重叠明确分工减少两个技能描述中的相似术语模型直接读取了脚本但没执行技能说明里只有知识没有触发执行逻辑引入 MCP 或函数调用技能内只写调用时机这张表看起来简单但每一条背后都是实在的调试成本。尤其“模型不触发技能”这点我花的排查时间最多。后来我才意识到模型判断技能是否适用主要靠description和当前对话的语义相似度如果 description 里堆了太多抽象说法反而会降低匹配率。我后来给自己的一个硬性要求是description必须包含至少一个具体的业务动作词比如“审查”“生成报价”“格式化日期”“检查权限”尽量避免“处理数据”“提供帮助”这种万金油动词。还有一个小细节值得提技能说明里的“第一步、第二步”这类流程描述模型会当成严格顺序来执行。有次我写“先通读全文再输出结论”结果模型真的只输出了一句话结论完全没做过程说明。后来我改成“通读全文并标记风险条款在输出结论时用表格列出标记结果”模型才开始给表格。这提醒我在技能文件里期望模型展示的过程步骤一定得写进要求里光靠“心里有数”是不行的。4.2 提升技能召唤率的两个关键参数最后说两个和“召唤率”密切相关的参数——这不是模型 API 里的某个魔法数字而是技能文件设计中容易被忽视的细节。第一个是 description 的触发条件设计。我测试过一个现象同一个技能description 写成“对文本进行润色提升表达能力”时触发率大约只有 40%改成“将输入内容改写为简洁、清晰、正式的中文适用于技术文档、汇报材料、对外公告等场景”之后触发率升到 80% 以上。差异在于后者的“场景词”更具体能让模型在对话初期就判断出该不该加载这个技能。第二个是示例文件的数量与质量。技能里带 1 个高质量示例的效果通常比 5 个粗糙示例的效果更好。我见过一些团队在技能里塞了几十个“典型场景”结果模型在处理新输入时反而迷惘因为它不知道该按哪个示例去套。我现在的一个经验法则是每个技能最多准备 3 个示例每个示例必须覆盖一类典型输入并标注清楚“这个示例适用于什么情况、为什么这么处理”。另外如果你使用的是支持调试界面的框架可以看模型每次调用技能前实际读取了哪些内容。我自己的习惯是一旦遇到“触发了技能但结果差很远”的情况先去看模型加载的是不是最新版的 SKILL.md有时候改完文件但没刷新缓存模型还在用旧版本执行结果自然不对。在实际项目中我还会给技能文件加上版本号--- name: contract-review version: 1.3.0 description: ... ---这样在排查时一眼就能看出当前模型使用的是哪个版本也方便回溯“上周结果准、这周开始飘了”到底是不是因为技能文件被改动过。写在最后技能Skills这套机制本质上是在给模型搭建一套“可插拔的经验系统”。它不像改一句 Prompt 那样零成本也不像训练一个模型那样重投入它更像是中间的“规范化沉淀”动作——把零散的经验变成结构化的、可复用的资产。我个人的体会是最开始花在整理技能文件上的时间会在后续每次执行同类任务时加倍回报回来。如果你正准备在项目里引入这套思路我会建议从一个小而具体的任务开始比如“格式化为 Markdown 表格”或“生成会议纪要模板”跑通整套流程后再逐步扩展技能库。别一上来就追求大而全技能的维护成本和技能数量是成正比的少而精往往走得更远。