# Codex CLI 图像生成 — Stage1 换装图的产图通道 跟 `H3-CONSOLE.md` 同一角色:一份外部生成服务的接入契约。H3 Console 只 产 mp4 不产图(`H3-CONSOLE.md`),Stage1 的"人物 + 衣服 → 换装图"要另找 通道,这里记录本机 Codex CLI 这条路的实测结果和接入方式。 **核对时间**:2026-09-01,`codex-cli 0.152.0`(`/opt/homebrew/bin/codex`), 已登录 ChatGPT 账号。标注"实测"的都是在这台机器上真跑过的;标注"未实测" 的是读文档得来的,别当既成事实。 --- ## 1. 先澄清三个名词 | 说法 | 实际情况 | |---|---| | "codex acp 接口" | **本机没有 `codex acp` 子命令**(实测:`codex acp --help` 直接落回交互式 CLI 的帮助)。ACP(Agent Client Protocol)是 Zed 那边的编辑器↔Agent 协议,Codex 侧由**第三方适配器** `codex-acp` 提供,不是官方 CLI 的一部分。而且 ACP 是给"交互式会话"用的,我们要的是批量出图,用不上它 | | "image2 文生图模型" | 是 **`gpt-image-2`**,OpenAI 2026-04-21 发布,已是 Codex CLI 的默认图像模型(取代 `gpt-image-1.5`)。**它不只文生图,也支持图片编辑**(多张输入图),这对我们更重要 | | "codex 的接口" | 官方对外接口是 `codex app-server`(stdio / unix socket / ws)、`codex mcp-server`(stdio MCP)、`codex exec`(一次性非交互)。**批量出图用 `codex exec` 最省事**,理由见第 4 节 | ⚠️ **协议层不等于能力层**:app-server / mcp-server 只是通信代理,它们暴露 的是"Codex Agent 的能力",不是一个固定的 `generate_image(prompt)` 方法。 能不能出图,取决于那个 Codex 运行环境装没装、启用没启用图像工具。 ## 2. 本机能力核对(实测) ``` $ codex features list | grep -i image image_generation stable true ← 已启用 view_image stable true ← 读本地图进上下文,编辑流程要用 ``` 内置技能在 `~/.codex/skills/.system/imagegen/`(`SKILL.md` + `references/` + `scripts/image_gen.py`)。 **一次真实出图(实测通过)**: ```bash codex exec --skip-git-repo-check -s workspace-write -o last.txt \ "Generate an image: a plain red rubber ball on a white studio floor. Then print the absolute path of the generated image file." ``` - 产物:`~/.codex/generated_images//exec-.png` - 实际尺寸 **1254×1254**,1.2 MB。当时我在 prompt 里只顺口写了"square 1024x1024",没给到。但后续换装实测里**把 `Size 1024x1536` 作为独立一行 明确写进 prompt,三张图全部精确命中** —— 所以尺寸不是控不住,是**要在 prompt 里明确要求** - `-o last.txt` 里拿到了绝对路径,**这是脚本取回文件的可靠方式** - 消耗 **29,914 tokens**(走 ChatGPT 订阅额度,不是 API 计费) **换装编辑(S3 spike,2026-09-01 实测通过)**:合成一组测试素材(1 张人物 全身图 + 2 张衣服平铺图),跑两次多图编辑换装,**两次都成功**: | 项 | 结果 | |---|---| | 人脸/发型/体型 | **完全保持**,看不出改动 | | 姿势/机位/背景/光线 | **完全保持** | | 服装还原度 | 高——旗袍的红缎、金边、盘扣、侧开衩,校服的水手领白条、红领巾、百褶裙,都准确转移 | | 尺寸 | 两次都精确给到要求的 **1024×1536** | | 耗时 | 约 **73 秒**/张 | | 消耗 | **23,253 / 23,268 tokens**/张 | | 一次 exec 生成 3 张图 | 38,894 tokens —— **批量塞进一次 exec 比一张一次省得多** | 素材和产物在 spike 目录,结论:**路径 A 的换装质量达标**。 ## 3. 两种模式(`SKILL.md` 原文,非推测) 技能明确只有两个顶层模式: ### 3.1 内置 `image_gen` 工具(默认) - **不需要 `OPENAI_API_KEY`**,走已登录的 ChatGPT 账号额度 - 支持生成 + 编辑 + 透明背景 - **编辑语义**:只能编辑"已经在对话上下文里可见"的图(附件或本轮先前生成 的图)。要编辑本地文件,**先用内置 `view_image` 工具把它读进上下文**, 再走编辑流程。`SKILL.md` 原话:不要承诺内置工具能按任意文件路径编辑 - **落盘位置固定在 `$CODEX_HOME/generated_images/...`**,内置工具**没有 目标路径参数**;要放到别处只能"先生成、再 move/copy" ### 3.2 CLI 回退模式 `scripts/image_gen.py` - **需要 `OPENAI_API_KEY`**(= 按张计费,跟订阅额度是两条账) - 三个子命令:`generate` / `edit` / `generate-batch` - 有内置模式没有的东西:**确定的输出路径**、`--quality`、`--mask`、 `--size` 精确控制、`--concurrency` 并发、`--dry-run` - `SKILL.md` 明确:**不要为了普通的质量/尺寸/路径控制就切到 CLI**;也 **不要修改 `scripts/image_gen.py`** ## 4. 我们的 Stage1 该怎么接 ### 4.1 换装 = `edit`,不是 `generate` 关键契约(`references/cli.md` / `image-api.md`): - 编辑端点 `POST /v1/images/edits`,**输入图最多 16 张** - **`--image` 可重复传,顺序有意义**,要在 prompt 里按 index 说明每张的 角色 —— 这正好是换装:`--image 人物.png --image 衣服.png` + prompt "把第 2 张的服装穿到第 1 张的人物身上,保持面部/发型/体型不变" - **`gpt-image-2` 对图片输入恒为 high fidelity**,不支持也不需要设 `input_fidelity` —— 对"换装但人脸不变"是好消息,它默认就是最高保真档 - 编辑 prompt 要**每轮重复不变量**("change only the outfit; keep the face, hairstyle and body unchanged")以减少漂移,这是官方 prompt 指导 - **实测发现的一个不一致**:换旗袍时它保留了人物原来的黑皮鞋;换校服时它 自作主张把鞋换成了乐福鞋并加了过膝袜。"outfit"的边界它自己在拿捏。 **prompt 里要显式规定鞋子怎么处理**(保留原鞋 / 一并替换 / 不入镜), 否则同一批产出的脚部会不统一 ### 4.2 尺寸:**480×832 是非法输入** `gpt-image-2` 的尺寸硬约束:边 ≤3840、**两边都是 16 的倍数**、长短边比 ≤3:1、**总像素 655,360 – 8,294,400**。 我们视频的 480×832 总像素只有 399,360,**低于下限,传进去会被拒**。 但这不是问题:**Stage1 的参考图不需要等于视频分辨率**。H3 出片的尺寸由 它自己的 `width`/`height` 参数决定(`H3-CONSOLE.md`),参考图给高一点反而 更清楚。竖屏候选(都已按上面四条约束验算过): | 尺寸 | 总像素 | 比例 | 合法 | |---|---|---|---| | `1024x1536` | 1,572,864 | 2:3 | ✅ 推荐 | | `832x1472` | 1,224,704 | ≈1.77:1,接近 9:16 | ✅ 更贴近视频构图 | | `480x832` | 399,360 | 9:16 | ❌ 像素数不足 | ### 4.3 批量:`edit` 没有 batch 子命令 `generate-batch` 只对 `generate` 有效(JSONL + `--concurrency`,默认 5)。 **我们的换装是 `edit`,所以批量得自己循环调用**——冷启动脚本要自己做 并发控制和失败重试,不能指望 `generate-batch`。 ### 4.4 内置模式 vs CLI 模式,怎么选 | | 内置 `image_gen`(走 `codex exec`) | CLI `image_gen.py` | |---|---|---| | 凭证 | 已登录的 ChatGPT 账号 | `OPENAI_API_KEY` | | 成本 | 订阅额度(实测一张 ≈3 万 token) | **按张计费** | | 输出路径 | 固定 `$CODEX_HOME/...`,要自己 move | `--out` 精确指定 | | 尺寸控制 | prompt 里明确写就能命中(实测 3/3 精确到 1024×1536);写得含糊会漂 | `--size` 精确 | | 并发 | 无(一次一个 exec 进程) | `--concurrency` | | 确定性 | 低(Agent 中转,可能自作主张) | 高(直接打 API) | **建议**:冷启动批量走**内置模式 + `codex exec`**,因为这个项目的整个前提 就是"冷启动内容零按次成本"(需求文档 4.3 节),订阅额度正好对上;确定性 差一点可以靠脚本兜(见 5.2 的取回约定)。真要上生产的实时付费路径,再 评估 CLI/API 模式或别的通道。 ## 5. 接入方式(建议写进冷启动脚本) ### 5.1 调用形态 ```bash codex exec --skip-git-repo-check -s workspace-write \ -o "$TMP/last.txt" \ "$PROMPT" \ -i "$CHARACTER_IMG" -i "$GARMENT_IMG" ``` **注意 prompt 在 `-i` 之前**,原因见下面的踩坑。 - `-i/--image` 可重复,把两张参考图直接附进初始 prompt(省掉手动 `view_image` 那一步) - `-o/--output-last-message` 把最后一条消息写进文件 —— **让 prompt 结尾 强制要求"只输出生成图的绝对路径"**,脚本读这个文件取回路径 - `--json` 也可以,输出 JSONL 事件流,要更结构化的进度时用 **⚠️ 踩坑(实测):`-i/--image` 是变长参数(`...`)** - `codex exec -i a.png -i b.png "PROMPT"` → **prompt 被当成第三个图片文件 吞掉**,进程转而从 stdin 读 prompt,报 `No prompt provided via stdin` - `codex exec "PROMPT" -i a.png b.png` → 两个文件挂在同一个 `-i` 上, 实测**挂死 10 分钟、零输出、不产图** - ✅ 正确写法:**prompt 放最前面,每个文件单独一个 `-i`** ``` codex exec [其他 flag] "$PROMPT" -i person.png -i garment.png ``` ### 5.2 取回约定(内置模式没有目标路径参数,必须自己搬) 1. prompt 末尾固定加一句:`Then print ONLY the absolute path of the generated image file, nothing else.` 2. 读 `-o` 指定的文件拿到路径 3. **校验**:文件存在、是 PNG、尺寸等于 prompt 里要求的值。尺寸只要在 prompt 里明确写就能命中(实测 3/3),但它不是硬参数,**校验不能省** 4. `copy` 到我们自己的 `uploads/composed/{uuid}.png`,**不要让产物只留在 `$CODEX_HOME`**(`SKILL.md` 明确要求项目引用的资产不能只躺在那) ### 5.3 沙箱 `codex exec` 默认带沙箱。`-s workspace-write` 实测够用。图片落在 `$CODEX_HOME` 而不是工作区,所以脚本要有读 `~/.codex/` 的权限。 ## 6. 还没验证的(正式接入前必须跑) 1. ~~**换装质量本身**~~ —— **已实测通过**(见第 2 节表格)。但用的是 gpt-image-2 自己生成的合成素材;**换成真实拍摄的人物照/衣服图后要再抽 查一遍**,真实照片的光线、背景杂乱度、衣服褶皱都比合成图难。 2. **并发**:多个 `codex exec` 同时跑会不会撞订阅限流,没测过。 3. **失败形态**:额度耗尽、内容被拒、超时各自返回什么,脚本要能区分 "重试有用"和"重试没用"。 4. **额度消耗**:单张约 3 万 token 是一次样本。冷启动要跑几十上百张, 实际配额够不够要先小批量试。 ## 7. 两个合规提醒(不是技术问题,但会让流水线在运行时断掉) - **订阅额度的用途**:内置模式跑在个人 ChatGPT 订阅上。把它当成一个对外 商业产品(付费直播间)的生产后端,是否符合 OpenAI 的订阅条款,值得先 确认一下。按张计费的 `OPENAI_API_KEY` 路径在这点上是干净的,代价是成本。 - **内容策略**:`gpt-image-2` 带内容审核(API 有 `moderation` 参数)。 冷启动阶段用我们自己的素材/合成人物没问题;但需求文档模式三是 **观众上传真人照片做换装**,这类请求大概率会被 OpenAI 侧拦下来。也就是 说 **这条通道适合第一期冷启动,不一定能承载第五期的付费传人物**——那时 候可能还是得回到自己的 GPU(ComfyUI)或别的供应商。这一点要早点想清楚, 别在第五期才发现通道不通。 ## 8. 相关文档 - `H3-CONSOLE.md` — Stage2 视频生成(内部 2080Ti 集群) - `docs/todo/dressup-dance-room.md` 8.1 — Stage1 的路径选择 - `docs/todo/dev-plan.md` S1/S3 — S3 已完成,S1/S2/S4 待跑 - `~/.codex/skills/.system/imagegen/SKILL.md` — 本机技能原文(本文引用的 契约都来自它和 `references/cli.md`、`references/image-api.md`)