最后核验:2026-10-23

先看结论

codex exec 是 Codex 的非交互模式:不打开终端界面,直接在脚本、CI 任务里运行。官方列出的适用场景有:作为流水线的一环(CI、合并前检查、定时任务);产出可以接到其他工具的输出(比如生成发布说明或摘要);把命令输出串进 Codex,再把 Codex 输出交给别的工具;以及用明确、预先设定的沙箱和审批设置运行。几个要点:

  • 输出分流:运行时进度写到 stderr,只有最终的 agent 消息写到 stdout,所以重定向和管道很直接;
  • 默认只读:codex exec 默认在只读沙箱里运行,需要改文件就显式放开,且遵循最小权限;
  • --full-auto 已不再支持:旧脚本要改用 --sandbox workspace-write,或用 --approve-for-me(经自动审核处理审批请求,配合 workspace-write 沙箱);
  • GitHub Actions 用官方 Action:用 openai/codex-action,不要自己装 CLI、再把 API Key 暴露给 shell 步骤;
  • 要结构化结果:用 --json 输出事件流,或用 --output-schema 要求最终回复符合 JSON Schema。

内容整理自 OpenAI 官方文档,核验日期 2026-10-23;参数与默认值以你安装的版本为准。

五分钟起步

把任务作为一个参数传入:

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

因为只有最终消息进 stdout,可以直接接管道或落盘:

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

不想把会话记录(rollout 文件)写到磁盘,加 --ephemeral:

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

如果标准输入有管道内容,同时又给了提示词参数,Codex 把提示词当作指令,把管道内容当作额外上下文:

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

权限与安全:默认只读,按需放开

官方的要求是:自动化里只设置工作流需要的最小权限。

  • 允许改文件:codex exec --sandbox workspace-write "<task>"
  • 允许更广的访问:codex exec --sandbox danger-full-access "<task>"。只在受控环境里用,例如隔离的 CI runner 或容器;

另外几个官方提到的开关和行为:

  • --ignore-user-config:这次运行不加载 $CODEX_HOME/config.toml;
  • --ignore-rules:在受控的自动化环境里跳过用户和项目的 execpolicy .rules 文件;
  • 如果某个启用的 MCP 服务器配置了 required = true 而初始化失败,codex exec 会报错退出,而不是跳过这个服务器继续跑;
  • 必须在 Git 仓库里运行:这是为了防止破坏性改动。只有在你确定环境安全时,才用 --skip-git-repo-check 绕过这条检查。

编者建议:先在本地用默认的只读模式把提示词跑通,确认输出合理,再决定是否放开写权限;放开时只放开 workspace-write,不要一步到位 danger-full-access。

让输出可被程序读取

事件流:--json

加上 --json,stdout 就变成 JSON Lines(JSONL)事件流,每行一个 JSON 对象,记录 Codex 运行过程中发出的所有事件:

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

官方列出的事件类型有 thread.started、turn.started、turn.completed、turn.failed、item.* 和 error;条目类型包括 agent 消息、推理、命令执行、文件改动、MCP 工具调用、网页搜索和计划更新。官方的样例流如下:

{"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>)把它写到文件里;它同时仍会打印到 stdout。

结构化输出:--output-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
}

运行并把最终 JSON 写到磁盘:

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

把命令输出交给 Codex

官方介绍了两种标准输入的写法,区别在“指令从哪来”:

  • 提示词加管道(prompt-plus-stdin):你自己写指令,把前一条命令的输出当作上下文。适合日志、测试结果、生成的数据:
npm test 2>&1 \
  | codex exec "summarize the failing tests and propose the smallest likely fix" \
  | tee test-summary.md

官方还给了几个同类用法:总结日志(tail -n 200 app.log | codex exec "identify the likely root cause ...")、分析 TLS 或 HTTP 问题(curl -vv ... 2>&1 | codex exec "explain the TLS or HTTP failure ...")、把 CI 失败写成 Slack 更新,或用 gh pr comment 把摘要贴到 PR 里。

  • 用 codex exec - 让标准输入成为完整提示词:省略提示词参数时,Codex 从标准输入读取提示词,- 是显式写法。适合提示词存在文件里、由脚本拼出来,或把实时命令输出与指令合在一起:
cat prompt.txt | codex exec -

两阶段流水线:resume

如果要接着上一次运行继续(比如先审查、再修复的两阶段流水线),用 resume 子命令:

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

也可以用 codex exec resume <SESSION_ID> 指定某个会话。

认证:API Key 是自动化的默认选择

codex exec 默认复用已保存的 CLI 认证;在 CI 里通常显式提供凭据。官方的要点:

  • GitHub Actions 用官方 Action(见下一节),它的设计就是减少 API Key 暴露:安装 Codex,启动 Responses API 代理,并按可配置的安全策略运行 Codex;
  • 不要把 OPENAI_API_KEY 或 CODEX_API_KEY 设成 job 级环境变量,尤其是会检出或运行仓库里受控代码的工作流:构建脚本、测试、依赖的生命周期钩子,或同一 job 里被攻破的 Action,都能读到这些环境变量;
  • 其他自动化环境:只在需要的那一次调用上设置 CODEX_API_KEY,并确保同一进程环境里没有不受信任的代码在运行。单次运行可以内联设置:
CODEX_API_KEY=<api-key> codex exec --json "triage open bug reports"

CODEX_API_KEY 可用于 codex exec、codex review、TypeScript SDK 和 codex exec-server --remote。

官方还单独提到一条进阶路径:在可信 runner 上用 ChatGPT 托管的认证(而不是 API Key)跑 CI。官方同时强调:API Key 更容易发放和轮换,是自动化的合适默认;~/.codex/auth.json 含有访问令牌,要当作密码对待,不要提交、不要贴进工单或聊天;不要把这种方式用于公开或开源仓库。详细步骤见官方的 CI/CD 认证说明。

用官方 GitHub Action 做 PR 审查

在 GitHub Actions 里,官方的做法是用 openai/codex-action@v1:它安装 Codex CLI,在提供 API Key 时启动 Responses API 代理,并按你指定的权限运行 codex exec。使用前提:

  • 把 OpenAI 密钥存成 GitHub secret(例如 OPENAI_API_KEY);
  • 在 Linux 或 macOS runner 上运行;Windows 需要设置 safety-strategy: unsafe;
  • 先检出代码,Codex 才能读取仓库内容;
  • 提示词可以用 prompt 写内联文本,或用 prompt-file 指向仓库里的文件(二选一),官方建议放在 .github/codex/prompts/。

官方示例:审查新的 pull request,并把 Codex 的回复发回 PR:

name: Codex pull request review
on:
  pull_request:
    types: [opened, synchronize, reopened]
jobs:
  codex:
    runs-on: ubuntu-latest
    permissions:
      contents: read
    outputs:
      final_message: ${{ steps.run_codex.outputs.final-message }}
    steps:
      - uses: actions/checkout@v5
        with:
          ref: refs/pull/${{ github.event.pull_request.number }}/merge
          fetch-depth: 0
          persist-credentials: false
      - name: Run Codex
        id: run_codex
        uses: openai/codex-action@v1
        with:
          openai-api-key: ${{ secrets.OPENAI_API_KEY }}
          prompt-file: .github/codex/prompts/review.md
          output-file: codex-output.md
  post_feedback:
    runs-on: ubuntu-latest
    needs: codex
    if: needs.codex.outputs.final_message != ''
    permissions:
      issues: write
      pull-requests: write
    steps:
      - name: Post Codex feedback
        uses: actions/github-script@v7
        with:
          github-token: ${{ github.token }}
          script: |
            await github.rest.issues.createComment({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: context.payload.pull_request.number,
              body: process.env.CODEX_FINAL_MESSAGE,
            });
        env:
          CODEX_FINAL_MESSAGE: ${{ needs.codex.outputs.final_message }}

注意这个示例把权限分在两个 job:运行 Codex 的 job 只有 contents: read,发评论的 job 才有 pull-requests: write。把 .github/codex/prompts/review.md 换成你自己的提示词文件即可。

常用输入

官方列出的、与 codex exec 选项对应的输入:

  • prompt 或 prompt-file:任务说明;
  • codex-args:额外的 CLI 参数,可以是 JSON 数组(如 ["--ephemeral"])或 shell 字符串(如 --profile ci);
  • model 和 effort:选择 Codex 代理配置,留空用默认;
  • sandbox:workspace-write、read-only、danger-full-access,选能完成任务的最窄的一档;
  • output-file:把最终消息存盘,供后续步骤上传或比对;
  • codex-version:固定 CLI 版本,留空用最新发布版;
  • codex-home:指向共享的 Codex 主目录,在多个步骤间复用配置或 MCP 设置。

权限与安全清单

官方提醒:在 GitHub 托管的 runner 上,除非你限制,否则 Codex 的权限很大。

  • safety-strategy 默认是 drop-sudo:在运行 Codex 之前移除 sudo,对这个 job 不可逆,用来保护内存里的密钥;Windows 必须设为 unsafe;
  • 用 unprivileged-user 配合 codex-user,以指定的无特权账号运行 Codex;
  • read-only 只是不让 Codex 改文件或联网,但它仍以较高权限运行,不要只靠 read-only 来保护密钥;
  • allow-users 与 allow-bots 限制谁能触发工作流,默认只有对仓库有写权限的用户可以运行;
  • 限制谁能启动工作流,优先用可信事件或明确的审批;
  • 净化来自 PR、提交信息、Issue 正文的输入,防止提示注入,把 HTML 注释和隐藏文本交给 Codex 之前先检查;
  • 让 Codex 作为 job 的最后一步,后续步骤就不会继承意外的状态变化;
  • 怀疑代理日志或 Action 输出泄露了密钥,立即轮换。

CI 失败自动修复:权限分离的六步模式

官方的非交互模式页还给了一个完整示例:CI 失败后自动提出修复。这个模式的价值在于把有密钥的步骤和有写权限的步骤分开:

  1. 主 CI 工作流失败时,触发一个后续工作流;
  2. 以只读仓库权限检出失败的那个提交;
  3. 在 Codex 之前运行安装类的命令,且这些步骤拿不到 OpenAI API Key;
  4. 运行 Codex GitHub Action,提示词里写明复现命令、只做最小改动、不要重构无关文件;
  5. 把 Codex 的本地改动保存成补丁(patch)工件;
  6. 在另一个 job 里应用补丁并开 PR。这个 job 有仓库写权限,但拿不到 OPENAI_API_KEY。

官方原文给出了完整的 YAML(以 Node.js 项目为例,需按你的技术栈调整安装和测试命令),详见官方文档;更详细的安全清单见官方 Action 仓库的 openai/codex-action 文档。

常见问题与排错

官方对 GitHub Action 列出的几类问题:

  • 同时设了 prompt 和 prompt-file:去掉重复的输入,只保留一个;
  • responses-api-proxy didn't write server info:确认 API Key 存在且有效,只有提供了 openai-api-key 才会启动代理;
  • 预期移除了 sudo,实际还在:确认前面的步骤没有恢复 sudo,且 runner 是 Linux 或 macOS,然后在新的 job 里重试;
  • drop-sudo 之后出现权限错误:在 Action 运行前先授予写权限(例如 chmod -R g+rwX "$GITHUB_WORKSPACE"),或改用无特权用户的模式;
  • 未授权的触发被拦截:如果需要允许服务账号,调整 allow-users 或 allow-bots。

以下是编者的补充,帮你在上线前自己核对:

  • 先在本地手工运行同一条 codex exec 命令,确认 stdout 里只有最终消息、进度在 stderr,再放进流水线;
  • 要消费 JSON 的脚本,先用 --json | jq 看一遍事件结构,再写解析;
  • 在流水线里把 Codex 的输出当作“建议”:生成的补丁走 PR、由人审阅,不要直接合并。

自查清单

  • 这个任务需要写权限吗?不需要就保持默认只读。
  • 如果需要,是不是只用了 workspace-write?danger-full-access 是不是只在隔离环境里?
  • 脚本里还有没有已经不被支持的 --full-auto?
  • API Key 有没有设成 job 级环境变量?有没有不受信任的代码和它在同一个进程环境里?
  • GitHub 上是不是用了 openai/codex-action?safety-strategy 是不是还保持默认的 drop-sudo?
  • 来自 PR、提交信息、Issue 的文本有没有经过净化再给 Codex?
  • 有写权限的步骤,是不是和有密钥的步骤分开了?

下一步读什么

官方来源

核验日期:2026-10-23。


WeAPI 企业模型调用入口,统一管理 Key、用量、日志、额度和团队权限 WeAPI 企业模型调用入口