把回复变成脚本能解析的 JSON:`codex exec --output-schema` 实战
把 Codex(OpenAI Codex)塞进脚本里,第一个卡住人的从来不是”它会不会干活”,而是”它干完之后我怎么读懂结果”。交互式终端里人眼一扫就明白的一段话,换成 shell 脚本或 CI 步骤去消费,就变成了拿正则抠段落、按换行切分、赌它这次的措辞和上次一样。跑十次能对八次,剩下两次半夜报错。
codex exec 有个选项专门治这个:--output-schema <FILE>。本机在 codex-cli 0.147.0(Windows 11)上执行 codex exec --help,这一项的官方说明是「一个 JSON Schema 文件路径,描述模型最终回复的结构」。也就是说,你先把想要的结构写成一份 JSON Schema 文件,再把文件路径交给它。
先把话说在前面:本文里的命令行选项与说明文字来自本机在 codex-cli 0.147.0(Windows 11)上跑 --help 得到的原文,配置文件键位与默认值来自官方 Configuration Reference 页面,我们没有发起过任何模型对话请求,所以下文不会出现”我跑了一次,它返回了什么什么字段”这种描述。命令怎么拼、验收看哪里,我讲清楚;真实产出长什么样,得你自己跑第一次的时候 dump 出来看。
一、schema 文件先写好
--output-schema 要的是文件路径,不是内联字符串,所以第一步是落一个文件。放哪儿无所谓,我习惯集中放在一个目录里,命令行上写绝对路径:
{
"type": "object",
"properties": {
"summary": { "type": "string" },
"risk_level": { "type": "string", "enum": ["low", "medium", "high"] },
"files": { "type": "array", "items": { "type": "string" } }
},
"required": ["summary", "risk_level", "files"],
"additionalProperties": false
}
说明两点,免得误会:
第一,summary / risk_level / files 这些是我按自己的业务需要起的字段名,跟 Codex 没有任何关系。你要什么字段就写什么字段,下游脚本按这套字段名读就行。
第二,--help 里对这个文件的描述只有”一个 JSON Schema 文件路径”这一句,没有说明它支持 JSON Schema 的哪些关键字、哪个 draft、对 additionalProperties 或 required 有没有额外要求。这些约束以官方文档为准,我这里不替它下结论。实践上的建议是:先从最朴素的一层对象 + 字符串/枚举/数组开始,跑通了再往里加嵌套和条件关键字,别一上来就写一份三层嵌套 + oneOf 的复杂 schema,出问题你都不知道是 schema 不被支持还是别的地方错了。
二、完整命令,逐项解释
Git Bash / macOS / Linux 侧:
codex exec \
--output-schema ~/codex-schemas/review-report.json \
-o ./codex-out/last-message.json \
--json \
-s read-only \
-a never \
--skip-git-repo-check \
--color never \
"审阅当前目录的构建脚本,按 schema 要求输出结果"
Windows PowerShell 侧,续行符和路径写法都不一样,别照抄上面那段:
codex exec `
--output-schema "$HOME\codex-schemas\review-report.json" `
-o ".\codex-out\last-message.json" `
--json `
-s read-only `
-a never `
--skip-git-repo-check `
--color never `
"审阅当前目录的构建脚本,按 schema 要求输出结果"
每个选项为什么在这儿:
--output-schema:主角,指向上一节那份文件。路径建议一律写绝对路径。命令行上还有个-C, --cd <DIR>能改 agent 的工作根目录,两个东西一起用的时候相对路径最容易让人算不清是相对谁,索性不给自己留这个坑。-o, --output-last-message <FILE>:--help原文是「把 agent 的最后一条消息写到文件」。这是你脚本真正要读的那个文件——最终回复直接落盘,不用从终端输出里切。--json:--help原文是「事件以 JSONL 打到 stdout」。它和-o不冲突,管的是两件事:-o给你结果,--json给你过程。-s read-only:沙箱模式,三个取值是read-only/workspace-write/danger-full-access。只让它读和总结,就选最紧的那档。-a never:审批策略,--help里对never的释义是「从不询问,执行失败直接回传给模型」。注意never不等于放开权限,它只是不再弹审批问你,能不能干仍然由沙箱决定。非交互场景不设它,一遇到需要审批的动作就没人应答了。--skip-git-repo-check:允许在非 Git 仓库里运行。分析临时目录、日志目录时必备,在正经仓库里可以不加。--color never:取值always/never/auto,默认auto。在 CI 日志里关掉颜色,省得 ANSI 转义码混进你抓取的文本。
还有几个按需的:--ephemeral 不把会话文件落盘;--ignore-user-config 不加载 $CODEX_HOME/config.toml(注意 --help 特别说明了 auth 仍然使用 CODEX_HOME,它只隔离配置不隔离登录态);--ignore-rules 不加载用户或项目的 execpolicy .rules 文件——这个别随手加,它绕开的是你自己定的执行策略。
输入从管道来的写法
codex exec 的位置参数 [PROMPT] 有两种进 stdin 的方式,--help 写得很清楚:不给参数或给 - 时从 stdin 读;stdin 是管道且同时给了 prompt,则 stdin 会作为 <stdin> 块追加。后一条特别顺手——指令写在参数里保持稳定,待处理的内容从管道喂:
cat build.log | codex exec \
--output-schema ~/codex-schemas/log-triage.json \
-o ./codex-out/triage.json \
-s read-only -a never --skip-git-repo-check \
"把 stdin 里的构建日志归类,按 schema 输出"
固定住一批设置:用 profile
命令行选项堆到八九个就该往配置里收了。-p, --profile <CONFIG_PROFILE_V2> 会把 $CODEX_HOME/<name>.config.toml 叠加到基础用户配置之上。建一个 ~/.codex/ci.config.toml:
sandbox_mode = "read-only"
approval_policy = "never"
model_reasoning_effort = "low"
hide_agent_reasoning = true
然后命令缩成 codex exec -p ci --output-schema ... -o ... "..."。其中 hide_agent_reasoning 官方说明是「在 TUI 与 codex exec 输出里抑制推理内容」,跑批量任务时日志会干净不少。以上为按官方文档键位组合的示例,未逐项实测,以官方文档为准。
三、产出物落在哪、怎么接下一步
只讲有依据的部分,两个出口:
出口一是 -o 指定的文件,里面是 agent 的最后一条消息。这是你 json.load() 的对象,也是加 --output-schema 的意义所在——让这条消息本身就是结构化的,而不是一段需要人读的话。
出口二是 stdout 上的 JSONL 事件流(--json)。JSONL 的意思是一行一个 JSON 对象,脚本按行读、逐行解析即可。至于每种事件有哪些字段、事件类型叫什么名字,--help 没给清单,我们也没跑过真实对话,所以本文不列任何字段名。你第一次接的时候老老实实 codex exec --json ... > events.jsonl,把文件拿到手翻一遍再写解析代码,比照着任何一篇文章里的字段名硬猜都靠谱。
接下一步的分工建议很朴素:结果判定读 -o 的文件,流程监控和排障读 JSONL。别把两者混在一个解析器里。
四、怎么验收:五个必看点
1. schema 文件本身是不是合法 JSON。 一个手写的 JSON 少个逗号是常事,先自己校一遍再交给 Codex:
python -c "import json;json.load(open('review-report.json',encoding='utf-8'));print('ok')"
2. 配置到底加载成功没有。 这是我们本机实测里最有价值的一条:在 codex-cli 0.147.0(Windows 11)上故意传一段语法不合法的 TOML(codex -c 'features=[unclosed' doctor --summary),命令没有崩溃退出,doctor 照常跑完,但输出里出现了这么一行:
✗ config config could not be loaded - Fix the reported config error, then rerun codex doctor.
也就是说配置坏掉时它不一定会拦你,而是安静地不加载。所以”我明明配了 profile / 配了 sandbox_mode,怎么好像没生效”这类问题,第一步就该跑 codex doctor --summary 看 Configuration 组里 config 这一行是不是 ok。
3. -c 的取值有没有被当成字符串。 --help 原文:-c 的 value 按 TOML 解析,解析失败则按字面字符串处理。这个设计很容易埋雷——你以为传了个布尔值,实际进去的是字符串,而且不报错。所以布尔和数组类的覆盖尽量写进 profile 文件,别在命令行上拼。
4. 别指望 --strict-config 兜住拼写错误。 它的作用是”config.toml 里出现本版本不认识的字段时直接报错退出”,但本机在 codex-cli 0.147.0(Windows 11)上执行 codex -c model_reasoning_effortt=high --strict-config exec --help(注意 effortt 多打了一个 t),结果是正常打印 help,没有报未知字段错误。说明这层校验发生在真正加载配置去跑会话的时候,--help 这类不进入会话的路径不触发。拿 --help 去”验证配置写对了”是白验。
5. 沙箱取值拼错会立刻挡下。 这一条反而让人安心,本机在 codex-cli 0.147.0(Windows 11)上执行 codex -s bogus-mode,报错是:
error: invalid value 'bogus-mode' for '--sandbox <SANDBOX_MODE>'
[possible values: read-only, workspace-write, danger-full-access]
For more information, try '--help'.
枚举类选项属于”错了当场炸”的一类,跟上面第 3、4 点的静默失败正好相反。心里有这个分界,排查时就知道该先怀疑谁。
最后还有一步纯业务的验收:结构合法不等于内容正确。schema 约束的是形状,risk_level 落在枚举里不代表这个判断是对的。脚本侧该有的业务校验一个都不能少,别把 schema 当成正确性的保证。
五、什么情况别这么干
要它真的改文件的时候。 -s read-only 下它动不了工作区;换成 workspace-write 之后,JSON 只是它自己的一份”工作自述”,改了什么必须回到 git status / git diff 上验,不能拿 JSON 里的字段当已落盘的证据。顺带一提,CLI 有个 apply(别名 a)子命令,--help 说明是「把 Codex agent 产生的最新 diff 以 git apply 应用到本地工作树」——改动的落地和结果的汇报是两条线,别混。
需要人中途拍板的活儿。 -a never 意味着不再问你,失败直接回传给模型自己处理。涉及删除、发布、改配置这类动作,老老实实用交互模式,或者用 untrusted(只有受信任命令免审批)这类更紧的策略。
只想看过程的时候。 --output-schema 管的是最终那一条回复。想知道中间发生了什么,是 --json 事件流的活儿,加 schema 没用。
要复盘的时候别加 --ephemeral。 它不把会话文件落盘,那 resume 也就无从谈起。CI 里为了干净加上它可以理解,但排查问题的那几次跑,留着。
任务依赖实时联网信息的时候要额外确认。 官方 Configuration Reference 里,配置项 web_search 默认值是 cached——既不是关闭也不是实时;CLI 的 --search 才是开实时联网搜索,而且 --help 明确写了启用后原生 web_search 工具对模型可用、无逐次调用审批。放进无人值守的流水线之前,这个权衡自己想清楚。
相关阅读
- 在 CI 里跑
codex exec:非仓库、免配置与超时这三件事 - 给 Codex CLI 装上 shell 补全:一份不靠猜的落地清单
- 用
codex exec把任务写成可重复执行的命令 - Codex 的六个使用面:一张图看懂该用哪个
本文依据 Codex 官方文档(learn.chatgpt.com/docs/ 的《Non-interactive mode》《Codex CLI》《Configuration Reference》页面)整理,核对日 2026-08-09;文中标注「本机实测」的部分基于 codex-cli 0.147.0 / Windows 11 环境下的只读命令输出。产品功能、模型与价格以官方最新说明为准。