ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Codex 调用 gpt-image-2 生图实战:Windows 固定配置、脚本封装与代理兼容

Codex 调用 gpt-image-2 生图实战:Windows 固定配置、脚本封装与代理兼容 1. 为什么要在 Windows 上把 Codex 生图流程固定下来如果你在 Windows 上用 Codex 调 gpt-image-2 生图最烦的往往不是模型本身而是每次都要重新拼一遍 API 地址、模型名、尺寸、质量参数还要手动处理返回的是 Base64 还是临时图片 URL。一次两次还行天天这么干光复制粘贴就能把耐心磨没。我这边的做法是把整条链路拆成三层JSON 存固定配置、PowerShell 做统一入口、Python 写真正的图像客户端。这样日常只需要给一句提示词和一个输出路径剩下的地址、模型、Key、依赖、响应解析全部自动完成。本文就按这个思路把 Windows 下 Codex 调用 gpt-image-2 的完整落地路径讲清楚包括 config.toml 与 settings.json 的固定配置骨架、PowerShell/Python 脚本封装以及代理兼容和报错回退。适合谁看已经在 Windows 上用 Codex 写代码、想顺手把生图能力接进工作区的人被兼容网关返回 URL 而不是 Base64 坑过的人以及希望一次配置后长期稳定出图、不想每次重配的人。下面所有命令和配置都可以直接复制改掉 Key 和地址就能跑。2. TaoToken 前置把地址、Key 和模型固定下来在写脚本之前先把「往哪发请求、用什么身份、调哪个模型」这三件事固定。TaoToken 提供 OpenAI 兼容的接口形态官网入口是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 基址是 https://taotoken.net/api 。注意 API 地址后面不加 UTM 参数保持干净。你需要先拿到一个可用的 API Key。进入控制台创建即可https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite Key 的创建和管理在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 。如果你还想先在网页里手动试一下模型对话效果可以用 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite 先验证提示词再落到脚本里。这里有个容易踩的坑base_url 到底带不带 /v1。OpenAI 兼容接口通常以 /v1 结尾但不同网关的路径拼接方式不一样。我的建议是先在配置里写成 https://taotoken.net/api/v1 如果调用返回 404 或路径错误再回退到 https://taotoken.net/api 试一次。这个「先固定、再验证、不行就回退」的思路后面排查章节还会用到。注意API Key 属于敏感凭据本文为了本地调用方便用明文文件保存但一定要加进 .gitignore不要上传到任何公开位置。生产环境更推荐系统凭据库或环境变量。3. 可复制配置config.toml、settings.json 与项目结构先把项目骨架搭好。下面这个结构把配置、脚本、输出、临时文件、运行依赖分开互不污染项目目录/ ├─ config/ │ ├─ imagegen.json # API 地址、模型及默认参数 │ └─ api-key.txt # API Key本地明文不提交 Git ├─ scripts/ │ ├─ generate-image.ps1 # PowerShell 统一入口 │ └─ imagegen_client.py # Python 图像客户端 ├─ outputs/ # 图片输出目录 ├─ work/ # 提示词文件等临时内容 ├─ .imagegen-runtime/ # 自动安装的 Python 依赖 └─ .gitignore3.1 config.toml 固定配置骨架如果你习惯用 TOML 管理 Codex 侧配置可以建一个 config/config.toml把模型和默认参数写死[imagegen] base_url https://taotoken.net/api/v1 model gpt-image-2 size 1024x1024 quality low output_format png timeout_seconds 6003.2 settings.json 固定配置骨架有些工作区用 settings.json 承载运行参数等价写法如下{ imagegen: { base_url: https://taotoken.net/api/v1, model: gpt-image-2, size: 1024x1024, quality: low, output_format: png, timeout_seconds: 600 } }3.3 imagegen.json 与 api-key.txt脚本实际读取的是 config/imagegen.json内容与上面保持一致{ base_url: https://taotoken.net/api/v1, model: gpt-image-2, size: 1024x1024, quality: low, output_format: png }参数含义对照如下参数说明base_urlOpenAI 兼容接口地址通常以 /v1 结尾model生图模型本文使用 gpt-image-2size默认分辨率如 1024x1024、1536x1024、2048x1152qualitylow、medium、high 或 autooutput_format输出格式本文使用 pnglow 适合快速预览构图正式海报再改 high。横向常用 1536x1024、2048x1152方形用 1024x1024 或 2048x2048。config/api-key.txt 里只放一行 Key不要加引号、不要加说明文字sk-your-api-key-here.gitignore 至少包含这两行config/api-key.txt .imagegen-runtime/4. 脚本封装Python 客户端 PowerShell 统一入口4.1 Python 图像客户端新建 scripts/imagegen_client.py。这段代码最关键的地方是同时判断 b64_json 和 url 两种响应字段import argparse import base64 from pathlib import Path def parse_args() - argparse.Namespace: parser argparse.ArgumentParser( descriptionGenerate an image with a GPT Image compatible API ) prompt_group parser.add_mutually_exclusive_group(requiredTrue) prompt_group.add_argument(--prompt) prompt_group.add_argument(--prompt-file) parser.add_argument(--out, requiredTrue) parser.add_argument(--model, requiredTrue) parser.add_argument(--size, requiredTrue) parser.add_argument(--quality, requiredTrue) parser.add_argument(--output-format, defaultpng) return parser.parse_args() def main() - int: args parse_args() from openai import OpenAI import httpx prompt args.prompt if args.prompt_file: prompt Path(args.prompt_file).read_text(encodingutf-8) result OpenAI().images.generate( modelargs.model, promptprompt, n1, sizeargs.size, qualityargs.quality, output_formatargs.output_format, ) item result.data[0] if item.b64_json: image_bytes base64.b64decode(item.b64_json) elif item.url: response httpx.get(item.url, timeout600, follow_redirectsTrue) response.raise_for_status() image_bytes response.content else: raise RuntimeError(The API response contains neither b64_json nor url) output Path(args.out).resolve() output.parent.mkdir(parentsTrue, exist_okTrue) output.write_bytes(image_bytes) print(fSaved image: {output} ({len(image_bytes)} bytes)) return 0 if __name__ __main__: raise SystemExit(main())如果只读 b64_json遇到返回 URL 的兼容网关就会在保存阶段报 TypeError: argument should be a bytes-like object or ASCII string, not NoneType。这并不代表生成失败只是响应格式和客户端预期不一致。4.2 PowerShell 统一入口新建 scripts/generate-image.ps1把配置读取、依赖隔离、凭据注入、参数覆盖都收进来[CmdletBinding(DefaultParameterSetName InlinePrompt)] param( [Parameter(Mandatory $true, ParameterSetName InlinePrompt)] [string]$Prompt, [Parameter(Mandatory $true, ParameterSetName PromptFile)] [string]$PromptFile, [Parameter(Mandatory $true)] [string]$OutFile, [string]$Model, [string]$Size, [ValidateSet(low, medium, high, auto)] [string]$Quality ) $ErrorActionPreference Stop $projectRoot Split-Path -Parent $PSScriptRoot $configPath Join-Path $projectRoot config\imagegen.json $keyPath Join-Path $projectRoot config\api-key.txt $clientPath Join-Path $PSScriptRoot imagegen_client.py $packagePath Join-Path $projectRoot .imagegen-runtime\python-packages if (-not (Test-Path -LiteralPath $configPath)) { throw Missing config: $configPath } if (-not (Test-Path -LiteralPath $keyPath)) { throw Missing API key: $keyPath } $config Get-Content -Raw -LiteralPath $configPath | ConvertFrom-Json if (-not $Model) { $Model $config.model } if (-not $Size) { $Size $config.size } if (-not $Quality) { $Quality $config.quality } [array]$pythonCandidates ( (Get-Command python -ErrorAction SilentlyContinue).Source, $env:USERPROFILE\.cache\codex-runtimes\codex-primary-runtime\dependencies\python\python.exe ) | Where-Object { $_ -and (Test-Path -LiteralPath $_) } if (-not $pythonCandidates) { throw Python not found. Open this project in Codex once. } $pythonExe $pythonCandidates[0] New-Item -ItemType Directory -Force -Path $packagePath | Out-Null $env:PYTHONPATH $packagePath $pythonExe -c import openai, httpx 2$null if ($LASTEXITCODE -ne 0) { Write-Host Installing local image-generation dependencies... $pythonExe -m pip install --disable-pip-version-check --target $packagePath openai httpx if ($LASTEXITCODE -ne 0) { throw Failed to install dependencies. } } $apiKey (Get-Content -Raw -LiteralPath $keyPath).Trim() if ([string]::IsNullOrWhiteSpace($apiKey)) { throw API key file is empty: $keyPath } try { $env:OPENAI_API_KEY $apiKey $env:OPENAI_BASE_URL $config.base_url $arguments ( $clientPath, --out, $OutFile, --model, $Model, --size, $Size, --quality, $Quality, --output-format, $config.output_format ) if ($PSCmdlet.ParameterSetName -eq PromptFile) { $arguments (--prompt-file, (Resolve-Path -LiteralPath $PromptFile).Path) } else { $arguments (--prompt, $Prompt) } $pythonExe arguments if ($LASTEXITCODE -ne 0) { throw Image generation failed: $LASTEXITCODE } } finally { $apiKey $null Remove-Item Env:OPENAI_API_KEY -ErrorAction SilentlyContinue Remove-Item Env:OPENAI_BASE_URL -ErrorAction SilentlyContinue Remove-Item Env:PYTHONPATH -ErrorAction SilentlyContinue }注意 [array]$pythonCandidates 这一行。如果候选路径只有一个变量被当成普通字符串处理$pythonCandidates[0] 可能只取到盘符首字母 C随后报 The term C is not recognized as a name of a cmdlet。显式声明为数组就能避开。5. 验证请求从内联提示词到提示词文件5.1 内联提示词快速验证配置完成后在项目根目录执行.\scripts\generate-image.ps1 -Prompt 一朵蓝色水彩花白色背景居中构图无文字无水印 -OutFile .\outputs\blue-flower.png成功时终端会打印类似 Saved image: ...\outputs\blue-flower.png (1234567 bytes)outputs 目录下出现 PNG 文件。第一次运行会自动安装依赖稍等即可。5.2 提示词文件跑复杂海报复杂海报适合把提示词存到 work/poster-prompt.txtUse case: stylized-concept Asset type: landscape character poster Primary request: 一张左右分屏的足球人物插画海报 Style/medium: 手绘数字水粉与墨线 Composition/framing: 2048x1152 横向画布严格左右平衡 Lighting/mood: 体育场灯光强烈但保留人物面部细节 Constraints: 无水印无乱码文字无多余人物执行时用命令行参数覆盖默认值.\scripts\generate-image.ps1 -PromptFile .\work\poster-prompt.txt -OutFile .\outputs\poster.png -Size 2048x1152 -Quality high-Size、-Quality、-Model 会覆盖 JSON 里的默认值这样一套脚本既能跑快速预览也能出正式大图。5.3 推荐的提示词结构复杂图片别只写一句主题用结构化字段更稳Use case: stylized-concept Asset type: 图片用途 Primary request: 核心画面要求 Scene/backdrop: 场景与背景 Subject: 主体、数量和位置 Style/medium: 插画、摄影、水彩、3D 等 Composition/framing: 横竖比例、景别和留白 Lighting/mood: 光线与情绪 Color palette: 主色与辅助色 Constraints: 必须满足的限制 Avoid: 不要出现的内容人物群像要明确写出总人数、左右各几人、中心与辅助人物位置、胸像还是全身、是否需要文字或队徽以及禁止重复人物、额外手臂、乱码和水印。6. 本篇常见错排查代理兼容与报错回退6.1 OPENAI_API_KEY is not set检查 config/api-key.txt 是否存在、是否为空。文件里不要加引号或说明文字只留一行 Key。脚本在 finally 里会清理环境变量所以每次调用都是重新注入不会残留。6.2 Authentication failed常见原因有几种Key 无效或过期base_url 缺少 /v1接口服务的 TLS 或证书与 PowerShell 客户端不兼容接口限制了来源 IP。如果 PowerShell 的 Invoke-RestMethod 失败而 Python SDK 能通就继续用本文的 Python 客户端通道这也是我把请求逻辑放在 Python 里的原因之一。6.3 生图完成后报 NoneType Base64 错误兼容网关可能返回 url 而不是 b64_json。本文客户端已经同时兼容两种字段遇到这个错先确认你用的是不是最新版客户端代码。6.4 content_policy_violation简化提示词里对真人身份、暴力、敏感内容或强身份复刻的表述。可以把「完全一致的真人肖像」改成「编辑插画风格的致敬形象」同时保留构图与服装要求。6.5 高质量图片等待时间长这是正常现象。建议先用 size 1024x1024、quality low 确认构图再改 2K 与 high 出最终版本。timeout 建议保持 600 秒以上避免大图被提前掐断。6.6 代理兼容与回退策略如果你的网络环境需要走代理优先在系统层或 Python 的 httpx 客户端里配置而不是在脚本里硬编码。回退顺序建议是先试 base_url 带 /v1失败再试不带 /v1先试 Python 通道失败再试 PowerShell 原生请求先试 low 质量失败再降尺寸。这样每一步都有明确的下一步动作不会卡死。7. 语义一致 CTA把生图接进你的 Codex 工作流配置固定下来之后日常生图就只剩提示词和输出路径两个变量。如果你还想在网页里先手动验证模型对话效果可以用模型对话入口https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite 。需要管理或轮换 Key去 API Keys 页面https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 。接入细节和参数说明看接入文档https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 。如果你打算长期用 Codex 做编码和 Agent 任务顺带把生图能力挂上去可以了解 Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 。最后提醒一句config/api-key.txt 永远不要提交到 Git截图和录屏里也别露出真实 Key。Key 一旦在公开页面出现立即作废重新生成。把这三层拆开之后简单插画、人物海报和高分辨率横幅都能用同一个命令生成剩下的就是调提示词了。
返回列表