Skill渐进式披露指南

手写 SKILL 加载:搞懂技能包的渐进式披露

把"技能"做成目录形态的说明书(SKILL.md + 脚本 + 扩展资料),Agent 启动时只注册一句话描述,命中后才装载全文,脚本由子进程执行------让模型用已有的工具循环按需获取知识,全程零框架。

写作目的:吃透 SKILL 与 Agent 的配合机制------SKILL 不是新的执行通道,而是一份"按需注入的任务说明书"。看懂渐进式披露,就理解了 Cursor、Qoder 这类产品里技能体系的底层逻辑。

一、为什么需要 SKILL:工具解决"能做什么",不解决"怎么编排"

从 Agent 架构看,工具(OpenAI tools 协议 / MCP)解决的是原子能力的接入:查天气、读网页、查待办,每个工具一份 JSON Schema 声明,模型决定调用、Agent 本地执行、结果回写。但有两类问题是工具层天然承载不了的:

  • 编排经验无处沉淀。"出差前先看天气和当地新闻,再根据温度给穿衣建议"------这类"多个工具怎么组合着用"的流程知识,写不进工具声明,只能塞进 system prompt。场景一多,system prompt 变成大杂烩,每轮请求还全量消耗 token。
  • 确定性逻辑不该交给模型推理。"12°C 穿外套、29°C 穿短袖并带伞"这种规则判断,小模型"凭感觉"输出不稳定;"早报固定排版"这种格式约束,写进提示词模型也会偶尔走样。它们本质是代码,不是提示词。

SKILL(技能包)就是为此而生:把流程知识(提示词形态)与确定性逻辑(脚本形态)打包成目录,按需装载进上下文,执行仍复用 Agent 已有的工具。它在整个 Agent 技术栈里居于应用层:

  • 协议层:模型如何调工具------OpenAI tools 协议,事实标准
  • 接入层:工具从哪来------MCP,标准化的工具接入
  • 应用层:能力打包复用------SKILL,提示词 + 工具清单 + 使用说明的打包,本文主角

二、原理:渐进式披露与四阶段配合

2.1 一个完整技能 = 三件套

  • SKILL.md 的 frontmatter :name + description 两行元数据,注册阶段唯一被读取的部分
  • SKILL.md 正文:使用场景、操作步骤(调哪些工具、什么顺序)、输出格式、注意事项------命中后才注入
  • scripts/ 目录:确定性逻辑脚本(规则计算、模板渲染),执行时才参与,源码永不进上下文
  • 其他扩展文件(可选):输出模板、参考资料,步骤提到时才逐级装载

2.2 四阶段配合流程

  1. 注册(启动时,成本极低):扫描技能目录,只解析每个 SKILL.md 的 frontmatter,拼成"技能清单"注入 system prompt。几十个技能也就几百 token。
  2. 匹配(每轮对话,模型自主完成):用户提问后,模型对照清单里的 description 自行判断命中哪个技能。这一步没有额外调用,就是模型推理的一部分------路由决策被交给了模型本身。
  3. 装载(命中后,按需注入) :模型调用 load_skill 把 SKILL.md 全文读入上下文,相当于临时追加一段领域专家指令;步骤里提到的扩展文件与脚本,再用对应工具逐级加载。
  4. 执行(复用已有工具):模型按说明书步骤调用业务工具、跑脚本,组织最终回答。SKILL 提供"怎么做",工具提供"能做什么",执行面一行不用改。

2.3 渐进式披露:用多少知识,付多少 token

上下文里与技能相关的内容分三级扩张:常驻的只有清单 (几百 token),命中才注入说明书全文 ,扩展资料与脚本结果用到才装载。没命中的技能知识永远不进上下文------这是 SKILL 相对"全部写进 system prompt"的根本优势。

与相邻机制的边界:

机制 提供什么 注入时机 扩展方式
Tool / MCP 原子能力(函数签名) 每轮全量放 tools 参数 改代码或起新 Server
意图路由 显式分发到专业 Agent 每轮先过路由器 写新规则、新 Agent
SKILL 流程知识 + 确定性脚本 命中才注入正文 加一个目录,不改代码

三、实现细节:注册、装载、执行三件套

3.1 技能目录与 SKILL.md

以一个"出行简报"技能为例(查天气 + 查当地新闻 + 脚本算穿衣建议):

markdown 复制代码
skills/
└── travel-briefing/
    ├── SKILL.md
    └── scripts/
        └── clothing-advice.js
markdown 复制代码
---
name: travel-briefing
description: 生成指定城市的出行简报:实时天气、穿衣建议、当地相关新闻
---

# 出行简报

## 操作步骤
1. 调用 get_weather 查询目标城市天气,提取温度数值与天气现象
2. 调用 get_news 查询当地新闻(可与第 1 步并行)
3. 调用 run_skill_script 执行 clothing-advice.js,输入 {"temp": 温度, "weather": 天气现象}
4. 按输出格式整理:天气概况 + 穿衣建议(原样引用脚本输出)+ 当地近况

## 注意事项
- 天气和新闻必须来自工具结果,禁止编造

说明书写作有两条实战经验:步骤要写清每一步调什么工具 (小模型会跳步),注意事项用禁止式措辞(如"禁止调用 read_url 读取正文"),约束力远强于建议式表述。

3.2 注册:启动时扫描,只读 frontmatter

javascript 复制代码
// 遍历技能目录,正则解析 --- 包裹块内的 name / description,不引入 yaml 依赖
const content = fs.readFileSync(skillFile, "utf-8");
const meta = content.match(/^---\n([\s\S]*?)\n---/)?.[1] ?? "";
const name = meta.match(/^name:\s*(.+)$/m)?.[1]?.trim();
const description = meta.match(/^description:\s*(.+)$/m)?.[1]?.trim();
SKILL_REGISTRY.set(name, { description, dir, content });

技能清单拼进 system prompt,并配一组使用规则,其中两条最关键:

  • 命中技能时,第一个工具调用必须是 load_skill------小模型对"先装载再执行"的顺序感不稳定,不给 few-shot 示例会跳过装载直接调业务工具;
  • 步骤要求跑脚本时必须真实执行,禁止自己编造脚本输出。

3.3 装载:load_skill / load_skill_file 长在 tools 协议上

"装载说明书"实现为两个普通本地工具,对模型完全透明------它只是又可调用两个函数,结果以 role=tool 回写进上下文:

  • load_skill(name):返回 SKILL.md 全文,并顺带列出附带文件与脚本清单(模型才知道后续还能装载、执行什么)
  • load_skill_file(name, file):读取扩展文件;路径经 normalize 后必须仍落在技能目录内(防 ../ 越权),且 scripts/ 下的脚本拒绝装载------脚本只能执行,读进上下文浪费预算还会诱导模型改写逻辑

装载结果末尾追加一句指令重申:"以上是说明书不是任务结果,必须逐步调用工具执行"。说明书全文很长,开头的 system 规则会被长上下文稀释,放在结果尾部提醒效果最好(近因效应)。

3.4 脚本执行:run_skill_script 的沙箱三件套

脚本在子进程中执行,安全防护三件套:

措施 防什么
路径前缀校验 脚本必须真实存在于该技能的 scripts/ 内,拒绝 ../ 越权
执行超时(到时杀进程) 脚本死循环或挂起输入,不能把请求永久挂住
输出截断 脚本可输出任意长文本,不截断会撞爆上下文预算

两个工程取舍值得记录:

  • 输入走 stdin 传 JSON,不走命令行参数 :免去 shell 转义与注入面,脚本侧解析也简单------process.stdin 读完 JSON.parse 即可;
  • 扩展名白名单 (.js 走 node、.py 走 python3,其余拒绝),错误也返回文本给模型自行修正。

脚本本身的定位是"确定性逻辑下沉",两个典型用途:

  • 规则计算 :温度分段 → 穿衣建议。注意天气数据源常返回英文现象(如 Patchy rain nearby),正则要中英文双匹配,否则叠加提示(带伞)会静默丢失;
  • 模板渲染:早报正文(日期行 + 编号标题列表)格式写死在代码里,排版永不走样,模型只在末尾补一句问候。

3.5 执行:ReAct 循环一行不用改

工具循环与纯工具版完全同构(发请求 → 有 tool_calls 就执行并回写 → 再请求),装载与脚本只是多了几种工具。一次典型问答的轮次序列:

scss 复制代码
第 1 轮  load_skill(travel-briefing)          ← 匹配命中,装载说明书
第 2 轮  get_weather + get_news(并行)        ← 按步骤调业务工具
第 3 轮  run_skill_script(clothing-advice.js)  ← 规则计算下沉到脚本
第 4 轮  无 tool_calls,流式输出最终回答        ← 按说明书格式整理

四、踩坑记录:小模型的五个失控模式(实测)

用 1.7B 级本地模型实测,SKILL 链路有五类真实失败,每一类都有对应的工程加固:

失控模式 根因 加固手段
装载说明书后跳过工具,直接编造回答 说明书全文稀释了开头的 system 规则 装载结果末尾追加指令重申 + system prompt 用 few-shot 固定"先装载再执行"顺序
隔一轮就重复调用 load_skill 同一技能 小模型记不住已装载状态 请求级 Set 记录已装载技能,重复调用返回"已装载,请继续执行步骤"短句,不再重灌全文
把脚本名填进 name 字段(技能名/脚本名混淆) 两个 name 概念在小模型处易混 技能未找到时跨技能反查脚本真实归属,自动纠偏继续执行
用自己的话改写脚本输出,丢掉关键信息(如"带伞") 模型有"润色"冲动 脚本结果加"【脚本输出,请原样引用】"前缀标记,说明书同步要求原样引用
反复尝试装载不存在的文件名,耗尽全部轮次 试错循环无收敛信号 错误信息里明确"没有此文件、输出格式已写在说明书中、请直接输出最终回答",阻断循环

一个通用结论:面向小模型的 SKILL 系统,健壮性一半来自说明书怎么写(禁止式措辞、步骤原子化),另一半来自执行层的容错设计(去重、纠偏、阻断信号)------把模型的每次失误都当成一种输入来处理。

延伸阅读

  • SKILL 与 MCP 是互补不是竞争:MCP 解决"工具从哪来"(接入层标准化),SKILL 解决"工具怎么用"(应用层经验打包)。技能步骤里调用的工具完全可以来自 MCP,两者对模型同为 tools 协议,彼此无感知
  • 与意图路由的取舍:路由把决策写成规则/独立 Agent,确定性强但扩展要改代码;SKILL 把决策交给模型读 description 判断,扩展只需加目录。领域少而固定选路由,技能多而常增选 SKILL
  • 脚本的安全边界:本文的子进程三件套适合学习场景,生产环境的完整形态是容器沙箱(独立文件系统、非 root、资源限额)------原则相同:路径校验、超时、输出截断一样不能少
  • 技能的动态化:本文在启动时刻注册技能清单;若要运行中热加载,扫描逻辑移入请求时执行并加缓存即可,工具循环无需任何改动
  • 社区标准:Anthropic 的 Agent Skills 规范即采用"目录 + SKILL.md + 渐进式披露"形态,本文实现与其核心机制同构,技能目录可互相迁移
相关推荐
Marco_康16 分钟前
AgentFleet 跨设备调度实测:303 tasks/s,设备掉线 0 丢任务
人工智能
QYR_1130 分钟前
年复合增长率11.4%!机器人指端视触觉传感器加速迈向规模化应用
人工智能·数码相机
武天旭1 小时前
AI安全--AI大模型的数据投毒攻击解析
人工智能·深度学习·安全
AI技术新视界1 小时前
LLM 提示词缓存(Prompt Caching)的秘密
人工智能·缓存·llm·prompt
火山引擎开发者社区1 小时前
从企业开发者到 Agent 先锋,火山引擎 Agent 先锋计划邀你进击!
人工智能
这张生成的图像能检测吗1 小时前
(论文速读)Ponder:通过神经渲染进行点云预训练
人工智能·深度学习·机器学习·点云·3d技术·神经渲染
johnsong1 小时前
AI前沿日报 · 2026-11-05:暗网与裂痕
人工智能
张彦峰ZYF1 小时前
升级了不等于变好了:AI回归测试的固定评测集、版本对比、质量阈值与CI门禁
人工智能·后端·模型或提示词升级·语言模型没有编译器与确定性输出·总体、切片与回退清单·红线、护栏与目标·ci门禁把判定写进合并路径
迪康coolmu2 小时前
企业U盘管控落地实战:基于迪康端点安全一体化管理系统的移动存储安全实践
运维·人工智能·经验分享·笔记·安全·电脑