Part Two · 核心操作
04
The Art of Editing · 改图的艺术

改图的艺术

从零画一张图,是把空白填满;改一张图,是在保留中改变。这一章讲内置 edit 的脾气:它只看得见对话里的图,它最怕你忘了说"哪些不许动",它默认另存新版、绝不覆盖。把这三件事吃透,你的每一次改图都能稳稳落地。

编辑和生成用的是同一支画笔,心法却相反。生成时你在乎"画出了什么";编辑时你更要在乎"没被画坏什么"。一次好的改图,衡量标准从来不是改动多大,而是该变的变了,该留的一丝没动

生成还是编辑:先划清那条界线

每个请求落地前,技能要你先判一次意图(intent)。这条界线很朴素,却决定了走哪条路:

判为"编辑"

用户想在保留某些部分的前提下,改一张已有的图。比如"把这张产品图的背景换成大理石"——产品本身要原封不动。这才是 edit

判为"生成"

用户只把图当成风格 / 构图 / 氛围的参考,或者干脆没给图。"照这张的色调,画一只新的猫"——主体是全新的,那是 generate(带参考图)。

关键判断 · 默认偏向"新图"

拿不准时,默认假定要新图,除非用户明显是在改一张已存在的图。一个可靠的口诀:问自己"原图上的像素,有没有要被尽量保留的?"——有,就是编辑;没有,就是生成。

内置 edit 只看得见"对话里的图"

这是内置编辑最容易踩空的一条语义,务必记牢:内置 edit 只对当前对话上下文里"可见"的图生效。所谓可见,只有两种来源——

那么,要改一张只躺在本地磁盘上、还没进对话的文件呢?不能直接喊它的路径让内置工具去改。正确顺序是:先用内置 view_image 把它载入对话上下文,让它"被看见",然后才能走内置 edit

要改一张本地文件 → 必经两步 本地文件 ~/hero.png 不在对话里 · 看不见 view_image 对话上下文 图已"被看见" CONTEXT · VISIBLE edit 改后成品 非破坏 · 另存新版 hero-edited.png 省掉中间一步,内置工具就"无图可改"——它不会去敲你的文件系统路径。
本地文件 → view_image 载入 → 内置 edit。一旦图进了对话,编辑才有了对象。
红线 · 内置不承诺"任意路径编辑"

不要向用户承诺"内置工具能改任意文件系统路径上的图"。内置 edit 没有这个能力——它只动对话里看得见的图。如果你需要的是直接对一个磁盘路径做改动、用蒙版、或动用某个仅 CLI 才有的参数,那是 CLI 回退的活儿,且必须用户明确要求才走(见本章第五节)。

不变量:只改 X,保持 Y

编辑的灵魂,是不变量(invariants)——那些你声明"无论如何都不能变"的东西。模型很乐意帮你重画,但你不点名要保的,它就可能顺手"优化"掉。所以编辑提示词的结构永远是一句话:只改 X,保持 Y 原样。

更要紧的是:不变量要每一轮迭代都重复一遍。编辑往往不是一次到位,而是连改几轮。如果第二轮你只说"再亮一点",却没重申"产品边缘和文字不许动",模型很可能在调亮的同时悄悄改了它们。

关键判断 · 每轮都把不变量再说一遍

把不变量当成每一轮编辑的"安全带",而不是开场白。每次只改一处,并在每条修改指令里原样附上完整的"保持清单",改完再复检。少说一句不变量,就多一处可能被改坏的地方。

下面用一个最常见的场景——只换背景、保持产品本身——把它写成一张可照抄的配方卡和提示词卡。

RECIPE

只换背景 · 产品边缘与外观不动

Use case
background-extraction(换 / 重置背景)
Asset type
产品图编辑
Input images
编辑目标 · 一张产品照(先 view_image 载入对话)
Primary request
把背景换成浅米色大理石台面,柔和自然光
Invariants(保持)
产品的形状 / 边缘轮廓 / 颜色 / 材质 / 标签文字、产品在画面中的位置与大小、整体透视
Constraints
只动背景;不重画产品;不加水印 / 文字 / 倒影
Avoid
产品变形、边缘被裁、颜色偏移、出现新物体
提示词 · 只换背景的编辑指令内置 image_gen · edit
把这张图的背景换成 浅米色大理石台面,柔和自然光从左上方打来只修改背景:完整保持产品本身不变——它的边缘轮廓、颜色、材质、瓶身上的标签文字,以及它在画面里的位置、大小和透视,全部保持原样,不要重画产品。不要添加倒影、不要新增任何物体、不要水印或文字。
edit不变量已声明
提示:"标签文字"这类关键不变量,最好逐字引用原文,并明确"保持原样、不要重新渲染"。否则模型容易把文字当成可以"重画"的图形,改出别字。

非破坏式保存:默认另存新版

编辑的第三条铁律,关乎的不是画面,而是文件默认非破坏式保存——另存一个新版本,绝不就地覆盖原图。

原因很实在:改图是迭代出来的,你随时可能想退回上一版,或拿几版做对比。一旦覆盖,原始素材就没了。所以收尾时不要写回原文件名,而是用版本化的兄弟文件名

唯一的例外:用户明确说"替换"

只有当用户明确要求替换、覆盖原图时,才就地写回。否则一律另存新版。同样地,编辑产物如果是"项目要用的资产",记得收尾前把它移动 / 复制进工作区,别只留在默认的 $CODEX_HOME/generated_images 路径里——那等于没交付。

什么时候必须上 CLI

内置 edit 覆盖了绝大多数改图需求。但有三类情况,它的语义触及不到,必须考虑 CLI 回退 scripts/image_gen.pyedit 子命令:

红线 · 用户要求,才走 CLI

即便撞上以上情况,也不要静默切换。CLI 回退要 OPENAI_API_KEY、要联网、可能改变成图风格——这是一次需要解释和确认的事。先告诉用户存在这条路径及其代价,得到明确同意后再走;内置工具失败或不可用时同理,先告知有此回退、需 Key,用户点头才上。另外:绝不修改 scripts/image_gen.py,缺什么先问。

terminal · 仅当用户点名 CLI 时
# 前提:环境里已配好 OPENAI_API_KEY(别贴进聊天) # 用户明确要"用蒙版、精确改这一块"——这才是 CLI 的活 $ codex exec "用 CLI 回退,按 mask 只重绘背景,产品不动" # 智能体随后调用 scripts/image_gen.py edit,带 --image / --mask / --out 等参数 $ python scripts/image_gen.py edit --image hero.png --mask bg-mask.png --out output/imagegen/hero-edited.png
提示:把这一节当成"最底层那个抽屉"。需要它时它很强,但内置能做到的事,就别为了路径或画质这点便利而打开它——尤其绝不为普通画质 / 尺寸 / 路径控制就把内置默默降级到 CLI。透明背景的取舍是另一个常见的"何时上 CLI"判断,留到后续章节细讲。

八个编辑类用例 · 速查表

技能把编辑场景归成八个用例 slug。判完意图是"编辑"后,再对照这张表选一个最贴近的 slug——它会帮你把不变量和提示词的重点理清楚。

编辑 slug一句话用途
text-localization替换 / 本地化图中文字(如把英文标语换成中文),保持版式与字体气质。
identity-preserve改动场景或姿态,但人物 / 角色的身份特征严格不变。
precise-object-edit精确增删 / 修改某个物体,画面其余部分原样保留。
lighting-weather只改光线、时段或天气氛围,主体与构图不动。
background-extraction抠出 / 替换 / 重置背景,主体边缘干净保留。
style-transfer把一种画风 / 介质迁移到已有图上,内容结构不变。
compositing把多张输入图合成进同一画面,处理好透视与光照衔接。
sketch-to-render把线稿 / 草图渲染成成品,忠实于原始构图与轮廓。

这八个 slug 不是标签游戏,而是一份"该保什么"的提醒清单。选定 slug,你就知道这一类编辑里哪些是天然的不变量——把它们写进每一轮提示词,改图就稳了。

本章 TL;DR

改图先判意图:要在保留前提下改已有图才是编辑,否则按生成处理。内置 edit 只对对话里可见的图生效——改本地文件要先 view_image 载入再 edit,它不承诺任意路径编辑。编辑的灵魂是不变量:"只改 X、保持 Y",且每一轮都要重复。保存默认非破坏式、另存新版(如 hero-v2.png),项目资产记得落地进工作区。只有需要路径控制 / 蒙版 / CLI-only 参数、且用户明确要求时,才走需 OPENAI_API_KEY 的 CLI 回退,绝不静默降级。