Skills解析

待思考:

  • 什么是Skills?
  • 他的好处?为什么这么设计?跟我们直接将提示词按文件划分有什么区别
  • 渐进式披露在skills上怎么体现的,有什么好处?
  • skills的拆分,我如何确定一个东西可以作为一个skills
  • 然后我提示词命中了多个skills怎么处理?
  • 跟skills绑定的工具我怎么处理?怎么去按需加载

1.什么是skills?

在 AI 架构(特别是类似 Semantic Kernel 或各类 Agent 框架)中,Skill(技能/插件)是一个封装了特定领域能力的独立模块。它不仅仅是一段提示词,它是**“意图(Prompt)+ 动作(代码/工具/API)+ 数据结构(输入/输出 schema)”**的集合体。

一个比较完整的 Skill 往往包含:

  • 意图描述:它解决什么问题(适用范围),不解决什么(边界)
  • 触发信号:什么样的用户请求应该命中它(关键词/语义/结构)
  • 工作流程:步骤化 SOP(先做什么、再做什么、失败怎么办)
  • 输入输出契约:需要哪些输入、输出长什么样(模板/字段/格式)
  • 工具策略:需要哪些工具、何时用、参数怎么填、如何校验结果
  • 质量控制:检查清单(自检点)、常见坑、回退策略
  • 示例/测试用例:几条典型输入 -> 期望输出(用于回归)

可以把它理解为 AI 的“手脚”和“特定领域的专业知识库”。

二 为什么这么设计?与“直接将提示词按文件划分”有何区别?

将提示词按文件划分只是文本层面的管理,而 Skill 是工程层面的封装

维度 直接将提示词按文件划分 Skills(技能化设计)
本质 静态的字符串模板。 可执行的软件模块(包含提示词、API、参数校验)。
执行能力 只能生成文本,无法直接改变外部世界。 可以调用原生代码(Native Functions)执行动作(如发邮件、查库)。
上下文感知 需要开发者手动组装历史记录和变量。 自带上下文管理和状态流转(Context Variables)。
互操作性 提示词之间孤立,难以互相调用。 Skill 之间可以像函数一样互相调用、组合、编排。

设计成 Skill 的好处:

  1. 高内聚低耦合:将 AI 逻辑和业务代码绑定在一起,方便维护和版本控制。
  2. 可复用性:一个写好的“日历管理 Skill”,可以直接跨项目拔插使用。
  3. 安全与隔离:可以对特定的 Skill 设置不同的权限边界(例如“转账 Skill”必须要求人类确认)。

三、 渐进式披露(Progressive Disclosure)在 Skills 上的体现与好处

渐进式披露是 UX 设计中的概念,在 AI 架构中,它意味着:不要一次性把所有的能力、工具和背景知识都塞给 LLM。

  • 体现方式: 系统启动时,大模型的 System Prompt 里只有一个“路由/规划器(Router/Planner)”的描述和各 Skill 的摘要描述。当用户提出需求时,路由层先判断需要用到哪个 Skill,然后再将该 Skill 内部详细的提示词和具体工具动态加载到当前对话上下文中。
  • 好处:
    1. 节省 Token 与成本:不需要每次对话都携带几万字的工具说明。
    2. 提升准确度(降低幻觉):LLM 的注意力机制(Attention)是有上限的。给的工具越多,它越容易“迷失”或调用错工具。只给它当前必需的 Skill,能极大提升决策的精准度。
    3. 突破上下文窗口限制:让你的系统理论上可以拥有无限个 Skills。

四、 如何确定一个东西可以作为一个 Skill?(拆分原则)

拆分 Skill 应该遵循软件工程中的单一职责原则(SRP)。你可以通过以下几个标准来判断:

  1. 领域边界(Domain Boundary):它是否属于同一个业务领域?例如:“查询天气”和“发邮件”属于不同领域,应拆分为 WeatherSkillEmailSkill
  2. 生命周期:如果某几个功能的输入/输出总是强关联,经常一起修改,那就放在一个 Skill 里。
  3. 复用概率:这个功能是否会在不同的场景下被调用?如果是,它就值得被独立成一个 Skill。

举个反例: 不要建一个叫做 DailyWorkSkill 的大杂烩,里面既有写周报,又有定外卖。 正例: 拆分为 ReportGenerationSkill(专精文本总结)和 FoodDeliverySkill(专精 API 调用和订单状态获取)。

五、 提示词命中了多个 Skills 怎么处理?

当用户的请求很复杂(例如:“帮我查一下明天的天气,然后给团队发一封邮件安排会议”)命中多个 Skills 时,通常有以下几种处理机制:

  1. 做法 1:选主 Skill(Most Specific Wins)

    当多个命中时,按以下顺序择优:

    1. 更具体的(范围更窄、约束更强)优先
    2. 置信度更高的(router score 更高)优先
    3. 更新版本更高的(v2 > v1)优先(如果你有版本体系)

    适用:大多数单意图任务(“帮我把这个表格做成图”)

    做法 2:Skill 组合(Primary + Secondary)

    把命中的 skills 分成:

    • Primary(主技能):决定整体输出目标与结构
    • Secondary(辅技能):提供某些子步骤的 SOP 或格式要求

    例子:
    “把会议纪要整理成一页 PDF 并加上公司抬头”

    • 主:会议纪要整理 skill(决定内容结构)
    • 辅:PDF 生成 skill(决定如何落盘与版式)

    关键点是:要有冲突解决规则,比如:

    • 输出格式冲突:以主 skill 为准
    • 工具使用冲突:以最小权限/最少工具为准
    • 风格冲突:以全局风格层 > 主 skill > 辅 skill

    做法 3:上层工作流 Skill(Orchestrator / Workflow Skill)

    当用户请求本身就是多步骤、多产物:
    “分析数据 -> 写结论 -> 生成图表 -> 做 PPT -> 发邮件”

    这时不要让多个技能平铺注入然后打架,而是:

    • 用一个“工作流 skill”先产出计划(plan)
    • 每一步调用一个子 skill(像函数调用一样)
    • 每一步结束做校验,再进入下一步

六、 与 Skills 绑定的工具怎么按需加载?

这是实现“渐进式披露”的核心工程难点,通常的做法是建立工具注册表与向量检索

  1. 构建 MetaData(元数据)注册表: 每个 Skill 及其包含的工具,在系统中注册时不仅要注册代码,还要提供一份 JSON Schema(包含工具名、描述、入参说明)。
  2. 两阶段检索/按需注入(Lazy Loading)
    • 阶段一(路由):用户的 Query 进来后,系统使用轻量级模型或向量数据库(RAG 思想),将 Query 与所有 Skill 的“描述”进行匹配(例如 Top-K 检索),找出最相关的 1-2 个 Skill。
    • 阶段二(组装):提取出这两个命中 Skill 所绑定的工具的 JSON Schema,将它们动态拼接到本次请求大模型的 toolsfunctions 参数中。
  3. 上下文释放:任务执行完毕后,这些被临时加载的工具定义从上下文历史中剔除,保持上下文干净。