Agent Skill 的工程化实践
从单 Skill 设计到多 Skill 编排:AI Agent 时代的工程化实践
引言:当 Skill 数量从 1 涨到 50
过去一年,关于 Skill 的文章大多停留在"如何写好一个 Skill"——SKILL.md 目录、YAML frontmatter、name + description 描述工程、Progressive Disclosure 渐进式披露。这套单 Skill 设计方法论几乎已经成为行业共识。
但当一个团队的 Skill 数量从 1 个膨胀到 50 个、100 个,问题就完全变了。你会遇到:
- Skill 之间的耦合:A Skill 的输出是 B Skill 的输入,谁来编排?
- Skill 的失控:用户问了一句"帮我订机票",结果触发了 3 个不该触发的 Skill,token 暴涨。
- Skill 的失败:某个 Skill 的
description写得不好,模型从来不调用它;或者被误调,导致整个 Agent 卡死。 - Skill 的演进:今天能用的 Skill,下个版本模型升级后,触发逻辑就变了,怎么办?
本文不重复"什么是 Skill"的基础内容,而是直击多 Skill 时代的工程化痛点:编排、治理、可观测。我会给出三个推荐框架(决策树、编排模式分类、健康度指标),以及一个跨领域实战案例,最后讨论 Skill 工程化的未来。
一、Skill 的本质再认识:从 Prompt 到"可治理的能力单元"
在进入多 Skill 体系之前,我们有必要重新对齐 Skill 的本质。已有文章把它定义为"比 Prompt 更好用的提示工程方案",这并不够准确。
我的定义是:Skill 是一个具备稳定身份、可独立治理、可被 Agent 在推理时按需装载的能力单元。
它包含三层含义:
- 稳定身份:
name + description是 Skill 在 Agent 眼中的"身份证",决定了它何时被选中、被谁调用。 - 可独立治理:每个 Skill 都有自己的版本号、作者、依赖、测试用例、调用指标,可以独立上下线。
- 按需装载:通过 渐进式披露 机制,Skill 的完整内容不必常驻上下文,只在触发时按层级加载。
理解这三层,才能理解为什么 Skill 不是一个"高级 Prompt",而是一个工程实体。它和微服务架构中的 Service、本地函数库中的 Function、IDE 中的插件,本质上是同一类事物——只不过它的运行环境是 LLM 的推理上下文。
二、原创框架一:Skill vs 子 Agent vs MCP 决策树
很多团队在系统设计时纠结:这件事到底该写成 Skill、子 Agent,还是 MCP Server?
这三者的能力边界我用一个决策树来概括:
Q1: 这个能力是否需要独立的工具/资源访问?
├── 是 → 走 MCP(Model Context Protocol)路径
│ (如:数据库查询、Git 操作、浏览器控制)
│
└── 否 → Q2: 这个能力是否需要独立的上下文/记忆?
├── 是 → 走 子 Agent 路径
│ (如:长链路研究、多轮对话、独立工具链)
│
└── 否 → Q3: 这个能力是否可在当前 Agent 上下文中按需调用?
├── 是 → 写为 Skill
│ (如:代码规范检查、commit 信息生成、特定领域 prompt 模板)
│
└── 否 → 应该拆成多个原子 Skill 组合
边界规则细化
- Skill 是"知识/提示/模板"的封装,不持久化上下文,不直接操作外部资源。它最适合"教 Agent 怎么想、怎么写"。
- 子 Agent 是"独立思考者",有自己的 context window、自己的工具栈、自己的终止条件。它适合需要"隔离、专注、长流程"的场景。
- MCP Server 是"能力的桥",把外部世界(数据库、文件系统、API)以标准化协议暴露给 Agent。它适合需要"可被多种 Agent 复用"的基础设施。
一个反例:把"调用 MySQL 查询用户订单"写成 Skill,结果每次都要把 SQL 模板和数据库连接信息塞进 Skill 里,既臃肿又危险。正确做法是写一个 MCP Server,Skill 只负责告诉 Agent “在什么场景下用这条 SQL 的思路”。
三、原创框架二:多 Skill 编排的四种模式
当 Skill 数量超过 10 个,编排就成了核心问题。我把多 Skill 协同归为四类基本模式:
1. 顺序模式(Pipeline)
Skill A → Skill B → Skill C
典型场景:代码评审流水线。先 code-lint-check Skill 做静态检查,再 security-scan Skill 做安全扫描,最后 review-summary Skill 生成报告。每个 Skill 只关心自己的输入输出契约。
实现要点:把 Skill 之间的中间产物(如扫描报告的 JSON)定义为标准 Schema,避免耦合到具体实现。
2. 分支模式(Router)
┌─ Skill B (条件1)
Router ─────┼─ Skill C (条件2)
└─ Skill D (默认)
典型场景:客服意图分发。根据用户输入的意图分类,决定调用退换货 Skill、咨询 Skill 还是投诉 Skill。这里需要一个"路由器"——可以是另一个 Skill(intent-router),也可以是主 Agent 的一段逻辑。
实现要点:路由器的判定逻辑必须显式且可解释,避免模型在歧义场景下随机选择。
3. 循环模式(Loop with Guard)
Skill A ──┐
↑ │
└─ Skill B (终止条件判定)
典型场景:自动修复 CI 失败。fix-attempt Skill 尝试修复,check-result Skill 判定是否通过。如果不通过且未超过最大次数,回到 fix-attempt。
实现要点:必须设置最大循环次数和超时,否则 Agent 会陷入死循环烧光 token。我见过生产事故就是因为某个 Skill 的终止判定写得太宽松,循环了 200 多次。
4. 协商模式(Multi-Skill Consensus)
┌─ Skill A (主张1 + 置信度)
User ───┼─ Skill B (主张2 + 置信度)
└─ Skill C (主张3 + 置信度)
│
Aggregator (投票/加权)
典型场景:投资决策辅助。多个 Skill 各自给出风险评估、市场情绪、技术面分析,最终由聚合器加权输出。
实现要点:每个 Skill 必须输出结构化的置信度,而不是自由文本,否则聚合器无法量化决策。
编排的"反模式"
- Skill 调用 Skill:Skill A 在自己的 description 里硬编码调用 Skill B 的指令。这会导致循环依赖和隐式编排,调试地狱。应改为显式编排(由主 Agent 或外部 Orchestrator 调度)。
- Skill 的 description 互相重叠:两个 Skill 的
description描述了相似的场景,模型会随机选择。必须用"互斥 + 完备(MECE)"原则设计 description。
四、原创框架三:Skill 健康度指标体系
可观测性是 Skill 工程化的基石。我提出四个核心指标,简称 S4 指标:
1. 命中率(Hit Rate)
Hit Rate = Skill 被触发的次数 / 用户请求总次数
健康参考值:20%-60%。如果某 Skill 的命中率长期 < 5%,说明它的 description 不够清晰或场景已经过时;如果 > 80%,说明它在抢别人的活,需要拆分或重新定位。
2. 误触发率(False Trigger Rate)
FTR = 人工判定为误触发的次数 / Skill 触发总次数
这是最难测的指标。建议方案:
- 在灰度阶段抽样 1% 的调用做人工标注。
- 建立"用户反馈 + 人工复审"的双轨机制。
- 用一个 LLM-as-Judge 的 Skill 来自动评估(注意:评估 Skill 和被评估 Skill 必须用不同模型,避免同源偏差)。
健康参考值:< 10%。超过 15% 说明 description 有歧义,需要重新写。
3. Token 成本(Token Cost per Invocation)
TCI = (input_tokens + output_tokens) × 单价
很多团队忽视了 Skill 的 token 成本。一个看似免费的 Skill,如果每次触发都要加载 5000 token 的 SKILL.md 到上下文,调用 1 万次就是 5000 万 token。
优化手段:
- 用 渐进式披露,分层加载(meta → instructions → resources)。
- 把 Skill 的高频片段做成"微型 Skill"(< 500 token),把低频片段合并为"完整 Skill"。
- 用 prompt caching(如果模型支持),把不变的 Skill description 缓存。
4. P99 延迟(Latency P99)
P99 = 第 99 百分位的端到端响应时间
Skill 是 Agent 推理链路上的额外一步,必然增加延迟。如果某个 Skill 让 P99 从 2s 飙升到 8s,就需要:
- 检查 Skill 内容是否导致模型思考过长(用更明确的指令减少推理轮次)。
- 把同步 Skill 改成异步预加载。
- 把 Skill 的执行放到子 Agent 里并发。
指标看板的最小实现
一个简化的 S4 看板应该长这样:
| Skill Name | Hit Rate | FTR | TCI | P99 | 状态 |
|---|---|---|---|---|---|
| code-review | 35% | 8% | 1200 | 3.2s | 健康 |
| db-query-helper | 5% | 45% | 800 | 1.1s | 需优化 description |
| fix-attempt | 12% | 6% | 4500 | 12.5s | token/延迟双高 |
五、跨领域实战案例:电商客服 SOP 的多 Skill 编排
为了把上面的框架串起来,我用"电商客服 SOP"做一个综合案例。
业务背景
一个中型电商平台,每天 10 万次客服咨询。原有方案是把所有规则塞进一个超长 prompt(3000+ 行),导致:
- 模型经常"忘记"早期规则。
- 响应慢(单次平均 4.5s)。
- 升级到新模型后,整个 prompt 要重写。
重构方案:多 Skill 编排
把超长 prompt 拆成 12 个 Skill,按四类编排模式组织:
阶段 1:意图路由(分支模式)
intent-router Skill:根据用户输入,输出意图标签(refund / logistics / product-inquiry / complaint / other)。
阶段 2:领域处理(顺序 + 协商模式)
- 退换货链路(顺序):
refund-policy-check→order-lookup(MCP)→refund-eligibility→response-generator。 - 物流咨询(分支):根据订单状态,分别走
logistics-normal、logistics-delay、logistics-lost三个 Skill。 - 投诉处理(协商):
sentiment-analyzer、policy-checker、risk-assessor三个 Skill 各自评分,由聚合 Skill 输出最终处理建议。
阶段 3:质检(循环模式)
quality-check Skill 对生成的回复做合规检查,如果不通过且重试次数 < 2,回到 response-generator 重新生成。
关键 Skill 的实现片段
intent-router 的 YAML frontmatter:
name: intent-router
description: 当用户输入为中文客服对话时使用。负责识别意图并路由到对应处理 Skill。仅做意图分类,不直接回答用户问题。
注意:description 里明确写了"不做回答",这是路由器的关键约束,避免模型直接越权生成回复。
refund-eligibility 的核心逻辑:
伪代码层面,Skill 的指令会要求模型:
- 调用
order-lookup(MCP)获取订单信息。 - 根据订单状态、用户历史、退款政策,输出结构化判定(
eligible/partial/not-eligible+ 原因)。 - 把判定结果传给
response-generator。
重构后的效果
- 响应延迟:平均从 4.5s 降到 2.8s(P99 从 9s 降到 5.5s)。
- token 成本:单次平均从 3500 token 降到 1400 token(Progressive Disclosure + 分层加载)。
- 规则维护:新增政策只需修改对应 Skill,不用动全局 prompt。
- 可观测:每个 Skill 的 S4 指标独立可见,能定位瓶颈 Skill。
这次重构的教训
- Skill 拆分不是越细越好:我们一度把每个退款规则拆成一个 Skill,导致编排开销过大。最后合并成"按业务域"为一个 Skill,规则用结构化数据(YAML/JSON)放在 resources 目录。
- 路由器的 description 必须极简:
intent-router一开始 description 写得太复杂,模型经常"自作主张"直接回复。后来精简到 2 句话,路由准确率从 78% 升到 94%。 - 循环模式一定要有"熔断":
quality-check一开始没有最大重试限制,遇到边缘 case 时反复重试,烧光 token。加上 2 次限制后稳定。
六、Skill 的失败模式与回退策略
任何 Skill 都不是 100% 可靠的。我总结了 7 种典型失败模式及应对:
| 失败模式 | 表现 | 根本原因 | 回退策略 |
|---|---|---|---|
| 静默失活 | Skill 从未被触发 | description 与用户措辞不匹配 | 增加触发关键词同义词、定期 A/B 测试 description |
| 过度触发 | Skill 在不该调用时被调用 | description 太宽泛 | 缩小 scope、加入"不适用场景"描述 |
| 上下文污染 | Skill 加载后导致主 Agent 行为偏移 | Skill 内容含强约束 | 用隔离子 Agent 包裹 Skill |
| 执行卡死 | Skill 内部逻辑死循环 | 缺少终止条件 | 设置超时 + 最大重试 + watchdog |
| 依赖缺失 | Skill 引用了不存在的 MCP | MCP 未正确注册 | 启动时自检依赖、优雅降级到本地实现 |
| 版本漂移 | Skill 在新模型上效果变差 | description 对老模型有效但新模型偏好改变 | 模型升级时跑回归测试集 |
| 权限越界 | Skill 实际做了超出 description 的事 | Skill 文件被篡改 | 签名校验 + 沙箱执行 + 操作审计 |
回退策略的三个层次
- Skill 内回退:Skill 自身提供 fallback 路径(如主路径失败时调用简化版)。
- 编排层回退:编排器发现 Skill 超时/错误时,跳过它或替换为等价 Skill。
- 平台层回退:整个 Agent 链路降级到无 Skill 的基础模式,保证核心功能可用。
七、Skill 的版本化、CI/CD 与灰度发布
当 Skill 数量超过 20,没有版本化就是灾难。我推荐如下实践:
1. 版本规范
- 遵循 SemVer:
major.minor.patch。 major:破坏性变更(description 语义、输入输出 schema)。minor:新增能力,向后兼容。patch:文档、提示词微调。
2. CI 流水线(每次提交触发)
lint SKILL.md ─┐
schema check ─┼─→ unit test → eval test → package → registry
description regression ─┘
其中 description regression 特别重要:用历史"应该触发该 Skill 的真实 query"作为测试集,验证 description 改动后命中率不退化。
3. 灰度发布
- 金丝雀(Canary):先对 1% 的用户启用新版本 Skill。
- A/B 对照:新旧版本同时运行,按 S4 指标对比。
- 紧急回滚:发现 FTR 飙升或 P99 异常时,一键回滚到上一个稳定版本。
4. Skill Registry
建立内部 Skill 注册表,类似 npm:
- 每个 Skill 有 metadata(作者、依赖、License、Eval Score)。
- 支持按场景搜索(如"所有退款相关 Skill")。
- 强制要求每个 Skill 配套一个最小 Eval 测试集。
八、Skill 工程化的未来展望
站在 2026 年中看,Skill 工程化正在经历几个清晰的演进方向:
1. 从"技能库"到"技能市场"
企业内部的 Skill Registry 会进一步开放,形成跨企业的 Skill Marketplace。但要解决两个问题:版权与计费(Skill 的 prompt 是知识产权)、安全审计(Skill 不能携带恶意指令)。可以预见会出现第三方"Skill 审计服务"。
2. 自动 Skill 发现与生成
未来会有"Skill Miner"工具:从团队历史对话、issue 列表、工单中自动挖掘重复模式,生成 Skill 草稿,由人工 review 后入库。这把 Skill 创建从"专家工程"变成"团队共创"。
3. Skill 之间的语义级互操作
现在的 Skill 通信靠"自由文本 + 约定俗成",未来会出现标准化的 Skill-to-Skill Protocol:结构化输入输出 schema、版本协商、能力声明。这和微服务从"REST 混沌"走向"OpenAPI + gRPC"是同一个故事。
4. 与 Agent OS 的融合
未来的 Agent OS(无论是 Claude Code、Codex、Cursor 还是新平台)会把 Skill 作为一等公民:原生支持 Skill 的发现、加载、编排、可观测。Skill 不再是"附加品",而是 Agent 能力的标准交付形态。
5. Skill 的"反脆弱"设计
随着模型越来越强,Skill 的作用可能会从"教模型怎么做"演化为"约束模型不要做什么"——反脆弱 Skill(如安全护栏、合规检查、越权阻断)会成为新的增长点。
结语
回到开篇的问题:单 Skill 设计是入门,多 Skill 编排是工程,Skill 治理是艺术。
更多推荐

所有评论(0)