04 · 云端、CI 与非交互模式
三条不同的自动化路子
| 方式 | 跑在哪 | 适合 |
|---|---|---|
codex exec | 你的机器 / 你的 CI 运行器 | 流水线、合并前检查、定时作业、跟别的命令拼管道 |
| Codex GitHub Action | GitHub 运行器 | PR 审查、CI 质量门、可重复的工作流任务 |
| Codex 云端 | OpenAI 托管的隔离容器 | 你想把活扔出去、回头看结果 |
codex exec:给脚本用的 Codex
codex exec "summarize the repository structure and list the top 5 risky areas"输出分流很关键:运行期间进度流到 stderr,只有最终的智能体消息打到 stdout。 所以重定向和管道都很干净:
codex exec "generate release notes for the last 10 commits" | tee release-notes.md不想在磁盘上留会话记录:
codex exec --ephemeral "triage this repository and suggest next steps"stdin 也能用。如果同时给了提示参数和管道输入,提示当指令,管道内容当额外上下文:
curl -s https://jsonplaceholder.typicode.com/comments \
| codex exec "format the top 20 items into a markdown table" \
> table.md权限:默认就是对的
codex exec 默认在只读沙盒里跑。 自动化里请按需要的最低权限来:
codex exec --sandbox workspace-write "<task>" # 允许改文件
codex exec --sandbox danger-full-access "<task>" # 只在隔离的运行器或容器里用旧的 --full-auto 还留着,但已弃用并会告警,新脚本直接写明 --sandbox workspace-write。
两个在受控自动化里有用的开关:
--ignore-user-config:这次运行不加载$CODEX_HOME/config.toml--ignore-rules:跳过用户和项目的 execpolicy.rules文件
另外:如果某个启用的 MCP 服务器配了 required = true 而初始化失败, codex exec 会报错退出,不会在缺服务器的情况下硬跑。这是好事,别绕过它。
机器可读的输出
codex exec --json "summarize the repo structure" | jq--json 之后 stdout 变成 JSON Lines 流,能拿到运行期间的每个事件: thread.started、turn.started、turn.completed、turn.failed、item.*、error。 条目类型涵盖智能体消息、推理、命令执行、文件更改、MCP 工具调用、网页搜索、计划更新。
{"type":"thread.started","thread_id":"0199a213-81c0-7800-8aa1-bbab2a035a53"}
{"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 要一个符合 JSON Schema 的最终响应—— 作业摘要、风险报告、发布元数据这类需要稳定字段的场景。
接着上一次跑
codex exec "review the change for race conditions"
codex exec resume --last "fix the race conditions you found"也可以 codex exec resume <SESSION_ID> 指定具体会话。两阶段流水线用得上。
它要求在 Git 仓库里跑
这是防破坏性改动的保护。确定环境安全的话可以 --skip-git-repo-check 跳过, 但在 CI 里一般没必要跳——代码本来就是签出来的。
GitHub Action
- 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官方建议用这个 Action,而不是自己装 CLI 再把 API 密钥传给 shell 步骤。 它会装 Codex、启动 Responses API 代理、按你指定的权限跑 codex exec, 把密钥暴露面收窄。
前提条件:密钥存成 GitHub 机密;在 Linux 或 macOS 运行器上跑 (Windows 必须设 safety-strategy: unsafe);先 checkout 再调用它。
safety-strategy 值得单独说
| 值 | 效果 |
|---|---|
drop-sudo(默认) | 跑 Codex 前移除 sudo,对该作业不可逆,保护内存中的机密 |
unprivileged-user | 配合 codex-user,以特定非特权账户运行 |
read-only | 阻止 Codex 改文件或联网,但运行时仍有提升的权限——别只靠它保护机密 |
unsafe | 不加保护,绝不要在多租户运行器上保持这个模式 |
另有 sandbox 限制 Codex 自己对文件系统和网络的访问, 以及 allow-users / allow-bots 限制谁能触发工作流 (默认只有有写权限的用户能跑)。
安全检查清单
官方列的四条,每条都是踩出来的:
- 限制谁能启动工作流——用受信任的事件或显式审批,别让所有人都能对你的仓库跑 Codex。
- 清洗来自 PR、提交消息、议题正文的提示输入,防提示注入。 HTML 注释和隐藏文本在喂给 Codex 前先看一眼。
- 保护
OPENAI_API_KEY:safety-strategy保持drop-sudo,或让 Codex 以非特权用户跑。 - 让 Codex 在作业的最后一步跑,免得后续步骤继承意外的状态改动。
密钥怎么放
这一条特别重要:如果工作流会签出或运行由代码仓库控制的代码, 不要把 OPENAI_API_KEY 或 CODEX_API_KEY 设成作业级环境变量。 同一作业里的构建脚本、测试、依赖生命周期钩子,或者一个被入侵的 Action,都能读到它。
单次运行用不同密钥的话内联给:
CODEX_API_KEY=<api-key> codex exec --json "triage open bug reports"如果你的云环境或 CI 运行时本来就有短期工作负载令牌, 优先用工作负载身份联合,别存 OpenAI 凭据。
用 Codex 用户账户(而不是 API 密钥)跑 CI 也是可以的,但注意: ~/.codex/auth.json 里是访问令牌,像密码一样保护,别提交、别贴工单、别在聊天里发。 官方明确说了不要把这个工作流用于公开或开源仓库。 API 密钥更容易预配和轮换,是自动化的合适默认选择。
Codex 云端
云端聊天跑在 OpenAI 管理的隔离容器里,碰不到你的主机系统。 它是两阶段的:
- 设置阶段:可以访问网络,装你指定的依赖。
- 智能体阶段:默认离线,除非你为这个环境启用了互联网访问。
给云端环境配的机密只在设置阶段可用,进智能体阶段之前就被移除了。 这个设计意味着:需要在智能体阶段用到的凭据,得换个方式给—— 把它当成一条约束,而不是一个 bug。
用云端必须用 ChatGPT 账号登录,API 密钥这条路走不通(见 快速上手 02)。