TellWorldAI 世界档案
问档案English

首页›实践›实践

实践

Codex 非交互模式:codex exec 写脚本

想让 Codex 在 CI 或脚本里跑?本文讲 codex exec 的用法:传入任务、接管道、选沙箱权限、输出 JSON,以及 CI 里 API key 怎么放才安全。

这篇适合谁、读完能做到什么

如果你想让 Codex 在 CI、定时任务或 shell 管道里运行,而不是每次在交互界面里操作,这篇适合你。读完你能用 codex exec 跑一个任务、保存输出、选对沙箱权限、得到机器可读的 JSON,并知道 API key 放在哪里才安全。[1]

codex exec 是什么

非交互模式让 Codex 在脚本里运行,不必打开交互界面,入口是 codex exec。[1] 它适合放进流水线,比如 CI、合并前检查和定时任务;也适合把输出交给其他工具、把命令输出接给 Codex 处理,或者用事先定好的沙箱和审批设置来运行。[1] 每个命令行参数的说明,可以在开发者命令参考里的 codex exec 条目中查到。[1]

第一个命令

把任务描述作为唯一参数传入。下面的命令让 Codex 梳理仓库结构,并列出风险最高的五个区域:[1]

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

运行时,进度信息输出到 stderr,stdout 里只有最终回复。所以结果很容易重定向,或者接到下一个命令里。[1]

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

不想把会话记录保存到磁盘,就加上 --ephemeral:[1]

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

用管道把数据交给 Codex

如果同时传了 stdin 和 prompt 参数,Codex 把 prompt 当作指令,把管道里的内容当作补充上下文。记住这个分工,就不会把指令误放进管道里。下面的例子先取一批评论数据,再让 Codex 整理成表格:[1]

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

还有两种 stdin 用法。第一种是「prompt 加 stdin」:指令自己写,命令的输出作为上下文。比如先跑测试,再让 Codex 总结失败的用例:[1]

npm test 2>&1 \
  | codex exec "summarize the failing tests and propose the smallest likely fix" \
  | tee test-summary.md

第二种是用 codex exec - 让 stdin 成为完整的 prompt,适合由脚本拼出来的提示词:[1]

cat prompt.txt | codex exec -

不带 prompt 参数时,Codex 同样从 stdin 读取 prompt;- 只是把这个行为写明确。[1]

权限:先给最少的

codex exec 默认在只读沙箱里运行。需要它改文件时,加上 --sandbox workspace-write。--sandbox danger-full-access 的权限更大,只应在隔离的 CI runner 或容器里使用。[1]

--full-auto 已经不再支持。旧脚本要改成 --sandbox workspace-write,或者改用 --approve-for-me,让审批请求经过自动审查,同时仍然运行在 workspace-write 沙箱中。[1]

需要跳过用户配置时,加 --ignore-user-config,它会跳过 $CODEX_HOME/config.toml。--ignore-rules 则跳过用户和项目的 execpolicy .rules 文件,适合受控的自动化环境。[1]

如果某个启用的 MCP 服务器配置了 required = true,而它初始化失败,codex exec 会报错退出,而不是在缺少它的情况下继续。[1]

输出机器可读的结果

加上 --json 后,stdout 变成 JSON Lines(JSONL)流,Codex 运行时的每个事件都会记一行:[1]

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

事件类型包括 thread.started、turn.started、turn.completed、turn.failed、item.* 和 error。条目类型有 agent 消息、推理过程、命令执行、文件改动、MCP 工具调用、网页搜索和计划更新。[1] 一段示例输出如下,每行是一个 JSON 对象:[1]

{"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}}

下游脚本可以逐行解析这些事件,看到 turn.failed 就能知道这一轮运行失败了,再决定是否重试或通知。[1]

如果只需要最后一条消息,用 -o <路径> 或 --output-last-message <路径>。消息会写进该文件,同时仍然打印到 stdout。[1]

用 JSON Schema 约束输出

下游步骤要依赖固定的字段名时,用 --output-schema 让最终回复符合一个 JSON Schema。这适合生成任务摘要、风险报告或发布元数据这类自动化流程。[1] schema 文件大致是这样:[1]

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

然后带上 schema 运行,并把结果写进文件:[1]

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

CI 里的认证

codex exec 默认复用机器上已保存的 CLI 登录状态。自动化任务通常要显式提供凭据。[1] 如果只想为某一次运行换一个 API key,可以在命令前内联设置 CODEX_API_KEY:[1]

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。[1]

安全上要注意:在会检出或运行仓库代码的工作流里,不要把 OPENAI_API_KEY 或 CODEX_API_KEY 设为整个 job 的环境变量。构建脚本、测试、依赖的生命周期钩子,或者被攻破的 action,都可能在同一个 job 里读到它们。[1]

在 GitHub Actions 里,文档建议直接使用官方的 Codex GitHub Action,而不是自己安装并登录 CLI。这个 action 会安装 Codex、启动一个 Responses API 代理,并按可配置的安全策略运行 Codex。[1]

如果确实需要以 Codex 用户账户在 CI/CD 中运行,那是高级用法。~/.codex/auth.json 含有访问令牌,要像对待密码一样保护:不要提交,不要贴进工单,也不要在聊天里分享。公开或开源仓库不要使用这种方式。[1]

续接上一次运行

两阶段的流水线里,可以用 resume 接着上一次的会话:[1]

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

也可以用 codex exec resume <SESSION_ID> 指定某个会话。[1] 用 --last 时则指向最近一次的会话,不必记住 ID。[1]

必须在 Git 仓库里运行

Codex 要求命令在 Git 仓库中执行,这样可以防止破坏性修改。这条限制对脚本同样生效,脚本报错时应先检查工作目录是不是仓库。只有在确认环境安全时,才加 --skip-git-repo-check 跳过这项检查。[1] 如果任务不在 Git 仓库里运行,先确认环境确实安全,再决定是否加这个参数。[1]

例子:CI 失败后自动修复

文档里给出了一个模式:主 CI 失败后,触发一个后续工作流;以只读的仓库权限检出失败的提交;在 Codex 之前运行安装等准备步骤,但不把 OpenAI API key 交给这些步骤;运行 Codex GitHub Action;把 Codex 产生的本地改动保存为 patch 产物;最后由单独的 job 应用这个 patch,并开一个 PR。[1]

在这个模式里,生成修复的 job 只有 contents: read 权限;负责开 PR 的 job 有写权限,但拿不到 OPENAI_API_KEY。[1] 写仓库的那一步因此接触不到 key。[1]

常见问题

  • 报错说不在 Git 仓库里。 确认当前目录位于 Git 仓库中。只有确认环境安全时,才加 --skip-git-repo-check。[1]
  • **旧脚本里的 --full-auto 不能用了。** 换成 --sandbox workspace-write,或者 --approve-for-me。[1]
  • 需要结构化的结果。 用 --output-schema 固定字段,再用 -o 把结果保存到文件。[1]
  • MCP 服务器没起来,整个命令退出了。 这是 required = true 的效果。如果允许缺少这个服务器,就不要把它设为必需。[1]

下一步

命令行参数的完整列表在官方的开发者命令参考里。[1]

来源

  1. 1
    Non-interactive modeOpenAI Codex docs

引用本页: Codex 非交互模式:codex exec 写脚本. TellWorld, https://www.tellworld.net/zh/practice/practice-codex-non-interactive. 更新于 2026-11-14

相关动态