Featured image of post AI 编程 CLI 工具怎么选:Claude Code、Codex CLI 与 OpenCode 对比

AI 编程 CLI 工具怎么选:Claude Code、Codex CLI 与 OpenCode 对比

从指令文件、权限模型、配置层级和多仓库实践四个维度,对比 Claude Code、Codex CLI 与 OpenCode,帮助快速建立选型判断。

-- 次浏览
-- 条评论

AI 编程 CLI 工具怎么选:Claude Code、Codex CLI 与 OpenCode 对比

如果把这三款工具都装到本地,第一眼看上去它们都像“命令行里的 AI 编程助手”,但真正拉开差距的地方,往往不是聊天体验,而是项目说明文件、权限边界、配置方式和多仓库协作能力。

这篇文章承担的是“总览文”角色,目标不是把每个细节一次讲完,而是帮你快速建立判断框架:哪一款更适合企业团队,哪一款更适合个人开发,哪一款在多模型和灵活性上更有优势。

如果你已经确定自己更关心某一个专题,可以直接跳到下面两篇文章继续看:


写在前面

选这类工具时,最容易掉进的坑,是只看“模型能力”而忽略“机制成本”。真正影响日常体验的,通常是下面几个问题:

  • 项目规则文件会不会自动继承,能不能覆盖多仓库场景。
  • 权限模型是白名单式、审批式,还是命令规则式。
  • 配置写法是否足够简单,团队成员能不能长期维护。
  • 当项目规模变大时,规则和权限会不会越来越难收拾。

如果先把这些问题想清楚,后面的表格和细节就不会只剩“参数对参数”的堆砌。


工具概览

维度Claude CodeCodex CLIOpenCode
开发方AnthropicOpenAISST(开源)
语言实现Node.jsNode.jsGo
开源❌ 闭源✅ 开源✅ 开源
发布时间2025 年初2025 年 4 月2025 年中
界面形式终端交互终端交互TUI + 终端 + 桌面应用
多模型支持❌ 仅 Claude❌ 仅 OpenAI✅ 支持多家提供商
定位企业级编程助手轻量代码助手开源全能编程 Agent

指令文件机制

指令文件用于向 AI 提供项目上下文、编码规范、工作流约定等自然语言说明,相当于 AI 的"项目说明书"。

文件名与位置

Claude Code — CLAUDE.md

层级路径说明
系统托管/etc/claude-code/CLAUDE.md(Linux)
/Library/Application Support/ClaudeCode/CLAUDE.md(macOS)
IT 管理员下发,最高优先级
用户全局~/.claude/CLAUDE.md对当前用户所有项目生效
项目根目录./CLAUDE.md./.claude/CLAUDE.md提交到 git,团队共享
子目录./src/CLAUDE.md./pkg/foo/CLAUDE.md懒加载,按需触发

Codex CLI — AGENTS.md

层级路径说明
用户全局~/.codex/AGENTS.md对所有项目生效
仓库根目录<git repo root>/AGENTS.md提交到 git,团队共享
当前工作目录<cwd>/AGENTS.md与仓库根不同时单独加载

注意:Codex CLI 不做目录向上遍历,只从以上三个固定路径加载,按顺序合并。可用 --no-project-docCODEX_DISABLE_PROJECT_DOC=1 禁用项目文件加载。

OpenCode — AGENTS.md(优先)/ CLAUDE.md(兼容回退)

层级路径说明
用户全局~/.config/opencode/AGENTS.md对所有项目生效,不提交 git
项目根目录./AGENTS.md提交到 git,团队共享
Claude 兼容(回退)./CLAUDE.md(无 AGENTS.md 时)迁移兼容,两者同时存在时忽略 CLAUDE.md
扩展引用通过 opencode.jsoninstructions 字段 glob 引入任意文件跨文件聚合

OpenCode 兼容说明:若同时存在 AGENTS.mdCLAUDE.md只读取 AGENTS.mdCLAUDE.md 被忽略。


目录继承行为

三个工具都支持向上遍历目录查找指令文件,但行为有所不同:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
多仓库场景示例(每个服务是独立的 git repo):

~/projects/
├── CLAUDE.md / AGENTS.md              ← 多仓库共享层(projects 目录)
├── order-service/                      ← git repo ①
│   ├── CLAUDE.md / AGENTS.md          ← 项目级
│   └── src/
│       └── order/
│           └── CLAUDE.md              ← 子模块级(当前工作目录)
└── notify-service/                     ← git repo ②
    └── CLAUDE.md / AGENTS.md          ← 项目级

Claude Code 遍历行为

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
当前工作目录:~/projects/order-service/src/order/

加载顺序(启动时全量加载):
  1. ~/.claude/CLAUDE.md                           ← 用户全局(独立加载,非遍历结果)
  2. ~/projects/CLAUDE.md                          ← 多仓库共享层(实测验证:越过 git root 继续向上)
  3. ~/projects/order-service/CLAUDE.md            ← 项目根目录
  4. ~/projects/order-service/src/CLAUDE.md        ← 遍历沿途(如存在)
  5. ~/projects/order-service/src/order/CLAUDE.md  ← 当前工作目录

子目录懒加载(按需):
  当 Claude 读取 src/payment/ 中的文件时,
  才加载 src/payment/CLAUDE.md(如果存在)

遍历终止条件:官方文档未明确说明,但经实测验证:Claude Code 不会停在 git root,会继续向上遍历父目录。例如工作目录为 /data/work/ai-mvn(git repo),/data/work/CLAUDE.md(repo 外的上级目录)同样会被加载。~/.claude/CLAUDE.md 是独立的用户全局配置,并非遍历结果。可通过 /context 命令查看当前会话实际加载的文件列表。

多仓库场景下的文件职责划分:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
~/.claude/CLAUDE.md                    → 个人偏好,所有项目通用(语言、风格)

~/projects/CLAUDE.md                   → 多仓库共享约定
                                          - 技术栈统一规范
                                          - 服务目录(所有服务地址、职责)
                                          - 跨服务 HTTP 调用约定
                                          - 接口变更协作流程

~/projects/order-service/CLAUDE.md    → 本服务内容
                                          - 本服务职责与模块结构
                                          - 本服务对外暴露的接口
                                          - 本服务依赖的上游接口契约(重点!)

~/projects/order-service/src/*/CLAUDE.md → 子模块特殊说明(可选)

示例:~/projects/CLAUDE.md(多仓库共享层)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
# 多服务共享规范

## 技术栈
- Java 8 + Spring Boot 2.x
- 服务间通信:HTTP REST,统一使用 Feign Client
- 统一响应结构:{ code: int, message: String, data: T }

## 服务目录
| 服务 | 职责 | 内网地址 |
|------|------|----------|
| user-service    | 用户账户、余额管理 | http://user-service:8001    |
| order-service   | 订单生命周期管理   | http://order-service:8002   |
| notify-service  | 短信/Push 通知     | http://notify-service:8003  |

## 跨服务开发约定
- 修改任何对外接口前,先确认所有下游调用方
- Feign Client 定义在各服务的 api 模块,不在 core 模块直接 HTTP 调用
- 接口字段变更(新增除外)需同步更新所有调用方

示例:~/projects/order-service/CLAUDE.md(项目层)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# order-service

## 本服务职责
管理订单全生命周期:创建 → 支付确认 → 发货 → 完成 / 取消

## 模块结构
- order-api    对外 Feign Client 接口定义(供其他服务引用)
- order-core   业务逻辑层
- order-server 启动入口 + Controller

## 本服务对外接口
- POST /api/orders              创建订单
- PUT  /api/orders/{id}/pay    支付回调
- GET  /api/orders/{id}         查询订单详情

## 依赖的上游接口(修改时需同步)

### user-service
- GET  /api/users/{id}/balance
  响应:{ code: 0, data: { balance: BigDecimal } }
- POST /api/users/{id}/balance/freeze
  请求:{ amount: BigDecimal, orderId: String }
  响应:{ code: 0, data: { freezeId: String } }

### notify-service
- POST /api/notify/send
  请求:{ userId: String, type: "ORDER_CREATED"|"ORDER_PAID", bizId: String }
  响应:{ code: 0, data: { msgId: String } }

Codex CLI 加载行为(固定路径,无目录遍历)

1
2
3
4
5
6
7
8
当前工作目录:~/projects/order-service/src/order/

加载顺序(仅三个固定路径,按顺序合并):
  1. ~/.codex/AGENTS.md                      ← 用户全局
  2. ~/projects/order-service/AGENTS.md      ← git 仓库根目录
  3. ~/projects/order-service/src/order/AGENTS.md ← 当前工作目录(与仓库根不同时)

不会加载 ~/projects/AGENTS.md(不在固定路径内,直接忽略)。

多仓库限制:Codex CLI 无法加载 ~/projects/ 层级的共享文件。跨项目共享内容只能放入 ~/.codex/AGENTS.md 用户全局文件,token 有限时需精简。

多仓库场景下的文件职责划分:

1
2
3
4
5
6
7
8
9
~/.codex/AGENTS.md                     → 必须承担所有跨项目内容
                                          - 技术栈规范
                                          - 服务目录
                                          - 跨服务约定
                                          (内容较多时注意 token 消耗)

~/projects/order-service/AGENTS.md    → 本服务内容
                                          - 本服务职责与接口
                                          - 依赖的上游接口契约

OpenCode 遍历行为

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
当前工作目录:~/projects/order-service/src/order/

加载顺序:
  1. ~/.config/opencode/AGENTS.md              ← 用户全局
  2. 从当前目录向上遍历至 git root,每层取一个文件
     - ~/projects/order-service/src/order/AGENTS.md  ← 当前目录
     - ~/projects/order-service/src/AGENTS.md         ← 若存在
     - ~/projects/order-service/AGENTS.md              ← git root,停止
  3. opencode.json 中 instructions 字段引用的额外文件

不会加载 ~/projects/AGENTS.md(遍历止于 git root)。

多仓库限制:与 Codex CLI 类似,OpenCode 停在 git root,无法自动读取 ~/projects/ 层级的共享文件。但可通过 opencode.jsoninstructions 字段显式引入。

多仓库场景下推荐用 instructions 引入共享文件:

1
2
3
4
5
6
7
8
9
~/projects/
├── _shared/                               ← 共享契约目录(非 git repo)
│   ├── conventions.md                     ← 技术栈、服务目录、跨服务约定
│   └── api-contracts/
│       ├── user-service.md
│       └── notify-service.md
└── order-service/
    ├── AGENTS.md                          ← 本服务职责与对外接口
    └── opencode.json                      ← 通过 instructions 引入共享内容
1
2
3
4
5
6
7
8
9
// ~/projects/order-service/opencode.json
{
  "instructions": [
    "./AGENTS.md",
    "~/_shared/conventions.md",
    "~/_shared/api-contracts/user-service.md",
    "~/_shared/api-contracts/notify-service.md"
  ]
}

多文件合并策略

工具合并方式优先级规则
Claude Code全部合并,所有层级的文件都加入上下文越具体的层级(越靠近当前目录)优先级越高;冲突指令 Claude 可能随机选择一个
Codex CLI全部合并,沿途所有文件拼接越靠近当前目录的文件内容排列在后,隐式优先
OpenCode⚠️ 每层级取一个文件,不跨文件合并;但可通过 instructions 字段显式引入多文件越靠近当前目录优先级越高

OpenCode instructions 字段示例(显式多文件合并)

1
2
3
4
5
6
7
8
9
// opencode.json
{
  "instructions": [
    "./AGENTS.md",
    "./docs/coding-standards.md",
    "packages/*/AGENTS.md",
    "https://example.com/shared-rules.md"
  ]
}

权限与设置文件机制

配置文件层级

Claude Code — settings.json(4 层级,固定路径,不遍历目录)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
优先级从高到低:

① 系统托管(不可被覆盖)
   macOS:   /Library/Application Support/ClaudeCode/managed-settings.json
   Linux:   /etc/claude-code/managed-settings.json
   Windows: C:\Program Files\ClaudeCode\managed-settings.json
            HKLM\SOFTWARE\Policies\ClaudeCode(注册表)

② 命令行参数(临时会话级覆盖)

③ 本地项目(个人私有,git 忽略)
   .claude/settings.local.json

④ 共享项目(团队共享,git 追踪)
   .claude/settings.json

⑤ 用户全局(最低优先级)
   ~/.claude/settings.json

注意:settings.json 不走目录遍历,只从上述固定路径加载。这与 CLAUDE.md 的行为完全不同——即使 ~/projects/.claude/settings.json 这样的路径存在,也不会被加载

与 CLAUDE.md 加载行为的核心差异:

1
2
CLAUDE.md      → 目录向上遍历,沿途所有文件全部加载(越过 git root 继续)
settings.json  → 固定 4 个路径,不做任何目录遍历

多仓库场景下的配置策略:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
~/projects/
├── CLAUDE.md                          ✅ 会被加载(目录遍历)
├── .claude/settings.json              ❌ 不会被加载(不在固定路径)
├── order-service/                     git repo ①
│   ├── CLAUDE.md                      ✅ 会被加载
│   └── .claude/
│       ├── settings.json              ✅ 项目级权限(团队共享)
│       └── settings.local.json        ✅ 本地个人权限(git 忽略)
└── notify-service/                    git repo ②
    ├── CLAUDE.md                      ✅ 会被加载
    └── .claude/
        └── settings.json              ✅ 项目级权限(团队共享)

跨多个项目共享权限配置,只能放入用户全局文件:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
// ~/.claude/settings.json(对所有项目生效)
{
  "permissions": {
    "allow": [
      "Bash(git *)",
      "Bash(mvn *)",
      "Bash(npm run *)"
    ],
    "deny": [
      "Bash(rm -rf *)",
      "Read(./.env*)"
    ],
    "ask": [
      "Bash(git push *)",
      "Bash(kubectl *)"
    ]
  }
}
1
2
3
4
5
6
7
8
9
// ~/projects/order-service/.claude/settings.json(仅 order-service 生效)
{
  "permissions": {
    "allow": [
      "Bash(java *)",
      "Bash(mvn spring-boot:run)"
    ]
  }
}
1
2
3
4
5
6
7
8
9
// ~/projects/order-service/.claude/settings.local.json(个人本地,不提交 git)
{
  "permissions": {
    "allow": [
      "Bash(ssh *)",
      "Read(~/.ssh/config)"
    ]
  }
}

合并结果:三个文件的 permissions 数组会跨层级合并去重,最终生效的规则是三者的并集。deny 规则任意层级设置后,低层级无法解除。

Codex CLI — 无配置文件

1
2
3
4
5
6
7
8
9
Codex CLI 没有权限配置文件,权限控制完全依赖启动参数:

  --approval-mode suggest    所有操作需用户确认(默认)
  --approval-mode auto-edit  文件编辑自动批准,shell 命令需确认
  --approval-mode full-auto  全自动执行(依赖 OS 沙箱隔离)

沙箱机制:
  macOS:Seatbelt(系统调用级别隔离)
  Linux:Docker 容器隔离

OpenCode — opencode.json(2 层级 + 远程配置,支持目录遍历)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
加载顺序(优先级从低到高):

① 远程组织配置(最低)
   .well-known/opencode(通过 HTTP 拉取,组织级默认值)

② 用户全局配置
   ~/.config/opencode/opencode.json

③ 环境变量指定路径
   $OPENCODE_CONFIG 指向的文件

④ 项目配置(从当前目录向上遍历查找)
   ./opencode.json

⑤ .opencode 目录(agents/, commands/, plugins/ 等子目录)

⑥ 内联配置(最高)
   $OPENCODE_CONFIG_CONTENT 环境变量内容

OpenCode 特点opencode.json 支持目录向上遍历查找(不同于 Claude Code 的固定路径),且多层级配置深度合并而非替换。


权限规则语法

Claude Code

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// .claude/settings.json
{
  "permissions": {
    "allow": [
      "Bash(npm run *)",           // Bash 命令,支持通配符
      "Bash(git commit *)",
      "Read(./src/**)",            // 文件读取,gitignore 风格
      "Read(~/.zshrc)",            // 波浪号路径
      "Edit(/src/**/*.java)",      // 文件编辑
      "WebFetch(domain:github.com)", // 域名匹配
      "Glob(**/*.ts)",             // 文件搜索
      "Grep(./src/**)",            // 内容搜索
      "mcp__server__toolname"      // MCP 工具
    ],
    "deny": [
      "Bash(rm -rf *)",
      "Bash(curl *)",
      "Read(./.env*)",             // 拒绝读取环境变量文件
      "Read(./secrets/**)"
    ],
    "ask": [
      "Bash(git push *)",          // 敏感操作需二次确认
      "Bash(docker *)"
    ]
  }
}

匹配规则deny → ask → allow首个匹配生效,后续规则忽略。

支持的工具名

工具说明模式示例
Bash(pattern)Shell 命令执行Bash(npm run *)
Read(pattern)文件读取Read(./src/**)
Edit(pattern)文件编辑Edit(**/*.java)
Write(pattern)文件写入Write(./tmp/**)
Glob(pattern)文件名搜索Glob(**/*.ts)
Grep(pattern)内容搜索Grep(./src/**)
WebFetch(domain:x)HTTP 请求WebFetch(domain:api.github.com)
Agent(name)子 Agent 调用Agent(general-purpose)
mcp__srv__toolMCP 工具mcp__filesystem__read

OpenCode

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// opencode.json
{
  "permission": {
    // 工具级别全局设置
    "read":      "allow",
    "edit":      "ask",
    "glob":      "allow",
    "grep":      "allow",
    "list":      "allow",
    "webfetch":  "ask",
    "task":      "allow",
    "lsp":       "allow",

    // bash 细粒度规则(最后匹配生效)
    "bash": {
      "*":              "ask",     // 默认:所有命令需确认
      "git status":     "allow",   // 精确匹配
      "git *":          "allow",   // 通配符
      "npm run *":      "allow",
      "rm *":           "deny",    // 拒绝危险命令
      "rm -rf *":       "deny"
    },

    // 全局快捷设置(覆盖所有工具)
    // "permission": "allow"       // 全部放行
    // "permission": "ask"         // 全部询问
    // "permission": "deny"        // 全部拒绝
  }
}

匹配规则最后匹配生效(Last Match Wins),与 Claude Code 相反。

支持的工具名

工具说明默认值
read文件读取allow
edit文件编辑allow
glob文件搜索allow
grep内容搜索allow
list目录列表allow
bashShell 命令ask
webfetchHTTP 请求allow
task任务执行allow
lsp语言服务器allow
skill技能调用allow
external_directory外部目录访问ask
doom_loop循环执行ask

特殊默认行为:即使 readallow.env 文件默认仍为 deny,需显式解除。

Codex CLI

1
2
3
4
5
6
7
# 无配置文件,仅启动参数
codex --approval-mode suggest    # 全部询问(默认)
codex --approval-mode auto-edit  # 文件编辑自动放行
codex --approval-mode full-auto  # 沙箱内全自动

# 沙箱说明:
# full-auto 模式下网络访问被完全禁止,文件系统访问受 OS 限制

合并策略

Claude Code settings.json 合并规则

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
数组类字段(跨层级合并,去重):
  permissions.allow
  permissions.deny
  permissions.ask
  sandbox.filesystem.allowWrite / denyWrite / denyRead
  hooks(各事件的 hook 列表)
  环境变量数组

示例:
  managed-settings.json:  allow: ["Bash(//opt/company-tools/*)"]
  ~/.claude/settings.json: allow: ["Bash(npm run *)"]
  .claude/settings.json:   allow: ["Bash(git *)"]
  最终生效:               allow: ["Bash(//opt/company-tools/*)", "Bash(npm run *)", "Bash(git *)"]

标量字段(高优先级完全覆盖低优先级):
  modeltheme 等配置项

deny 的特殊地位:
  任何层级的 deny 规则均生效,低层级无法解除 managed  deny

OpenCode opencode.json 合并规则

OpenCode 使用深度合并(Deep Merge),同时注意最后匹配生效(Last Match Wins)的规则逻辑,这两点组合起来决定了最终权限行为。

规则一:多层级配置文件深度合并

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
~/.config/opencode/opencode.json(用户全局):
{
  "permission": {
    "read":  "allow",
    "edit":  "allow",
    "bash": {
      "*":       "ask",      // 默认所有 bash 命令需确认
      "git *":   "allow"     // git 命令放行
    }
  }
}

./opencode.json(项目级):
{
  "permission": {
    "webfetch": "deny",      // 项目级禁止 HTTP 请求
    "bash": {
      "npm run *": "allow"   // 项目级追加:npm 命令放行
    }
  }
}

合并结果:
{
  "permission": {
    "read":     "allow",     // 来自全局
    "edit":     "allow",     // 来自全局
    "webfetch": "deny",      // 来自项目(新增字段)
    "bash": {
      "*":         "ask",    // 来自全局
      "git *":     "allow",  // 来自全局
      "npm run *": "allow"   // 来自项目(追加)
    }
  }
}

规则二:bash 规则内部按"最后匹配"生效

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
合并后的 bash 规则:
  "*":         "ask"     ← 通配兜底
  "git *":     "allow"   ← 覆盖通配,git 命令放行
  "npm run *": "allow"   ← 覆盖通配,npm 命令放行

执行 "git commit -m fix" 时:
  匹配 "*"       → ask
  匹配 "git *"   → allow    ← 最后匹配,最终生效 ✅

执行 "curl http://..." 时:
  匹配 "*"       → ask      ← 只有这一条匹配,最终生效 ✅

执行 "rm -rf /tmp" 时:
  匹配 "*"       → ask      ← 最终生效 ✅(没有更具体的规则覆盖)

规则三:Agent 级别的 permission 覆盖全局(不合并)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
opencode.json:
{
  "permission": {
    "bash": { "*": "ask", "git *": "allow" }   // 全局权限
  },
  "agent": {
    "reviewer": {
      "permission": {
        "read": "allow",
        "bash": "deny",    // ← 直接覆盖,不与全局 bash 规则合并
        "edit": "deny"
      }
    }
  }
}

reviewer agent 最终权限:
  read:  "allow"   ← 来自 agent 定义
  bash:  "deny"    ← 来自 agent 定义(全局的 git * allow 被完全忽略)
  edit:  "deny"    ← 来自 agent 定义

默认 agent 最终权限:
  bash:  { "*": "ask", "git *": "allow" }  ← 使用全局规则

与 Claude Code 的关键区别:Claude Code 的 deny 一旦设置任意层级均不可逆;OpenCode 的 agent 级别可以完全覆盖全局规则,包括把全局的 deny 改回 allow


详细配置参考

Claude Code

完整 settings.json 示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
// .claude/settings.json(项目级,团队共享)
{
  "model": "claude-opus-4-6",

  "permissions": {
    "allow": [
      "Bash(npm run *)",
      "Bash(mvn *)",
      "Bash(git add *)",
      "Bash(git commit *)",
      "Bash(git status)",
      "Bash(git diff *)",
      "Bash(git log *)",
      "Read(./**)",
      "Edit(./src/**)",
      "Glob(**/*.java)",
      "Grep(./src/**)"
    ],
    "deny": [
      "Bash(rm -rf *)",
      "Bash(git push *)",
      "Bash(curl *)",
      "Read(./.env*)",
      "Read(./secrets/**)",
      "Read(./credentials/**)"
    ],
    "ask": [
      "Bash(git push *)",
      "Bash(docker *)",
      "Bash(kubectl *)",
      "WebFetch(*)"
    ]
  },

  "env": {
    "JAVA_HOME": "/usr/lib/jvm/java-8-openjdk",
    "MAVEN_OPTS": "-Xmx2g"
  }
}
1
2
3
4
5
6
7
8
9
// .claude/settings.local.json(本地私有,git 忽略)
{
  "permissions": {
    "allow": [
      "Bash(ssh *)",
      "Read(~/.ssh/config)"
    ]
  }
}

CLAUDE.md 加载顺序完整示意

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
启动时加载(全量,按优先级从低到高):
  /etc/claude-code/CLAUDE.md              → 系统策略
  ~/.claude/CLAUDE.md                     → 用户全局
  ~/projects/CLAUDE.md                    → 中间路径(如存在)
  ~/projects/my-app/CLAUDE.md             → 项目根目录
  ~/projects/my-app/src/api/CLAUDE.md     → 当前工作目录

按需加载(访问时触发):
  ~/projects/my-app/src/auth/CLAUDE.md    → 当 Claude 读取 auth/ 中文件时加载
  ~/projects/my-app/test/CLAUDE.md        → 当 Claude 读取 test/ 中文件时加载

CLAUDE.md Import 语法

1
2
3
4
5
<!-- CLAUDE.md 中引用其他文件 -->
@./docs/coding-standards.md
@./docs/api-guidelines.md
@~/.claude/personal-preferences.md
@/absolute/path/to/shared-rules.md

Codex CLI

启动参数参考

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# 基础使用
codex "帮我重构这个函数"
codex --model gpt-4o "解释这段代码"

# 权限模式
codex --approval-mode suggest    # 默认:所有操作需确认
codex --approval-mode auto-edit  # 文件编辑自动批准
codex --approval-mode full-auto  # 全自动(需沙箱支持)

# 沙箱控制
codex --no-sandbox               # 禁用沙箱(不推荐)

# 上下文控制
codex --context ./README.md      # 指定额外上下文文件
codex --cwd ./src                # 指定工作目录

AGENTS.md 示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# Project Rules

## Tech Stack
- Node.js 18+, TypeScript 5.x
- Express.js for REST APIs
- Prisma ORM with PostgreSQL

## Coding Standards
- Use async/await, avoid callbacks
- All functions must have TypeScript types
- Test files: *.test.ts

## Git Conventions
- Commit format: feat/fix/docs/refactor: description
- Never commit directly to main

OpenCode

完整 opencode.json 示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
// opencode.json(项目级)
{
  // 默认模型
  "model": "anthropic/claude-sonnet-4-6",
  "small_model": "anthropic/claude-haiku-4-5",

  // 权限配置
  "permission": {
    "read":     "allow",
    "edit":     "allow",
    "glob":     "allow",
    "grep":     "allow",
    "list":     "allow",
    "webfetch": "ask",
    "bash": {
      "*":              "ask",
      "git *":          "allow",
      "npm run *":      "allow",
      "yarn *":         "allow",
      "cat *":          "allow",
      "ls *":           "allow",
      "find *":         "allow",
      "rm -rf *":       "deny",
      "curl *":         "deny",
      "wget *":         "deny"
    }
  },

  // 额外指令文件(支持 glob 和 URL)
  "instructions": [
    "./AGENTS.md",
    "./docs/coding-standards.md",
    "packages/*/AGENTS.md"
  ],

  // 自定义 Agent
  "agent": {
    "reviewer": {
      "model": "anthropic/claude-opus-4-6",
      "prompt": "You are a strict code reviewer focused on security and performance.",
      "permission": {
        "read":  "allow",
        "edit":  "deny",
        "bash":  "deny"
      }
    }
  },

  // MCP 服务器
  "mcp": {
    "filesystem": {
      "type": "local",
      "command": ["mcp-server-filesystem", "./"]
    }
  },

  // 自动更新
  "autoupdate": true,

  // 文件快照(用于变更追踪)
  "snapshot": true
}

Agent 权限继承示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
{
  // 全局权限:bash 默认询问
  "permission": {
    "bash": { "*": "ask" }
  },

  "agent": {
    // build agent:继承全局 + 扩展允许
    "build": {
      "permission": {
        "bash": {
          "*":         "ask",     // 继承全局
          "npm *":     "allow",   // agent 扩展
          "make *":    "allow"
        }
      }
    },
    // plan agent:只读,覆盖全局
    "plan": {
      "permission": {
        "read":  "allow",
        "edit":  "deny",
        "bash":  "deny"
      }
    }
  }
}

横向对比总表

指令文件对比

特性Claude CodeCodex CLIOpenCode
文件名CLAUDE.mdAGENTS.mdAGENTS.md(优先)
CLAUDE.md(兼容回退)
用户全局路径~/.claude/CLAUDE.md~/.codex/AGENTS.md~/.config/opencode/AGENTS.md
项目路径遍历中找到的所有层级git 仓库根目录 AGENTS.md./AGENTS.md
向上目录遍历✅ 全部加载(越过 git root 继续向上,实测验证)❌ 三个固定路径✅ 每层取一个(停在 git root)
子目录懒加载✅ 按需触发
多文件全量合并✅(三个固定文件合并)⚠️ 需借助 instructions 字段
Import 语法@path❌(用 instructions 代替)
系统级策略文件⚠️ 远程 .well-known/opencode
兼容对方格式✅ 兼容 CLAUDE.md

权限设置对比

特性Claude CodeCodex CLIOpenCode
权限配置文件settings.jsonopencode.json
层级数量4层(managed/user/project/local)2层 + 远程(remote/global/project)
目录向上遍历❌ 固定路径✅ 向上遍历查找
企业管控层✅ managed 不可覆盖⚠️ 远程配置(需 HTTPS)
细粒度 allow/deny/ask
匹配规则逻辑首个匹配生效(deny→ask→allow)最后匹配生效
数组跨层合并✅ permissions 数组跨层合并✅ 深度合并
Agent 级别权限✅ 可覆盖全局
沙箱机制规则白名单macOS Seatbelt / Docker规则白名单
.env 文件保护⚠️ 需手动 deny✅ 默认 deny

规则匹配逻辑对比

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
Claude Code(首个匹配):
  规则顺序:deny → ask → allow
  第一个匹配的规则立即生效,后续规则被忽略
  适合:明确的白名单/黑名单,规则顺序无歧义

  示例:
    deny:  ["Bash(rm *)"]
    allow: ["Bash(rm -rf /tmp/*)"]  ← 永远不会生效(已被 deny 首先匹配)

OpenCode(最后匹配):
  同一工具下,越靠后的规则优先级越高
  适合:从宽泛默认逐步精细化覆盖

  示例:
    "bash": {
      "*":            "ask",       // 默认询问
      "rm *":         "deny",      // 拒绝 rm
      "rm /tmp/*":    "allow"      // 最后匹配:/tmp 下 rm 允许 ✅
    }

选型建议

按场景推荐

场景推荐工具理由
企业团队,需严格权限管控Claude Codemanaged 层不可覆盖,4层细粒度管控
个人开发,快速上手Codex CLI无配置负担,沙箱保底安全
开源项目,多模型切换OpenCode多 Provider 支持,配置灵活,TUI 体验好
已有 CLAUDE.md 迁移OpenCode内置 CLAUDE.md 兼容回退
需要 Agent 分角色权限OpenCode原生支持多 Agent 差异化权限

成熟度评估

1
2
3
4
5
6
7
8
9
权限体系成熟度:
  Claude Code  ████████████  最完整,企业级
  OpenCode     ████████░░░░  快速迭代,功能完善
  Codex CLI    ████░░░░░░░░  简单,靠 OS 沙箱兜底

指令文件机制:
  Claude Code  ████████████  最完整,懒加载 + Import
  Codex CLI    ████████░░░░  简单直接,全量合并
  OpenCode     ███████░░░░░  灵活,兼容性好,合并需显式配置

总结

如果你所在的是团队协作环境,并且很在意规则继承、权限边界和企业级治理,Claude Code 的整体体系更成熟。

如果你想以最低学习成本进入 AI 编程 CLI,Codex CLI 更像“先跑起来再说”的选择,简单但边界也更粗。

如果你既在意多模型能力,又愿意自己维护规则和权限,OpenCode 的灵活性会更有吸引力。

总览文适合用来完成第一轮选型,真正准备落地时,建议再回到指令文件和权限两篇专题文,把细节啃透。

参考资料