第 19 章 Agent Skill:能力复用体系
本章要解决的问题
多个 Agent 都要用同一套流程(比如「先查库再总结」)------怎么封装成可复用的 Skill,避免重复造轮子?
章节大纲
- 19.1 Skill 是什么:可复用流程封装
- 19.2 Skill 的设计规范与版本管理
- 19.3 技能编排与组合策略
- 🛠 解决方案:Skill 复用度评估与过度抽象治理
19.1 Skill 是什么:可复用流程封装
19.1.1 一句话定义
Skill(技能)是把"提示词 + 工具 + 流程逻辑"打包成可复用的能力单元------任何 Agent 需要这项能力时,直接调用这个 Skill,而不是重新写一遍。
19.1.2 为什么需要 Skill:重复造轮子之痛
看一个真实的重复场景:
text
场景:三个 Agent 都要"先查客户资料,再生成个性化回复"
- 客服 Agent:查客户 → 生成回复
- 销售 Agent:查客户 → 生成跟进话术
- 运营 Agent:查客户 → 生成关怀消息
如果不封装:
- 三个 Agent 各写一套"查客户 + 生成"的提示词和工具逻辑
- 客户查询逻辑改了(加了个字段),要改三个地方
- 新 Agent 入职,又得抄一遍
Skill 把"查客户"抽出来做成一个 Skill:改一次,所有 Agent 受益;新 Agent 直接用。
19.1.3 Skill vs 工具 vs 提示词:三者的区别
| 概念 | 粒度 | 内容 | 类比 |
|---|---|---|---|
| 提示词 | 最小 | 一段文本 | 一句话指令 |
| 工具(第 5/14 章) | 单动作 | 一个函数 | 一个动作 |
| Skill | 流程级 | 提示词 + 工具 + 流程逻辑 | 一套标准作业程序(SOP) |

图 1:提示词 vs 工具 vs Skill
Skill = 工具的组合 + 流程的封装。工具是"零件",Skill 是"装配好的部件"------Skill 可以调用多个工具,也可以只包含提示词逻辑。
19.2 Skill 的设计规范与版本管理
19.2.1 Skill 的标准结构
一个生产级 Skill 应该包含四个部分:

图 2:Skill 四部分结构
python
class Skill:
# 1. 元信息(给"谁在什么时候用"看)
name: str # 唯一名称,如 "customer_profile"
description: str # 何时用/何时不用(供 Agent 决策)
version: str # 版本号,如 "1.2.0"
# 2. 依赖(需要哪些工具/其他 Skill)
requires_tools: list # ["query_customer", "get_order_history"]
requires_skills: list # 可依赖其他 Skill
# 3. 执行逻辑(流程编排)
def run(self, context):
# 先查客户
profile = call_tool("query_customer", context["customer_id"])
# 再查历史
history = call_tool("get_order_history", context["customer_id"])
# 组合返回
return {"profile": profile, "history": history}
# 4. 输出契约(下游怎么消费)
output_schema: dict # {"profile": {...}, "history": [...]}
四个部分缺一不可:元信息(可被发现)、依赖(可被组装)、逻辑(可被复用)、输出契约(可被消费)。
19.2.2 Skill 的设计规范
| 规范 | 说明 | 反例 → 正例 |
|---|---|---|
| 单一职责 | 一个 Skill 只做一件事 | "客户服务" → "查客户画像" |
| 输入输出显式化 | 明确参数与返回结构 | 隐式传全局 → 显式 schema |
| 描述写"何时用" | 供 Agent/编排器决策 | "处理客户" → "查客户画像,生成个性化回复前用" |
| 错误可感知 | 失败返回结构化错误 | 抛异常 → 返回 {"error": ...} |
| 无副作用 | 默认只读,写操作显式声明 | 静默改数据 → 声明写操作 |
19.2.3 Skill 的版本管理
Skill 是"代码资产",必须版本化(呼应第 24 章 G4 配置版本化):
| 版本变化 | 语义 | 影响 |
|---|---|---|
| 补丁(1.2.0 → 1.2.1) | Bug 修复,接口不变 | 可平滑升级 |
| 次版本(1.2 → 1.3) | 新增能力,接口兼容 | 向后兼容 |
| 主版本(1.x → 2.0) | 接口破坏 | 需迁移,下游要改 |
版本管理的实践:
- Skill 随代码库进 Git,有 changelog。
- 依赖 Skill 的 Agent 声明
required_version范围。 - 破坏性变更用"新旧并行 + 灰度切换"(呼应第 20 章灰度)。
19.3 技能编排与组合策略
19.3.1 Skill 的组合:积木式搭建
Skill 的价值在组合------像搭积木一样拼出复杂能力:

图 3:Skill 组合依赖
yaml
Skill: customer_profile(查客户画像)
└─ 依赖工具: query_customer, get_order_history
Skill: personalized_reply(个性化回复)
└─ 依赖 Skill: customer_profile
└─ 流程: 调 profile → 按画像生成回复 → 质检
Skill 依赖 Skill(嵌套组合)时,注意两点:① 依赖关系要声明清楚(谁依赖谁);② 避免循环依赖(A 依赖 B、B 又依赖 A)。
19.3.2 Skill 注册表:能力中心
生产级团队维护一个 Skill 注册表(能力目录):

图 4:Skill 注册表
python
SKILL_REGISTRY = {
"customer_profile": CustomerProfileSkill(version="1.2.0"),
"personalized_reply": PersonalizedReplySkill(version="2.0.0"),
"rag_answer": RAGAnswerSkill(version="1.0.3"),
# ... 更多 Skill
}
def get_skill(name, version=None):
skill = SKILL_REGISTRY[name]
if version and skill.version != version:
raise SkillVersionError( # 自定义异常
f"Skill {name} 版本不匹配: 需要 {version}, 当前 {skill.version}")
return skill
注册表的价值:能力可见(谁有什么 Skill)、可治理(版本/权限)、可复用(新 Agent 直接取用)。
19.3.3 Skill 与 Agent 的两种使用方式
| 方式 | 机制 | 适用 |
|---|---|---|
| 显式编排 | Agent 流程代码里直接调用 Skill | 流程固定的场景 |
| 动态发现 | 把 Skill 描述告诉模型,模型按需调用(Skill 即"高级工具") | 灵活任务 |
动态发现模式把 Skill 当成"更大粒度的工具"暴露给模型------Skill 的描述写清楚"何时用",模型自己决定要不要调用(呼应第 14 章工具增强:Skill 是工具的超集)。
19.4 完整实战:从 0 封装一个「客户画像 Skill」
用一个贯穿性的例子,把 19.1-19.3 的知识串起来:封装"客户画像"Skill------它是客服、销售、运营三个 Agent 都要用的能力。
19.4.1 需求定义
text
场景:三个 Agent 都需要"输入客户 ID → 输出结构化客户画像"
- 客服 Agent:查客户偏好辅助回复
- 销售 Agent:查客户购买力辅助话术
- 运营 Agent:查客户活跃度辅助关怀
共性:都要调用 3 个数据源,组装成统一画像
判断:同一流程出现 3 次(满足"三次法则")→ 值得封装 Skill。
19.4.2 Skill 实现(四部分结构)
python
import json, time
class CustomerProfileSkill:
"""客户画像 Skill:输入客户ID,输出结构化画像。"""
VERSION = "1.2.0" # 元信息:版本
NAME = "customer_profile" # 元信息:名称
DESCRIPTION = ( # 元信息:何时用/何时不用
"生成客户画像(偏好/购买力/活跃度)。"
"当需要个性化回复、推荐、关怀时使用;"
"仅查询不修改数据。"
)
REQUIRES_TOOLS = [ # 依赖:所需工具
"query_customer_base", # 客户基础信息
"query_purchase_history", # 购买历史
"query_interaction_log", # 交互记录
]
def __init__(self, tool_registry):
self.tools = tool_registry # 注入工具注册表
def run(self, customer_id: str) -> dict:
"""执行流程:并行拉 3 个数据源 → 组装画像(第12章并行)"""
start = time.time()
try:
base = self.tools.call("query_customer_base", {"id": customer_id})
history = self.tools.call("query_purchase_history", {"id": customer_id})
logs = self.tools.call("query_interaction_log", {"id": customer_id})
except ToolError as e:
return {"error": str(e), "trace": {"latency_ms": ...}} # 错误可感知
# 组装(结构化输出契约)
profile = {
"customer_id": customer_id,
"preferences": extract_prefs(history, logs), # 偏好
"purchase_power": calc_power(history), # 购买力
"activity": calc_activity(logs), # 活跃度
"updated_at": time.strftime("%Y-%m-%d"),
}
return profile
# 输出契约(供下游 Agent 消费)
OUTPUT_SCHEMA = {
"customer_id": "string",
"preferences": "list[string]",
"purchase_power": "low|medium|high",
"activity": "active|normal|inactive",
"updated_at": "date",
}
这个实现体现了 Skill 四部分的完整落地:元信息(NAME/DESCRIPTION/VERSION)、依赖(REQUIRES_TOOLS)、执行逻辑(run 方法)、输出契约(OUTPUT_SCHEMA)。
19.4.3 三个 Agent 的复用(显式编排)
python
# 客服 Agent 使用
def support_agent_reply(customer_id, question):
profile = skills.get("customer_profile").run(customer_id) # 复用
return llm.chat(f"客户画像:{profile}\n问题:{question}")
# 销售 Agent 使用(同样一行)
def sales_agent_talk(customer_id):
profile = skills.get("customer_profile").run(customer_id)
return llm.chat(f"客户画像:{profile},生成跟进话术")
# 运营 Agent 使用
def ops_agent_care(customer_id):
profile = skills.get("customer_profile").run(customer_id)
if profile["activity"] == "inactive":
return send_care_message(customer_id)
return None
复用收益:画像逻辑改一次(比如新增一个数据源),三个 Agent 全部生效------这就是 Skill 的核心价值。
19.4.4 升级 Skill 的正确姿势(版本管理实践)
假设要新增"客户风险标签"字段(破坏性变更,因为输出契约变了):
text
1. 新建 v2.0.0(输出契约加 risk 字段)
2. 老 Agent 继续用 v1.2.0(不强制迁移)
3. 新 Agent 用 v2.0.0
4. 灰度验证 v2 输出正确性 → 逐个迁移老 Agent
5. 全部迁移后下线 v1(或保留兼容层)
关键:破坏性变更不强制下游立刻升级,而是"新旧并行 + 逐个迁移"(呼应第 20 章灰度、第 24 章 G4 版本化)。
🛠 解决方案:Skill 复用度评估与过度抽象治理
常见问题
- "Skill 没人用,白封装了" :Skill 设计脱离真实需求。对策:先有 2~3 个真实使用方再封装------"三次法则":重复出现 3 次才值得抽 Skill。
- "过度抽象,为了复用而复用":把只出现 1 次的东西也封装了,反而增加复杂度。对策:复用度评估(见速查表),低复用不封装。
- "Skill 改坏了,下游全崩":无版本管理 + 无灰度。对策:版本化 + 破坏性变更灰度切换(19.2.3)。
- "Skill 依赖一团乱":循环依赖/依赖不明。对策:依赖显式声明 + 依赖图检查(防循环)。
- "Skill 和工具职责不清":把单动作封装成 Skill(过度)、或把流程硬塞进工具(不足)。对策:单动作用工具,多步流程才用 Skill(19.1.3 粒度对照)。
解决方案速查表
| 现象 | 根因 | 解决方案 |
|---|---|---|
| Skill 没人用 | 脱离需求 | 三次法则再封装 |
| 过度抽象 | 为复用而复用 | 复用度评估 |
| 改坏下游 | 无版本控制 | 版本化 + 灰度 |
| 依赖混乱 | 声明不清 | 显式声明 + 防循环 |
| 职责不清 | 粒度错位 | 单动作→工具,流程→Skill |
实战提示
- 三次法则:同一流程出现 3 次才封装 Skill,别第 1 次就抽。
- Skill 是"装配好的部件":工具是零件,Skill 是 SOP------粒度别搞反。
- 版本化是底线:Skill 改了会波及所有使用者,版本 + 灰度缺一不可。
- 描述决定复用率:描述写清楚"何时用",模型和同事才知道什么时候该用它。
- 注册表是能力资产:维护 Skill 目录,让能力可见、可治理、可复用。