Skip to content

Skills — 领域知识模块

上下文视角:Skills 是按需加载的系统指令片段——让领域知识以模块形式进入上下文。

上一节的 Command 和这一节的 Skill,底层做的是同一件事——把额外 prompt 注入上下文。从持续性来说,两者没区别:一旦进入上下文,后续每轮请求都跟着(参见上下文一节——LLM 无状态,每次重发全部)。

那区别在哪?两点:

  • 谁触发:Command 是你手动输入 / 触发;Skill 由 LLM 根据任务判断,通过工具调用按需加载。
  • 怎么进入:Command 触发即全文展开;Skill 先以名称和简短描述的形式出现在上下文中,LLM 判断需要时再加载完整内容。

Command 是"这次做什么",Skill 是"从现在起怎么做"。

SKILLS SYSTEM Modular Context Injection AVAILABLE SKILLS GIT-MASTER Version Ctrl DEPLOYED WRITER Tech Prose DB-ADMIN Query Opt AGENT CONTEXT BASE SYSTEM INSTRUCTION Role: Helpful Assistant SKILL SLOT (PERSISTENT) VUE-PRO Frontend BEHAVIOR Writing Vue 3 Composition API... COMMANDS /publish One-off /test One-off Commands are tools. Used once, put back. SKILL: Persistent "Mode" COMMAND: Transient Action SVG v2.0 • KNOLLING LAYOUT
SKILLS SYSTEM Modular Context Injection AVAILABLE SKILLS GIT-MASTER Version Ctrl DEPLOYED WRITER Tech Prose DB-ADMIN Query Opt AGENT CONTEXT BASE SYSTEM INSTRUCTION Role: Helpful Assistant SKILL SLOT (PERSISTENT) VUE-PRO Frontend BEHAVIOR Writing Vue 3 Composition API... COMMANDS /publish One-off /test One-off Commands are tools. Used once, put back. SKILL: Persistent "Mode" COMMAND: Transient Action SVG v2.0 • KNOLLING LAYOUT

加载前后的行为差异

最直观的理解方式:同一个任务,加载 Skill 前后的输出对比。

── 加载前 ──

Agent 的 System Instructions 很简单:

json
// → REQUEST(部分)
{
  "system": "你是一个 AI 编程助手。"
}

你说:"帮我 commit 这些改动。"

Agent 生成:git commit -m "update files"

── 加载 git-master Skill ──

json
// → REQUEST(部分)
{
  "system": "你是一个 AI 编程助手。\n\n## git-master Skill\n- commit 消息必须遵循 conventional commit 规范 (fix:, feat:, docs: 等)\n- 消息体解释'为什么',而不是'什么'\n- 禁止 --no-verify\n- ..."
}

── 加载后 ──

同样的请求:"帮我 commit 这些改动。"

Agent 生成:feat(auth): add JWT token refresh endpoint,附上详细的 body 解释为什么需要这个变更。

LLM 没有"学会"新知识——它只是看到了更详细的指令。加载 Skill 就是把内容塞进发给 LLM 的请求里。注入到 system 字段还是 messages 里?因工具而异,但效果相同:Skill 的规则在后续每轮请求中持续生效。

先发现,后加载

上面的例子简化了加载过程。实际上,Skill 进入上下文分两步。

第一步:启动时,Agent 把所有可用 Skill 的元数据注入上下文。

json
// → REQUEST(启动时,部分)
{
  "system": "...\n\n## Available Skills\n- git-master: Git 操作专家,遵循 conventional commit 规范\n- frontend-ui-ux: 前端设计与 UI/UX 最佳实践\n- ..."
}

LLM 看到的是一份清单——名称和简短描述,不是完整内容。上下文成本极低。

第二步:LLM 判断当前任务需要某个 Skill 时,主动调用工具加载全文。

json
// ← RESPONSE(LLM 决定加载 skill)
{
  "tool_calls": [
    {
      "name": "load_skill",
      "arguments": { "name": "git-master" }
    }
  ]
}

Agent 读取 Skill 文件的完整内容,注入到后续请求中。从这一刻起,Skill 的规则才真正占用上下文。

这就是渐进式披露(progressive disclosure)——不用的 Skill 只占一行元数据的空间;用到了才展开全文。主流开源工具(Codex、Gemini CLI、OpenCode)都采用了这个模式,只是触发工具的名称各异。

Skills vs. Commands

二者底层机制相同——都是把额外 prompt 注入上下文。差异在以下几点:

特性Slash CommandsSkills
触发方式用户手动 / 触发LLM 根据任务判断,通过工具调用加载
进入方式触发即全文展开,作为 user message 进入对话历史启动时只有元数据(名称+描述);LLM 按需加载全文
持续性进入后每轮请求都带(随对话历史)进入后每轮请求都带(部分工具支持中途停用)
粒度"这次做什么""从现在起怎么做"
举例/review加载 git-master

不同工具加载 Skill 的语法各异,但流程相同:启动时注入元数据 → LLM 按需加载全文 → 注入后每轮请求都带上。

生态:可复用的行为模式

Commands 和 Skills 都可以封装成文件、提交到仓库、在团队间共享。分发机制上二者没区别。Skill 更适合做成可复用模块,是因为持续性——加载一次后自动生效,不需要每次手动触发。

  • 个人:把你的工作流封装成 Skill 文件。
  • 团队:为项目创建共享 Skill,统一编码规范。
  • 社区:为特定技术栈发布公开 Skill——React 组件设计原则、Go 错误处理模式。

代价呢?每个加载的 Skill 都持续占着上下文窗口。加载三个 Skill,每轮请求就多带三份完整指令。加载前问自己:这次任务真的需要它吗?

还有指令冲突。一个 Skill 要求注释详尽,另一个要求极简,Agent 怎么选?有的工具支持中途停用,有的不支持——不支持的,加载了就到会话结束。加载前的判断比加载后的管理更重要。

本节小结

  • 上下文流动:加载 Skill = 其内容注入到每轮请求中,持续占用上下文窗口。部分工具支持中途停用释放空间,其余到会话结束。它产生的是稳定的、可复现的领域行为模式。
  • 风险:加载过多 Skill 会撑爆上下文窗口。更隐蔽的问题:不同 Skill 的指令可能冲突——一个要求注释详尽,另一个要求极简——Agent 行为变得不可预测。
  • 可审计性:Agent 日志应记录哪个 Skill 在何时被加载或停用。Agent 行为异常?先查当前加载的 Skill 列表和它们的内容。

Skill 不是免费的。每多加载一个,上下文就少一块留给真正要做的事。

下一节看 Agent-Native CLI Tools——Skills 给 Agent 注入行为知识,CLI Tools 给它可执行的能力。