5028 words
25 minutes
From Prompt to Skill:Agent 技能机制与上下文调度

1. 问题从哪里开始#

理解 Agent Skill(智能体技能)最常见的误区,是把它想象成”给模型装了个插件”或”让模型学会了新本事”。这两种直觉都不准确。

真正需要先接受的前提是:Skill 从头到尾没有触及大语言模型(LLM)本身——它不修改任何一个模型权重,不改变模型的推理过程,也不是模型”内部”的一部分。一个 Skill 最终对模型产生影响的唯一途径,和一段普通提示词(prompt)完全一样:变成 token,进入上下文窗口(context window),被同一次前向推理(forward pass)读取。

所以要真正搞懂 Skill 是什么,不能停留在”它是一种能力封装”这种模糊说法:

  • 它到底以什么形式存在于磁盘上?
  • 它以什么角色(role)、在什么时机进入上下文窗口?
  • 它和普通 prompt、和 system prompt、和 tool call、和 MCP 到底是什么关系?

我们可以通过这几个问题来搞懂skill。

本质上,Skill 是一套围绕”上下文窗口”这一稀缺资源做加载调度的机制,而不是一样神秘的新东西。


2. Skill 的起源:谁提出的,为了解决什么#

Agent Skills 这一概念由 Anthropic 在 2025 年 10 月正式提出,并很快演变成一个跨平台的开放格式——微软 Copilot Studio、GitHub Copilot、Cursor、Gemini CLI 等生态随后都采用或兼容了这套思路。

它要解决的,是纯 prompt 工程在规模化时的三个结构性痛点:

纯 prompt 的痛点具体表现Skill 的对策
不可复用每次做同类任务都要重新粘贴一大段指令把流程写一次,存成文件,到处调用
占满上下文想让模型”随时会做” N 种任务,就得把 N 套完整指令全塞进 system prompt,窗口被撑爆平时只暴露一行简短描述,用到才展开
要人手动触发用户得自己判断”这次该用哪套指令”由编排器(orchestrator)根据描述自动选择

简单来说:Skill 是把 prompt 工程”产品化”了——加上了持久化、按需加载、自动路由,以及(关键的)可选的代码执行能力。


3. Skill 到底是什么:定义与形式#

从底层来讲,一个 Skill 就是磁盘上的一个文件夹。文件夹里必须有一个 SKILL.md 文件,可选地附带脚本、参考文档、模板等资源。

一个完整 Skill 在磁盘上长这样:

pdf-skill/ ← 整个 Skill 就是一个文件夹
├── SKILL.md ← 核心:元数据(标题)+ 正文(指令)
├── scripts/ ← 可执行脚本
│ ├── fill_form.py
│ └── merge_pdf.py
├── references/ ← 参考文档
│ └── pdf_spec_notes.md
└── assets/ ← 模板 / 静态素材
└── letterhead_template.pdf

SKILL.md 本身内部又分两部分:

---
name: pdf-form-filler
description: 当用户需要填写或处理 PDF 表单时使用 ← 元数据(标题)
---
# 填写 PDF 表单 ← 正文(指令)1. 读取用户提供的字段数据
2. 调用 scripts/fill_form.py 完成填充
3. 细节规格见 references/pdf_spec_notes.md
...

它把”某一类任务该怎么做”的流程性知识固化下来,让一个通用模型在需要时表现得像某个领域的专家。


4. 三层结构:渐进式披露(Progressive Disclosure)#

Skill 最核心的设计,是把内容分成三层,按需逐层加载。这套机制叫渐进式披露,目的只有一个:省上下文窗口

层级内容加载时机Token 成本
L1 元数据frontmatter 里的 name + description(约几十 token)启动时常驻,让模型”知道有这本书”极小,一直付
L2 正文SKILL.md 的完整 Markdown 指令仅当任务匹配时才注入触发才付
L3 资源scripts/ references/ assets/ 里的文件按需读取或执行见第 9、11 节

用一个类比贯穿理解:

  • L1 元数据 = 一本书的书名 / 目录里的一行标题——“第 7 章:如何填 PDF 表单”。
  • L2 正文 = 第 7 章的完整内容。平时不翻,真要做这件事时才翻到那一页读进来。
  • L3 资源 = 附录里的计算器和详细规格表。你用计算器算,但不需要把它的电路图背下来。

正因如此,有 50 个 Skill,平时只占 50 行简短描述的成本(几百 token),而不是 50 套完整指令。模型在有限窗口里能”认识”上百种能力,却不必时刻背着它们的全文。

flowchart TD
A[会话启动] --> B[L1: 50 行 description 常驻 system]
B --> C{用户提出需求}
C -->|匹配到某 Skill| D[L2: 该 Skill 正文动态注入]
D --> E{正文里引用了资源?}
E -->|要执行脚本| F[L3 scripts: 窗口外运行, 只回填结果]
E -->|要查参考| G[L3 references: 按需读取部分进窗口]
E -->|不需要| H[直接完成任务]

5. 例子:生成规范 Excel#

用同一个任务对比”纯 prompt”和”Skill”,能立刻看清差别。任务是:把一批数据做成一张格式规范的 Excel 表

方案 A — 纯 Prompt(每次手敲):

请帮我生成 Excel。要求:
- 表头加粗、底色深蓝、白字
- 冻结首行,数字列右对齐保留 2 位小数
- 金额列用千分位,列宽自适应
- 用 openpyxl 输出到 output.xlsx
数据如下:...

下次再做同类任务,这段又得从头贴一遍。

方案 B — Skill(建一次,长期复用):

xlsx-skill/
├── SKILL.md # name + description + 上面那套格式规范
└── scripts/
└── format_table.py # 真正干活的代码

之后你只需说”把这批数据做成 Excel”,模型读到 L1 描述判断匹配,把 L2 正文拉进来,再调用 format_table.py 完成——那段格式规范再也不用手敲。


6. Skill vs Prompt:本质相同,定位不同#

两者本质上都是”外部输入”:都不改变模型权重,都以 token 进入上下文,由同一次推理处理。 从这个意义上说,它们和微调(fine-tuning)、RLHF 这种真正改动参数的手段有本质区别——后者才”触及根本”。

但在”外部提示”这个大类里,两者定位差别很清楚:

维度PromptSkill
形态一段即时文本一个文件夹(SKILL.md + 可选资源)
生命周期一次性,用完即弃持久化,跨会话 / 跨项目复用
加载方式写多少就全量进窗口渐进式披露,平时只占一行描述
触发者人手动输入模型 / 编排器自主判断何时调用
能力边界纯文本,不能自带可执行代码L3 可附带脚本,能被执行
类比口头临时交代一件事一本写好、需要时才翻的操作手册

关键区别不在”是否触及模型”,而在”复用性 + 加载机制 + 谁来触发 + 能否外挂执行”。 Skill 可以粗略理解成”被规范化、模块化、按需加载的 prompt 仓库”,外加一层纯 prompt 做不到的可执行能力。


7. Skill 是不是 system prompt?#

既然skill是以prompt的形式出现在上下文,那么它的role是什么,是system prompt吗?

答案是:不完全等于,但有交集,而且必须精确措辞。

先厘清 “system prompt” 到底指什么。在一次推理里,送进上下文窗口的文本按**角色(role)**分层:

角色内容特点
System人设、全局规则、可用工具 / 技能清单常驻、权威最高、用户一般看不到
User用户当前的话逐轮变化
Assistant模型自己的回复逐轮生成

所谓 system prompt,就是 System 角色那一段,而它的定义里隐含了”静态常驻”。

Skill 的两层内容,落点不同:

  • L1 元数据(那行描述) → 确实被塞进 System 区并常驻,让模型一直知道有哪些技能可选。这部分算 system prompt 的一部分。
  • L2 正文 → 触发后动态注入。它以 System 级的权威进入,但它是”会进出的”,不是一开始就钉在那儿的固定 prompt。

所以严谨的表述是:

L2 正文是”动态注入的 system 级指令片段”,而不是”一段动态的 system prompt”。

而且要记住:Skill ≠ 只有正文。它还有 L3 那层——那是窗口外的可执行代码,根本不是 prompt。所以”本质上是一种 prompt”这句话只覆盖了 L1 + L2。


8. 动态注入 vs 静态注入:区别到底在哪#

这是理解 Skill 机制的核心:

对模型的单次前向推理来说,“一开始注入”和”运行时注入”没有任何区别。 模型只看它这一刻窗口里有什么 token,token 不带时间戳,模型无从分辨哪段是开机就有、哪段是刚才才塞的。

那区别在哪?在整场多轮对话里,这段文本存在多久、占用多少、由谁决定。

一开始注入(静态)运行时注入(动态)
进入时机会话启动,第 0 轮就在某轮触发条件满足才加入
存在时长全程常驻,每一轮都在用完可撤走,只在相关轮次占用
谁决定系统预先写死编排器根据当前需要临时决定
Token 成本每一轮都重复付这份钱只在需要的轮次付

一个推演最能说明问题。假设有 50 个 Skill、对话进行 10 轮:

  • 若全部静态注入:每一轮窗口都背着 50 套完整正文(比如 5 万 token),被重复喂 10 次,而大部分这次根本用不上——纯浪费,上下文窗口很快撑满。
  • 若动态注入:任何一轮窗口里只有”50 行索引 + 当前用得上的那 1 套正文”,省下 90%+ 的空间。

动态注入最大的价值是”可逆、可调度”:

系统能用有限窗口支撑海量能力——模型平时只背一份薄目录,真要用哪一章,编排器现场翻开塞给它,用完合上。


9. L3 资源:不进窗口,怎么执行?#

这里要破除第二个误区:“进上下文”和”被执行”是两条完全独立的路径。 上下文窗口是给模型”读”的;执行是在模型之外的机器上”跑”的。

模型本身不运行任何代码。 LLM 是个文本预测器,只会输出 token。真正干活的是它旁边的运行环境(runtime / sandbox / 工具执行器)。流程是:

① 模型在 L2 正文里读到:"调用 scripts/format_table.py 处理数据"
② 模型据此输出一个动作指令 token:
{ "tool": "bash", "command": "python scripts/format_table.py data.csv" }
③ 外部执行器收到 → 在沙箱里真正运行那个 .py 文件
④ 脚本跑完,把【结果】(成功/报错/输出值)作为文本回填进上下文窗口
⑤ 模型读到结果,继续下一步

所以进出上下文的到底是什么,要分清:

东西进上下文吗说明
脚本的文件名 / 调用指令✅ 进模型需要知道”有这工具、怎么调”
脚本的源代码内容❌ 不进那几百行代码模型不用读
脚本的运行结果✅ 进成功 / 失败 / 输出值,回填给模型看

bash 与 MCP tool:两种执行路径#

L3 的”让机器跑”本质就是工具调用(tool calling),而 bash 和 MCP tool 是它下面的两种实现路径,不是二选一的对立关系。

Bash / 代码执行工具MCP tool
本质授予模型一个”执行 shell 命令”的通用工具授予模型一批”预定义好的具体工具”
粒度粗、万能——一个 bash 能干任何事细、专用——每个 tool 一个明确 schema
跑在哪Agent 自带的代码沙箱外部 MCP server 进程里
典型场景Skill 自带脚本、临时计算、文件操作连数据库、调外部 API、访问企业系统

分工大致是:

  • Skill 的 L3 脚本 → 走 bash / 代码执行:处理”技能包自带、本地就能算的活”。Anthropic 官方的 Agent Skills 设计里,L3 资源就是靠代码执行工具跑的,不依赖 MCP
  • MCP tool → 走 MCP 协议:处理”要连出去的活”。

而且两者可嵌套:一个 Skill 的 L2 正文完全可以写”第 2 步:调 MCP 的 query_db 取数;第 3 步:用本地脚本 format.py 排版”。它们都只是 L2 指令层可调度的”执行手段”。

bash 跑在哪台机器上#

执行环境由”承载这个 Agent 的宿主”提供,而不是模型自带。

产品形态bash / 代码跑在哪环境性质
云端 Agent 服务服务商后端起的一次性容器 / 微型 VM云端沙箱,任务结束即销毁
Claude Desktop 客户端自身不带通用沙箱,靠外挂 MCP server执行落到 server 所在处(可能是你本机)
Codex CLI / Claude Code直接跑在你本机的 shell你的真实电脑,有真实文件访问权
IDE 插件(Copilot / Cursor)通常在你本地工作区执行你的开发机环境

10. role 的定义权与生效层级#

一个更底层的问题:注入进上下文的那段东西,role 到底是谁定的、在哪一层生效?这要拆成两个不同的问题。

role 的”格式 / 字段” —— 定义权在 API 协议层#

role: "system" / "user" / "assistant" / "tool" 这套词汇表,由模型提供商的 API 规范定义。你(调用方)只能从它允许的 role 里挑,不能自己发明一个 role: "boss" ,API 会报错。所以”有哪些 role 可选”的定义权在接口层

role 的”效力 / 权威” —— 影响在模型端(训练里)#

为什么 system 比 user 权威?这个高低次序是谁赋予的?

答案是:在模型端,通过训练固化的。

关键在于理解:对底层 Transformer 来说,输入其实是一整条被”拼平”的 token 序列,role 不是独立信道,而是被编码成特殊标记塞进序列里的:

<|system|> 你要遵守... <|end|>
<|user|> 帮我做... <|end|>
<|assistant|> ...

那些 <|system|> <|user|>特殊 token / 分隔标记。模型之所以”知道” system 那段更权威,不是因为字段名有魔力,而是在**训练阶段(instruction tuning + RLHF)**被喂了海量样本,反复学到:“当 system 段与 user 段冲突时,优先服从 system。“

层面定义权在哪
role 有哪些、字段叫什么、格式API 协议层
role 之间的权威高低、谁压谁模型端,由训练固化
把 role 转成模型能读的形式(套 chat template、加特殊 token)中间的 serving 层

拿一个没经过对齐训练的裸 base model,给它标 role: system,它根本不会因此更服从——因为它没被训练过”要尊重 system”。可见 role 的效力不在字段本身,而在模型学没学过

那 Skill 正文注入时是什么 role#

这是实现相关的,但有一点确定:它绝不会是 user(否则会被后续 user 输入覆盖,且角色语义错乱),一定在”权威侧”。主流实现有几种:

注入方式具体 role场景
合并 / 追加进 systemsystem直接把正文拼进或作为额外一条 system message
通过”读 skill 文件”工具拿到tool / functionAnthropic 式 Agent Skills 常接近这种,复用读文件管线
developer 分层体系developer部分新体系用它承载”应用级指令”,介于 system 与 user 之间

所以:Skill 正文以 “system 级的权威” 进入上下文永远成立;但它在消息数组里挂的字面 role,取决于产品是”直接当 system 拼进去”还是”当作一次工具读取的返回”。


11. L3 的 reference 如何参与上下文#

L3 内部还要再分”读”和”跑”两种命运——第 9 节讲的是”跑”(脚本),这里讲”读”(参考资料)。

核心区别 通常不是被系统被动”直接加载”,而是模型主动去”读”的。

L2 正文L3 reference
进场方式Skill 一触发,系统主动注入模型读了 L2 后,自己决定要不要读
主动权编排器 / 系统模型自己
类比翻开书直接看到第 7 章开头第 7 章写”详见附录 B”,模型再翻附录 B

具体流程——它走的是和 L3 脚本执行一模一样的工具调用管线,只不过脚本是”跑”、reference 是”读”:

① 模型读到 L2 正文:"详细规格见 references/spec.md"
② 模型判断:这次任务需要这个细节
③ 模型输出动作 → { "tool": "read_file", "path": "references/spec.md" }
④ 外部执行器读取该文件 → 把内容(或指定的某几段)作为【结果】回填
⑤ 这段文本进入上下文,role 通常是 tool,模型接着用

所以 reference 回填进上下文时,最典型的 role 是 tool(工具返回结果)——因为它复用了现成的文件读取管线,和 L3 脚本共用一套机制。同样,这也是实现相关的:少数实现会直接把内容拼进 system 上下文,role 就成了 system

reference 常常不是全量加载。它的价值恰恰在于可以只读需要的片段——带 offset 的部分读取,或先读目录 / 摘要再决定深入哪段。这就是**“更深一层的渐进式披露”** → L2 渐进过一次,reference 内部还能再渐进一次,尽量少占窗口。


12. 核心结论#

  1. Skill 从头到尾没有触及 LLM 本身。 它不改权重、不改推理,最终只是以 token 进入上下文窗口,和普通 prompt 走同一条路。它与微调 / RLHF 有本质区别。

  2. Skill 由 Anthropic 于 2025 年 10 月提出,现已成为跨平台开放格式。 它把 prompt 工程”产品化”,解决了纯 prompt 的三大痛点:不可复用、占满上下文、要人手动触发。

  3. 一个 Skill 就是一个文件夹,核心是 SKILL.md,内容分三层 元数据(常驻的”书名”)、L2 正文(动态注入的”章节内容”)、L3 资源(窗口外的脚本 / 参考 / 素材)。

  4. 渐进式披露是它的灵魂。 平时只暴露 L1 的简短描述,匹配到任务才注入 L2;省的是上下文窗口这一稀缺资源的调度效率,而非模型的理解力。

  5. “动态注入”与”静态注入”对模型单次推理无区别(token 不带时间戳),区别在多轮对话中”存在多久、占多少、谁调度”——静态是纹身,动态是便利贴。

  6. L1 + L2 本质是”动态加载的 system 级提示”;L3 不是提示,是窗口外的可执行资源。 L3 内部又分两种命运:脚本”给机器跑”(bash 或 MCP,不进窗口,只回填结果),参考资料”给模型读”(按需读片段进窗口,role 通常是 tool)。

  7. role 的词汇表由 API 定义,role 的权力由训练在模型端刻死。 Skill 正文以 system 级权威进入上下文永远成立,但其字面 role(system / tool / developer)取决于具体产品实现,唯一确定的是它绝不是 user。

Skill 不是一样神秘的新东西,而是一套围绕上下文窗口做加载调度的机制——用一个静态常驻的”书名”(L1)在 system 里挂号,用到时把”正文”(L2)以 system 级权威动态注入,必要时再指挥窗口外的脚本(L3)去干活。读的归读,跑的归跑,谁都不挤占本就稀缺的上下文窗口。

From Prompt to Skill:Agent 技能机制与上下文调度
https://fuwari.vercel.app/posts/prompt-to-skill/
Author
Akatsuki Sky
Published at
2026-08-31
License
CC BY-NC-SA 4.0