Skill 设计与开发指南:Agent 的可复用能力单元

2026-06-10SkillAgent设计模式

什么是 Skill

Skill 是 Agent 系统中的可复用业务能力单元。它不是简单的工具函数,而是封装了完整业务逻辑、Prompt 模板、工具调用链、错误处理的独立模块。一个 Skill 通常包含:SKILL.md(指令描述)+ 脚本/工具链 + 状态管理。

Skill vs Tool vs Plugin

维度Tool(工具)Skill(技能)Plugin(插件)
粒度单一函数调用多步骤业务流程外部系统集成
示例get_weather()旅行规划、文档生成Slack集成、GitHub连接
状态无状态有状态(Skill内上下文)视实现而定
编排由Agent直接调用有自己的编排逻辑由框架管理
复用性跨项目跨场景跨系统

Skill 的核心组成

my-skill/
├── SKILL.md           # Skill 描述:能力边界、触发条件、使用说明
├── skill.py           # 核心逻辑:编排、工具调用、错误处理
├── prompts/           # Prompt 模板
│   ├── system.md
│   └── examples.md
├── tools/             # Skill 专属工具
│   └── api_client.py
└── config.yaml        # 配置:模型、超时、降级策略

SKILL.md 的写法

SKILL.md 是 Skill 的"说明书",Agent 通过它理解 Skill 的能力和触发条件:

# 旅行规划 Skill

## 触发条件
用户表达旅行意图时触发(关键词:旅行、旅游、出行、攻略)

## 能力边界
- ✅ 能做的:热门目的地推荐、行程规划、景点查询
- ❌ 不能做的:实际预订、支付、签证办理

## 输入要求
- 目的地(必填)
- 天数(可选,默认3天)
- 偏好(可选:美食/文化/自然)

## 输出格式
按天分段的结构化行程 + 景点简介 + 交通建议

## 降级策略
高德API不可用时 → 使用预置热门目的地数据

Skill 的设计原则

  1. 单一职责:一个 Skill 只做一件事,做透彻。不要做"万能 Skill"
  2. 显式边界:明确声明能力范围和不能做的事,避免 Agent 滥用
  3. 自描述:通过 SKILL.md 让 Agent 自动理解用法,无需硬编码路由
  4. 可降级:外部依赖失败时有备选方案,不阻断整体流程
  5. 可观测:记录每次调用的输入、输出、耗时、错误
  6. 可测试:每个 Skill 可以独立测试,不依赖完整的 Agent 系统

Skill 的注册与路由

Agent 发现和调用 Skill 有两种主流方式:

方式一:SKILL.md 注入 Prompt

将所有已注册 Skill 的 SKILL.md 内容注入 System Prompt,Agent 通过 Function Calling 决定调用哪个 Skill。适合 Skill 数量少(<10)的场景。

# System Prompt 片段
## 可用技能
${skills.map(s => s.mdContent).join('\n---\n')}

当用户需求匹配某技能时,调用 activate_skill(skill_name, params)

方式二:Router + Orchestrator 路由

一个轻量 Router 根据用户意图匹配 Skill,Orchestrator 管理 Skill 的生命周期。适合 Skill 数量多(10+)的生产环境。

# 意图路由
intent = router.classify(user_message)
if intent == "travel":
    skill = skills["travel-planner"]
elif intent == "document":
    skill = skills["docx-writer"]
result = orchestrator.run(skill, user_message, context)

Skill 的状态管理

Skill 可能需要维护调用间的状态:

  • 无状态 Skill:每次调用独立,如天气查询、翻译
  • 会话级状态:在一次对话中保持上下文,如旅行规划的中间步骤
  • 持久化状态:跨会话保持数据,如用户偏好、历史记录
class TravelSkill:
    def __init__(self):
        self.sessions = {}  # session_id → 行程草稿

    async def run(self, session_id, input):
        if session_id not in self.sessions:
            self.sessions[session_id] = {"draft": None}
        # 使用和更新 session state

Skill 开发的常见问题

问题一:Skill 之间互相调用导致循环

解决方案:禁止 Skill 间直接调用,统一由 Orchestrator 编排;或者限制最大调用深度(≤3层)。

问题二:SKILL.md 过长导致 Token 浪费

解决方案:SKILL.md 只写摘要(≤500 tokens),完整文档放独立文件,Agent 需要时再动态加载。

问题三:Skill 返回结果不可控

解决方案:定义标准输出 Schema,Skill 的所有返回值必须符合 Schema,加入输出校验层。

问题四:多个 Skill 的 Prompt 冲突

解决方案:Skill 的 System Prompt 用分隔符隔离;设置优先级,高优先级 Skill 的 Prompt 不被覆盖。

未标记