Skill:Agent 的能力扩展系统

24 阅读6分钟

Skill:Agent 的能力扩展系统

一、Skill 的定义

Skill(技能) 是一种模块化的、自包含的能力扩展包,它为 AI Agent 注入特定领域的专业知识、工作流程和工具资源——它让一个通用型 Agent 转变为具备特定专业能力的领域专家。

Skill 能做什么

维度说明示例
专业工作流多步骤的领域特定操作流程创建 PowerPoint 的标准步骤、PDF 表单填写流程
工具集成与特定文件格式或 API 的交互规范DOCX 的 OpenXML 操作、PDF 的文本提取方法
领域知识Agent 本身不具备的专有知识公司内部业务规则、数据库 Schema、API 规范
复用资源避免重复编写相同代码或重复查找文档PDF 旋转脚本、React 项目模板、品牌 Logo

二、Skill 的组成结构

每个 Skill 是一个独立目录,包含一个必需的元数据文件和三类可选资源:

skill-name/
├── SKILL.md              # 必需:元数据 + 使用指令
├── scripts/              # 可选:可执行脚本
├── references/           # 可选:参考文档
└── assets/               # 可选:模板与素材资源

各组件说明

组件必需内容加载时机
SKILL.mdYAML 元数据(namedescription)+ Markdown 指令Skill 激活后加载
scripts/Python、Bash 等可执行脚本Agent 按需执行
references/API 文档、数据模式、策略规范等Agent 按需读取
assets/模板、图片、字体、代码脚手架等直接用于产出物

三、Skill 的工作原理:渐进式披露

Skill 采用 Progressive Disclosure(渐进式披露) 设计,通过三层加载机制高效管理上下文窗口:

┌──────────────────────────────────────────────────────────────┐
│  Level 1:Metadata(元数据)                                  │
│  内容:name + description(约 50-100 词)                      │
│  加载:Agent 初始化时注入,始终常驻上下文                       │
│  作用:告知 Agent"有哪些 Skill、各自能做什么"                  │
└──────────────────────────────┬───────────────────────────────┘
                               │ 用户请求到达,进行匹配判断
                               ▼
┌──────────────────────────────────────────────────────────────┐
│  Level 2:Body(主体指令)                                    │
│  内容:SKILL.md 的 Markdown 部分(工作流程、使用指南)          │
│  加载:Skill 被判定"激活"后,才加载到上下文                     │
│  作用:指导 Agent 如何执行具体任务                              │
└──────────────────────────────┬───────────────────────────────┘
                               │ Agent 执行过程中按需使用
                               ▼
┌──────────────────────────────────────────────────────────────┐
│  Level 3:Bundled Resources(捆绑资源)                       │
│  内容:scripts / references / assets                          │
│  加载:Agent 根据任务需要,选择性读取或执行                      │
│  作用:提供具体的工具、知识和素材(无大小限制)                  │
└──────────────────────────────────────────────────────────────┘

核心设计要点

  • 未激活 Skill 的 L2/L3 永远不会进入上下文窗口
  • description 是唯一的匹配依据,其质量直接决定激活准确率
  • L3 的脚本可在不加载到上下文的情况下直接执行,效率极高

四、Skill 的激活机制:语义匹配

当用户请求到达时,Agent 需要将请求意图与各个 Skill 的 description 进行匹配,决定是否激活。这是 Skill 系统的核心路由环节。

4.1 匹配的维度

Agent 从三个维度判断 Skill 是否应该激活:

维度判断依据示例
功能域匹配用户请求是否涉及 description 描述的功能范围用户说"做 PPT"匹配 pptx skill
任务类型匹配是否是 description 中明确列出的任务类型"添加批注"匹配 docx skill 的"添加 comments"
上下文匹配当前对话上下文是否需要该 Skill 的专业能力上传了 .xlsx 文件后,用户说"分析数据"匹配 xlsx skill

4.2 语义匹配的实现方案

方案一:基于 LLM 的意图路由

将 Skill 列表和用户请求输入 LLM,由模型判断激活哪些 Skill。

【系统提示词】
你是 Skill Router。可用技能如下:

1. pptx: 处理 PowerPoint 演示文稿(.pptx),包括创建、编辑、
   重新设计、格式化、美化,以及将其他格式转换为 PPT
2. xlsx: 处理 Excel 电子表格,包括数据分析、公式计算、
   图表生成、格式设置
3. pdf: 处理 PDF 文档,包括创建、编辑、文本提取、表单填写

用户请求: {user_input}
请判断应激活哪些技能,返回 JSON:
{
  "activated_skills": ["skill-name"],
  "confidence": 0.95,
  "reason": "用户明确要求创建PPT演示文稿"
}
优点缺点
理解能力强,能处理复杂、模糊、间接的表达增加一次 LLM 调用,有延迟
可天然支持多 Skill 激活判断成本较高
能通过 few-shot 提升准确率需要精心设计 prompt
方案二:Embedding 相似度匹配

预计算 Skill description 的向量,通过余弦相似度快速匹配。

def route_by_embedding(user_query, skills, threshold=0.75):
    """基于 Embedding 的 Skill 路由"""
    import numpy as np
    from sentence_transformers import SentenceTransformer
    
    model = SentenceTransformer('all-MiniLM-L6-v2')
    
    # 预计算 Skill description 向量(可缓存)
    skill_embeddings = {
        skill.name: model.encode(skill.description) 
        for skill in skills
    }
    
    # 用户请求向量化
    query_vec = model.encode(user_query)
    
    # 计算相似度,召回 Top-K
    results = []
    for name, emb in skill_embeddings.items():
        sim = cosine_similarity(query_vec, emb)
        if sim > threshold:
            results.append((name, sim))
    
    return sorted(results, key=lambda x: x[1], reverse=True)
优点缺点
计算极快(毫秒级),无 LLM 调用开销对否定句、条件句理解有限
成本低,适合高频场景难以处理需要推理的复杂匹配
可预计算缓存需要维护向量数据库
方案三:混合路由策略(推荐)

结合规则、Embedding 和 LLM 三层,兼顾速度与精度。

def hybrid_route(user_query, file_ext=None, skills=None):
    """
    三层混合路由策略
    Layer 1: 规则匹配(最快)
    Layer 2: Embedding 相似度(快速召回)
    Layer 3: LLM 判断(兜底)
    """
    activated = []
    
    # ========== Layer 1: 规则匹配 ==========
    if file_ext == ".pptx":
        return ["pptx"]          # 文件类型明确,直接路由
    if file_ext == ".xlsx":
        return ["xlsx"]
    
    # 关键词硬规则
    if any(kw in user_query for kw in ["幻灯片", "演示文稿", "PPT"]):
        return ["pptx"]
    
    # ========== Layer 2: Embedding 召回 ==========
    candidates = route_by_embedding(user_query, skills, threshold=0.70)
    if candidates and candidates[0][1] > 0.85:
        return [name for name, _ in candidates[:2]]
    
    # ========== Layer 3: LLM 兜底 ==========
    return llm_route(user_query, skills)

三层架构图

用户请求 + 文件扩展名
        
        
┌──────────────────┐
 Layer 1: 规则匹配   ◄── 文件后缀、明确关键词、硬规则
 延迟:< 1ms        
└────┬───────────┬─┘
     │匹配成功   │未匹配
                
  直接返回  ┌──────────────────┐
             Layer 2: Embedding│ ◄── 向量相似度计算,Top-K 召回
             延迟:1-10ms      
            └────┬──────────┬──┘
                 │高置信度   │低置信度
                            
              返回结果  ┌──────────────────┐
                         Layer 3: LLM 判断  ◄── 复杂语义理解
                         延迟:100-500ms   
                        └────────┬─────────┘
                                 
                              返回结果

4.3 多 Skill 协作

复杂任务可能需要多个 Skill 按序协作:

{
  "primary_skill": "pptx",
  "supporting_skills": ["xlsx", "pdf"],
  "execution_order": ["xlsx", "pdf", "pptx"],
  "reason": "需先从 Excel 提取数据,再参考 PDF 报告,最终生成 PPT 汇报"
}

典型协作场景

用户请求激活 Skill协作顺序
"把 Excel 数据做成 PPT"xlsxpptx先读取数据,再生成幻灯片
"分析 PDF 里的表格并导出 Excel"pdfxlsx先提取内容,再结构化输出
"基于数据库生成 Word 报告"backend-buildingdocx先查询数据,再生成文档

关键设计哲学

  • 上下文是稀缺资源:未激活的 Skill 不占空间
  • 描述是匹配的唯一入口:写好 description 至关重要
  • 按需加载是无上限的:再长的参考资料、再复杂的脚本都不影响上下文
  • 渐进式披露保护性能:大多数请求在 L1/L2 就能解决,极少走到 L3