接入教程

GPT Image 2 中转接入:按张计费、参数差异与验收方法

把图像模型当成文本模型来接,账单和行为都会出乎意料。图像按张计费而非按 token,倍率规则常常与文本分开,参数支持也各家不一。这几项都要单独验一遍——本文用一次实测把差异逐条摆出来。

图像模型中转实测的四项观察:耗时 18.2 秒、返回 base64、尺寸参数未被采纳、扣费与 token 数无关
一次最小的图像生成请求里,四项行为都和文本模型的直觉相反

一次实测:四项和文本模型不一样的行为

为了写这篇,我们对一个 OpenAI 兼容网关发了一次最小的图像生成请求:gpt-image-2n=1,请求尺寸 1024x1024

四项观察,每一项都和文本模型的直觉相反:

观察结果含义
耗时18.2 秒文本对话通常 1-3 秒,沿用文本超时会大量误报失败
返回格式b64_json,没有 URL 选项客户端要能直接解 base64,不能假设拿到的是链接
尺寸参数请求 1024x1024实际返回 1254x1254参数没有被采纳,而且没有报错
计费金额是一个固定值,与 usage 里的 token 数算不出换算关系token 统计只是统计,不是计费依据

这次返回的 usage 是这样的:

{
  "input_tokens": 15,
  "input_tokens_details": { "image_tokens": 0, "text_tokens": 15 },
  "output_tokens": 515,
  "output_tokens_details": { "image_tokens": 515, "text_tokens": 0 },
  "total_tokens": 530
}

结构完整,字段齐全,看起来完全可以拿来算钱。但实际扣费金额按任何合理单价都算不出这 530 个 token——差了一个数量级。这是本文最重要的一条:图像的 usage 和图像的账单,是两回事。

另外,同一个账户下文本调用的实际扣费是标价的一个折扣倍数,而这次图像调用的两个金额字段完全相等。折扣倍率没有应用到图像上。

最大的差异:计费单位不是 token

文本模型按输入输出 token 计费,图像模型通常按生成的张数计费,与提示词长度关系很小。写一句话的提示词和写三百字的提示词,出一张图的价格基本一样。

按 token 计费与按张计费的链路对比:文本由 token 数、单价、折扣倍率三项相乘,图像只有张数乘固定单价,折扣倍率不适用
两种计费口径可以在同一个账户下同时存在,规则却不一样

这带来两个后果。

第一,倍率可能不适用。 很多网关对文本模型给折扣倍率,图像模型却按原价结算。下单前要单独问图像模型的计价,不要假设和文本一样——上面那次实测正是这种情况。

第二,用量页面的 token 数没有参考价值。 核对账单时应当看金额和张数,而不是 token 数。如果你写了一个按 token 估算成本的脚本,它在图像请求上会给出错得离谱的数字。

倍率与结算口径的通用说明见中转站倍率与计费口径;把成本纳入日常监控的做法见AI API 成本控制

必须单独验证的四项

文本能跑通不代表图像能跑通。这四项要分开测。

验证项为什么单独测
端点是否开放图像生成常是独立端点或独立分组,可能根本没开
返回格式有的返回 URL,有的返回 base64,客户端处理方式不同
尺寸与质量参数支持的取值各家不同,传不支持的值可能静默降级或直接忽略
并发与超时图像生成耗时远长于文本,默认超时常常不够

第三项的「静默」值得警惕:你请求了某个尺寸,它按另一个尺寸生成,不报错。上面那次实测就是这样——传 1024,回 1254,HTTP 200。

发现的办法是核对返回图像的实际尺寸,而不是相信请求参数。返回体里通常有 size 字段,或者直接读解码后的图片头。如果你的产品对尺寸有硬要求(比如要贴进固定版式),这一步必须做。

质量参数同理:请求高质量、按低质量生成并按低质量计费而不报错,是可能发生的。

超时要单独设

图像生成的耗时通常在十几秒到一分钟量级。上面那次最简单的请求就用了 18.2 秒——那还只是「白底红圆」这种最简单的提示词。沿用文本的超时设置会大量误报失败。

参数文本对话图像生成
连接超时10 秒10 秒
读取超时60 秒180 秒起
重试可重试谨慎,失败的请求可能已产生计费

重试这一条要特别注意。如果一次图像请求实际已在上游生成成功但响应超时,重试会再生成一次,两次都计费。图像单价远高于文本,重复计费的代价更明显——文本重试一次多花的是零头,图像重试一次多花的是一整张的钱。

安全做法是:图像请求不自动重试,失败后先查用量明细确认是否已扣费,再决定是否重发。这属于「有副作用的调用不能盲目重试」的一种,完整判断标准见中转站重试与故障回退

验收流程

三条命令,下单前跑一遍。

BASE="https://你的网关/v1"; KEY="你的密钥"

# 1. 确认模型在列表里
curl -s "$BASE/models" -H "Authorization: Bearer $KEY" \
  | grep -o '"id":"[^"]*image[^"]*"'

# 2. 最小生成请求,注意超时设长
curl -s --max-time 180 "$BASE/images/generations" \
  -H "Authorization: Bearer $KEY" -H "content-type: application/json" \
  -d '{"model":"你的图像模型ID","prompt":"a red circle on white background","n":1,"size":"1024x1024"}'

# 3. 立刻查用量,确认扣了多少
curl -s "$BASE/usage" -H "Authorization: Bearer $KEY"

第三步是关键。生成成功后马上查用量,记下这一张扣了多少钱、计价单位是什么。这个数字才是你做预算的依据,宣传页上的倍率不是。

做第二步时,别忘了把返回体里的 size 和你请求的值比一下。

步骤通过标准
1模型 ID 出现在列表中
2返回图像数据或 URL,180 秒内完成,且返回尺寸与请求一致
3用量记录出现,金额和张数对得上

文本端点的对应验收流程见中转站实测方法;如果你要在一个网关上同时用文本和图像模型,还要确认它们是不是同一个分组,见多模型 API 网关

图像输入的一个坑

如果你要做图生图或让模型分析图片,注意图片输入的传递方式。两种选择:传 URL 让上游去拉,或者转成 base64 直接嵌在请求里。

实测中,走网关时 URL 方式经常失败,上游拉取会返回错误。原因可能是上游的出网限制、URL 本身的可达性、或者网关没有正确透传。报错信息通常只说下载失败,不会告诉你是哪一层的问题。

base64 方式更可靠,代价是请求体变大。多数客户端库默认就用 base64,所以这个坑更容易在你手写 HTTP 请求时踩到。

如果你遇到「传图片报错但纯文本正常」,先换成 base64 试一次,大概率能解决。

常见问题

图像模型的倍率和文本一样吗?

不一定,很多情况下不一样。我们实测的那次,文本调用的实际扣费是标价的一个折扣倍数,而图像调用的标价和实际扣费完全相等,也就是折扣没应用到图像上。必须单独问,并用验收流程实测一张确认。

生成失败了会扣费吗?

取决于失败发生在哪一段。请求没到上游不会扣,上游生成了但传输失败通常会扣。这也是不建议自动重试的原因。查用量明细是唯一可靠的确认方式。

怎么控制图像的成本?

三条:单独给图像设用量上限;不自动重试;生成前先用小尺寸低质量试一次提示词效果,满意再出高质量版本。

为什么请求的尺寸和返回的尺寸对不上?

网关或上游可能忽略了 size 参数,按自己的默认值生成,并且不报错。实测中我们请求 1024x1024,返回的是 1254x1254。判断办法是读返回体里的 size 字段,不要相信请求参数。

usage 里有 token 数,为什么不能用来算钱?

图像按张计费,usage 里的 token 统计和实际扣费金额之间没有换算关系。我们实测那次返回 530 tokens,按任何合理单价都算不出实际扣费金额,差一个数量级。核对账单要看金额和张数。

AI API 成本控制

把用量、单价与上限纳入日常监控,在账单出来之前发现异常消耗。