Headless / CI 集成
CC 用 -p/--bare + stream-json 把交互会话降维成管道命令;Codex 用 exec 子命令 + JSONL 事件流原生面向自动化。两家都有官方 GitHub Action,CI 确定性策略截然不同。
Headless / CI 集成
结论
CC 的 headless 是「交互模式加 -p 开关」:默认仍加载本机 hooks/MCP/CLAUDE.md,要确定性必须显式 --bare;输出三档(text/json/stream-json),结构化输出走 --json-schema,权限靠 --allowedTools/--permission-mode 白名单。Codex 的 headless 是独立子命令 codex exec:默认不带 TUI 包袱,--json 输出 thread.*/turn.*/item.* JSONL 事件,--output-schema 约束最终响应,-o 直接落最终消息文件,turn 失败时显式 exit(1)「automation-friendly signaling」。CI 认证:CC 走 ANTHROPIC_API_KEY(或 Bedrock/Vertex 凭据),Codex 支持 CODEX_API_KEY / OPENAI_API_KEY / CODEX_ACCESS_TOKEN 三个环境变量。两家都有官方 Action:anthropics/claude-code-action@v1(@claude 提及驱动 + claude_args 透传)与 openai/codex-action(codex 仓库自己的 CI 在用,output-schema + final-message 输出)。
研究问题
- CC
-p模式的输出协议、退出码与确定性边界在哪? codex exec --json的事件 schema 与错误信号语义?- CI 内的认证、权限收敛与产物回传各自怎么做?
各 Agent 设计与实现
Claude Code
print 模式:claude -p "<prompt>" 非交互执行,所有 CLI 选项可叠加 [一手文档](claude-code-docs/docs/headless.md:15-35)。关键开关:
--bare:跳过 hooks/skills/plugins/MCP/auto memory/CLAUDE.md 的自动发现,「useful for CI and scripts where you need the same result on every machine」;官方明示--bare将来会成为-p的默认(headless.md:37-63)[一手文档]。bare 模式跳过 OAuth/keychain,认证只认ANTHROPIC_API_KEY或--settings里的apiKeyHelper(headless.md:59)。--output-format text|json|stream-json;json含total_cost_usd、session_id;stream-json+--verbose+--include-partial-messages逐 token 流(headless.md:105-155)。--json-schema '<schema>'→ 响应的structured_output字段(headless.md:117-125)。--max-turns N:限制 agentic 轮数,「Exits with an error when the limit is reached」(cli-reference.md:86)[一手文档]。- 退出码语义:stdin 超 10MB 上限「exits with a clear error and a non-zero status」(
headless.md:86);重试期间发system/api_retry事件(attempt/max_retries/error 分类,headless.md:157-169);system/init事件带plugins/plugin_errors字段,官方建议「Use the plugin fields to fail CI when a plugin did not load」(headless.md:171-177)[一手文档]。 - 后台任务:
-p返回结果后约 5 秒强杀 background Bash(v2.1.163 前会被永不退出的后台进程挂死,headless.md:67)。
权限策略(CI 确定性):--allowedTools "Bash(git diff *),Read" 用权限规则语法做前缀白名单;--permission-mode dontAsk 拒绝一切白名单外动作(locked-down CI),acceptEdits 自动放行文件写和 mkdir/mv/cp 类命令,其余仍需规则,否则 run 中止(headless.md:194-216)[一手文档]。注意:/code-review 等用户侧 skill 在 -p 模式不可用,要用自然语言描述任务(headless.md:218-220)。
会话续传:--continue 接最近会话,--resume <session_id> 指定会话;session_id 从 --output-format json 的输出里 jq -r '.session_id' 捕获(headless.md:234-252)。
GitHub Actions:anthropics/claude-code-action,@claude 在 issue/PR 评论里触发,模式自动检测(v1 移除了 beta 的 mode: tag/agent);beta 的 max_turns/model/allowed_tools 全部折叠进 claude_args(即透传 CLI flag),prompt 直接给任务(github-actions.md:88-110 的 Breaking Changes 对照表)[一手文档]。安装走 /install-github-app 或手动装 GitHub App(Contents/Issues/PR 读写权限)+ ANTHROPIC_API_KEY secret(github-actions.md:43-72);官方强调「Your code stays on Github's runners」——这是与托管 Code Review(跑在 Anthropic 侧)的关键边界。GitLab CI/CD 有对应文档(gitlab-ci-cd.md),Bedrock/Vertex 走各自凭据。
plugin 安装可观测:设 CLAUDE_CODE_SYNC_PLUGIN_INSTALL 后,首 turn 前会流式发出 system/plugin_install 事件(status: started/installed/failed/completed,headless.md:178-188)——CI 里装 marketplace 插件的进度与失败可以被脚本捕获,而不是黑盒等待 [一手文档]。
Codex CLI
exec 子命令:codex exec [OPTIONS] [PROMPT],prompt 缺省或 - 时读 stdin;stdin 与 prompt 同时给时 stdin 以 <stdin> 块附加(codex-rs/exec/src/cli.rs:81-86)[一手源码]。关键 flag(均出自 exec/src/cli.rs):
--json(alias--experimental-json):JSONL 事件流到 stdout(:63-70)--output-schema FILE:JSON Schema 约束最终响应(:52-54)-o/--output-last-message FILE:最终消息落文件——CI 产物回传最省事的通道(:72-79)--ephemeral:不落盘 session 文件(:30-32);--ignore-user-config:不读$CODEX_HOME/config.toml(auth 仍用 CODEX_HOME,:34-36);--ignore-rules:跳过 execpolicy.rules(:38-40)——这三个加--strict-config就是 Codex 版「bare mode」--skip-git-repo-check:允许在非 git 目录跑(:26-28)- 子命令:
codex exec resume <id>|--last续跑、codex exec review评审(:165-172,见 code-review 章) --full-auto已废弃,提示改用--sandbox workspace-write(:102-111)
JSONL 事件 schema [一手源码](exec/src/exec_events.rs:9-38,serde tag type):thread.started / turn.started / turn.completed(带 usage)/ turn.failed / item.started / item.updated / item.completed / error。item 细类含 AgentMessageItem/ReasoningItem/CommandExecutionItem/FileChangeItem/McpToolCallItem/WebSearchItem/TodoListItem 等(exec_events.rs:104-315)。
退出码:事件循环里跟踪 error_seen——server 报不可重试错误、或 turn 终态为 Failed/Interrupted 时置位,收尾 std::process::exit(1),注释明言「exit with a non-zero status for automation-friendly signaling」(exec/src/lib.rs:925-1030)[一手源码]。
CI 认证:环境变量常量定义在 login/src/auth/manager.rs:516-518:OPENAI_API_KEY、CODEX_API_KEY、CODEX_ACCESS_TOKEN,均做非空 trim 读取(:520-533)[一手源码]。docs/authentication.md 是指向 developers.openai.com 的存根,细节以源码为准。
GitHub Action:openai/codex-action@...# v1.7 在 codex 仓库自己的 issue 去重工作流中实战使用:输入 openai-api-key(secret)、sandbox: read-only、safety-strategy: drop-sudo、output-schema(内联 JSON Schema),输出 final-message 供下游 job 消费(.github/workflows/issue-deduplicator.yml:59-99,114)[一手源码]——这是「exec + 结构化输出 + 产物回传」的官方范本。
差异矩阵
| 维度 | Claude Code | Codex CLI |
|---|---|---|
| 非交互入口 | claude -p(交互模式的降维开关) | codex exec(独立子命令) |
| 确定性模式 | --bare(显式跳过本机配置,未来默认) | --ignore-user-config + --ignore-rules + --ephemeral |
| 流式输出 | --output-format stream-json(type: system/assistant/result…) | --json(type: thread./turn./item.*) |
| 结构化输出 | --json-schema → structured_output | --output-schema FILE → 最终响应本体 |
| 产物回传 | json 输出 jq 提取(.result/.session_id) | -o FILE 落最终消息 / Action 的 final-message |
| 轮数限制 | --max-turns(超限报错退出) | 无对应 flag(未检索到)[一手源码-缺失] |
| 失败信号 | 非零退出 + system/api_retry/plugin_errors 事件 | error_seen → exit(1);turn.failed 事件 |
| 权限收敛 | --allowedTools 规则 + --permission-mode dontAsk/acceptEdits | --sandbox read-only/workspace-write + execpolicy rules |
| CI 认证 | ANTHROPIC_API_KEY / Bedrock / Vertex | CODEX_API_KEY / OPENAI_API_KEY / CODEX_ACCESS_TOKEN |
| 官方 Action | anthropics/claude-code-action@v1(@claude 提及 + claude_args) | openai/codex-action(v1.7,官方仓库自用) |
最小复现
# CC:确定性 CI 调用 + 结构化输出
claude --bare -p "Extract function names from auth.py" \
--output-format json \
--json-schema '{"type":"object","properties":{"functions":{"type":"array","items":{"type":"string"}}},"required":["functions"]}' \
| jq '.structured_output'
# CC:捕获 session 再续跑
sid=$(claude --bare -p "Start a review" --output-format json | jq -r '.session_id')
claude -p "Continue that review" --resume "$sid"
# Codex:JSONL 事件流 + 最终消息落盘 + 失败即非零退出
codex exec --json --ephemeral --skip-git-repo-check \
-o /tmp/last.md "总结这个目录" ; echo "exit=$?"
# {"type":"thread.started",...}
# {"type":"item.completed","item":{"type":"agent_message",...}}
# {"type":"turn.completed","usage":{...}}
# Codex:续跑最近一次 headless 会话
codex exec resume --last "继续,把结论写成表格"
# Codex:管道输入——stdin 与 prompt 并存时 stdin 以 <stdin> 块附加(cli.rs:81-86)
git diff origin/main | codex exec --json "评审这个 diff"Harness 接入建议(Yoda 实践)
- Yoda 的任务模型若要加「无人值守 run」(定时任务/批处理),CC 侧统一用
--bare -p --output-format stream-json模板:bare 隔离用户机器上的 hooks/MCP 差异,正是 Yoda 多机一致性需要的;同时监听system/init的plugin_errors在 run 开始即 fail-fast。 - Codex 侧用
codex exec --json+-o,并把CODEX_SANDBOX_MODE/CODEX_APPROVAL_POLICY(Yoda 已有这两个 optional env,yoda/AGENTS.md)映射到--sandbox与 config override,避免 headless run 卡在审批上。 - 退出码契约不同:CC 在 max-turns/stdin 超限等多种情况非零退出,Codex 只有 turn 失败/中断一种
exit(1)——Yoda 的 run 状态机不要只看退出码,应同时消费turn.failed/system/api_retry事件。 - 产物回传统一抽象成「最终消息 + 结构化 JSON」两个槽位:CC 填
.result/.structured_output,Codex 填-o文件 /--output-schema响应,与openai/codex-action的final-message同构。
失效条件
-
--bare成为-p默认后(官方已预告),「-p默认加载本机配置」的描述过期 - 2026-06-15 起
claude -p计入独立 Agent SDK 额度(headless.md:10),CI 成本结论需按新计费复核 -
--experimental-json转正 /ThreadEvent增删字段(exec_events.rs)需回归解析器 -
openai/codex-action输入面(safety-strategy等)随版本变化;本章引用的是 v1.7 pinned commit - Codex 若新增 max-turns 类限制 flag,差异矩阵需更新
参考资料
- CC:
claude-code-docs/docs/headless.md、cli-reference.md、github-actions.md、gitlab-ci-cd.md - Codex 源码:
codex-rs/exec/src/cli.rs、exec/src/exec_events.rs、exec/src/lib.rs:925-1030、login/src/auth/manager.rs:516-533、.github/workflows/issue-deduplicator.yml(均 @ b89ce9a) - Codex 文档存根:
codex/docs/exec.md→ https://developers.openai.com/codex/noninteractive - 交叉章节:
chapters/workflow/sdk.md(SDK 即这些 flag 的程序化包装)、chapters/workflow/code-review.md(CI 内评审)
PR Review / 代码评审
CC 的评审是三层产品(本地 /review、云端 ultrareview 多 agent 舰队、托管 GitHub Code Review 服务);Codex 是一条 review 任务管线贯穿 TUI /review、codex exec review 与 app-server review/start,外加给审批用的 guardian 自动评审。
IDE / ACP 集成
CC 用「lockfile 发现 + IDE 充当 MCP server」把 CLI 接进编辑器,扩展自带 GUI 面板;Codex 用 app-server JSON-RPC 给官方 VS Code 扩展供电。两家在本快照中都未实现 ACP。