技能系统:Agent 的训练手册
本章摘要:
技能系统的核心是按需加载——上下文是稀缺资源,把所有知识塞进系统提示既浪费空间又稀释模型判断。技能用"名称+描述"先进入名单,用到时再加载完整内容。
如果说 Agent Loop 是 Agent 的心跳,工具系统是它的双手,那技能系统就是一本训练手册。
有了手,Agent 能读写文件、执行命令;但"能做什么"不等于"知道怎么做"。Git 提交规范、代码审查清单、部署流程——这些领域知识不能靠模型自己猜,需要被注入。
最直接的办法是把所有知识塞进系统提示。但这样有两个问题:
- 浪费空间——大部分技能与当前任务无关
- 稀释判断——无关信息让模型难以聚焦
技能系统的解法是按需加载:
- 第一阶段(启动时):系统提示只放名称和描述,每个约一两百字
- 第二阶段(按需时):模型判断需要某个技能时,才加载它的完整内容
这种两阶段加载的设计哲学和查字典非常类似,不需要把字典完整背下来,而只需要记住字本身的拼写即可。
技能的来源层级
技能可以来自不同位置,按作用范围划分:
- 系统级:编译进二进制,开箱即用
- 管理策略级:企业管理员下发
- 用户级:跨所有项目的个人偏好
- 项目级:仅当前项目生效
- 远程级:通过外部协议(MCP)提供的远程技能
启动时,系统按优先级合并去重。多层之间是拼接而非覆盖——去重是基于文件路径,不是技能名称。不同来源提供的同名技能可以共存,只有同一个文件通过符号链接等方式出现在多个目录时才会去重。
技能的加载方式

在扫描各来源目录,合并去重后,技能按是否带触发条件分成两类:
- 无条件技能:立即可用,注入系统提示
- 有条件技能:带触发规则(SKILL 的配置中带
paths字段,如paths: ["src/**/*.ts"],只有处理符合"src/**/*.ts"通配符的文件时会进入技能列表),会先进入待命池,等条件满足后被激活(会被放到一个<system-reminder>包裹的用户提示词块中,下次一并发送给模型 API)
对于子项目的技能(比如 sub-project/.claude/skills/some-skill),也只会在操作该子项目的时候被动态加载,类似上述有条件技能。
等到模型需要使用该技能时,则会经历如下步骤:
根据技能的
context配置:判断是 inline 执行(直接加载到当前的上下文中)还是 fork 执行(复制一份当前的上下文单独执行技能,完成后返回结果,类似后续会介绍的 fork subagent 的方式,防止当前的上下文污染)根据技能的
arguments配置:类似于字符串模板,可以根据用户传入的参数来替换技能中的占位符。根据技能的
allowed-tools配置:将这些工具的权限改为直接放行。
注意:
allowed-tools只是将某些工具改成直接放行,而不是说禁用其余工具
写一本自己的训练手册
技能本质上是一个目录,里面放一个 SKILL.md 文件。SKILL.md 的开头是一段 YAML 格式配置(frontmatter),后续是 Markdown 正文。
可用配置项
所有字段都非必需,但是推荐至少写 name 和 description 字段。
| 字段 | 描述 |
|---|---|
name | / 菜单中的显示名称。不参与命令匹配——调用时按目录名匹配,未设置 name 时回退为目录名 |
description | 功能说明和使用场景。Claude 用它决定何时调用。省略则取正文第一段 |
when_to_use | 何时调用的额外上下文(触发短语、示例请求),追加到 description 后,合并展示于技能列表中 |
argument-hint | 在输入框键入斜杠命令时,会作为浅灰色的占位符显示,用于提示该命令期望的参数内容 |
arguments | 命名位置参数,用于正文中的 $name 替换。按顺序映射到参数位置 |
disable-model-invocation | true 阻止 Agent 自动加载,仅限 /name 手动触发。默认 false |
user-invocable | false 从 / 菜单隐藏,用于背景知识类技能。默认 true |
allowed-tools | 技能激活时可免确认使用的工具列表 |
model | 覆盖当前轮次的模型,如 sonnet、haiku、inherit(保持当前) |
effort | 思考力度:low、medium、high、xhigh、max |
context | 设为 fork 在独立子代理中运行 |
agent | context: fork 时使用的子代理类型,比如 Explore、Plan |
hooks | 可以在此处定义随技能加载的生命周期钩子 |
paths | 仅在处理与 paths 定义匹配的文件时将该技能注入上下文 |
shell | 技能中内联命令使用的 shell,bash(默认)或 powershell |
示例
<!-- ~/.claude/skills/gen-api/SKILL.md -->
---
description: 生成 REST API 端点的完整代码骨架
when_to_use: 需要创建新的 API 端点时
arguments: method resource
argument-hint: "[GET|POST|PUT|DELETE] [resource-name]"
allowed-tools:
- Read
- Write
- Grep
- Glob
---
为资源 $resource 创建 $method 方法的 REST API 实现。
基于项目既有模式,生成以下文件:
1. 路由定义
2. 请求/响应类型
3. 控制器逻辑
4. 基本测试参数按位置映射,顺序必须严格:
/gen-api POST users → $method=POST, $resource=users ✓
/gen-api users POST → $method=users, $resource=POST ✗(参数错位)调用方式:
- 手动触发:输入
/gen-api POST users - 自动触发:对模型说"帮我生成一个创建用户的 API",模型识别意图后自动调用该技能
参数不足 arguments 声明数量时,多余变量替换为空字符串。未使用 $name 占位符的多余参数会追加到内容末尾。
三条核心原则
一技一事。 技能粒度要细——"全栈开发"技能不如"API 生成""组件生成""测试生成"三个独立技能。
描述精确。 描述是模型选择技能的依据。模糊描述导致选错——"代码审查"比"帮助改进代码"好得多。
用条件技能减少噪音。 加触发规则,只在操作匹配文件时激活。技能多不是问题,技能同时出现在列表里才是问题。
本章要点
- 技能系统是 Agent 的"训练手册",把领域知识按需注入
- 按需加载有两层含义:①启动时只放名称描述 ②条件技能按触发条件激活
- 多层技能按优先级合并,拼接而非覆盖
- 最小权限原则体现在 allowed-tools:技能可限定允许使用的工具
- 写技能的核心是一技一事、描述精确、触发合理