OpenAI Codex 中文教程

非交互模式

用 codex exec 在脚本、CI 和自动化流水线中运行 Codex

非交互模式允许你在脚本里直接调用 Codex,例如 CI 任务,而不必打开交互式 TUI。入口命令是 codex exec

如果你需要查看更细的 flag 说明,请直接点击 codex exec 查看。

何时使用 codex exec

当你希望 Codex:

  • 作为流水线的一部分运行,例如 CI、预合并检查或定时任务
  • 输出可继续传给其他工具处理的结果,例如 release notes 或摘要
  • 自然嵌入 CLI 工作流,把命令输出传给 Codex,再把 Codex 输出交给其他命令
  • 在一开始就显式固定沙箱和审批设置

就适合使用 codex exec

基本用法

最简单的方式是把任务提示词作为单个参数传入:

codex exec "summarize the repository structure and list the top 5 risky areas"

执行期间,Codex 会把进度写到 stderr,只把最终智能体消息写到 stdout。这让你很容易把结果重定向或接到管道里:

codex exec "generate release notes for the last 10 commits" | tee release-notes.md

如果你不想把会话运行记录文件持久化到磁盘,可以加 --ephemeral

codex exec --ephemeral "triage this repository and suggest next steps"

如果同时提供了提示词参数,并且 stdin 里也有输入,Codex 会把命令行提示词当作指令,把 stdin 内容当作额外上下文。

这很适合“一个命令生成数据,直接交给 Codex 处理”的场景:

curl -s https://jsonplaceholder.typicode.com/comments \
  | codex exec "format the top 20 items into a markdown table" \
  > table.md

更复杂的 stdin 用法见下文的高级 stdin 管道模式

权限与安全

默认情况下,codex exec 运行在只读沙箱中。

在自动化环境里,应始终只授予工作流所需的最小权限:

  • 允许编辑:codex exec --sandbox workspace-write "<task>"
  • 允许更广访问:codex exec --sandbox danger-full-access "<task>"

danger-full-access 只适合在受控环境中使用,例如隔离的 CI runner 或单用途容器。

Codex 仍保留 codex exec --full-auto 作为已弃用的兼容 flag,并会打印警告。新脚本请优先使用显式的 --sandbox workspace-write flag。

如果需要一次不加载 $CODEX_HOME/config.toml 的运行,请使用 --ignore-user-config;如果需要在受控自动化环境中跳过用户和项目 execpolicy .rules 文件,请使用 --ignore-rules

如果你把某个 MCP server 配置成 required = true,并且它初始化失败,codex exec 会直接报错退出,而不会在缺少这个 MCP server 的情况下继续执行。

让输出可供机器读取

如果你要在脚本里消费 Codex 输出,推荐启用 JSON Lines:

codex exec --json "summarize the repo structure" | jq

启用 --json 后,stdout 会变成 JSONL 事件流,因此你可以捕获 Codex 运行期间发出的每个事件。常见事件类型包括 thread.startedturn.startedturn.completedturn.faileditem.*error

常见 item 类型包括智能体消息、推理、命令执行、文件改动、MCP 工具调用、网页搜索和计划更新。

示例 JSONL 输出如下:

{"type":"thread.started","thread_id":"0199a213-81c0-7800-8aa1-bbab2a035a53"}
{"type":"turn.started"}
{"type":"item.started","item":{"id":"item_1","type":"command_execution","command":"bash -lc ls","status":"in_progress"}}
{"type":"item.completed","item":{"id":"item_3","type":"agent_message","text":"Repo contains docs, sdk, and examples directories."}}
{"type":"turn.completed","usage":{"input_tokens":24763,"cached_input_tokens":24448,"output_tokens":122,"reasoning_output_tokens":0}}

如果你只需要最终消息,可以使用 -o <path> / --output-last-message <path> 把它写入文件。Codex 会把最终消息写入文件,同时仍然打印到 stdout(详见 codex exec)。

通过 Schema 生成结构化输出

如果你的下游步骤需要稳定的结构化数据,可以用 --output-schema 传入 JSON Schema,要求最终响应符合该结构。这很适合需要稳定字段的自动化工作流,例如任务摘要、风险报告或发布元数据。

schema.json

{
  "type": "object",
  "properties": {
    "project_name": { "type": "string" },
    "programming_languages": {
      "type": "array",
      "items": { "type": "string" }
    }
  },
  "required": ["project_name", "programming_languages"],
  "additionalProperties": false
}

运行方式:

codex exec "Extract project metadata" \
  --output-schema ./schema.json \
  -o ./project-metadata.json

最终输出示例:

{
  "project_name": "Codex CLI",
  "programming_languages": ["Rust", "TypeScript", "Shell"]
}

在自动化中认证

默认情况下,codex exec 会复用 CLI 已保存的认证状态。在自动化中,更常见的做法是显式提供凭据。

使用 API key 认证

对于 GitHub Actions,请优先使用 Codex GitHub Action,而不是自行安装并认证 CLI。该 action 会安装 Codex、启动 Responses API proxy,并用可配置的安全策略运行 Codex,从而减少 API key 暴露面。

不要在会检出或运行仓库受控代码的 workflow 中,把 OPENAI_API_KEYCODEX_API_KEY 设置为 job 级环境变量。同一个 job 里的构建脚本、测试、依赖 lifecycle hooks,或被攻陷的 action 都可能读取这些环境变量。

在其他自动化环境中,只把 CODEX_API_KEY 设置给单次 codex exec 调用,并确保同一个进程环境中不会运行不受信任的代码。

CODEX_API_KEY=<api-key> codex exec --json "triage open bug reports"

CODEX_API_KEY 只在 codex exec 中受支持。

在 CI/CD 中使用 ChatGPT 管理的认证(高级)

如果你需要在 CI/CD 作业中使用 Codex 用户账号而不是 API key 来运行,请阅读本节。例如,企业团队在受信任的 runner 上使用由 ChatGPT 管理的 Codex 访问,或需要使用 ChatGPT / Codex 的速率限制而不是 API key 配额的用户,都适合这种方式。

API key 仍然是自动化场景的默认首选,因为它更容易发放和轮换。只有在你明确需要以自己的 Codex 账号身份运行时,才应选择这条路径。

不要在公开仓库或开源仓库中使用这套流程。如果 runner 上无法执行 codex login,应通过安全存储预先注入 auth.json,再在 runner 上运行 Codex,让 Codex 就地刷新该文件,并在多次运行之间持久化更新后的文件。

详见 在 CI/CD 中维护 Codex 账号认证(高级)

恢复非交互会话

如果你要在一个多阶段流水线中继续上一次运行,可以使用 resume 子命令:

codex exec "review the change for race conditions"
codex exec resume --last "fix the race conditions you found"

你也可以直接指定某个 session ID:

codex exec resume <SESSION_ID>

需要 Git 仓库

Codex 默认要求命令在 Git 仓库中执行,以减少破坏性改动的风险。如果你确认当前环境安全,可以使用 codex exec --skip-git-repo-check 跳过这项检查。

常见自动化模式

示例:在 GitHub Actions 中自动修复 CI 失败

对于 GitHub Actions workflow,请使用 openai/codex-action,而不是安装 Codex 并把 API key 传给 shell step。该 action 会为 OpenAI API key 启动安全 proxy。

你可以用 Codex 在 CI 失败后自动提出修复建议。一个典型模式如下:

  1. 在主 CI 工作流失败后触发后续工作流。
  2. 以只读仓库权限检出失败的 commit。
  3. 在运行 Codex 之前执行 setup 命令,不把 OpenAI API key 暴露给这些步骤。
  4. 运行 Codex GitHub Action。
  5. 把 Codex 的本地改动保存为 patch artifact。
  6. 在另一个 job 中应用 patch 并创建 PR。

Codex job 只有 contents: read 权限。Codex 运行结束后,它只把 diff 序列化为 artifact。open_pr job 拥有仓库写权限,但不会收到 OPENAI_API_KEY

下面的示例假定是 Node.js 项目。请按你的技术栈调整 setup 和 test 命令。

更深入的安全检查清单见 Codex GitHub Action security guidance

name: Codex auto-fix on CI failure

on:
  workflow_run:
    workflows: ["CI"]
    types: [completed]

jobs:
  generate_fix:
    if: ${{ github.event.workflow_run.conclusion == 'failure' }}
    runs-on: ubuntu-latest
    permissions:
      contents: read
    outputs:
      has_patch: ${{ steps.diff.outputs.has_patch }}
    steps:
      - uses: actions/checkout@v5
        with:
          ref: ${{ github.event.workflow_run.head_sha }}
          fetch-depth: 0
          persist-credentials: false

      - uses: actions/setup-node@v4
        with:
          node-version: "20"

      - name: Install dependencies
        run: |
          if [ -f package-lock.json ]; then npm ci; fi

      - name: Run Codex
        uses: openai/codex-action@v1
        with:
          openai-api-key: ${{ secrets.OPENAI_API_KEY }}
          prompt: |
            The CI workflow "${{ github.event.workflow_run.name }}" failed for commit
            ${{ github.event.workflow_run.head_sha }}.

            Run `npm test --silent` to reproduce the failure. Identify the minimal
            change needed to make the tests pass, implement only that change, and
            run `npm test --silent` again.

            Do not refactor unrelated files.

      - name: Create patch artifact
        id: diff
        run: |
          git add -N .
          git diff --binary HEAD > codex.patch
          if [ -s codex.patch ]; then
            echo "has_patch=true" >> "$GITHUB_OUTPUT"
          else
            echo "has_patch=false" >> "$GITHUB_OUTPUT"
          fi

      - name: Upload patch artifact
        if: steps.diff.outputs.has_patch == 'true'
        uses: actions/upload-artifact@v4
        with:
          name: codex-fix-patch
          path: codex.patch
          if-no-files-found: error

  open_pr:
    runs-on: ubuntu-latest
    needs: generate_fix
    if: needs.generate_fix.outputs.has_patch == 'true'
    permissions:
      contents: write
      pull-requests: write
    steps:
      - uses: actions/checkout@v5
        with:
          ref: ${{ github.event.workflow_run.head_sha }}
          fetch-depth: 0

      - uses: actions/download-artifact@v4
        with:
          name: codex-fix-patch

      - name: Apply Codex patch
        run: git apply --index codex.patch

      - name: Open pull request
        env:
          GH_TOKEN: ${{ github.token }}
          FAILED_HEAD_BRANCH: ${{ github.event.workflow_run.head_branch }}
          FAILED_HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
          RUN_ID: ${{ github.event.workflow_run.run_id }}
        run: |
          branch="codex/auto-fix-$RUN_ID"

          git config user.name "github-actions[bot]"
          git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
          git switch -c "$branch"
          git commit -m "Auto-fix failing CI via Codex"
          git push origin "$branch"

          {
            echo "Codex generated this patch after CI failed for \`$FAILED_HEAD_SHA\`."
            echo
            echo "Review the changes before merging."
          } > pr-body.md

          gh pr create \
            --base "$FAILED_HEAD_BRANCH" \
            --head "$branch" \
            --title "Auto-fix failing CI via Codex" \
            --body-file pr-body.md

高级 stdin 管道模式

当另一个命令要把结果交给 Codex 时,应根据“指令来自哪里”来选择 stdin 模式。如果你已经知道指令,只是想把命令输出作为上下文传给 Codex,就用“提示词 + stdin”;如果 stdin 本身就是完整提示词,就用 codex exec -

使用提示词 + stdin

这种模式适合上游命令已经生成了你想让 Codex 检查的数据,而你只需自己补充解释任务目标:

npm test 2>&1 \
  | codex exec "summarize the failing tests and propose the smallest likely fix" \
  | tee test-summary.md
更多提示词 + stdin 示例

汇总日志

tail -n 200 app.log \
  | codex exec "identify the likely root cause, cite the most important errors, and suggest the next three debugging steps" \
  > log-triage.md

分析 TLS 或 HTTP 故障

curl -vv https://api.example.com/health 2>&1 \
  | codex exec "explain the TLS or HTTP failure and suggest the most likely fix" \
  > tls-debug.md

生成可直接发到 Slack 的更新

gh run view 123456 --log \
  | codex exec "write a concise Slack-ready update on the CI failure, including the likely cause and next step" \
  | pbcopy

根据 CI 日志起草 PR 评论

gh run view 123456 --log \
  | codex exec "summarize the failure in 5 bullets for the pull request thread" \
  | gh pr comment 789 --body-file -

当 stdin 本身就是完整提示词时使用 codex exec -

如果你不提供提示词参数,Codex 会从 stdin 读取完整提示词。显式写成 codex exec - 可以强制采用这种行为。

这很适合把提示词存在文件里、用 shell 脚本拼装提示词,或者把实时命令输出和说明拼接后整体交给 Codex:

cat prompt.txt | codex exec -
printf "Summarize this error log in 3 bullets:\n\n%s\n" "$(tail -n 200 app.log)" \
  | codex exec -
generate_prompt.sh | codex exec - --json > result.jsonl