如果你第一眼看到skills这个项目名,第一反应还是简历上的“特长与技能”,那你可能要在 AI Agent 开发语境里换个角度理解它。最近大半年,我一直在折腾 Agent 的技能化改造,skills这个词在工程圈里已经成了一个相当具体的概念:它指的不是大模型自身的能力,而是开发者预先封装好、随 Agent 一起加载的一组指令、脚本、数据文件和校验规则。说得直白一点,它就是给大模型准备的“岗位 SOP 手册”。
这套东西能解决什么问题呢?举个最典型的场景:你让 Agent 帮你生成库存预警报告,第一次它算错临界值,第二次格式不对,第三次忘了写异常说明。你每次都要重复纠正,重复调 prompt,体验非常崩溃。使用skills之后,你把这些“总出错”的环节固化成技能包,Agent 一旦识别到“库存预警”这个任务,就直接按包里写好的步骤、脚本和校验逻辑走,正确率从“看运气”变成“看代码”。这篇文章适合所有在搭 Agent、或者准备让 Agent 做复杂任务的开发者,我会从原理讲到自己动手封装技能包,再讲到线上遇到的坑和排查方法,尽量把能直接抄作业的部分都交代清楚。
1. 先搞清楚什么是 skills,以及它解决了什么问题
1.1 一个词引发的误读与正名
第一次看到项目名叫skills的时候,我也下意识以为这是个人成长类的知识库。直到接触了 Agent 工程化,才发现完全不是一回事。在 Agent 领域里,skills指的是一个自包含的能力包:里面有说明文档、有参考脚本、有校验规则,甚至带一些样例数据。它被放进 Agent 的运行环境后,模型会在恰当的时机发现它、读取它、然后按照里面的指示执行任务。
这个思路最有价值的一点,是把“模型学会做某件事”变成了“开发者替模型把某件事的流程写清楚”。你可以把一个技能包理解成给新来的实习生准备的标准化手册——实习生可能什么都不懂,但你只要把手册递给他,说“遇到这种情况就翻第 3 章,按第 3 章做”,他就能把活干得有模有样。大模型也是这样,它的推理能力很强,但它的“工作记忆”和“稳定性”并不靠谱,skills恰好补上这一环:把正确的做法固化下来,让模型不只靠临场发挥。
目前不少主流 Agent 框架都开始支持这种能力形态,有的叫 skills,有的叫 actions,有的叫插件式技能。名称有差异,内核是一致的:让开发者的领域知识和经验,能够以结构化文件的形式传递给模型。如果你在搭自己的 Agent,这个概念越早理解越好,后面所有技巧都建立在它之上。
1.2 Skills 和 API、工具调用、Prompt 模板的本质区别
我见过不少朋友问:skills不就是把多段 Prompt 拼在一起吗?和 Function Calling(工具调用)又有什么区别?这里我必须掰开揉碎讲清楚,因为这三个东西在工程里的定位完全不同。
| 对比维度 | Function Calling / API 工具 | 普通 Prompt 模板 | Skills 技能包 |
|---|---|---|---|
| 核心载体 | 后端代码 + 函数定义 | 纯文本提示词 | 文档 + 脚本 + 数据文件 |
| 执行逻辑 | 模型只负责出参数,逻辑在代码里 | 完全靠模型推理 | 模型负责流程编排,脚本负责确定性计算 |
| 可靠性 | 高,确定性执行 | 低,每次结果都可能有差异 | 中高,脚本校验兜底 |
| 适用场景 | 原子操作:查天气、下单、查库存 | 风格约束、输出格式约束 | 多步骤流程、需要校验和重试的任务 |
| 可移植性 | 需要配套后端服务 | 复制文本就能用 | 整个目录拷贝即可复用 |
Function Calling 适合处理“一个动作就能完成”的事情,比如调用天气接口,模型只需要传一个城市名。但现实中的任务往往是复合型的:拉数据、清数据、算指标、写报告、自查一遍,这是一个多步骤工作流,不是一个函数调用能搞定的。如果强行拆成多个 function,你得在后端写大量状态管理代码,Agent 每一次都要维护上下文状态,开发成本很高。
而普通 Prompt 模板又太“软”了,它只能约束模型的表达方式,无法约束模型的计算过程。你说“请仔细计算”,它该算错还是算错。skills恰好卡在中间:模型负责“理解意图、编排步骤、组织输出”,脚本负责“精确计算、解析文件、校验结果”,两者配合,既保留了大模型的灵活性,又拿到了代码的确定性。
1.3 为什么不用 Function Calling 就非要搞 Skills
从工程经验来看,Function Calling 和skills其实是互补关系,不是替代关系。真正推动我用skills的,是下面三个痛点。
第一个痛点是多步骤任务的编排问题。Function Calling 每次只调一个函数,而复杂任务需要循环:如果第一步算出来的指标有问题,第二步就没必要执行。这种“带条件的流程控制”如果全写在后端代码里,你会写出一堆 if-else,而且每加一个场景就要改代码。skills则把流程控制权交给模型,让模型根据文档里的步骤和脚本返回的校验结果自己决定下一步怎么走。
第二个痛点是可移植性。我做一个技能包,本质上是创建了一个目录。这个目录可以放进 Git 仓库,可以发给同事,可以挂载到不同的 Agent 环境里。我踩过不少次坑,知道 Function Calling 的后端代码往往和业务系统深度耦合,换个环境基本重写一遍;而skills只要目录能读,说明文档写清楚,模型就能用。
第三个痛点是试错成本。改一段提示词,跑一遍,看看效果;不对再改再跑。这个循环非常快,不需要重新部署服务。skills的每一次调整都是文件级别的改动,对于我这种喜欢快速迭代的人来说,体验好太多了。后面你会看到,光是改description里的一句话,就能显著改变技能命中率,这种“低成本调优”是skills模式最吸引人的地方。
2. 设计一套 skills 体系前的思考:哪些能力值得沉淀
2.1 从自己的真实工作流里挖掘,而不是凭空发明
很多新手一上来就喜欢列一个“全能技能清单”:数据处理、报告生成、代码审查、邮件撰写……列了一堆,结果 Agent 一个都用不好。我自己的经验是,技能一定是从失败里长出来的,不是从设想里规划出来的。
最靠谱的挖掘方法叫“倒推法”:翻一翻你过去一周和 Agent 的对话记录,找出那些“你反复纠正模型、反复补充细节”的任务。比如我最初做库存预警 Agent 时,模型总是把“低于安全库存”和“低于补货点”混为一谈,算出来的预警名单每次都不对。我一个同事气得不行,说“再这样下去还不如自己做”。后来我花了一个下午,把安全库存的计算规则、临界值定义、例外情况全部写进一个inventory_alert技能包里,之后再跑,结果基本一致。
所以我的建议是,先别急着设计技能,先做记录。连续记录三到五天,看看哪些任务是你每次都要给模型“擦屁股”的。这些任务就是高潜力的技能候选点。相比之下,那种“一次性任务”比如“帮我把这句话改通顺”“给我讲个笑话”,完全不需要做成技能,普通对话就能解决。
2.2 把复杂任务拆成可复用的原子模块
确定了一个大方向之后,下一步是把任务拆小。我经常用一个类比:技能就像乐高积木块,单个积木要足够简单、足够通用,才能拼出不同组合。你直接造一个“客户分析报告”的大型技能,里面塞满了几十个步骤,听起来很强大,但实际用起来会发现,换个数据源或者换个报告格式,整个技能就废了。
正确的做法是把“客户分析报告”拆成:数据提取、数据清洗、指标计算、报告排版、质量校验。其中“数据提取规则”和“指标计算方式”大概率是可以复用的,做成独立技能;“报告排版”可能一次一个样,那就不用做成技能,写普通 Prompt 就够了。拆的时候有一个判断标准:如果这个子任务在不同场景下会被反复用到,它就是好技能;如果它只是某个大任务里的一次性环节,它就不配拥有技能包。
这个拆分过程也帮你理清了依赖关系。比如“指标计算”技能可能会依赖“数据清洗”技能的输出,那么你需要在技能文档里写清楚前置条件。模型不会自动理解技能之间的依赖,文档里写明白,它才知道“先跑清洗,再跑计算”。
2.3 判定一个技能是否合格的四条标准
我做了十几个技能包之后,总结出四条验收标准,分享出来给大家参考。任何技能,如果四条里有一条不满足,我都会打回重做。
- 边界清晰:用一句话能说清楚这个技能负责什么,不负责什么。如果一个技能的描述里出现了“等等”两个字,边界大概率已经失控了。
- 可验证:技能跑完必须有一个明确的产出物,比如一份 JSON、一段摘要、一个文件,并且要写清楚“合格输出长什么样”。
- 可组合:这个技能可以被其他技能引用,输入输出都要规范化。比如技能统一输出 JSON 格式,互相调用时就方便。
- 文档自洽:让一个没看过你代码的人,只通过技能包里的文档,就能完全理解和使用这个技能。模型第一次触发时本质上也只读这些文档,文档写不清楚,模型就会乱来。
这个标准不是我拍脑袋想出来的,是吃了不少亏换来的。我最初做过一个叫data_helper的技能,描述写着“处理各种数据处理任务”,边界宽到没边。结果就是模型把什么都往这个技能里塞,遇到任何数据问题都触发它,连“把用户输入的文本转成大写”这种小事也触发它,严重干扰正常流程。后来我把这个大杂烩技能删掉,拆成了csv_validator、date_normalizer、duplicate_remover三个边界清晰的技能包,才恢复正常。每次拆技能我都提醒自己:一个技能只做一件事,做好就是赢。
3. 手把手做一个带验证与纠错的 skills 包
3.1 目录结构怎么搭,清单文件写什么
动手做技能包之前,先看一个我实际在用的目录结构,它基本符合主流框架的预期:
skills/ inventory_alert/ SKILL.md scripts/ calculate_threshold.py validate_output.py assets/ thresholds.json sample_report.md tests/ case1.json case2.json这个结构里,SKILL.md是灵魂文件,也就是技能说明文档。模型触发一个技能时,第一件事就是读这个文件,所以它的质量直接决定技能的执行效果。scripts目录放可执行的辅助脚本,负责模型不擅长的精确计算和数据校验。assets目录放静态参考文件,比如阈值配置、样例输出。tests目录放测试用例,方便你自己验证,也能让 Agent 在自检时调用。
我给每个SKILL.md都统一用一套六段式结构,你可以直接参考:
--- name: inventory_alert description: 当用户需要计算库存预警、识别临界库存、生成库存预警报告时使用本技能。仅用于正式预警任务,不用于日常库存讨论。 --- # 库存预警技能 ## 1. 输入要求 必须包含商品列表、当前库存数量、安全库存阈值,否则先问用户补齐。 ## 2. 执行步骤 1. 读取 assets/thresholds.json 中的安全库存配置。 2. 运行 scripts/calculate_threshold.py,传入商品库存数据。 3. 根据脚本输出,筛选低于安全库存的商品。 ## 3. 校验方法 运行 scripts/validate_output.py 检查输出 JSON 是否符合 schema,exit code 为 0 才算通过。 ## 4. 输出格式 返回 JSON:{ "alert_items": [...], "generated_at": "..." },附一段简要说明文字。 ## 5. 失败处理 如果校验失败,读取错误信息,修正输入后重新执行,最多重试 3 次。这里我要特别强调description的写法,前 100 个字定生死,模型就靠它判断要不要启动这个技能。不要写“本技能可以生成库存预警报告”这种能力式描述,要写成“当用户需要计算库存预警、识别临界库存、生成库存预警报告时使用本技能”,直接告诉模型触发时机。
3.2 技能说明文档的写法,直接影响模型调用率
我调试技能命中率时发现,SKILL.md里最影响成败的地方有两处:description和“执行步骤”。description 决定了技能会不会被触发,执行步骤决定了触发之后干得好不好。
description的正确写法,我总结成一句话:触发条件优先,能力说明次之。你要在描述里写清楚“什么情况下用”,而不是“这个技能擅长什么”。我对比过两个版本的效果,改一版描述后命中率从 55% 提升到 92%,差距就是这么明显。
| 写法类型 | 示例 | 实际效果 |
|---|---|---|
| 能力式写法 | “本技能提供库存预警计算服务” | 模型不知道什么时候该用,经常不触发 |
| 触发式写法 | “当用户需要计算库存预警、识别临界库存、生成库存预警报告时使用” | 触发准确率大幅提升 |
| 带反例写法 | 上面基础上加一句“不用于普通库存查询” | 误触发率明显下降 |
执行步骤这里有个新手很容易踩的坑:写得像散文,不像规程。模型读步骤时是按顺序执行的,“如果数据缺失就跳过”“情况允许的话可以尝试”“根据实际情况灵活处理”这种语义模糊的话,模型不好把握。我的习惯是,每条步骤都写成明确动作 + 明确产出,比如“读取配置文件 → 运行脚本 → 检查 exit code”,每一步都是可判断、可完成的动作卡片。
3.3 参考实现:脚本技能与提示词技能的分工
技能包里不一定非得有脚本,它可以是纯提示式的,也可以带脚本,关键是看任务性质。我这里给两类都做示例,方便你根据场景选型。
纯提示词技能适合“规则明确但计算简单”的任务。举个会议纪实的例子:
--- name: meeting_minutes description: 当用户提供了会议记录文本,需要生成结构化会议纪要时使用本技能。需要输出决议、待办、负责人和截止时间。 --- # 会议纪要整理 ## 步骤 1. 从输入中提取所有结论性语句,归入“决议”。 2. 找到所有带责任人的动作,归入“待办”,写明负责人和截止时间。 3. 按标准模板输出 Markdown,缺少的信息标注“待补充”。这种技能没有脚本,靠的是模型自身的理解和排版能力,做起来速度快,见效也快。但注意,纯提示技能的输出质量波动比较大,我在需要高强度一致的场景里不会用它。
带脚本的技能适合“需要精确计算、文件解析、格式校验”的任务。举例来说,一个 CSV 校验脚本:
# scripts/validate_output.py import csv import json import sys def validate(file_path: str) -> None: required_columns = ["item_id", "stock", "threshold", "alert"] with open(file_path, encoding="utf-8") as f: rows = list(csv.DictReader(f)) if not rows: print("ERROR: empty rows", file=sys.stderr) sys.exit(1) missing_cols = [c for c in required_columns if c not in rows[0]] if missing_cols: print(f"ERROR: missing columns: {missing_cols}", file=sys.stderr) sys.exit(1) for i, row in enumerate(rows): if not row["item_id"] or not row["stock"].strip().isdigit(): print(f"ERROR: invalid row {i}", file=sys.stderr) sys.exit(1) print("OK") sys.exit(0) if __name__ == "__main__": validate(sys.argv[1])这个脚本的价值在于,它把“检查列是否齐全、值是否合法”这种确定性的工作从模型手里拿过来了。模型做这种校验经常有疏漏,比如漏看某一列或者容忍了空值,而脚本一跑就知道结果。看一个技能包的含金量,就看它有没有把关键校验点交给脚本而不是模型。
3.4 让模型学会自我验证与自动纠错
这是我想重点分享的一节。很多人做技能第一天就能跑通,但跑不出稳定的效果,区别就在有没有设计“验证与纠错闭环”。
我在每个带脚本的技能包里,都会强制写一段“失败处理”逻辑,让模型遵循这个循环:
- 执行完主流程后,运行校验脚本检查产出物,比如验证 CSV 的列数、JSON 的 schema、文件是否生成。
- 校验脚本返回 exit code。0 代表通过,非 0 代表失败,同时会输出具体错误信息。
- 模型收到非 0 的返回值,判断自己哪一步做错了——是输入数据格式不对,还是脚本参数传错了,还是漏了某个前置步骤。
- 修复问题后重跑校验,最多重试 3 次。3 次不过,停止并通知用户,别自己硬撑。
这个写法看起来简单,但对模型的稳定输出帮助巨大。执行任务就像做菜,普通提示词相当于“凭感觉放盐”,带闭环的技能相当于“放完盐自己尝一口,太咸了加点水,太淡了再加盐”。模型自己会判断失败原因,而不是傻乎乎地把错误结果交给用户。
我还习惯在技能包里放一组测试用例,比如tests/case1.json,写清楚输入和期望输出。自检的时候让模型先跑测试用例,确认技能能跑通,再处理用户真实数据。这个方法在技能包交付给别人时特别有用,对方不需要懂代码,直接跑一遍测试就知道这个技能能不能用。
4. 实际接入流程与参数调优心得
4.1 把 skills 挂载到 Agent 的完整流程
不同框架接入skills的细节不太一样,有的是放到特定目录下自动扫描,有的需要在配置文件里声明。但核心思路是一致的,我建议按照下面这个顺序来做,不管用什么框架都能适配:
- 确定技能目录:把技能放在 Agent 能访问的路径下,比如项目根目录的
skills/文件夹,确认 Agent 有读取权限。 - 配置执行权限:脚本技能要执行 Python 或 Shell 命令,需要在 Agent 配置里允许相应命令的白名单,做不到的话脚本形同虚设。这一步别省,我吃过一次亏:技能是装了,脚本一个都没跑,因为权限被限制了。
- 设置技能加载上限:不要一股脑把所有技能都加载到上下文里,先评估单个技能说明文档的 token 消耗。一般建议同时加载 5 到 8 个核心技能就够,后面我会说怎么按需扩展。
- 做冒烟测试:用一句明确的触发指令测试,比如“请使用库存预警技能处理这份数据”,确认技能能被触发并正常执行。
- 加日志埋点:记录每次技能触发的上下文、输入长度、调用结果,方便后面排查问题。
接入之后一定要跑一个真实任务验证,别只测测试用例。真实数据的脏格式经常超出预期,测试用例覆盖不到,早点暴露问题反而好处理。
4.2 命中率与误调用问题:怎么调整描述
技能接入之后,紧接着要面对的问题就是“命中率”。这里的命中率指两件事:一是该用的时候有没有触发,二是不该用的时候会不会误触发。我调命中率调了不下十几次,分享几个真实心得。
先解决“不触发”。我最初给一个weekly_report技能写的描述是“生成周报”,结果模型一周都没触发过一次,因为它不知道“这周的项目进度总结”“把本周完成情况整理成报告”这些说法也算周报。后来我把描述改成了触发式写法,加了一堆常见的用户说法变体:
当用户要求生成周报、总结本周工作进展、汇总本周项目状态,或者提到“周报”关键词时,优先使用本技能。
改完之后,命中率立刻上来了。模型是靠语义匹配判断触发条件的,你的描述里覆盖的用户说法越多,触发概率越高。
再解决“误触发”。误触发一般是description里的关键词范围太宽导致的。比如我最早做了一个csv_tool,写的是“处理 CSV 文件相关任务”,结果用户说“帮我把这个 CSV 里的时间格式改一下”,系统同时触发了csv_tool、date_normalizer两个技能,模型纠结了半天。解决办法是给技能加“不适用场景”说明,比如改成“本技能仅用于 CSV 文件结构校验和列处理,不用于修改单元格数据”。这里面的逻辑是给模型画一条界限,告诉它哪些情况别来,它做决策时就有据可依了。
4.3 上下文膨胀控制与并发场景注意
skills不是免费的午晚餐。Agent 每次执行任务都要把技能包文档读取到上下文里,一个SKILL.md大约 2000 到 5000 token,如果你的技能数量多了,上下文会被大量占用,不仅影响响应速度,还会压缩模型处理用户输入的注意力空间。
我实测过一组数据:单个技能包平均 3000 token,加载 10 个就是 30000 token,这一大块内容还没开始干活就已经烧进去了。解决办法是两级索引加载:先加载一个总索引,每个技能只占一行 title + description 摘要,Agent 根据用户问题判断需要用哪个技能,再按需读取完整技能文档。这个策略能让常驻上下文的消耗从 30000 token 降到 2000 token 左右,同时保证模型能发现所有技能的存在。
再提醒一句并发场景的问题。如果同一个 Agent 要处理多个任务,每个任务可能会触发不同的技能,技能内的脚本不能设计成“全局唯一状态”。我见过有人把技能脚本写成了只有一份临时文件,结果两个任务同时跑,文件互相覆盖,数据全乱了。正确的做法是:每个技能脚本运行时使用独立的临时目录,或者传入任务 ID 作为文件名前缀,保证每轮执行之间互不干扰。
5. 常见问题与排查技巧实录
5.1 技能明明存在却从不被调用
这是我被问过最多的问题。技能包放在那里,文档写得也没问题,但模型就是不碰它。遇到这种情况,按照下面四个步骤排查:
- 确认技能目录可见:检查 Agent 的配置路径是否真的指向了技能目录,有些部署环境权限限制导致模型读不到这些文件。
- 检查 description 有没有触发词:再看一遍描述里是不是全在说功能,没有出现任何触发场景词。如果是,改成“当用户要求……时使用”。
- 检查有没有技能抢占:如果两个技能的 description 有重叠,模型可能每次都选另一个热门技能。把每个技能的前 50 个字拿出来对比,重合度高的要及时修订。
- 尝试显式触发:在对话里直接说“请使用 xxx 技能完成任务”,如果显式触发能跑通而隐式触发不行,说明描述还没覆盖到用户实际的说法。
我还遇到过一次比较隐蔽的问题:框架的加载上限设置得太低,技能虽然放在目录里,但 Agent 只会加载前 5 个,我的新技能排在第 7 个,永远不被注意到。后来我把配置改成了按需加载才解决。
5.2 技能接管了不该管的任务
这和“不触发”是反方向的毛病。表面上看,技能能干活了,但干的是隔壁的活。最常见的场景是技能 A 和技能 B 都带“报告”关键词,比如“生成库存报告”和“生成销售报告”,模型一看到“报告”就迷糊,有时候两个都触发,有时候只触发一个错的。
我的处理方式是给技能加“负向独占声明”。比如sales_report的技能描述里明确写“本技能只处理销售相关报告,不处理库存、采购、财务类报告”,库存技能里也做同样的事。这种做法本质上是在帮助模型做排除法,效果立竿见影。
还有一次误接管是因为系统提示词里写了“如果用户提到报告,优先调用报告类技能”,这一句话把模型带沟里了。回头检查你会发现,问题未必出在技能包本身,系统的全局指令也会误导模型。排查时要同时看两边。
5.3 多个技能互相冲突时怎么仲裁
当 System Prompt 里没有明确优先级时,模型碰到多个技能同时满足触发条件的情况,行为就变得不稳定。我试过几个方案,比较靠谱的有两种。
第一种是“路由仲裁”技能。我专门写了一个skill_dispatcher,它的职责是做决策:读取用户输入,判断当前任务应该归属哪一类,然后直接调用目标技能。这种方案适合技能数量多、场景差异大的情况,相当于给 Agent 配了一个“前台接待”,先把任务分诊到正确科室。
第二种是在技能内部互相声明依赖和优先级。比如monthly_summary技能,我在文档里写“本技能依赖 inventory_alert 和 sales_report 输出,如果两个任务重叠,先执行 inventory_alert 再执行 monthly_summary”。这相当于给模型一张优先顺序表,它照做就行了。
我个人的建议是从小规模场景开始,技能超过 10 个之后再上路由仲裁,不然一个 dispatcher 本身就占了不少上下文,得不偿失。
5.4 调试 skills 包的两个实用技巧
调试skills比调试普通代码费劲,因为模型的行为有随机性,你很难判断一个失败到底是代码问题还是模型发挥问题。我学到的两个技巧很管用。
第一个技巧是“让模型说出决策理由”。我在测试提示词里加一句:“先说明你选择这个技能的依据,再开始执行。”这样模型在技能调用之前会解释它看到了什么、为什么选它,问题出在描述还是出在逻辑,一目了然。实际项目里我也会在正式环境加上轻量的理由输出日志,方便回溯问题。
第二个技巧是“最小复现”。调试时只保留一个技能,把其他技能全部移到临时目录,再跑触发测试。这样如果技能还是没反应,问题一定出在这个技能本身;如果技能正常了,说明是被别的技能影响了。这个思路和代码调试里“二分定位”是同一个逻辑,很朴素,但能省无数心烦时间。
5.5 技能版本升级与灰度策略
skills包也是代码,是代码就会迭代。我最初改技能时直接覆盖原文件,结果模型行为在几天内前后不一致,线上任务经常结果变化,用户都被搞糊涂了。后来我定了三条规则:
第一条,每个技能包维护一个版本号,写在SKILL.md的 frontmatter 里,同时保留变更记录。没有版本信息的技能,在正式环境里就是个隐患。
第二条,新版本技能以v2命名共存,比如inventory_alert_v2,在描述里明确写“这是 v2 版本,优先使用”,跑几天观察结果稳定后再把 v1 下架。不要两个版本同时启用太久,会让模型判断混乱。
第三条,改动后一定要跑一遍技能包里的测试用例。别只靠一次真实对话验证,那次可能刚好碰上模型状态好,不代表稳定输出。把测试用例固化下来,每次改完跑一遍,通过再上线,这才算一个标准的发布流程。
我在实际项目里还会给每个技能包配一个“演示指令”,比如在描述里注明“如果你想验证本技能,可以说‘运行技能自带的演示任务’”。这样技能包交付给团队里不熟悉 Agent 开发的同事时,对方不用读长文档,一句话就能跑通验证流程,确认技能工作正常。这个习惯帮我减少了很多沟通成本,也让我意识到skills真正沉淀下来的,不只是几段提示词和脚本,而是让团队的领域知识变成了一套可以记录、可测试、可传承的资产。