如何准确地调用 Skills?
Skills 越来越多以后,最容易犯的错误,是把“如何准确调用”理解成“如何记住所有名称”。但当你已经有 A、B、C、D 四个 Skills 时,真正的问题不是记忆,而是路由:面对一句自然语言需求,如何识别它包含哪些任务,如何判断每个任务需要什么能力,以及如何确认没有遗漏。
这篇文章给出一套适合个人知识库和 Agent 工作流的调用方法。核心原则只有一句话:不要让模型直接从一句话跳到一个 Skill,而要让它经过“意图拆解—候选召回—覆盖检查—执行复盘”的路由层。
一、为什么“一个需求对应一个 Skill”经常不准确
用户说的通常是结果,不是步骤。例如:
把这篇公众号文章整理成一篇可以发布的文章。
这句话至少可能包含以下任务:获取原文、提取正文、整理结构、核对来源、改写表达、生成发布稿。若只根据“文章”或“公众号”命中一个 Skill,常见结果有两种:
- 只完成了内容抓取,却没有完成整理和改写;
- 误调用了发布类 Skill,在用户只是要求“准备稿件”时产生了外部操作。
因此,准确调用不是找一个最像的名称,而是把结果拆成一组可检查的原子任务。
二、准确调用 Skills 的五步路由
1. 先识别意图,不急着匹配名称
先从需求中提取五个要素:
- 目标:最终想得到什么结果;
- 输入:文章、网页、文件、数据,还是一段想法;
- 输出:笔记、报告、图片、代码、发布稿或外部动作;
- 约束:风格、格式、范围、时效和隐私要求;
- 副作用:是否允许发送、发布、修改原文件或调用外部服务。
“整理成可发布文章”和“直接发布到公众号”只有几个字的差别,但它们的副作用完全不同,不能被视为同一个意图。
2. 按原子任务召回候选 Skills
不要只为整句话找一个 Skill,而要为每个原子任务分别找候选能力。候选召回可以同时参考:
- Skill 的 description 和适用场景;
- 用户常用别名、中文叫法和口语表达;
- 输入类型与目标输出;
- 过去已经验证过的相似案例;
- 当前是否启用,以及是否具备所需工具和权限。
名称只是内部标识。对用户而言,article-extractor、内容提取、把网页正文拿出来可能是同一个意图入口。
3. 明确标记“必需、条件、排除”
候选列表不能只写“要调用什么”,还要写“为什么不调用其他能力”。建议把每个候选放入三类:
| 类别 | 含义 | 示例 |
|---|---|---|
| 必需 | 没有它,目标就无法完整交付 | 提取原文、整理结构 |
| 条件 | 只有出现特定条件时才调用 | 需要配图时调用图片 Skill |
| 排除 | 当前请求明确不需要,或有不应产生的副作用 | 未获授权时不发布、不发送 |
以 A、B、C、D 四个 Skills 为例,“把公众号文章整理成可发布版本”可以形成这样的调用清单:
| Skill | 任务 | 决策 |
|---|---|---|
| A | 获取并提取文章内容 | 必需 |
| B | 将内容整理成文章结构 | 必需 |
| C | 按指定风格改写和校对 | 必需或条件,取决于用户是否要求改写 |
| D | 发布到外部平台 | 排除,除非用户明确授权发布 |
这样即使最后只执行 A、B、C,也能说明 D 是经过判断后不调用的,而不是被遗忘了。
4. 执行前做一次覆盖检查
真正开始工作前,先生成一份很短的调用清单,至少包括:
我的理解:把已有文章加工成可发布稿,不执行外部发布。
调用顺序:
1. A:提取原文
2. B:整理结构
3. C:按目标风格改写并校对
明确不调用:
- D:当前没有发布授权
覆盖检查:
- 输入获取:已覆盖
- 内容加工:已覆盖
- 风格要求:已覆盖
- 发布动作:有意排除
- 未覆盖能力:无;若需要配图或事实核查,另行确认这一步是减少遗漏的关键。只要还有一个原子任务处于“没有候选 Skill”的状态,就应该把它标记出来,而不是假装整个需求已经覆盖。
5. 完成后复盘,但不要把每次调用都改成新规则
执行结束后检查四件事:
- 每个必需任务是否真的完成;
- 是否调用了不必要或越权的 Skill;
- 用户是否补充了原本没有识别出的意图;
- 这次经验是否值得成为以后稳定适用的路由规则。
前两项是本次任务的质量检查,最后一项才是 Skills 系统的长期学习。
三、如何让意图识别越来越精准
每个 Skill 的路由档案,不能只写一句“这是做什么的”。至少应该有以下字段:
display_title:给人看的清晰名称;aliases:中文名、英文名、简称和用户口语;when:哪些目标、输入和输出会触发它;avoid:哪些相似场景不应该触发它;prerequisites:需要的文件类型、工具、权限或前置步骤;outputs:它实际产生什么结果;order:在常见流程中位于前置、处理中间还是收尾;risk:是否会修改文件、发送信息或产生外部副作用;confidence:当前路由判断的可信度;source:这条规则来自官方说明、用户指定,还是已验证案例。
其中最重要的是正向和反向边界。只有“什么时候用”,没有“什么时候不要用”,相似 Skills 就容易互相抢占;只有别名,没有输入输出和副作用,模型仍然难以判断调用顺序。
当两个候选都可能适用时,不必为了追求表面上的确定而强行选择。应当比较“哪个选择会改变最终结果”,只有会改变路由、权限或交付格式的歧义,才值得向用户提问。
四、intent-overrides.json 应该记录什么
intent-overrides.json 可以作为稳定的人工路由覆盖层,但不适合充当每次调用的流水账,也不应该每运行一次就自动追加一条模糊经验。建议把信息分成四层:
skill-usage-log.jsonl 每一次调用的事实记录
skill-cases/ 经过整理的成功、遗漏和误调用案例
skill-routes.json 普通场景下稳定、可复用的路由规则
intent-overrides.json 用户明确指定的例外和优先级覆盖例如,用户明确说“以后只要说整理文章,就先提取正文,再按我的写作风格改写”,这才适合进入稳定路由或人工覆盖。一次偶然的调用,最多先进入使用日志;如果后续出现两三次相似且结果良好的案例,再考虑把它晋升为通用规则。
可以遵循三个晋升条件:
- 用户明确表达长期偏好,例如“以后都这样”;
- 相似场景重复出现,且路由结果被验证为正确;
- 发生了明确的遗漏或误调用,需要增加触发词、排除条件或优先级。
这样做的目的,是避免规则文件越积越厚,最后把偶然上下文误当成普遍规律。
五、怎样验证“没有遗漏”
不要只测试一个成功例子。每个重要路由至少准备三类案例:
- 正向案例:应该调用这个 Skill 的典型说法;
- 近邻案例:看起来相似,但应该调用另一个 Skill 的说法;
- 排除案例:明确不允许产生某种副作用的说法。
验证时关注四个指标:
- 召回:应该用的 Skill 有没有进入候选集;
- 精度:不该用的 Skill 有没有被误选;
- 覆盖:所有必需原子任务有没有明确归属;
- 可审计:能不能解释为什么调用、为什么不调用,以及规则从哪里来。
如果系统不能保证百分之百正确,至少要保证不把不确定性藏起来:显示当前解释、调用清单、排除项和未覆盖项。可见的“不确定”,比无提示的漏调用更容易修正。
六、适合个人 Skills 库的最小落地方式
不必一开始就重做所有 Skills,也不必先记住它们的名字。可以按以下顺序建立路由层:
- 先保留现有 Skills 及其原始说明,避免因为批量改名破坏依赖;
- 建立一个统一目录,登记每个 Skill 的功能、别名、边界和风险;
- 为高频工作流建立场景预设,例如“文章整理”“知识归档”“图像制作”“发布前校对”;
- 每次执行都生成简短调用清单和使用日志;
- 定期把经过验证的案例晋升为路由规则,把失败案例转化为反向触发条件;
- 当一个 Skill 长期没有独立价值,或与另一个 Skill 边界重叠,再考虑合并或停用。
最终形成的不是一张让人死记硬背的 Skills 名单,而是一层能够把自然语言需求连接到能力集合的“意图路由层”。
结语
准确调用 Skills 的关键,不是让用户承担更多记忆负担,而是让系统承担更多识别、拆解、解释和复盘工作。面对简单需求,系统要主动问自己:这句话包含哪些原子任务?哪些能力是必需的?哪些只是条件调用?哪些动作必须排除?还有什么没有被覆盖?
只要每次调用前有覆盖检查,调用后有结果复盘,稳定规则和运行记录分开维护,Skills 越多并不必然让系统越混乱。它反而可以逐渐从“靠名称搜索”变成“按意图路由”。