乐于分享
好东西不私藏

AI编程助手Skill技能系统深度拆解-Claude Code和OpenCode的技能到底怎么玩

AI编程助手Skill技能系统深度拆解-Claude Code和OpenCode的技能到底怎么玩

AI 编程助手 Skill 技能系统深度拆解:Claude Code 和 OpenCode 的技能到底怎么玩?

上篇文章《AI 编程助手约束文件全解析:CLAUDE.md 和 AGENTS.md 到底怎么配?》发出来之后,后台好几个人问了同一个问题:「你提到的 Skill 技能系统,到底是什么?怎么用?和约束文件是什么关系?」

说实话这个问题我当时故意没展开——因为技能系统的水比约束文件深多了。约束文件解决的是「告诉 AI 你的项目规矩」,而技能系统解决的是「让 AI 学会新本事」。一个是员工手册,一个是技能培训。

今天就把这事彻底说清楚。Claude Code 和 OpenCode 的 Skill 系统,从设计理念到目录结构到加载机制,全拆一遍。


先理解一个问题:约束文件够用了,为什么还要技能?

上篇文章说过,CLAUDE.md / AGENTS.md 是给 AI 的「员工手册」——项目用什么技术栈、编码规范是什么、哪些红线不能碰。

但你有没有遇到过这种情况:

  • 你想让 AI 帮你生成一张信息图,它不知道该调哪个 API、用什么参数
  • 你想让 AI 把代码部署到测试环境,它不知道你的部署流程是 3 步还是 5 步
  • 你想让 AI 分析一个 CSV 文件,它每次都要从头写一遍 pandas 代码,而且每次写的还不太一样

这些事靠约束文件是搞不定的。约束文件告诉 AI「怎么做是对的」,但不教它「怎么做一件具体的事」。

技能系统就是来补这个缺口的——把一整套可复用的工作流打包成一个「技能包」,AI 需要的时候加载进来,按步骤执行。

打个比方:约束文件是公司的《员工守则》,技能是《岗位操作手册》。守则告诉你「不能迟到」「代码要写注释」,操作手册教你「怎么一步步把容器部署到 K8s」。


Claude Code 的 Skill 系统

先说 Claude Code 的方案。Anthropic 在这块迭代得很快,最新版本已经把之前的 Custom Commands(自定义命令)和 Skills(技能)合并成了统一的技能体系。

核心概念:SKILL.md

每个技能就是一个文件夹,里面必须有一个 SKILL.md 文件,这是技能的入口。

explain-code/├── SKILL.md           # 必须有,技能入口├── scripts/           # 可选,可执行脚本│   └── analyze.py├── references/        # 可选,参考文档│   └── api-docs.md└── assets/            # 可选,模板、图片等资源    └── template.html

SKILL.md 由两部分组成——YAML 头部元数据 + Markdown 正文指令

name: explain-codedescription: 用可视化图表和类比解释代码。当用户问”这段代码怎么工作的”时自动触发。解释代码时,按以下步骤进行:1. **先打比方**:把代码逻辑比作日常生活中的场景2. **画个图**:用 ASCII 字符画展示代码的流程或结构3. **逐步讲解**:一步步说清楚代码做了什么4. **点出坑**:这段代码有什么常见的误用或陷阱?

头部的 description 极其关键——Claude 根据这个描述来决定「要不要自动加载这个技能」。你问它「这段代码怎么工作的?」,它看到 description 里写了「当用户问怎么工作时触发」,就会自动把这个技能加载进来。

技能放哪?三个位置,各管各的

位置
路径
作用域
场景
个人级
~/.claude/skills/<技能名>/SKILL.md
所有项目通用
你个人的通用工作流
项目级
.claude/skills/<技能名>/SKILL.md
仅当前项目
团队共享,提交到 Git
插件级
<插件>/skills/<技能名>/SKILL.md
插件启用时可用
第三方技能包分发

优先级:企业级 > 个人级 > 项目级。同名技能按优先级覆盖,插件级技能有独立命名空间(/插件名:技能名),不会冲突。

还有个实用特性——子目录自动发现。如果你在 packages/frontend/ 下工作,Claude Code 会自动去找 packages/frontend/.claude/skills/ 里的技能。Monorepo 的福音。

加载机制:三级渐进式

这是 Claude Code 技能系统最精巧的设计——不是所有技能内容都一次性塞进上下文

层级
加载什么
什么时候加载
大概多大
第一层
name + description
会话启动时
约 100 词/技能
第二层
SKILL.md 完整正文
技能被触发时
建议 < 500 行
第三层
scripts/、references/、assets/
Claude 按需读取
无限制

启动时只把所有技能的名称和描述加载进去(占上下文窗口 2%,约 16000 字符),让 Claude 知道「我有哪些技能可用」。只有当某个技能被触发(用户手动 /技能名 或 Claude 根据对话自动判断),才把完整的 SKILL.md 内容加载进来。

脚本和参考文档?Claude 自己判断需不需要读。你在 SKILL.md 里写上「表单填写的详细指南见 forms.md」,Claude 碰到表单任务时自己去读,不碰就不读。

这个设计的好处是省 token。 你可以装 50 个技能,但日常对话中可能只触发 2-3 个,大部分技能只贡献了一行描述文字的开销。

谁来触发?可以控制

技能触发有两种方式:

  1. 用户手动调用:输入 /技能名
    ,就像用斜杠命令
  2. Claude 自动触发:Claude 根据对话内容匹配 description,觉得相关就自动加载

但有些技能你不想让 Claude 自作主张——比如部署到生产环境的技能。Claude 觉得「代码看着差不多了」就自动部署?想想就刺激。

两个控制开关:

name: deploydescription: 部署应用到生产环境disable-model-invocation: true   # Claude 不能自动触发,只能用户手动 /deploy
name: legacy-system-contextdescription: 老系统的技术背景知识user-invocable: false   # 用户不能手动调用,只有 Claude 觉得需要时才加载
配置
用户能调
Claude 能调
适用场景
默认
大部分技能
disable-model-invocation: true
不能
部署、发送通知等有副作用的操作
user-invocable: false
不能
背景知识、内部规范等参考类技能

参数传递:$ARGUMENTS

技能支持接收参数,用 $ARGUMENTS 占位符:

name: fix-issuedescription: 修复 GitHub issuedisable-model-invocation: true修复 GitHub issue $ARGUMENTS,遵循项目编码规范:1. 阅读 issue 描述2. 理解需求3. 实现修复4. 编写测试5. 创建 commit

用户输入 /fix-issue 123,Claude 收到的就是「修复 GitHub issue 123」。还支持按位置取参数:$ARGUMENTS[0]$ARGUMENTS[1] 或简写 $0$1

动态注入:Shell 命令预处理

这个功能有点意思—— ` !command` 语法可以在技能内容发送给 Claude 之前,先执行一段 Shell 命令,把结果注入进去:

name: pr-summarydescription: 总结 PR 变更内容context: fork## PR 上下文– PR diff: !`gh pr diff`– PR 评论: !`gh pr view –comments`– 变更文件: !`gh pr diff –name-only`## 你的任务总结这个 PR 的变更…

技能被触发时,三个 gh 命令先执行,输出替换掉原始占位符,Claude 收到的是包含真实 PR 数据的完整提示词。这是预处理,不是 Claude 在执行。

子代理执行:context: fork

加上 context: fork,技能会在一个独立的子代理里运行,和主会话隔离:

name: deep-researchdescription: 深度调研某个主题context: forkagent: Explore深入调研 $ARGUMENTS:1. 用 Glob 和 Grep 查找相关文件2. 阅读分析代码3. 输出带文件引用的调研报告

agent 字段指定用哪种子代理执行(ExplorePlan 或自定义的),执行完把结果汇总返回给主会话。适合那种需要大量读取文件但不应该污染主对话上下文的任务。

内置技能:开箱即用

Claude Code 自带了几个官方技能:

技能
功能
/simplify
审查最近修改的文件,检查代码复用/质量/效率问题并自动修复
/batch
跨代码库大规模并行修改,每个子任务独立 worktree
/debug
排查当前会话问题,读取 debug 日志定位原因
/loop
定时循环执行某个提示词(轮询部署状态等)
/claude-api
加载 Claude API 参考文档

/batch 比较值得一提——它会把一个大任务拆成 5-30 个独立子任务,每个子任务在独立的 git worktree 里并行执行,各自跑测试、各自提 PR。适合「把项目从 React 迁移到 Vue」这种大规模改造。

和 Custom Commands 的关系

如果你之前用过 Claude Code 的 .claude/commands/ 目录,不用急着迁移——旧的命令文件继续生效。技能系统是 commands 的超集,.claude/commands/deploy.md 和 .claude/skills/deploy/SKILL.md 效果一样。同名情况下技能优先。

官方建议新的都用 skills,因为 skills 支持附带脚本和参考文件,commands 只是单个 Markdown 文件。


OpenCode 的 Skill 系统

OpenCode 的技能系统和 Claude Code 思路类似,但实现上走了不同的路。

核心概念:也是 SKILL.md

每个技能也是一个文件夹 + SKILL.md 入口,结构几乎一样:

image-service/├── SKILL.md           # 技能入口├── config/            # 配置文件│   └── settings.json├── scripts/           # 可执行脚本│   ├── text_to_image.py│   └── image_to_text.py├── docs/              # 参考文档└── references/        # 详细 API 文档

SKILL.md 的格式也是 YAML 头部 + Markdown 正文:

name: image-servicedescription: 多模态图像处理技能,支持文生图、图生图、视觉分析。  当用户消息包含图片路径、URL 或提及图像处理时自动触发。metadata:  version: “1.0.0”# 图像处理技能## 能力概述| 能力 | 说明 | 脚本 ||—–|——|——|| 文生图 | 文本描述生成图片 | `scripts/text_to_image.py` || 图生图 | 已有图片编辑 | `scripts/image_to_image.py` |

到这里为止,看着和 Claude Code 很像。但接下来就不一样了。

技能放哪?只有一个默认位置

OpenCode 的技能只有一个自动发现路径

~/.config/opencode/skills/├── image-service/│   └── SKILL.md├── deep-research/│   └── SKILL.md├── xlsx/│   └── SKILL.md└── …(其他技能)

放在这个目录下的技能,OpenCode 启动时自动扫描、自动注入上下文,不需要任何额外注册。

跟 Claude Code 的区别在这:

对比项
Claude Code
OpenCode
个人级
~/.claude/skills/ ~/.config/opencode/skills/
项目级
.claude/skills/

 ✅
不支持 ❌
子目录发现
支持 ✅
不支持 ❌
插件级
支持(命名空间隔离)✅
不支持 ❌

OpenCode 没有项目级技能目录。我之前专门做了个实验——在项目根目录下建了 skills/test-skill/SKILL.md,重启之后 AI 完全识别不到。只有全局目录 ~/.config/opencode/skills/ 才是自动发现路径

这意味着 OpenCode 的所有技能都是「全局共享」的,没法给某个项目单独配一套技能。

变通方案:用 AGENTS.md 实现「项目级技能」

虽然 OpenCode 官方不支持项目级 skills 目录,但有个实用的变通方案——在项目的 AGENTS.md 里手动注册技能清单,指定任意路径的技能

比如你的项目有些专属脚本和工作流,不想污染全局 skills 目录,可以这么搞:

第一步,在项目里建一个 skills 目录:

myproject/├── AGENTS.md├── .project-skills/          # 项目专属技能│   ├── deploy-staging/│   │   ├── SKILL.md│   │   └── scripts/│   │       └── deploy.sh│   └── gen-api-doc/│       ├── SKILL.md│       └── scripts/│           └── gen_doc.py└── src/

第二步,在项目的 AGENTS.md 里注册这些技能:

## 项目专属技能本项目包含以下专属技能,使用时请先加载对应技能:### deploy-staging– **路径**:`.project-skills/deploy-staging/SKILL.md`– **用途**:部署到预发布环境– **触发词**:部署预发、发布 staging– **使用方式**:执行时先读取 `.project-skills/deploy-staging/SKILL.md` 获取完整操作步骤### gen-api-doc– **路径**:`.project-skills/gen-api-doc/SKILL.md`– **用途**:根据代码注释生成 API 文档– **触发词**:生成 API 文档、更新接口文档– **使用方式**:执行时先读取 `.project-skills/gen-api-doc/SKILL.md` 获取完整操作步骤

原理很简单:AGENTS.md 本身就是 AI 的「指令文件」,你在里面写清楚「这个项目有这些技能,文件在这个路径,什么时候用」,AI 就会按描述去读取对应的 SKILL.md 并执行。

本质上是用 AGENTS.md 当了一个「手动索引」,把技能发现的工作从系统自动扫描降级为约束文件声明。虽然没有自动发现那么优雅,但胜在灵活——你可以把技能放在任何路径,甚至引用项目外的共享目录

这个方案还有个隐藏好处:项目级技能跟着 Git 走,团队成员 clone 下来就能用,不需要每个人都往全局 skills 目录里装一遍。

加载机制:也是渐进式,但方式不同

OpenCode 的技能加载分两步:

  1. 启动时:扫描 ~/.config/opencode/skills/
     下所有技能,读取每个 SKILL.md 的 name 和 description,注入到系统提示词
  2. 触发时:用户调用 /技能名
     或 AI 通过 skill() 函数主动加载,此时才读取完整的 SKILL.md 内容

和 Claude Code 的三级渐进式类似。但 OpenCode 有个额外的机制——内置技能

除了用户安装的技能,OpenCode 还内置了 4 个技能:

内置技能
用途
playwright
浏览器自动化
frontend-ui-ux
前端 UI/UX 开发
git-master
Git 操作
dev-browser
持久化浏览器自动化

最终可用的技能列表 = 内置技能 + 全局目录自动扫描。是并集关系。

之前的坑:手动注册

这里得说一段历史。早期版本的 OpenCode,技能安装到 ~/.config/opencode/skills/ 之后,还需要在 AGENTS.md 里手动注册,写上触发词和调用方式。不注册的技能 AI 看不到,等于白装。

后来 OpenCode 升级了技能发现机制,从「手动声明」变成了「自动扫描+注入」。现在 AGENTS.md 里的技能清单变成了可选的补充说明——写上也不会冲突,但不写也能正常发现和使用。

别问我怎么知道这个坑的。

调用方式:斜杠命令 + 技能函数

OpenCode 的技能有两种调用方式:

1. 用户手动调用: 输入 /技能名,和 Claude Code 一样

/image-service/deep-research 帮我调研 RAG 的最新方案

2. AI 自动触发: OpenCode 给 AI 提供了一个 skill() 工具函数,AI 在对话过程中可以自己决定加载某个技能:

# AI 内部调用(用户看不到这个过程)skill(name=”image-service”)

触发逻辑和 Claude Code 类似——根据 description 里的关键词匹配。你说「帮我生成一张图」,AI 看到 image-service 的描述里写了「图像处理」,就自动加载。

技能里的脚本

OpenCode 的技能大量使用了脚本机制。拿 image-service 技能来说,它不是靠 AI「自由发挥」来生成图片,而是调用预写好的 Python 脚本:

# 文生图python ~/.config/opencode/skills/image-service/scripts/text_to_image.py “一只猫在写代码” -r 16:9 -o cat.png# 图生图python ~/.config/opencode/skills/image-service/scripts/image_to_image.py input.png “改成水彩风格” -o output.png

这个思路和 Claude Code 的 scripts/ 目录一样——把需要确定性执行的操作封装成脚本,AI 负责编排调用,不负责重写逻辑。每次执行结果一致,不会出现「今天生成的代码和昨天不一样」的玄学问题。

OpenCode 特有:Agent 分发 + 技能加载

OpenCode 有个 Claude Code 没有的特性——多 Agent 分发时携带技能

OpenCode 支持把任务分发给不同的子代理执行,分发时可以指定「这个子代理需要加载哪些技能」:

task(  category=”visual-engineering”,  load_skills=[“image-service”, “frontend-ui-ux”],  prompt=”生成一张活动海报…”)

子代理是无状态的——它不知道全局有哪些技能。你不通过 load_skills 传给它,它就是个「什么都不会」的白板。这个设计和 Claude Code 的 context: fork + agent 类似,但更显式——你必须明确告诉子代理该装什么技能。


正面对比:两套系统的核心差异

目录结构对比

维度
Claude Code
OpenCode
技能入口
SKILL.md

(相同)
SKILL.md

(相同)
个人级路径
~/.claude/skills/ ~/.config/opencode/skills/
项目级路径
.claude/skills/

 ✅
不支持 ❌
子目录发现
支持 ✅
不支持 ❌
插件分发
支持(命名空间隔离)✅
不支持 ❌
企业级管理
支持 ✅
不支持 ❌

技能配置对比

能力
Claude Code
OpenCode
自动触发控制
disable-model-invocation

 / user-invocable
仅靠 description 匹配
参数传递
$ARGUMENTS

$0~$N
斜杠命令后跟参数
工具限制
allowed-tools

 字段
子代理执行
context: fork

 + agent
task()

 + load_skills
动态注入
` !command` 预处理
Hooks 生命周期
支持(17 种事件)
指定模型
model

 字段
通过 category 间接指定

加载机制对比

行为
Claude Code
OpenCode
启动时加载
所有技能的 name + description(上下文 2%)
所有技能的 name + description
触发时加载
SKILL.md 完整正文
SKILL.md 完整正文
按需加载
references/、scripts/ 由 Claude 自行决定
参考文档由 AI 自行决定
技能上限
有字符预算(可通过环境变量调整)
无明确限制
热更新
支持,编辑后不用重启
需要新开会话

适用场景对比

场景
推荐
原因
个人常用工作流
两者都行
全局技能目录功能一致
团队共享技能
Claude Code
支持项目级 + Git 提交
企业统一管理
Claude Code
支持 managed settings
多 Agent 协作
OpenCode
load_skills

 显式装载更灵活
第三方技能分发
Claude Code
插件系统 + 命名空间
需要严格控制触发
Claude Code
disable-model-invocation

 开关

实战:从零创建一个技能

光说不练假把式。下面用一个「部署到测试环境」的技能,分别演示两边怎么创建。

Claude Code 版本

# 创建技能目录(项目级,提交到 Git 共享给团队)mkdir -p .claude/skills/deploy-test

写 .claude/skills/deploy-test/SKILL.md

name: deploy-testdescription: 部署应用到测试环境disable-model-invocation: trueallowed-tools: Bash(npm *), Bash(docker *), Bash(kubectl *)部署 $ARGUMENTS 到测试环境:1. 运行测试:`npm test`2. 构建镜像:`docker build -t app:test .`3. 推送镜像:`docker push registry.example.com/app:test`4. 更新 K8s:`kubectl set image deployment/app app=registry.example.com/app:test -n test`5. 等待就绪:`kubectl rollout status deployment/app -n test`6. 验证健康检查:`curl -f http://test.example.com/health`

使用:/deploy-test v1.2.3

OpenCode 版本

# 创建技能目录(全局,所有项目可用)mkdir -p ~/.config/opencode/skills/deploy-test

写 ~/.config/opencode/skills/deploy-test/SKILL.md

name: deploy-testdescription: 部署应用到测试环境。当用户说”部署到测试”、”发布测试环境”时触发。部署应用到测试环境,按以下步骤执行:1. 运行测试:`npm test`2. 构建镜像:`docker build -t app:test .`3. 推送镜像:`docker push registry.example.com/app:test`4. 更新 K8s:`kubectl set image deployment/app app=registry.example.com/app:test -n test`5. 等待就绪:`kubectl rollout status deployment/app -n test`6. 验证健康检查:`curl -f http://test.example.com/health`

使用:/deploy-test 或直接说「部署到测试环境」

区别在哪?

区别点
Claude Code
OpenCode
存放位置
项目级(可提交 Git)
全局级(不跟项目走)
触发控制
disable-model-invocation

 禁止自动触发
无法禁止,靠 description 匹配
工具限制
allowed-tools

 白名单
无限制
参数传递
$ARGUMENTS

 占位符
跟在斜杠命令后面

写好 SKILL.md 的几条经验

不管用哪个工具,SKILL.md 的质量直接决定技能好不好用。踩了一些坑之后,总结几条:

1. description 是灵魂,写不好等于白写

AI 根据 description 判断要不要加载你的技能。写得太笼统——每次对话都乱触发;写得太窄——该用的时候不触发。

# 太笼统:聊什么都能匹配上description: 处理各种任务# 太窄:只有精确输入才触发description: 处理 16:9 比例的 PNG 格式科技风海报# 刚好:明确能力边界 + 列出触发场景description: 多模态图像处理。支持文生图、图生图、视觉分析。  当用户消息包含图片文件路径、图片 URL,或提及生成图片、  分析图片时触发。

2. SKILL.md 控制在 500 行以内

每次技能触发,整个 SKILL.md 都会被塞进上下文。太长了不仅费 token,AI 的注意力也会被稀释。

详细的 API 文档、使用示例、配置说明——拆到 references/ 目录下的独立文件里,在 SKILL.md 中用链接引用:

## 高级用法– 表单填写详细指南:见 [forms.md](forms.md)– API 完整参考:见 [reference.md](reference.md)

Claude 需要的时候自己去读,不需要的时候不占空间。

3. 能用脚本的别让 AI 自由发挥

AI 每次「自由发挥」写出来的代码可能不一样。涉及到文件操作、API 调用、部署流程这种需要确定性的事,封装成脚本:

## 使用方式运行文生图脚本(确定性执行,每次结果一致):python scripts/text_to_image.py “描述” -r 16:9 -o output.png

脚本的好处:确定性高、可以独立测试、token 消耗低(执行但不需要读进上下文)。

4. 同一技能里区分「参考内容」和「任务内容」

有些技能是给 AI 补充背景知识的(coding conventions、API 规范),有些是教 AI 执行具体任务的(部署、生成报告)。别混在一起:

  • 参考型技能:主要是约束和规范,AI 在执行其他任务时参考。适合自动触发。
  • 任务型技能:有明确的执行步骤,用户主动调用。适合 disable-model-invocation: true

总结

Skill 技能系统是约束文件的自然延伸——约束文件管「什么是对的」,技能管「怎么把事做对」。

两边的设计哲学差异很明显:

  • Claude Code:走的是精细化路线。项目级/个人级/企业级分层、触发控制开关、工具白名单、Hooks 生命周期、动态注入——功能全但学习曲线陡
  • OpenCode:走的是简洁路线。全局目录自动扫描、自动注入、多 Agent 分发时显式装载——上手快但缺乏精细控制

选哪个?老话——看场景:

  • 团队协作、需要把技能提交到 Git → Claude Code
  • 个人使用、快速搭建工作流 → OpenCode 更省心
  • 两个都用 → 技能的核心逻辑(脚本、参考文档)抽成独立文件,SKILL.md 各写一份包装

不过有一点是共通的:技能的价值不在于数量,在于每个技能的 description 写得好不好、SKILL.md 的指令清不清晰、脚本够不够稳定。 装了 50 个技能但触发逻辑乱七八糟,还不如 5 个精心打磨的技能好使。

工具是死的,手艺是活的。


*接上篇约束文件全解析,这篇把技能系统也讲完了。下回有人问「Skill 是什么」,甩这篇文章就行。*


#AI编程 #ClaudeCode #OpenCode #Skill技能 #AI编程助手 #编程工具 #效率工具 #AIAgent #开发者工具 #技能系统 

     觉得有用?扫码关注「昕悦技术栈」持续输出实战干货

长按识别二维码,关注我!

本站文章均为手工撰写未经允许谢绝转载:夜雨聆风 » AI编程助手Skill技能系统深度拆解-Claude Code和OpenCode的技能到底怎么玩

猜你喜欢

  • 暂无文章