青蛙小白

Skill(技能)

Skill(技能) 是将项目背景、代码规范、常用命令、测试方式、已知坑点等隐性知识,打包成 Agent 可在会话中调用的可复用单元。

为什么需要 Skill

没有 Skill,开发者面对两个选择:

  1. 每次对话都把约定重新塞进 Prompt(每轮重复,费时且容易遗漏)
  2. 让 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-toolsskill 激活时的工具预批准或移除
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.mdSkill
作用域仓库内所有任务特定工作流或应用
加载方式每次在仓库内工作时自动读取名称 + 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 CodexSKILL.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 作为上下文,再把新的持久函数写入编排引擎作为产出。

相关概念

参考来源
  1. 1. https://addyosmani.com/blog/loop-engineering/
  2. 2. https://openai.com/index/unrolling-the-codex-agent-loop/
  3. 3. https://x.com/djfarrelly/status/2067677007140278630
  4. 4. https://code.claude.com/docs/en/best-practices
  5. 5. https://code.claude.com/docs/en/memory
  6. 6. https://code.claude.com/docs/en/sub-agents
  7. 7. https://code.claude.com/docs/en/skills
  8. 8. https://x.com/ClaudeDevs/status/2074208949205881033
  9. 9. https://www.anthropic.com/engineering/equipping-agents-for-the-real-world-with-agent-skills
  10. 10. https://agentskills.io/home
  11. 11. https://agentskills.io/specification
  12. 12. https://developers.openai.com/api/docs/guides/tools-shell
  13. 13. https://developers.openai.com/api/docs/guides/tools-skills
  14. 14. https://developers.openai.com/cookbook/examples/skills_in_api
  15. 15. https://developers.openai.com/blog/rethinking-skills-and-prompts-for-gpt-6-astra
评论