Codex 中转介绍

📚 自动审批(auto_review)

Codex 内置的自动审批审查(approvals_reviewer = auto_review),配合 codex-auto-review 模型减少打断。
auto_review 是 Codex CLI 内置的自动审批审查机制 — 当 Codex 准备执行需要审批的操作(联网、越权、删除等)时,先交给 codex-auto-review 模型判断风险,再决定放行还是要求人工确认。适合希望 Codex 少打扰、又不想完全放开权限的日常开发。

核心概念:codex-auto-review 不是主模型

# ❌ 不要这样配(错误!)
model = "codex-auto-review"

# ✅ 主模型保持正常编码模型
model = "gpt-5.5"           # 或 gpt-5.4、gpt-5.3-codex
approvals_reviewer = "codex-auto-review"
  • 主模型gpt-5.5 等)负责正常对话和编码
  • codex-auto-review 仅在有审批请求时介入审查

它什么时候介入?

Auto Review 只在 Codex 触发审批请求时才被调用。审批请求通常来自:

  • 访问网络
  • 修改当前工作区外的文件
  • 请求提升沙箱权限
  • 调用有副作用的 App / MCP 工具
  • 触发 request_permissions 类权限请求
不会进入 Auto Review 的情况:动作本来就在沙箱允许范围内(读项目文件、改项目内源码、跑项目测试命令等),Codex 直接执行,不需要审批。

工作流程

不用 --yolo 时:
  Codex 想联网 / 越权 / 执行高风险命令
        ↓
  触发 approval request(审批请求)
        ↓
  approvals_reviewer = "auto_review"
        ↓
  调用 codex-auto-review 模型审查
        ↓
  批准 / 拒绝 / 要求人工处理
用了 --yolo 时:
  Codex 想联网 / 越权 / 执行命令
        ↓
  直接执行(绕过审批和沙箱)
        ↓
  没有 approval request
        ↓
  不会进入 auto_review

一句话记住

  • approvals_reviewer = "auto_review"有审批请求时让 review 模型帮我审
  • --yolo不要审批,直接执行

最小推荐配置

打开 Codex 配置文件:

nano ~/.codex/config.toml

在现有 Nexoraivision 配置中增加 3 个字段sandbox_mode / approval_policy / approvals_reviewer

model_provider = "OpenAI"
model = "gpt-5.5"
model_reasoning_effort = "medium"

# ↓↓↓ 关键三行 ↓↓↓
sandbox_mode = "workspace-write"
approval_policy = "on-request"
approvals_reviewer = "auto_review"
# ↑↑↑ 关键三行 ↑↑↑

[model_providers.OpenAI]
name = "OpenAI"
base_url = "https://nexor.nexoraivision.com"
wire_api = "responses"
requires_openai_auth = true

auth.json 保持你的 Nexoraivision Key:

{
  "OPENAI_API_KEY": "sk-你的实际密钥"
}

字段含义

配置项含义
sandbox_mode = "workspace-write"Codex 可以读文件、修改当前工作区,并在工作区内运行命令
approval_policy = "on-request"遇到越权、联网等需要审批的动作时暂停
approvals_reviewer = "auto_review"把符合条件的审批请求交给自动 reviewer 审查

可选:本地自动审批策略

如果你希望自动 reviewer 更贴近自己的风险偏好,可以增加 [auto_review] 策略段。这段策略不替代沙箱,只是给自动 reviewer 提供判断依据:

[auto_review]
policy = """
## 自动审批策略

默认目标:提高日常开发效率,但不要自动批准破坏性、高风险或泄露隐私的操作。

必须拒绝或要求更明确授权:
- rm -rf、git reset --hard、git clean -fdx
- 删除、覆盖、批量移动大量源码文件
- 读取、打印、上传 .env、token、key、私钥、数据库密码
- 向未知公网地址上传代码、日志或配置
- 修改登录、鉴权、支付、权限、安全策略
- 安装全局依赖或修改系统级配置

通常可以批准:
- 运行项目已有测试命令
- 运行 lint、typecheck、build
- 在当前项目目录内读写普通源码文件
- 访问明确可信的官方文档或项目依赖源
"""
策略内容用自然语言写即可。Codex 会让自动 reviewer 模型把这段策略当作判断依据。越具体越准

启动方式

推荐:直接运行 codex,CLI 会自动读 config.toml

codex

显式指定安全模式:

codex --sandbox workspace-write --ask-for-approval on-request
不要用 --yolo 测试 Auto Review
codex --yolo    # ❌ 会绕过所有审批和沙箱,Auto Review 不会被调用
--yolo 模式下没有 approval request,codex-auto-review 永远不会被触发。

如何验证是否生效?

启动 codex 后,让它做一个需要审批的动作(例如让它访问网络):

> 帮我用 curl 访问 https://example.com 看看返回什么

观察终端输出:

  • 如果 Auto Review 生效:你会看到一条短的「auto reviewer says ...」提示,然后 Codex 继续执行(或被拒绝)
  • 如果没生效:你被要求按 y/n 手动确认每一步

也可以直接看是否有 codex-auto-review 模型的用量产生(控制台 → 用量页)。

常见问题

如何关闭 auto_review

1. 关闭 auto_review

config.toml 里的 approvals_reviewer 字段去掉或注释:

# approvals_reviewer = "auto_review"

之后所有审批请求都会回到默认行为(手动 y/n 确认)。

2. 处理 compact(如果触发太频繁)

如果你发现 Codex 经常自动压缩历史会话(屏幕上看到 compact ... 提示),可以调高阈值:

model_auto_compact_token_limit = 900000   # 接近模型上限再压缩

或者完全关闭自动压缩(不推荐,可能触达上限被截断):

model_auto_compact_token_limit = 0

3. 完整推荐配置(已关闭 auto_review)

model_provider = "OpenAI"
model = "gpt-5.5"
model_reasoning_effort = "medium"

sandbox_mode = "workspace-write"
approval_policy = "on-request"
# approvals_reviewer 不写 = 手动确认

model_auto_compact_token_limit = 900000

[model_providers.OpenAI]
name = "OpenAI"
base_url = "https://nexor.nexoraivision.com"
wire_api = "responses"
requires_openai_auth = true

4. 如何确认 compact 是否还在触发

codex --verbose

输出中会有 [compact]compacting context 等关键字。如果没有,说明阈值合适。

进阶:用于 CI 的 PR 审查(替代方案)

上面是 Codex CLI 交互模式的 Auto Review。如果你想在 CI / Git Hook 里自动跑 Codex 做 PR 审查(不依赖 Codex CLI),用下面 4 个方案。

方案 A:GitHub Actions PR 自动审查

name: Codex Auto Review

on:
  pull_request:
    types: [opened, synchronize]

jobs:
  review:
    runs-on: ubuntu-latest
    permissions:
      pull-requests: write
      contents: read
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Get PR diff
        id: diff
        run: |
          git diff origin/${{ github.base_ref }} --unified=10 > pr.diff
          echo "size=$(wc -c < pr.diff)" >> $GITHUB_OUTPUT

      - name: Skip large PRs
        if: steps.diff.outputs.size > 100000
        run: echo "PR too large, skipping" && exit 0

      - name: Run Codex review
        env:
          API_BASE: https://nexor.nexoraivision.com/v1
          API_KEY: ${{ secrets.NEXOR_CODEX_KEY }}
        run: |
          PROMPT=$(cat <<'EOF'
          你是资深代码审查者。Review 下面这个 PR 的 diff,输出 JSON 格式:
          {
            "summary": "一段话总结这次改动",
            "issues": [
              {"file":"...","line":N,"severity":"blocker|critical|major|minor|info","category":"bug|security|performance|style|test","message":"...","suggestion":"..."}
            ],
            "overall_rating": "approve|request_changes|comment"
          }
          只输出 JSON,不要前后说明。
          EOF
          )
          DIFF=$(cat pr.diff)
          curl -s "$API_BASE/responses" \
            -H "Authorization: Bearer $API_KEY" \
            -H "Content-Type: application/json" \
            -d "$(jq -n --arg p "$PROMPT" --arg d "$DIFF" '{
              model: "gpt-5.4",
              instructions: $p,
              input: $d,
              reasoning: {effort: "high"},
              max_output_tokens: 4000
            }')" > review.json

      - name: Post comment on PR
        uses: actions/github-script@v7
        with:
          script: |
            const fs = require('fs')
            const resp = JSON.parse(fs.readFileSync('review.json', 'utf8'))
            const text = resp.output?.[0]?.content?.[0]?.text || '(no review)'
            const review = JSON.parse(text)
            const body = [
              `## 🤖 Codex Auto Review`, ``,
              `**总评**:${review.summary}`,
              `**评级**:\`${review.overall_rating}\``, ``,
              `### 发现的问题`,
              ...review.issues.map(i =>
                `- **[${i.severity}]** \`${i.file}:${i.line}\` (${i.category}) — ${i.message}\n  💡 ${i.suggestion}`
              )
            ].join('\n')
            await github.rest.issues.createComment({
              ...context.repo,
              issue_number: context.issue.number,
              body
            })

需要在仓库 Settings → Secrets and variables → ActionsNEXOR_CODEX_KEY 密钥。

方案 B:GitLab CI

codex-review:
  stage: review
  image: alpine:latest
  only:
    - merge_requests
  before_script:
    - apk add --no-cache curl git jq
  script:
    - git diff origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME --unified=10 > mr.diff
    - |
      curl -s https://nexor.nexoraivision.com/v1/responses \
        -H "Authorization: Bearer $NEXOR_CODEX_KEY" \
        -H "Content-Type: application/json" \
        -d "$(jq -n --rawfile d mr.diff '{
          model: "gpt-5.4",
          instructions: "review 这个 MR 的 diff,输出问题清单",
          input: $d,
          reasoning: {effort: "high"}
        }')" \
        | jq -r '.output[0].content[0].text' > review.md
    - |
      curl --request POST \
        --header "PRIVATE-TOKEN: $CI_API_TOKEN" \
        --data-urlencode "body=$(cat review.md)" \
        "$CI_API_V4_URL/projects/$CI_PROJECT_ID/merge_requests/$CI_MERGE_REQUEST_IID/notes"

方案 C:本地 Git pre-push hook

.git/hooks/pre-push

#!/usr/bin/env bash
set -e

RANGE="${1:-origin/main..HEAD}"
DIFF=$(git diff "$RANGE" --unified=10)
[ -z "$DIFF" ] && exit 0

echo "🤖 Codex pre-push review..."
RESULT=$(curl -s https://nexor.nexoraivision.com/v1/responses \
  -H "Authorization: Bearer $NEXOR_CODEX_KEY" \
  -H "Content-Type: application/json" \
  -d "$(jq -n --arg d "$DIFF" '{
    model: "gpt-5.4-mini",
    instructions: "用一句话评价此次改动,仅当发现明显 bug 或安全问题时返回 BLOCK,否则返回 OK",
    input: $d,
    reasoning: {effort: "medium"}
  }')")

ANSWER=$(echo "$RESULT" | jq -r '.output[0].content[0].text')
echo "$ANSWER"

if echo "$ANSWER" | grep -q "BLOCK"; then
  echo "❌ Codex flagged issues. Push aborted. Pass --no-verify to skip."
  exit 1
fi

方案 D:手动跑 CLI

如果不想搭 CI,最简单:

git diff main | codex -p "review 这段 diff,找潜在 bug / 安全 / 性能 / 风格问题"

参考资料