Skill(技能)
Skill(技能) 是将项目背景、代码规范、常用命令、测试方式、已知坑点等隐性知识,打包成 Agent 可在会话中调用的可复用单元。
为什么需要 Skill
没有 Skill,开发者面对两个选择:
- 每次对话都把约定重新塞进 Prompt(每轮重复,费时且容易遗漏)
- 让 Agent 从代码库推断规范(隐性知识推不出来)
Addy Osmani 把这种知识缺口命名为 Intent Debt(意图债):约定存在于人脑中,Agent 每次都要重新猜测,猜错了再纠正,形成隐性成本。
Skill 是这个问题的解法——把"凡是反复告诉 Agent 的事情"沉淀为可调用文件,长期上下文变成可复用资产,而不是每次从零开始喂。
Skill 与 Harness 的关系
Skill 和 Harness Engineering(驾驭工程) 的概念在实践中高度重合,没有官方标准的严格区分。粗略说:
- Skill:偏向"知识层"——告诉 Agent 这个项目的约定和上下文是什么
- Harness:偏向"执行层"——规定 Agent 如何运行、约束、验证
同一个调研报告的工作流,既可以叫 Skill(复用的知识包),也可以叫 Harness(框住 AI 的工作流程)。
本质上,我们与 AI 的所有互动都是三样东西的排列组合:提示词、代码逻辑、私有数据/外部接口。Skill 是这三者的封装,目的是用确定的约定去约束 AI 概率的不确定性。
Skill vs Plugin:格式与发布方式
这两个概念容易混淆,但它们处于不同层次:
- Skill:是格式——一个包含
SKILL.md的文件夹,记录项目惯例、构建步骤、历史决策。Agent 在会话中直接读取调用。 - Plugin:是发布方式——当你想跨仓库共享或打包多个 Skill 时,才需要打包成 Plugin。
单个项目内部只需要 Skill;Plugin 是 Skill 的分发和复用机制,供跨团队、跨仓库场景使用。
SKILL.md 文件结构
Skill 是一个文件夹,内含 SKILL.md 以及可选的脚本、参考文档和附加资产。SKILL.md 本身有固定的结构:YAML frontmatter 声明元数据,正文是给 Agent 读的指令。
---
name: ci-triage
description: Classify CI failures by root cause (env, flake, real bug,
dependency, infra), draft fixes for the easy ones, escalate the rest.
Trigger whenever a workflow run fails or on the morning triage loop.
---
# CI triage skill
## Classification rules
- env: missing secret, wrong env var, infra not provisioned. # human
- flake: passes on retry without code change. # retry once, then file
- bug: deterministic failure tied to recent commit. # draft fix
- dependency: failure tied to a version bump. # draft rollback
- infra: timeout, OOM, runner issue. # escalate
## Fix patterns
- Auth tests → check src/auth/middleware first
- Database tests → verify migration applied in CI env
- E2E tests → check selectors against the latest UI snapshot
## Never do
- Disable failing tests — always file as escalation instead
- Modify CI config without human approval
- Touch src/payments/ or src/billing/ (in claude/permissions.md)
## State
Update STATE.md after each run: file paths checked, classifications,
PRs opened, items escalated.几个关键设计点:
name:Skill 的唯一标识,用于显式调用(如 Codex 的$ci-triage)或触发规则匹配description:告诉 Agent 什么场景该选这个 Skill;应尽量短、只说清楚何时适用(见下文"为新一代模型校准 Skill"——过长或互相矛盾的描述反而让模型选错)- “Never do” 节:把约束写成明确的禁止列表,比散在正文里的"注意事项"更难被遗漏
- “State” 节:声明每轮结束后 Agent 需要更新什么——这是 Skill 和循环状态管理交接的协议
SKILL.md 旁边的可选文件(脚本、参考资料、资产)可以被 SKILL.md 引用,供 Agent 在执行中调用,而不是把所有内容都堆进一个文件。
Agent Skills 开放格式
Agent Skills 是 Anthropic 把上述模式产品化并开放出来的具体格式。它将 Skill 定义为一个目录:SKILL.md 是入口,scripts/ 放可执行代码,references/ 放按需读取的参考材料,assets/ 放模板、图片或数据文件。规范层面要求 name 和 description,并建议把主文件保持短小,把低频细节拆到支持文件。
这套格式的核心设计是渐进披露:
flowchart LR
M[启动时加载\nname + description] --> T{"任务触发?"}
T -- "否" --> K[不加载正文]
T -- "是" --> S[读取 SKILL.md]
S --> R[按需读取 references / assets]
S --> C[按需运行 scripts]
R --> W[完成任务]
C --> W
从 Context Engineering(上下文工程)看,Agent Skills 是 Select 策略的文件系统实现:把“知道有哪些能力”与“真正加载能力细节”分开。它也把自然语言流程和确定性代码放在同一个可版本化单元里,让 Skill 不只是 prompt 片段,而是可审查、可复用、可迁移的 Agent 能力包。
Anthropic 后续把 Agent Skills 发布为开放标准,目标是让同一个 Skill 能在多个兼容 Agent 客户端之间迁移。OpenAI API 的 Skills 功能也声明兼容这个开放标准,并把同类文件束做成可上传、版本化、挂载到 Shell 工具环境的 API 能力。这里要区分两层:Skill 是本词条讨论的泛化能力积累单元;Agent Skills 是一个具体开放格式和生态规范。OpenAI API 里的 Skills 更像这个格式在某个 API surface 上的实现方式,不必单独泛化成新概念。
Claude Code 的 Skill 机制
Claude Code 把 Skill 设计成比 CLAUDE.md 更细粒度的按需上下文:CLAUDE.md 适合每次会话都要读的稳定规则,Skill 适合某类任务才需要的长流程、参考材料和可执行脚本。官方文档也说明,旧的 .claude/commands/*.md 自定义命令已经并入 Skill 体系;同名 command 和 skill 同时存在时,skill 优先。
Skill 可以放在多个层级:
| 位置 | 作用域 |
|---|---|
| 企业托管设置 | 组织内所有用户 |
~/.claude/skills/<name>/SKILL.md | 当前用户所有项目 |
项目 .claude/skills/<name>/SKILL.md | 当前项目,可提交到仓库 |
Plugin 的 skills/ 目录 | 启用该 plugin 的环境 |
命令名主要由文件位置决定,而不是 frontmatter 的 name。普通 skill 目录名就是 /skill-name;plugin 内的 skill 会带 plugin 命名空间;只有 plugin 根目录 SKILL.md 这一种情况会用 frontmatter 的 name 生成命令名。同名时,企业、个人、项目和 bundled skill 之间有覆盖优先级,嵌套目录里的同名 skill 则会以目录限定名出现。
加载生命周期
Skill 不是每次启动都全文塞进上下文。Claude Code 平时只暴露 skill 名称和描述;当用户显式调用或模型判断相关时,才把渲染后的 SKILL.md 正文注入当前会话。注入后它会在本轮会话中保留;如果同一 skill 内容没有变化,再次调用不会重复追加全文。自动压缩时,最近调用过的 skill 会在预算内被带入压缩后上下文。
这个生命周期解释了 Skill 的写法边界:description 要足够具体,帮助模型判断何时加载;正文则应写成任务执行时真正需要的操作协议。把大段背景材料直接放进常驻规则会污染 Context Engineering(上下文工程) 预算;放进 Skill 则可以等待任务需要时再加载。
Frontmatter 控制面
Claude Code 的 SKILL.md frontmatter 支持一组 harness 级控制字段:
| 字段 | 作用 |
|---|---|
description / when_to_use | 帮助模型判断何时触发 |
disable-model-invocation | 只允许人显式调用,避免模型自动使用 |
user-invocable | 是否出现在 / 菜单 |
allowed-tools / disallowed-tools | skill 激活时的工具预批准或移除 |
model / effort | 调整本轮 skill 使用的模型与推理力度 |
context: fork / agent | 让 skill 在独立 subagent 上下文中运行 |
paths | 仅在处理匹配路径时自动触发 |
hooks | 声明 skill 生命周期相关 Hook |
这些字段让 Skill 不只是"一段提示词",而是 Harness Engineering(驾驭工程) 的配置单元。尤其是 allowed-tools,它可以减少低风险工具调用的审批摩擦,但不会绕过全局权限设置;高风险操作仍应由权限、Hook 或沙箱兜底。
动态上下文与支持文件
Claude Code 支持在 skill 正文中用 ! 命令注入动态上下文:命令在 skill 内容发送给模型前执行,输出替换占位符。例如把 git diff、PR 信息或当前环境版本预先嵌入任务说明。多行命令可放进特殊 fenced block。这个机制适合把"先查当前状态"变成 skill 的固定前置步骤,但也意味着项目级 skill 需要像脚本一样接受代码审查。
SKILL.md 同目录还可以放参考文档、示例、模板和脚本。推荐做法是让主文件保持简洁,只在需要时引用支持文件;脚本路径可用 ${CLAUDE_SKILL_DIR} 或 ${CLAUDE_PROJECT_DIR} 这类变量保持跨安装位置可移植。对于需要图表、报告或交互式 HTML 的任务,Skill 可以把脚本作为稳定执行单元,Claude 负责选择、运行和解释结果。
Subagent 与评估
把 context: fork 写进 Skill frontmatter 后,Claude Code 会把该 skill 作为任务提示交给一个独立 Subagent(子智能体) 执行。这个模式适合研究、审查、批量分析等高噪声任务:主会话只拿结果,不继承中间搜索日志。反过来,自定义 subagent 也可以在自己的定义里预载指定 Skill,让专职 Agent 启动时自带领域协议。
Skill 的质量需要单独评估:一方面要测它是否在该触发的 prompt 上触发,另一方面要测触发后输出是否比无 Skill 更好。官方文档建议用 fresh session 做 baseline 对比,避免当前作者会话里的残留上下文掩盖 Skill 自身缺陷。这一点和 Eval(评估) 的原则一致:不要只看模型有没有"使用"工具,要看使用后任务结果是否稳定变好。
在循环工程中的位置
Loop Engineering(循环工程)的 5 个核心模块之一。循环是自动跑的,Agent 不在场时无法被临时指导;Skill 是循环可以长期可信运行的知识基础。
没有 Skill,Loop 只是一个昂贵的 while true——每轮都重新购买同一份上下文,成本上升但能力不沉淀。有 Skill,Loop 才开始积累组织记忆:稳定规则、操作流程、失败经验都在 Skill 里,下一轮 Agent 不需要从零猜,直接加载。Skill 才是复利,Loop 只是管道。
没有 Skill 的循环,就像员工每天早上看过期文档——跑得越快,错得越多。
在 Claude Code 的 loop 设计里,Skill 还有一个更具体的用途:把人类 reviewer 原本手动做的检查步骤编码成可复用验证流程。比如前端改动不能只看 diff,而应启动 dev server、打开页面、点击新控件、检查 console、截图前后状态、必要时跑性能 trace。把这些步骤写进 SKILL.md 后,Turn-based loop 和 /goal loop 都能更接近端到端自检,而不是每轮等人指出“你还没真正验证”。
Skill 和 Agent Memory(Agent 记忆) 分工不同:Skill 由人维护,封装可复用的专项流程和领域知识;Memory 由人或 Agent 在运行中更新,保存任务状态、验证结果、发现的偏好和经验模式。两者可能记录相似事实,关键差别是何时加载、由谁维护:Skill 在相关任务触发时按需读取,Memory 随工作积累并在启动或检索时进入上下文。
Skill 是 harness 改进的积累单元。 每次流程在新情况下失败,把教训补进对应的 Skill,下一次运行就继承了这个经验。这就是"自我改进系统"的实质——不是模型在学习,而是 Skill 文件在积累。模型没变,但 harness 变锋利了。
为新一代模型校准 Skill
Skill 是写给模型的指令,而模型在不断变强——OpenAI 在《Rethinking skills and prompts for GPT-6 Astra》中总结了 GPT-6 Astra 一代暴露出的 Skill 失败模式与 $skill-creator 的更新方向:
- 描述过载:人们习惯往项目里打包大量 Skill,而每个 Skill 的 name + description 都会进入模型上下文。Skill 一多,Codex 会开始截短描述来装下它们——模型实际看到的描述变少,更难挑对 Skill。更糟的是,描述之间常常互相矛盾,或过度强调触发场景,导致模型加载与任务无关的指令。
- 描述尽量短、触发边界要清晰:不好的描述让模型在"碰到任何和数据库相关的东西"时都触发(如"Use when working with databases, queries, models, or persistence"),好的描述只说清楚何时适用(如"Use when adding or changing a migration, or reviewing its rollout"——只在处理 migration 时触发)。
- 渐进披露写法:读 Skill 消耗上下文,把任务推向压缩、引入不适用的指导。对包含多个工作流的 Skill,根文档应做成最小 router:只给模型足够的指引告诉它去哪找(支持文档、脚本),不强迫它读当下无关的内容。
- 过度具体的指南现在反而妨碍:许多 Skill 被写成详细的 itinerary 或 recipe;模型对 nuance 和歧义的理解已经好得多,以前靠细则换来的可靠性,现在可能以牺牲结果为代价。
- 跨模型考虑:仓库里的 Skill 也在指导其他贡献者的 Agent,它们可能用不同模型。帮助 Sol 或 GPT-5.6 Luna 的指导可能过度约束 GPT-6 Astra——留下指令时考虑谁会读它们。
同一个教训也适用于 AGENTS.md 与任务 prompt。
常驻规则文件:AGENTS.md
AGENTS.md 是一个开放格式标准:把给 Agent 的项目指令写成 Markdown 文件,放在仓库根目录(或子目录)中,Agent 在仓库内工作时自动读取。与 Skill 针对某类任务、按需触发不同,AGENTS.md 的作用域是仓库内的所有任务——修一个 typo 和重构一个模块,Agent 都会在同样的指令下工作。它通常承载构建/测试命令、代码规范、目录结构说明、已知坑点、安全边界和验证方式;具体语义(始终加载、向上查找、是否允许模型写入)由各 harness 决定,详见 Agent Memory(Agent 记忆)中的语义辨析。
| 维度 | AGENTS.md | Skill |
|---|---|---|
| 作用域 | 仓库内所有任务 | 特定工作流或应用 |
| 加载方式 | 每次在仓库内工作时自动读取 | 名称 + description 常驻,命中任务后读正文 |
| 适合内容 | 稳定规则、命令、边界 | 长流程、参考资料、可执行脚本 |
| 维护频率 | 随模型换代与仓库演进重审 | 随流程失败沉淀教训 |
AGENTS.md 里的每条指令都是写给模型的,因此上文对 Skill 的校准经验(描述短、渐进披露、少而准)同样适用。OpenAI 在同一篇文章中对 AGENTS.md 的具体建议:
按需阅读,不要强制预读:旧的"每次编辑前先读 architecture.md、database.md、deployment.md"是给需要推着的模型写的;现在应改成按用途指向——“architecture.md 用于服务边界,database.md 用于 schema 改动,deployment.md 在准备部署时读”。要求每次编辑前读全仓库文档是烧上下文、拖慢工作的好办法;指文档仍然有用,但要带语境。修一个 typo 不需要先做全仓库导览。
不要重复模型已内化的习惯:以前的模型需要鼓励才跑测试、检查自己的工作,新一代模型会自己做,同样的指令只会导致不必要的测试。
给它权限而不是只给约束:新一代模型更全面,但对任务走多远可能更谨慎。可以在 AGENTS.md 里为已知安全的工作流显式授权:
本地测试使用一次性 fixtures,无生产访问。运行它们,修复由所请求改动导致的失败,并重跑受影响的测试,无需每一步请求批准。
重写决策边界的语言:如果过去为防止其他模型越权写了很重的"先问再做",切到 GPT-6 Astra 后应考虑更新——它把边界当真,可能在你实际希望它继续的地方停下工作。详见 Agent Guardrails(Agent 护栏)。
换模型也是清理指令的好时机,但不需要人工逐条过:OpenAI 建议直接让 Astra 按上述原则对仓库指令做一次审计,再去做以前不敢做的事。
工具实现
| 工具 | Skill 形式 |
|---|---|
| Claude Code | .claude/skills/ 下的按需技能;支持 frontmatter、动态上下文、支持文件、forked subagent 和 plugin 分发 |
| OpenAI Codex | SKILL.md 文件 |
| OpenAI API | 通过 POST /v1/skills 上传版本化 Skill bundle,并在 Responses API 的 Shell 工具环境中挂载 |
| 通用约定 | 常驻规则文件(全局)+ Skill(任务相关)+ Memory(运行中积累) |
Claude Code 的自定义 Subagent(子智能体)可在 frontmatter 的 skills 字段中声明预载 Skill。被列出的 Skill 全文会在 subagent 启动时注入其独立上下文;这个字段只控制预加载,不构成访问白名单。若要完全禁止 subagent 临时调用其他 Skill,需要从其工具权限中移除 Skill。
Codex 的 CLI 在构造初始输入时,会把配置好的技能元数据、技能使用说明和项目文档一起聚合到用户指令中。也就是说,Skill 不是模型外部的"文档备注",而是 Agent Loop(智能体循环)初始上下文的一部分,会直接影响模型后续工具调用和执行策略。
OpenAI API 则把 Skill 放进工具层:一个 Skill bundle 是带 SKILL.md manifest 的版本化文件束,SKILL.md frontmatter 至少提供 name 和 description,用于发现和路由;正文提供模型在真正使用该 Skill 时才需要读取的操作说明。上传时可以用 POST /v1/skills multipart 传多个文件,也可以上传 zip。一个 bundle 只能包含一个 SKILL.md 或 skill.md;OpenAI 当前限制包括 zip 最大 50 MB、单个 Skill 版本最多 500 个文件、单个未压缩文件最大 25 MB。
挂载时,OpenAI 托管容器 Shell(hosted shell,environment.type: "container_auto")使用已上传的 skill_reference,可指定整数版本或 "latest";local shell 不能使用已上传的 skill_reference,而是用本地 name、description 和 path 暴露 Skill 文件。OpenAI 也支持 inline skill:把 zip bundle 以 base64 形式作为 type: "inline" 放进环境的 skills 数组。平台会把 Skill 的 name、description 和 path 加入用户 prompt 上下文;模型需要时再读取 SKILL.md。这意味着 Skill 的正文在优先级上仍是用户输入,不等同于 system prompt。
版本管理是 API Skills 与本地文件型 Skill 的一个重要差别。未指定版本时使用 default_version;latest_version 指向最新上传;skill_reference.version 可以是整数版本,也可以是 "latest"。生产系统通常应固定 Skill 版本,而不是长期浮动到最新版本,因为 Skill 会影响规划、工具使用和命令执行,版本漂移相当于在不改应用代码的情况下改变 Agent 行为。
Skill 这个词的另一种用法
在 Durable Execution(持久执行)语境里,“Skill” 指的是另一层东西:一个多步骤、可重试、可独立部署的持久工作流函数——“循环的资产”。它不存在于上下文里,而是存在于编排引擎里,进程重启后继续运行。Matt Van Horn 的表述:The loop is plumbing. The asset is the skill it calls.
两种用法不矛盾,而是分工:本词条描述的 Skill 是 SKILL.md 文件,告诉 Agent “这个项目怎么做事”;持久工作流意义上的 Skill 是 Agent 写出并部署的可执行函数,是系统层面的能力积累。在编排感知 Agent的场景里,两者同时存在:Agent 加载 SKILL.md 作为上下文,再把新的持久函数写入编排引擎作为产出。
相关概念
- Intent Debt(意图债) — Skill 要消除的核心问题
- Loop Engineering(循环工程) — Skill 是 Loop 5 大模块之一
- Agent Memory(Agent 记忆) — 与 Skill 互补的动态状态层
- Harness Engineering(驾驭工程) — 与 Skill 高度重合的执行层约束
- Context Engineering(上下文工程) — Skill 是上下文工程中"长期稳定知识"的持久化方式
- Codex — 使用 Skill 元数据构造 Agent 初始上下文的具体工具
- Durable Execution(持久执行) — 持久工作流 Skill 所依赖的基础设施层
- Claude Code —
.claude/skills/和CLAUDE.md的具体宿主环境