OpenCode / ClaudeCode / Codex Skills 等文件夹兼容性对比
多个维度(Instructions / Skills / Commands / Agents / Hooks / Rules / MCP / 配置文件)逐项拆解
- 直接读:skills 文件内容基本上能得到三家互认。
- 搬目录:commands / agents 从
.claude/复制到.opencode/,内容通常能复用。 - 要重写:hooks(配置 vs JS/TS 模块)/ config(JSON vs TOML)范式不同。
- 软链共享:用
.shared/+ 软链把 skills / AGENTS.md 做成单一源;其他目录格式 / 范式不同,必须独立维护。 - Skills 互认:遵循 Agent Skills 开放标准,最低 SKILL.md 可直接迁移。
一图看懂:三个工具的兼容性矩阵
| 对比维度 | ClaudeCode | Codex | OpenCode |
|---|---|---|---|
| Instructions | CLAUDE.md | AGENTS.mdCLAUDE.md(需配置)1 | AGENTS.mdCLAUDE.md(fallback) |
| Skills | .claude/skills/ | .agents/skills/ | .opencode/skills/.agents/skills/.claude/skills/ |
| Commands | .claude/commands/ | 不支持(仅内置) | .opencode/commands/ |
| Agents | .claude/agents/(markdown) | .codex/agents/(TOML) | .opencode/agents/(markdown) |
| Hooks | .claude/settings.json.claude/hooks/ 是脚本存放约定,不自动加载2事件: PreToolUse / PostToolUse 等 | .codex/hooks.json 或 .codex/config.toml没有 .codex/hooks/ 目录事件: PreToolUse / PostToolUse / SessionStart 等 | .opencode/plugins/*.{js,ts}没有 .opencode/hooks/ 目录事件: tool.execute.before / tool.execute.after 等 |
| Rules | .claude/rules/*.md(paths frontmatter)3 | .codex/rules/(prefix_rule)4 | 不支持 |
| MCP | .mcp.json5字段: mcpServers类型: stdio / http | .codex/config.toml字段: [mcp_servers.<name>]类型: stdio / http | opencode.json6字段: mcp类型: local / remote |
| 配置文件 | .claude/settings.json | .codex/config.toml | opencode.json6 |
-
"需配置"是什么意思:Codex 默认只读
AGENTS.md——CLAUDE.md要在config.toml里显式加上才会读:project_doc_fallback_filenames = ["CLAUDE.md"]不写这一行,
CLAUDE.md就被忽略。和 OpenCode 的CLAUDE.md自动 fallback 形成对比。 -
"不自动加载"是什么意思:放在
.claude/hooks/xxx.sh的脚本不会自己跑——必须在~/.claude/settings.json或.claude/settings.json里用hooks.<event>.hooks[].command字段显式引用脚本路径才会触发。常见配置:{"hooks": {"PostToolUse": [{"matcher": "Edit|Write","hooks": [{ "type": "command", "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/format.sh" }]}]}}不放 settings.json 引用的话,
.claude/hooks/里的脚本就是孤儿文件,Claude Code 永远不会执行。所以叫"约定俗成的脚本存放位置"——目录是给人看的,不是工具读的。 -
"paths frontmatter"是什么:Claude Code 规则文件顶部用 YAML 写
paths字段,只在 Claude 操作匹配这些 glob 模式的文件时才加载规则:---paths:- "src/api/**/*.ts"- "lib/**/*.ts"---# API 开发规则- 所有 API 端点必须做入参校验不写
paths字段的规则文件无条件加载(每次会话都进上下文)。paths支持 glob 模式:模式 匹配 **/*.ts所有 TypeScript 文件 src/**/*src/目录下所有文件*.md项目根的 markdown src/components/*.tsx特定目录的 React 组件 -
"prefix_rule"是什么:Codex 规则系统用函数式语法
prefix_rule()定义命令前缀 + 决策(allow / deny / ask),比 Claude Code 的路径作用域更底层——直接拦截 shell 命令前缀而不是加载提示词:prefix_rule(pattern = ["git"], decision = "allow")prefix_rule(pattern = ["rm", "-rf"], decision = "deny")prefix_rule(pattern = ["sudo"], decision = "ask")pattern:匹配的命令前缀数组(按 token 匹配,不是正则)decision:匹配后 Codex 的处理方式(allow直接执行、deny直接拒绝、ask询问用户)
规则文件用
codex execpolicy check <cmd>测试是否被拦截。和 Claude Code 的差异:Claude 用 prompt 引导("操作这些文件时..."),Codex 用命令拦截("这些命令前缀...做...")——一个在输入端劝导,一个在执行端强制。 -
.mcp.json不在.claude/下:Claude Code 大部分配置(settings.json/rules//hooks//agents//skills/)都藏在.claude/里,但.mcp.json是例外——它在项目根,和package.json同级。原因是设计上要git add进去让团队共享(参考 Claude Code MCP 文档 - project-scope 小节):{"mcpServers": {"context7": {"type": "stdio","command": "npx","args": ["-y", "@upstash/context7-mcp"]}}}如果想团队共享某个 MCP 配置:放在项目根
.mcp.json(commit 进去);如果只想本地用:放~/.claude.json(不 commit)。 -
opencode.json也不在.opencode/下:OpenCode 把所有东西都藏进.opencode/(agents / commands / skills / plugins)——但主配置文件是例外,放在项目根,和package.json同级。和 Claude Code 的.mcp.json(见注脚 5)是同一种设计哲学:让工具的核心配置git add进版本控制,方便团队共享。{"$schema": "https://opencode.ai/config.json","model": "anthropic/claude-sonnet-4-6"}如果想团队共享:放在项目根
opencode.json(commit 进去);如果只想本地用:放~/.config/opencode/opencode.json(不 commit)。
关键限定:OpenCode 的原生目录是 .opencode/——表格里 Skills 行那三个并列的路径(.opencode/、.claude/、.agents/)只对 skills 成立。所有 commands / agents 必须放 .opencode/ 下,.agents/commands/、.agents/agents/ 这类路径不会被读取。换句话说,.agents/ 只在 skills 这一层作为兼容路径存在,不要把它当成 OpenCode 的"通用命名空间"。
Codex 的目录命名约定:.agents/ vs .codex/
矩阵表里 Codex 那列混用了 .agents/ 和 .codex/ 两种前缀——别搞混,两个前缀用途完全不同:
| 前缀 | Codex 放什么 | 跨工具吗 |
|---|---|---|
.agents/ | Skills(.agents/skills/、~/.agents/skills/) | ✅ OpenCode / Claude Code 也读 |
.codex/ | config / rules / agents / hooks(.codex/config.toml、.codex/rules/、.codex/agents/ 等) | ❌ Codex 专属 |
简单记法:
.agents/= "agent 生态通用"的命名空间——OpenAI 刻意选了中立前缀,方便和 OpenCode / Claude Code 互操作(只对 skills 有效).codex/= "Codex 自己"的命名空间——所有 Codex 特有的配置、规则、agents、hooks 都放这里
这是 Codex 和 Claude Code 的关键设计差异:Anthropic 把所有东西塞在 .claude/(自家品牌),OpenAI 把"通用"和"自家"分开放。结果就是:Codex 的 skills 天然能跨工具用(.agents/skills/ 是中立前缀),但 agents / rules 必须重新实现(.codex/ 没工具认)。
三个工具的 Skills 语法兼容性
三家 skill 格式层完全统一——都遵循 Agent Skills 开放标准。SKILL.md 的最低要求在三个工具里一致:
---
name: my-skill # 必填,kebab-case,要和目录名一致
description: ... # 必填,告诉模型什么时候触发
---
# Skill 正文(markdown 指令)
最低要求下,一个 SKILL.md 可以塞到任意一个工具的 skills 目录直接用——三家互认。
工具专属扩展(frontmatter 字段)
最低要求之外,三家各自加了私有字段。这些字段不互通——一家写的,另一家会忽略但不会报错:
| 字段 | ClaudeCode | Codex | OpenCode |
|---|---|---|---|
name | ✅ 必填 | ✅ 必填 | ✅ 必填 |
description | ✅ 必填 | ✅ 必填 | ✅ 必填 |
license | ✅ 通用 | ✅ 通用 | ✅ 通用 |
compatibility | ✅ 通用 | ✅ 通用 | ✅ 通用 |
metadata | ✅ 通用 | ✅ 通用 | ✅ 通用 |
disable-model-invocation | ✅ Claude 专属 | ❌ 不识别 | ❌ 不识别 |
paths(路径作用域触发) | ✅ Claude 专属 | ❌ 不识别 | ❌ 不识别 |
| Codex 专属字段 | ❌ 不识别 | ✅ Codex 专属 | ❌ 不识别 |
| OpenCode 专属字段 | ❌ 不识别 | ❌ 不识别 | ✅ OpenCode 专属 |
通用字段三家都认,但实际"工具专属"字段(如下面的
disable-model-invocation)只有那个工具会用——其他工具默默忽略,不会报错。
实战建议
写跨工具 skill 时只写最低要求字段:
---
name: deploy-staging
description: Deploy current project to staging environment. Use when the user asks to deploy or push to staging.
---
# Deploy to Staging
1. Run `pnpm build`
2. Run `pnpm test`
3. Deploy to staging server via `pnpm deploy:staging`
这种 skill 放到 .opencode/skills/、.claude/skills/、.agents/skills/ 都能跑——三个工具都会按 description 触发。
如果要用工具独有特性(比如 Claude 的 disable-model-invocation 让用户手动 /skill-name 才触发,不让模型自动调用),就要为那个工具单独写一份,不能共享。
资源目录也通用
SKILL.md 同级可以放 scripts/、references/、assets/ 等子目录,三家都认——子目录里可以放脚本、模板、参考资料,模型会按 SKILL.md 里的指引去读。
用软链接共享同一份文件
既然矩阵表里有不少重复扫描的目录(OpenCode 同时读 .opencode/、.claude/、.agents/;Codex 也读 .agents/skills/ 和 .claude/skills/ 等),用软链接把同一份文件映射到多个目标就能避免复制——一份源文件,多个工具共享。
1. 共享 skill 文件夹
把 skills 放在一个源目录,每个工具的 skills 目录建软链接指过去:
# 假设 skills 放在 .shared/skills/
mkdir -p .shared/skills
# 三个工具的 skills 目录都指向同一个源
ln -s ../.shared/skills/deploy-staging .opencode/skills/deploy-staging
ln -s ../.shared/skills/deploy-staging .claude/skills/deploy-staging
ln -s ../.shared/skills/deploy-staging .agents/skills/deploy-staging
改一份全部生效——不用在三个工具分别维护。
2. CLAUDE.md ↔ AGENTS.md 别名
矩阵 Instructions 行显示两家都读 AGENTS.md(OpenCode 主选)+ CLAUDE.md(Claude 主选 / OpenCode fallback)。用软链接让两个文件名指向同一份内容:
# 实际写一份 AGENTS.md,CLAUDE.md 用软链接指向它
echo "# Project rules..." > AGENTS.md
ln -s AGENTS.md CLAUDE.md
这样:
- Claude Code 读
CLAUDE.md(它的主选) - OpenCode 读
AGENTS.md(主选)+CLAUDE.md(fallback)——两个文件名同一个内容,零冲突 - Codex 读
AGENTS.md(它的原生)
3. 跨命名空间映射
如果你已经在 .claude/skills/ 下维护了一套 skills,想让 Codex 和 OpenCode 也能用,最省事的是软链接映射:
# 让 Codex 和 OpenCode 直接读 Claude 维护的 skills
ln -s ../.claude/skills .agents/skills # Codex 看得到
ln -s ../.claude/skills .opencode/skills # OpenCode 看得到
或者反过来——
# 维护一份共享 skills,让 Claude Code 也能用
mkdir -p .shared/skills
ln -s ../.shared/skills .claude/skills
4. 跨项目共享
软链接还能跨项目边界——比如把全局共享的规则放在 ~/.config/shared/,再软链接到每个项目:
mkdir -p ~/.config/shared/rules
ln -s ~/.config/shared/rules ~/projects/project-a/.claude/rules
ln -s ~/.config/shared/rules ~/projects/project-b/.claude/rules
Claude Code 文档显式支持这种用法("symlinks are resolved and loaded normally, and circular symlinks are detected and handled gracefully")。
平台注意
| 系统 | 命令 | 备注 |
|---|---|---|
| Linux / macOS | ln -s TARGET LINK_NAME | 原生支持 |
| Windows | mklink /D LINK_NAME TARGET | 参数顺序相反;需要开发者模式或管理员权限 |
| WSL | ln -s(在 WSL 文件系统内) | 跨 Windows / WSL 边界的软链接可能失效 |
⚠️ Windows 上最稳的方式是用 Git Bash 或 WSL 跑
ln -s,直接 PowerShell 跑mklink容易出权限问题。
软链接的副作用
| 副作用 | 说明 |
|---|---|
| 编辑行为 | 大多数编辑器(VSCode、Cursor)通过软链接编辑会直接改源文件——这是期望行为 |
| 删除软链接 | rm symlink 不会删源文件;rm symlink/(带斜杠)才会进入链接目录删源文件 |
| 循环引用 | 工具层面通常有检测(Claude Code 文档明确说 "circular symlinks are detected and handled gracefully");写软链接时避免 A → B → A |
| 跨设备软链接 | 性能略低,工具扫描时会跟随——一般无感知 |
最终推荐的文件夹结构
把上文所有结论落到一个实际目录布局上——用软链接避免重复,三家工具能同时跑:
project-root/
├── AGENTS.md # 主规则文件(实际内容)
├── CLAUDE.md -> AGENTS.md # 软链接:Claude 工具的入口
├── opencode.json # OpenCode 主配置(项目根)
├── .mcp.json # Claude MCP(项目根)
│
├── .shared/ # ⭐ 自 定义共享源(一份真相)
│ ├── skills/ # 所有 SKILL.md 都放这里
│ ├── agents/ # agent 定义放这里
│ ├── commands/ # command 定义放这里
│ └── rules/ # 通用规则放这里
│
├── .opencode/ # OpenCode 原生目录
│ ├── skills/ -> ../.shared/skills/ # 软链到共享源
│ ├── agents/ -> ../.shared/agents/ # 软链到共享源
│ ├── commands/ -> ../.shared/commands/ # 软链到共享源
│ └── plugins/ # OpenCode 独有:JS/TS 钩子
│
├── .claude/ # ClaudeCode 原生目录
│ ├── skills/ -> ../.shared/skills/ # 软链到共享源
│ ├── agents/ -> ../.shared/agents/ # 软链到共享源
│ ├── commands/ -> ../.shared/commands/ # 软链到共享源
│ ├── rules/ -> ../.shared/rules/ # 软链到共享源
│ └── hooks/ # ClaudeCode 脚本约定目录
│
├── .agents/ # Codex / OpenCode 都读的中立前缀
│ └── skills/ -> ../.shared/skills/ # 软链到共享源
│
└── .codex/ # Codex 原生目录
├── config.toml # Codex 自己的配置(TOML)
├── agents/ # Codex sub-agents(TOML)
└── hooks/ # Codex hooks 配置
一键搭建脚本
把下面脚本保存为 setup-ai-agents.sh,在新项目里跑一遍就能完成上面这套结构:
#!/usr/bin/env bash
# setup-ai-agents.sh
# 给项目搭建 ClaudeCode / Codex / OpenCode 三工具兼容的目录结构
# 用法:bash setup-ai-agents.sh
set -euo pipefail
# 1. 共享源目录
mkdir -p .shared/{skills,agents,commands,rules}
# 2. 主规则文件
[ -f AGENTS.md ] || cat > AGENTS.md << 'EOF'
# Project Rules
> 本文件同时被 ClaudeCode(通过 CLAUDE.md 软链)和 OpenCode / Codex(直接)读取。
## Coding Standards
- TypeScript strict mode
- 2-space indent
- pnpm for package management
EOF
ln -sf AGENTS.md CLAUDE.md
# 3. OpenCode 软链接
mkdir -p .opencode/plugins
for d in skills agents commands; do
ln -sfn "../.shared/$d" ".opencode/$d"
done
# 4. ClaudeCode 软链接
for d in skills agents commands rules; do
ln -sfn "../.shared/$d" ".claude/$d"
done
# 5. Codex / OpenCode 共享的 .agents/skills
mkdir -p .agents
ln -sfn ../.shared/skills .agents/skills
# 6. Codex 原生目录
mkdir -p .codex/{agents,hooks}
echo "✅ 三工具目录结构搭建完成"
echo " AGENTS.md / CLAUDE.md / .shared/ / .opencode/ / .claude/ / .agents/ / .codex/"
echo ""
echo "下一步:"
echo " 1. 编辑 .shared/skills/ 下的 SKILL.md,三个工具都会自动看到"
echo " 2. 编辑 AGENTS.md,ClaudeCode(通过软链)和 OpenCode / Codex 都生效"
echo " 3. 把这套结构 commit 进去,团队成员 clone 后跑同一脚本即可"
验证结构
跑完脚本后用这几条命令确认软链接都通了:
# 1. 看目录结构
tree -L 2 -F .shared .opencode .claude .agents .codex
# 2. 验证软链接没断
find .opencode .claude .agents -type l ! -exec test -e {} \; -print
# (无输出 = 所有软链接都指向有效目标)
# 3. 看 CLAUDE.md 是不是真的指向 AGENTS.md
ls -la CLAUDE.md
# 输出:CLAUDE.md -> AGENTS.md
# 4. 实际读软链接验证内容一致
cat .opencode/skills/deploy-staging/SKILL.md
cat .claude/skills/deploy-staging/SKILL.md
cat .agents/skills/deploy-staging/SKILL.md
# 三次输出应该完全一致(同一个源文件)
几个关键设计选择
| 选择 | 理由 |
|---|---|
.shared/ 目录 | 显式划出"共享源"边界——读者一眼看出哪些是一份真相、哪些是各工具的视图 |
| AGENTS.md 是源文件,CLAUDE.md 是软链 | OpenCode 把 AGENTS.md 列为主选——把实际内容写在它里面,CLAUDE.md 只是别名 |
.codex/ 没有软链出去 | Codex 的 agents 是 TOML 格式(其他两家是 markdown),不能和 .shared/agents/ 共享——必须独立维护 |
.opencode/plugins/ 是唯一目录 | OpenCode 的 hooks 是 JS/TS 代码模块,不能和 ClaudeCode / Codex 的 hooks 配置文件共享 |
.codex/config.toml 没软链到 .opencode/ | Codex 用 TOML、OpenCode 用 JSON,配置格式不同——必须各自维护 |
维护成本真相:实际使用中,只有
.shared/skills/和AGENTS.md是真正"一份真相"——其他目录(.codex/agents/、.opencode/plugins/、三个工具的 hooks / MCP)都需要独立维护,因为它们要么格式不同,要么范式不同。
References
- Claude Code Memory 文档 ——
CLAUDE.md/.claude/rules// paths frontmatter - Claude Code Skills 文档 ——
.claude/skills//SKILL.md规范 - Claude Code Subagents 文档 ——
.claude/agents/(markdown + frontmatter) - Claude Code Hooks 指南 ——
settings.json的hooks段 +PreToolUse/PostToolUse等事件 - Claude Code MCP 文档 ——
.mcp.json(项目级 scope 在项目根) - Codex Config 基础 ——
config.toml位置、section 列表 - Codex AGENTS.md 指南 ——
AGENTS.md/ override 机制 /project_doc_fallback_filenames - Codex Rules 文档 ——
.codex/rules/的prefix_rule()语法 - Codex Subagents 文档 ——
.codex/agents/*.toml自定义 sub-agents - Codex Hooks 文档 —— JSON / TOML hooks 事件名
- Codex MCP 文档 ——
[mcp_servers.<name>]配置 - OpenCode Rules 文档 ——
AGENTS.md/CLAUDE.md优先级、禁用开关 - OpenCode Skills 文档 —— 6 个搜索目录(
.opencode/、.claude/、.agents/)+ SKILL.md 加载顺序 - OpenCode Commands 文档 ——
.opencode/commands/路径 - OpenCode Agents 文档 ——
.opencode/agents/markdown frontmatter - OpenCode Plugins 文档 ——
.opencode/plugins/*.{js,ts}hooks 实现 - OpenCode MCP Servers 文档 ——
opencode.json的mcp段(local/remote) - OpenCode Config Schema ——
opencode.jsonJSON Schema - Agent Skills 开放标准 —— SKILL.md 通用规范(
name+description必填、SKILL.md必须大写、frontmatter schema)