主题
技能包与复用
一句话:技能包把散落在提示词、文档和个人习惯里的可执行流程,固化成可发现、可授权、可测试的单元;换来复用与一致,代价是维护版本、权限和失效边界。
为什么需要
同一类任务,三个人能写出三套提示词:步骤在对话里、上次记录里、个人记忆里。规则散落在 AGENTS.md、Wiki 和代码注释中,新人和 Agent 都要被重复交代;产出结构每次不同,复盘时找不到标准做法。技能包把“怎么做、能用哪些工具、输出什么”固化成一份来源,按需加载,重复交代只发生一次。
核心机制
三层来源
| 来源 | 优势 | 代价 | 适用 |
|---|---|---|---|
| 官方 | 接口稳定、随平台升级、责任清晰 | 偏通用,不懂团队约定 | 通用能力 |
| 社区 | 覆盖快、场景多、可改造 | 来源与版本不可控,可能夹带过时做法或恶意指令 | 非敏感通用任务 |
| 自研 | 贴合内部系统、权限与合规 | 建设维护成本最高,必须有 owner | 内部流程与专有数据 |
先官方、再社区、最后自研:通用能力不必重造,社区包要过审查,只有内部上下文和权限才是自研的理由。
最小结构:四件套
- 入口描述:名称、触发场景、版本、owner、来源;描述是路由元数据,写“什么时候用”。
- 流程或提示词:前置条件、步骤、判断点、停止条件;信息不足时停下来问。
- allowed_tools:显式工具与范围,最小权限,禁止通配符。
- output_schema 与示例:结构化输出、必填字段、错误形状,配正例、负例和权限拒绝用例。
没有输出契约,技能包只是风格化提示词;没有测试用例,改提示词时无法判断变好还是变坏。
拆分粒度:一个包只做一类任务
- 触发条件能用一句话说清,且与相邻技能的边界不重叠;说不清就说明还没拆对。
- 流程超过十步、包含多个判断分支时,拆成“主流程 + 子技能”,由主流程按条件调用,而不是把所有分支塞进一份长提示词。
- 需要不同权限或不同角色的部分分开:只读分析和写操作放在两个包里,授权边界才不会被流程复杂度稀释。
- 依赖大量参考资料时,正文只留决策步骤,把模板、长清单和脚本放进
references/或scripts/,按需读取。
拆得太细会让路由变难、维护成本上升;拆得太粗则无法复用和授权。判断标准不是行数,而是“换一个任务时,这个包能否整体复用,还是大部分内容都要改”。
技能包、子代理、hook 怎么选
| 机制 | 解决什么 | 典型用法 | 不该用它做什么 |
|---|---|---|---|
| 技能包 | 可复用的流程与输出契约 | 发布说明、代码审查、故障复盘 | 强制拦截危险操作 |
| 子代理 | 上下文隔离与并行 | 大范围检索、独立审查 | 传递必须逐字保留的长上下文 |
| hook | 确定性的前置/后置拦截 | 禁止写生产目录、提交前跑检查 | 需要理解语义的判断 |
| MCP | 连接外部工具与数据 | 查工单、读知识库、调内部 API | 定义团队内部流程 |
能用代码或 hook 拦住的约束,不要只写在技能包里;需要语义判断的步骤,不要硬编码成 hook。技能包负责“怎么做”,不负责“一定做得成”。
团队技能库怎么组织
- 命名与目录:按“领域-动作”命名,目录里同时放入口、schema、示例和变更记录;搜索时先命中描述,再打开正文。
- 评审与 owner:新包和改流程都要有人签字,写操作额外过安全评审;无 owner 的包不进默认列表。
- 度量:跟踪命中率、任务成功率、人工接管率、平均 token 与延迟;长期零命中的包下线,而不是继续堆在库里。
- 组合:允许主技能调用子技能,但限制调用深度和总预算,避免一个入口拖出一长串隐式流程。
命中描述只说明“该用它”,不代表有权限或结果可信;权限不足或输出校验失败都应升级,而不是放宽约束继续做。
与 AGENTS.md 的分工
AGENTS.md 放长期事实:技术栈、目录、命令、约定、禁区,每次会话都加载,所以要短而稳定。技能包放可执行流程:某类任务按什么步骤做、用哪些工具、输出什么结构,按需加载。判断口径是“是什么、不能做什么”写 AGENTS.md,“怎么做、做完输出什么”写技能包;两者不要互相复制,改的时候必然漏一处。
版本、owner、评审与下线
- 版本:语义化版本;提示词、工具列表、输出 schema 任一变化都升版本,保留兼容窗口。
- owner:每个包有负责人和用途说明;无 owner 不上架,避免僵尸技能。
- 评审:过三关——流程正确、工具权限最小、示例与负例覆盖失败路径;写操作加安全评审。
- 发布与下线:先影子运行再小范围启用;下线先标废弃、保留重定向,确认零调用后移除;异常时 kill switch 能立即停用。
社区技能的风险
社区技能是可执行内容的供应链,不是无害文本:描述或正文可能藏提示注入,示例可能调用过时 API,allowed_tools 可能申请过宽,工具还可能把内部数据带出边界。防线是允许列表、版本钉住、来源与签名校验、最小权限、沙箱限制出网、审计与 kill switch;审查过的包也要随上游版本复评。
实战场景
案例:一个社区技能包把内部数据带出了边界
一个 GitHub 上评分不错的 code-review 包,团队直接装进了默认列表。两个月后的出网流量审计发现,这台开发机在审查时会向一个陌生域名发 POST,请求体里带着内部仓库的文件路径与函数签名。包本身没有恶意样本特征,它只是 allowed_tools 里申请了一个 web.fetch,正文里写着“参考社区最佳实践时先拉取规则”,而那个 URL 是硬编码的。
排查过程值得记:先确认不是模型行为——审计日志里 URL 与包正文一致;再看权限声明——包声明的工具比流程实际需要的多出一个;最后看出网策略——开发机默认允许出网,这层的缺失才是它能把数据带出去的原因。
| 层 | 当时的缺口 | 补上后的判据 |
|---|---|---|
| 包内容审查 | 只看了 README 有没有可疑说明 | 逐条核对 allowed_tools 与正文步骤,多余的直接删;硬编码 URL 全部改为允许列表内域名 |
| 运行时授权 | 包声明什么就给什么 | 运行时二次校验,声明与任务需要取交集;只读分析包不给写工具 |
| 网络边界 | 开发机默认可出网 | 默认拒绝出站,白名单放行;这条不依赖包的自觉 |
| 版本与应急 | 装完就不再管 | 版本钉住、来源与签名校验、上游更新触发复评;kill switch 能按包名立即停用 |
复盘要点:社区包是可执行内容的供应链,审查的是“它能调用什么、会往哪发”,不是“它读起来正不正常”。正文里“防线是允许列表、版本钉住、最小权限、沙箱限制出网、审计与 kill switch”这句,缺任何一条都拦不住这次事故——只删包而不收网络边界,下一个包还会再来一遍。
案例:技能库涨到四十多个,Agent 开始用错包
库里从七八个包涨到四十多个后,出现了两类反常现象:一是同一句“帮我整理这次发布的变更说明”,有时命中 release-notes,有时命中 changelog-draft,两边格式不同,产出每次要人工重排;二是命中率统计显示约三成包长期零命中,却仍全部注入路由描述,占了上下文。
排查不看模型,看描述。把每个包的 description 摊开对比,触发场景重叠的一眼就能看出来——两个包的描述都写了“整理变更内容时使用”,路由只能靠语义相似度赌。这就是“一个包只做一类任务”里那条判据的实际含义:触发条件一句话说清,且与相邻技能边界不重叠;说不清不是描述要润色,是包还没拆对或该合并。
对症动作,按顺序执行:
- 先合并重叠描述的包,保留一个入口,另一个改成子技能由主流程按条件调用;调用深度限制在两层(经验值,需按任务复杂度校准),避免一个入口拖出隐式长流程。
- 再下线长期零命中的包。下线不是直接删:先标废弃、保留重定向,确认零调用后再移除,避免某个团队的脚本还在按名字引用。
- 最后把“相似描述互相抢命中”做成发布检查项:新包上架前,用它的描述去检索现有库,命中分数最高的既有包要人工确认不冲突。
案例:改了一句公共包的提示词,二十个团队的产出同时漂移
有人为了修一个字段留空的问题,在 release-notes 的正文里加了两句“优先按影响面排序”。包没升版本,第二天多个团队反馈发布说明结构变了,schema 校验通过率下降。没有变更记录、没有影子运行、owner 不明确,回滚时连“改之前是哪一版”都要靠 git 翻。
三条纪律把这类事故变成可控变更:
text
版本:提示词、allowed_tools、output_schema 任一变化都必须升版本——哪怕只改一句话
发布:先影子运行(新版本与旧版本同时执行,只采用旧版本结果),比对命中率、成功率、人工升级率、token 成本
回滚:保留兼容窗口,异常时按包名 + 版本号一键停用判据是“改动能不能被单独回滚”。一句提示词的改动如果无法回滚,说明它没有被当作一次发布,而技能包的价值恰恰在于它是可版本化的资产;不做版本与灰度,四十个包就是四十份没人敢动的旧文档。
最小上手
一个最小技能包是一个目录:SKILL.md(入口与流程)、schema.json(输出契约)、examples/(正例、负例、权限拒绝)。
markdown
---
name: release-notes
description: 根据合并记录生成发布说明;整理本次发布内容时使用
version: 1.0.0
owner: platform-team
allowed_tools: [git.log, issue.read]
output_schema: schema.json
---
1. 确认版本范围与目标分支,缺失就停止并询问。
2. 读取合并记录,按 feat / fix / breaking 分类,只引用带 issue 链接的条目。
3. 按 schema 输出,不确定的字段留空并说明原因。验证:python -m json.tool skills/release-notes/schema.json 确认 schema 合法;再用三个正例、一个负例和一个权限拒绝用例跑一遍,检查字段、升级行为和停止条件。
生产动作
- 注册与发现:登记名称、触发描述、版本、owner、数据分级和风险等级;描述要能区分相邻技能,避免互相抢命中。
- 权限:
allowed_tools按任务最小化,写操作单独申请;运行时再做一次工具级校验,不能只信包里的声明。 - 灰度与度量:新版本先影子运行,看命中率、成功率、人工升级率和 token 成本;异常版本可回退。
- 排障:没触发查描述与路由;触发但缺权限查
allowed_tools与运行时授权;输出不合 schema 查模板与示例。
边界
- 一次性任务不值得打包:模式不稳定或只有一个人用,先重复几次再固化。
- 技能包不是权限系统:提示词里的“不要删数据”拦不住工具调用,边界在运行时和网关。
- 不是越多越好:技能数量上升会降低路由准确率,相似描述互相抢命中;定期合并和下线。
- 社区包不能免审:来源可信不等于内容可信,版本更新也可能引入新指令。
- 模型或工具升级后要复测:旧示例可能失效,把复测放进版本升级流程。
讲清楚
技能包解决重复交代和做法漂移:同一类任务每次重新讲步骤、产出结构还不一样。做法是把入口描述、执行流程、工具权限和输出契约打成小单元,按需加载、按版本管理,并用示例和负例验证。它和 AGENTS.md 分工明确:后者放长期事实和禁区,前者放可执行流程。来源分官方、社区、自研,社区包要当供应链审查,防提示注入、过时 API 和权限过宽。难的不是写包,而是持续维护 owner、版本、评审和下线,否则只是另一堆没人敢用的旧文档。
适用:支持技能包 / Agent Skills 的运行时 | 初稿 2026-10