Skills解析

Skills解析
mengnankkzhou待思考:
- 什么是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 的好处:
- 高内聚低耦合:将 AI 逻辑和业务代码绑定在一起,方便维护和版本控制。
- 可复用性:一个写好的“日历管理 Skill”,可以直接跨项目拔插使用。
- 安全与隔离:可以对特定的 Skill 设置不同的权限边界(例如“转账 Skill”必须要求人类确认)。
三、 渐进式披露(Progressive Disclosure)在 Skills 上的体现与好处
渐进式披露是 UX 设计中的概念,在 AI 架构中,它意味着:不要一次性把所有的能力、工具和背景知识都塞给 LLM。
- 体现方式: 系统启动时,大模型的 System Prompt 里只有一个“路由/规划器(Router/Planner)”的描述和各 Skill 的摘要描述。当用户提出需求时,路由层先判断需要用到哪个 Skill,然后再将该 Skill 内部详细的提示词和具体工具动态加载到当前对话上下文中。
- 好处:
- 节省 Token 与成本:不需要每次对话都携带几万字的工具说明。
- 提升准确度(降低幻觉):LLM 的注意力机制(Attention)是有上限的。给的工具越多,它越容易“迷失”或调用错工具。只给它当前必需的 Skill,能极大提升决策的精准度。
- 突破上下文窗口限制:让你的系统理论上可以拥有无限个 Skills。
四、 如何确定一个东西可以作为一个 Skill?(拆分原则)
拆分 Skill 应该遵循软件工程中的单一职责原则(SRP)。你可以通过以下几个标准来判断:
- 领域边界(Domain Boundary):它是否属于同一个业务领域?例如:“查询天气”和“发邮件”属于不同领域,应拆分为
WeatherSkill和EmailSkill。 - 生命周期:如果某几个功能的输入/输出总是强关联,经常一起修改,那就放在一个 Skill 里。
- 复用概率:这个功能是否会在不同的场景下被调用?如果是,它就值得被独立成一个 Skill。
举个反例: 不要建一个叫做 DailyWorkSkill 的大杂烩,里面既有写周报,又有定外卖。 正例: 拆分为 ReportGenerationSkill(专精文本总结)和 FoodDeliverySkill(专精 API 调用和订单状态获取)。
五、 提示词命中了多个 Skills 怎么处理?
当用户的请求很复杂(例如:“帮我查一下明天的天气,然后给团队发一封邮件安排会议”)命中多个 Skills 时,通常有以下几种处理机制:
-
做法 1:选主 Skill(Most Specific Wins)
当多个命中时,按以下顺序择优:
- 更具体的(范围更窄、约束更强)优先
- 置信度更高的(router score 更高)优先
- 更新版本更高的(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 绑定的工具怎么按需加载?
这是实现“渐进式披露”的核心工程难点,通常的做法是建立工具注册表与向量检索:
- 构建 MetaData(元数据)注册表: 每个 Skill 及其包含的工具,在系统中注册时不仅要注册代码,还要提供一份 JSON Schema(包含工具名、描述、入参说明)。
- 两阶段检索/按需注入(Lazy Loading):
- 阶段一(路由):用户的 Query 进来后,系统使用轻量级模型或向量数据库(RAG 思想),将 Query 与所有 Skill 的“描述”进行匹配(例如 Top-K 检索),找出最相关的 1-2 个 Skill。
- 阶段二(组装):提取出这两个命中 Skill 所绑定的工具的 JSON Schema,将它们动态拼接到本次请求大模型的
tools或functions参数中。
- 上下文释放:任务执行完毕后,这些被临时加载的工具定义从上下文历史中剔除,保持上下文干净。





