构建不会超支的批量图像生成流水线
不存在所谓的批量端点。在两条公开图像路由上,一次准入请求只返回一张候选图,因此生产级批量流水线本质上是你在 Nano Banana 2(gemini-3.1-flash-image)或 GPT Image 2 之前自建的持久队列——配有有界 worker、每资产尝试预算、终态 usage 核对,以及作为最终资金边界的密钥终身消费上限。
·
一次准入调用只返回一个候选项
两条公开图像路由都不接受数量、清单或提示词文件夹。对 gemini-3.1-flash-image 的 generateContent 调用返回一个候选项,图像以 base64 形式放在 inlineData 中;OpenAI 兼容的 POST /v1/images/generations(gpt-image-2)返回单元素 data 数组,内含 b64_json。模型永远看不到“生成 500 个变体”——批量大小是队列的属性,不是请求的属性。
// gemini-3.1-flash-image → one candidate, image as base64 inlineData
{
"candidates": [
{ "content": { "parts": [ { "inlineData": { "mimeType": "image/png", "data": "<base64>" } } ] } }
],
"usageMetadata": { "promptTokenCount": 24, "candidatesTokenCount": 1120, "totalTokenCount": 1144 }
}
// gpt-image-2 → single-element data array, image as b64_json
{
"created": 1754800000,
"data": [ { "b64_json": "<base64>" } ],
"usage": { "input_tokens": 38, "output_tokens": 4096, "total_tokens": 4134 }
}设计阶段就要为两种形态规划存储:base64 只解码一次,对字节计算 checksum 并与任务一起持久化。若路由返回 URL 形态,那是一项有独立过期时间的抓取任务,而不是持久资产。
另见: 图像生成 API 的真实计价方式
每个资产一个持久任务,而不是每个提示词
- 01入队前先创建稳定 asset ID 与不可变 brief——提示词、参考图、受保护特征。
- 02在任务 payload 中固定模型、协议、输出尺寸与最大尝试次数,让重试复现同一决策而不是新决策。
- 03给每个 worker 分配有界的队列切片,一次提供商请求只对应一个候选项;绝不要求模型内部批量。
- 04把 request ID、终态 usage、输出 checksum 与验证结论随资产版本原子保存。
- 05只有存储与下游发布确认同一资产版本后,任务才算完成。
{
"asset_id": "catalog/sku-1042/hero-v3",
"idempotency_key": "sku-1042:hero-v3:attempt-1",
"model": "gemini-3.1-flash-image",
"size": "1K",
"max_attempts": 2,
"spending_key": "image-production"
}500 个 SKU 批次的成本演算
Nano Banana 2 公布了固定的图像输出计费项:1K 为 1,120 个 image token,官方 $0.0672,普通 B2C 为 $0.0336;同样五折后 2K 为 $0.0504,4K 为 $0.0756。GPT Image 2 没有诚实的单张常数:普通 B2C 的 image output 按每 1M token $15 计费,结算总额以终态 usage 为准。演算应按固定计费项进行,因为这是运行前唯一可知的部分。
| 项目 | 数值 |
|---|---|
| campaign 中的资产 | 500 个 SKU |
| 每资产候选数 | 2 |
| 准入调用数 | 1,000 |
| 每个 1K 候选项的图像输出(普通 B2C) | $0.0336 |
| 基础图像输出支出 | 1,000 × $0.0336 = $33.60 |
| 重试预算:10% 资产各增加一次尝试 | +$3.36 |
| 最坏情况图像输出支出 | $36.96 |
以上仅为图像输出项;text/image input、可选文本或思考输出以及 grounding 需按终态 usage 另计。B2C 五折会把官方 usage 减半,但不会限制 资产 × 候选 × 重试 × 分辨率 的乘积——它的边界由你来设定。
限制每一个倍增因素,而不只是单价
| 倍增因素 | 保护措施 |
|---|---|
| 资产数 | 明确队列长度与 campaign 预算 |
| 变体 | 每个资产最大候选数 |
| 重试 | 仅明确未开始的尝试;总 deadline |
| 分辨率 | 默认 1K;按交付规则升级 |
| 参考图 | 只发送 brief 必需文件 |
| 并发 | 小型 worker 上限与 429 cooling |
密钥的终身消费上限是所有应用层保护措施失效后的最后一道资金边界。把它设为 campaign 预算加实测安全余量,而不是账户余额。
重试、冷却与可观测性规则
- 图像字节或完整提供商响应交付后绝不重试——这种重试是第二次付费候选项,而不是恢复。
- 歧义超时属于核对工作:先按 request ID 对照仪表板扣费,再判断没有发生可计费生成。
- 遇到 429 时遵守 Retry-After、provider cooling 与 jitter,并受总 deadline 约束;立即扇出会放大容量事件。
- 统计尝试次数、验收资产、结算 nanoUSD 与验证失败原因;提示词和密钥不进入 metrics。
- 对每个验收资产成本与失败占比告警,而不只看 HTTP 成功率——全绿的批次也可能很昂贵。
每个验收资产的结算成本才是批次真实的单位经济性:它把 token 价格、分辨率、重试与质量拒绝折进业务真正购买的那个数字。
用独立密钥与预算隔离批量通道
让批量 worker 使用带终身消费上限和过期时间的独立密钥:队列出 bug 时最多耗尽 campaign 预算,而不会动到账户。通过 Google 或 GitHub 创建的新账户自带 $5 平台欢迎奖励余额,足够在首次充值前把流水线端到端跑通;之后可按任意整数美元金额用银行卡或加密货币(如 USDT、BTC)充值。预付余额永不过期,也没有需要按量选择的订阅。
- 每个工作负载一把密钥:批量生成绝不与交互或编辑流量共用密钥。
- campaign 结束前,把每笔结算扣费与其 request ID 逐一对账。
- 每个新 campaign 开始前重新检查终身消费上限,而不是只在初始化时设置一次。
常见问题
一个 API 请求能生成整个批次吗?
在已发布路由上不能。一次准入调用返回一张候选图,没有可以放大它的 count 参数。批次大小、顺序与并发属于持久队列——预算也正是在那里、在资金发生变动之前被执行。
1,000 张图的批次要多少钱?
Nano Banana 2 在 1K 下每个候选项的固定图像输出项为 1,120 token,普通 B2C 即 $0.0336:1,000 个候选项的图像输出为 $33.60,另加终态 usage 中的输入与可选 grounding。GPT Image 2 普通 B2C 的 image output 为每 1M token $15,没有固定单张价格,批次总额只能按结算 usage 得出。
如何阻止失控的图像批处理?
组合使用:带终身消费上限的独立密钥、明确队列长度、有界 worker、每资产最大尝试次数与总 campaign 预算。各层独立失效,而密钥级上限是即使其他全部失灵仍然成立的边界。
429 应该立即重试吗?
不应该。遵守 Retry-After 与 provider cooling,加入 jitter,并为每个任务保留总 deadline。容量事件中的立即扇出会把减速变成你自己花钱造成的故障。
流水线应存 base64 还是 URL?
API 响应是传输层而不是存储层。base64 只解码一次,计算 checksum 后把字节存入自有对象存储,再发布优化过的 WebP/AVIF 衍生品;绝不能把原始 API payload 直接当店面资产。
五折适用于批次中的每次调用吗?
普通 B2C 适用:每次准入调用的官方 usage(生成或编辑)都按五折计。B2B 按协商策略,OpenKeys 按官方价格 1:1。折扣从不证明某个模型当前对特定密钥可用。