In one sentence: this SKILL drives gpt-image-cli, generating or editing images with the OpenAI gpt-image-2.5 series
(gpt-image-2.5-flare by default,gpt-image-2.5-sunburst for refinement).
Core principles: always go through the gpt-image-cli entry point (do not hand-assemble curl); default to flare, switch to
sunburst according to the rules below and explain the reason in the report; after every image generation you must Read the PNG just written in this round before reporting;
the exploration stage relies on a complete, self-consistent prompt, while the refinement stage relies on edit chained incremental edits.
Prerequisites
- Confirm that
gpt-image-cliis executable (which gpt-image-cliorgpt-image-cli --version, version ≥ 1.3.0 is required for--model). If not executable, prompt the user tonpm install -g @zhoujinandrew/gpt-image-cliornpm link。 - in the repository. Configure the API key: prefer the env
OPENAI_API_KEY; if missing, guide them togpt-image-cli config init(interactive, requires a TTY) orconfig set api_key <value>。 - Self-built/proxy endpoint:
gpt-image-cli config set endpoint https://<...>/v1or--endpoint <url>for a one-time override. For Azure or multi-endpoint scenarios, see the next section.
Multi-endpoint configuration (OpenAI / Azure)
Supports saving multiple endpoints at the same time (public OpenAI, self-built proxy, Azure deployment) and switching between them.
gpt-image-cli config list # 查看所有 profile,带 active 标记
gpt-image-cli config use <name> # 切换 active profile
gpt-image-cli config add <name> --type azure # 向导式新增 Azure profile
gpt-image-cli config add <name> --type openai # 向导式新增 OpenAI profile
gpt-image-cli --profile <name> generate ... # 单次覆盖,不改 active
gpt-image-cli config show [<name>] # 查看具体 profile(api_key 已脱敏)
Azure profile fields:endpoint(resource root URL, excluding the /openai/deployments/...
path),deployment、api_version、api_key、auth_style(api-key
by default, matching Microsoft documentation; or bearer corresponding to Authorization: Bearer <key>
-style gateways).
Azure profile conventions and limitations:
- The deployment name must be the same as the model ID(
gpt-image-2.5-flare/gpt-image-2.5-sunburst), so that--modelcan switch models directly on Azure. output_format=webpis not supported; usepngorjpeginstead (the CLI will error out directly before the request).- size / aspect ratio rules are the same as for OpenAI (see below).
Environment variables:OPENAI_API_KEY / OPENAI_BASE_URL can still serve as "zero-profile"
temporary credentials;GPT_IMAGE_PROFILE can temporarily switch to another profile without changing active;
priority --profile flag > GPT_IMAGE_PROFILE env > 文件 active。
Model selection
| Model | Positioning | Used for |
|---|---|---|
gpt-image-2.5-flare |
Fast, high image quality, default | One-shot image generation, exploring candidates, batch |
gpt-image-2.5-sunburst |
Flagship, strongest editing precision and multi-round consistency | Refinement stage, final draft |
Both have the same token unit price; sunburst is noticeably slower. Not passing --model means flare;
to use sunburst, add --model gpt-image-2.5-sunburst
before any command
(for OpenAI profiles change the model field; for Azure profiles change the deployment name).
Rules for switching to sunburst(switch if any is hit; switch automatically without asking the user, but include a one-line reason in the report):
editand the user requests strict preservation constraints such as "leave everything else unchanged, only change X".- Already in the refinement stage (the user has selected a baseline version from the exploration candidates).
- The user says this is the final draft / KV / hero shot / client delivery.
- The user explicitly names sunburst.
In all other cases, use flare.
Core commands
Text-to-image (generate)
- Basic:
gpt-image-cli generate -p "<prompt>" --out ./out.png - Control aspect ratio/quality:
-s 1920x1088 -q high - Batch + output directory:
-n 4 --out ./outdir/ - Specify model:
gpt-image-cli --model gpt-image-2.5-sunburst generate ... - Get base64 via a pipe:
... --stdout-base64 | base64 -d > out.png(the envelope goes to stderr)
Image-to-Image (edit)
- Single-image edit:
gpt-image-cli edit --image base.png -p "<指令>" --out new.png - Multi-image composition: multiple
--image, e.g.--image a.png --image b.png -p "把 a 里的物体放到 b 的场景中" - Local edit: also add
--mask mask.png(the white area of the mask is what gets changed) - Do not pass
--input-fidelity: the gpt-image-2.5 series does not support this parameter; passing it returns 400; 2.5'seditis itself high-fidelity, just use the prompt to state "what to keep"
Read the result
stdout is a JSON envelope by default:{ ok, data: { model, paths, size, usage, ... } },
data.model is the model actually used this time. Configure --jq '.data.paths[0]' to filter the result to the path
field — the output is still in envelope form:{"ok": true, "data": "/abs/path.png"}. In the shell, then | jq -r .data to get the bare string.
Explore → Select → Refine → Deliver
Trigger conditions: the user says "show me a draft first", "give me a few to pick from", "multi-round optimization", "generate → feedback → revise", or after the first version comes out, continues to describe revision opinions.When the user wants just one image in one sentence, do not enter the pipeline, directly flare a single image.
Artifact directory:./refine/<topic>/,<topic> comes from the user's short name for this task (if not given, make one in
kebab-case according to the task semantics, e.g. poster-hero); if the directory already has v1.png, switch to
./refine/<topic>-<YYYYMMDD-HHMM>/, to avoid overwriting history.
1. Explore (flare,generate)
- Default
-n 3 -q medium(-nupper limit is 4, don't produce a dozen at once and overwhelm the user's ability to choose),-sfixed throughout once selected - Artifact
v1a.png / v1b.png / v1c.png; one by oneRead, reporting one sentence of key visual elements per image - User asks to change direction entirely → rewrite the prompt and explore another round, still flare
2. Select
- User names one →
cp refine/<topic>/v1b.png refine/<topic>/v1.png, as the refinement baseline - From this step on, switch to sunburst, and when reporting state "entering the refinement stage, using sunburst from now on"
3. Refine (sunburst,edit)
- Each round
gpt-image-cli --model gpt-image-2.5-sunburst edit --image v(N-1).png -p "<两段模板>" --out vN.png - Chained accumulation: use the previous version as the base image, describe only this round's increment (template in the next section)
- After generation
Readthis round's vN, report "changed X / kept Y" - If drift is found (elements that should not move have changed) → roll back to an earlier clean version as the base image and redo this round
4. Deliver
- User finalizes →
cp refine/<topic>/vN.png refine/<topic>/final.png - When extreme detail is needed, use the same prompt plus
-q xhighto regenerate the final version;maxuse only when the user explicitly requests it final.pngcan be used directly as the first frame or reference image for a video model (such as seedance)
Prompts and discipline for multi-round optimization
The process is in the previous section; here is how to write the prompt for each round.
Exploration stage (generate) — four-part self-consistent template: each time it composes from scratch, so the prompt must be fully self-contained.
[主体与构图]:<主角是什么、怎么摆、视角方向>
[配色与风格]:<主色调、辅色、质感、艺术风格>
[关键细节]:<文字/LOGO/小物件等绝不能丢的元素>
[本轮修改]:<用户这次提的反馈,叠加不替换>
Expand into a natural-language prompt (without [...] tags), within 200 characters.
Refinement stage (edit) — two-part template: the model can see the base image, so do not restate all elements; restating instead induces it to redraw.
[保持不变]:<列出本轮绝不能动的元素,如"人物姿态、Logo、包装文字、灯光">
[本轮只改]:<一句增量指令,如"把背景换成黑色镜面台面">
Expand into two or three natural-language sentences.
Must do
- After each round's generation
Readthis round's just-written PNG (not an old image, not from memory) - Exploration prompt fully self-contained; refinement prompt clearly states "what to keep / only what to change"
-sstable across rounds; after entering refinement, the model is fixed to sunburst- In each round, explicitly tell the user "what was changed / what was kept"; when switching models, explain why
Must not do
- During the exploration phase, do not write "like before but brighter" / "keep it the same, only change X"; generate has no context
- During the refinement phase, do not stuff the entire exploration prompt verbatim into
edit, that amounts to making it redraw - Do not change
-sacross rounds, it will cause a big jump in composition - Do not pass
--input-fidelity - Do not finish generating without
Readand then give the user a summary
Red Flags — stop immediately when these signals appear
- I am about to write the next prompt from memory → Stop, first
Readthe image just generated - During the exploration phase, I am about to write "keep the previous but..." → Stop, rewrite the full prompt according to the four-part template
- During the refinement phase, I am about to restate the entire image → Stop, change it to a two-part "keep / only change"
- I am about to change
-sto a different value → Stop, first ask the user whether they want to change the composition - The user has already selected the baseline, and I am still using flare → Stop, switch to sunburst and explain
Limitations and fallbacks
Even with sunburst, slight drift may still occur after multiple chained rounds. Once you notice it, do not stubbornly keep stacking; roll back to the most recent clean version as the base image and redo this round. When multiple elements are required to remain pixel-identical, write them one by one into [保持不变], and if necessary pair with --mask to open only the area to be changed.
Size and aspect ratio (-s)
-s accepts auto or <width>x<height>, default auto。Do not memorize a few "allowed sizes", free combinations are fine, as long as the following 4 constraints are satisfied:
| Constraint | Value |
|---|---|
| Each side | 256–3840 px (supports 4K UHD) |
| Both sides must be | a multiple of 16 |
| Total pixels | 655,360 – 8,294,400(≈ 0.66MP – 8.3MP) |
| Long-to-short side ratio | between 1:3 and 3:1 |
Derivation formula for any aspect ratio: for desired ratio R:S, long side L, then W = L, H = L * S / R,
finally align each down to a multiple of 16. Example: 16:9 @ L=1920 → H = 1920 * 9/16 = 1080 → align to 16 → 1088。
Common size quick reference
| Ratio | Low resolution | Medium | High / 4K |
|---|---|---|---|
| 1:1 square | 1024x1024 | 2048x2048 | 2880x2880 |
| 3:2 landscape (native) | 1536x1024 | 2304x1536 | 3072x2048 |
| 2:3 portrait (native) | 1024x1536 | 1536x2304 | 2048x3072 |
| 16:9 slide/video | 1600x896 | 1920x1088 | 2560x1440 / 3840x2160 |
| 9:16 short video/Story | 896x1600 | 1088x1920 | 1440x2560 / 2160x3840 |
| 4:3 print | 1280x960 | 2048x1536 | 2880x2160 |
| 21:9 ultra-wide poster | 1680x720 | 2240x960 | 3360x1440 |
⚠️ Prompt and canvas consistency: the aspect ratio declared in the prompt
(e.g. "16:9 for slide", "portrait poster") must match -s , otherwise the model composes according to one ratio
while the canvas is another, and when the finished piece is placed on the final medium it will feel stretched. When unsure:
- Do not hardcode ratio numbers in the prompt, use semantic words instead ("landscape slide"/"vertical poster")
- Or use
-s autoLet the model choose the native size (1024x1024 / 1024x1536 / 1536x1024), and keep the prompt in generic semantics too
Parameter selection suggestions
-q Values:low / medium / high / xhigh / max / auto, the higher it is, the more output tokens and the slower it gets.
| Intent | Recommended parameters |
|---|---|
| Uncertain about size | -s auto + prompt only states semantics ("landscape"/"portrait") |
| PPT/screen sharing 16:9 | -s 1920x1088 or -s 2560x1440 |
| Mobile short video/Story 9:16 | -s 1088x1920 |
| Square social post | -s 1024x1024(preview) / -s 2048x2048(final) |
| 4K UHD maximum detail | -s 3840x2160(landscape) or -s 2160x3840(portrait) |
| Explore candidates | flare + -q low or medium + -n 3 |
| One-shot image generation | flare + -q high |
| Final delivery | sunburst + -q xhigh |
| Extreme detail (user explicitly requests) | sunburst + -q max |
| Transparent background (icons/stickers) | -b transparent -f png(or -f webp) |
| Strictly preserve + only modify local parts | sunburst edit, add if necessary --mask |
| No prompt but want to make a variant | edit --image src.png -p "a variation of this image" |
| JPEG compression control | -f jpeg --compression 80 |
Handling common errors
CONFIG_MISSING→ guide the user toconfig initorexport OPENAI_API_KEY=...OPENAI_API_ERRORstatus=429→ quota/rate limit, suggest lowering-qor reducing-n, or wait a bit and retryOPENAI_API_ERRORstatus=400invalid_input_fidelity_model→ remove--input-fidelity, 2.5 does not support itOPENAI_API_ERRORstatus=400Other → readerror.details.message, usually the prompt or size does not comply with policyOPENAI_API_ERRORstatus=404DeploymentNotFound→ that deployment does not exist on Azure, verify whether--modelvalue matches the deployment nameINVALID_INPUT quality must be one of→-qonly accepts low/medium/high/xhigh/max/autoINVALID_INPUT size dimensions must be multiples of 16→ align the side length to the nearest multiple of 16INVALID_INPUT size dimensions must be at most 3840px→ exceeds the 4K UHD upper limit, lower to ≤ 3840INVALID_INPUT total pixels must be ...→ area out of bounds, either scale down overall or switch to a less extreme aspect ratioINVALID_INPUT aspect ratio must be between 3:1 and 1:3→ aspect ratio too extreme, change to within 21:9INVALID_INPUTTransparent background →--background transparentrequires--output-format pngorwebpIO_ERROR→ check whether the--outdirectory exists and is writableNETWORK_ERROR→ network or endpoint configuration anomaly, verifygpt-image-cli config show
Safety and expectations
- A flare 1024x1024 usually takes tens of seconds, sunburst is about 1.5–2 times that;
editcompared withgenerateslightly slower; large resolutions (≥ 4MP),xhigh/max、-n > 1will be noticeably slower and more expensive. Single-run measured reference (1024x1024): flare high about 33 seconds / 1756 output tokens, sunburst high about 60 seconds, sunburst xhigh about 90 seconds / 3122 output tokens, all will fluctuate with load. - For calls over 30 seconds, first tell the user "it's generating, about a minute", then wait for the result.
- When cwd is not suitable, be sure to pass
--out, do not write to disk by default in any directory. - Do not write the API key into shell history: use
OPENAI_API_KEYenv orconfig init。 - Preferred for script scenarios is
--format json+--jq, stable and parseable.
Do not do
- Do not use this SKILL to analyze or recognize existing images (vision task, this CLI does not cover it).
- Do not pass
--modelto switch models by other means (do not change the profile's deployment field to switch temporarily). - Do not piece together
curlCall the OpenAI Images endpoint — go through the CLI to ensure unified envelope/error paths. - Do not write an aspect ratio in the prompt that is inconsistent with
-s; the canvas and semantics must align. - Do not use sunburst or
xhighduring the exploration phase; that is a pure waste.