Claude Opus 5.5 已在 SeedRouter 上线

把图像集成迁移到 SeedRouter

把 GPT Image 2 集成迁移到 SeedRouter:映射请求字段、处理异步任务,并验证基于 URL 的图像交付。

以 Markdown 阅读

把图像 API 迁移到 SeedRouter,需要核对请求与响应的契约,而不只是换掉 API 密钥和基础 URL。GPT Image 2 使用的是大家熟悉的那套图像生成字段,但提交之后返回的是一个任务 ID。你的应用必须保存这个 ID、轮询直到完成,然后读取生成好的图像 URL。

最小可用的迁移,是从服务端代码发起一次文生图请求。先把这一条跑通,再去迁移参考图编辑、遮罩或更大的批量。在新链路通过同样的验收检查之前,请保留现有集成可用。

哪些假设需要改变?

找到那段把图像请求变成可用文件的代码。它现在可能期望首个响应里就带着图像、可能在解码一个 base64 字段,或者在用 multipart 上传。这些假设都必须逐条对照 SeedRouter 的 GPT Image 2 参考文档核实。

现有假设SeedRouter 的契约应用需要的改动
提交后返回成品图像提交后返回一个任务引用在等待输出之前先保存 id
输出在提交响应的 data 数组里已完成任务的图像在 output.data 中在任务完成后再读取结果
客户端解码 b64_json图像以托管 URL 的形式返回下载返回的这些 URL
编辑时上传文件字节参考图使用 images 的 URL 对象让输入图像可以通过 URL 访问
用一个单独的编辑路径来选择编辑由 images 和 mask 决定执行哪种操作统一使用对外的 generations 端点
客户端超时意味着出图失败任务可能仍在处理中用保存下来的 ID 继续查询

这就是为什么即便某个同步的 Images SDK 支持配置基础 URL,它也不是可以直接替换的方案。该保留的模型设置照旧保留,但要改造那段等待并消费结果的应用代码。

先映射请求字段,再动代码

先从 model、prompt、size、quality 和 n 开始。模型 ID 使用 gpt-image-2。尺寸请明确写成 1024x1024 这样的值,或者使用 auto;不要把原有的 resolution 字段或一个比例字符串直接当作尺寸沿用过来。

SeedRouter 的 OpenAPI 文档是核对时很好的对照材料。请比对你的应用实际发送的字段,包括 SDK 自动补上的值,而不是只看调用处能看到的那几个参数。未知字段会被拒绝。

对这个模型来说,style、response_format 以及可配置的 input_fidelity 都不是被接受的请求字段。请把这些假设删掉,而不是塞进一个通用的 options 对象里藏起来。请求同样不支持 stream 和 partial_images;在这套集成里,进度是通过任务状态来反馈的。

输出设置之间存在依赖。需要透明效果时,请选择 PNG。output_compression 只在 JPEG 下传入,PNG 不要传。压缩值为 0 是合法的,所以不要用真值判断把它替换成默认值。这些细节很小,一次成功的基础请求根本覆盖不到。

替换掉「响应是同步的」这个假设

下面这段 Node.js 示例提交一次请求并打印出任务 ID。请在服务器上设置 SEEDROUTER_API_KEY;绝不要把密钥放进浏览器代码或公开的环境变量里。

const response = await fetch('https://api.seedrouter.ai/v1/images/generations', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.SEEDROUTER_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    model: 'gpt-image-2',
    prompt: 'A cobalt-blue ceramic mug on a pale gray tabletop.',
    size: '1024x1024',
    quality: 'low',
    n: 1,
  }),
  signal: AbortSignal.timeout(60000),
});
const task = await response.json();
if (!response.ok) {
  // Preserve a task reference if one accompanies an uncertain submission.
  if (typeof task.id === 'string') console.log('Task reference:', task.id);
  throw new Error(`Submission needs review: HTTP ${response.status}`);
}
if (typeof task.id !== 'string' || !task.id) throw new Error('Missing task ID.');
console.log(task.id); // Persist this ID with your application's image record.

手工冒烟测试时,打印出 ID 就够了。但在真实应用里,请在把控制权交还给用户之前先把它存下来。这样即使用户已经跳转到别处,你的图像记录也能保持在「处理中」状态,之后再查询就能把结果取回来。

用同样的授权请求头调用 GET https://api.seedrouter.ai/v1/tasks/{id} 来查询进度。状态为 completed 时读取 output.data[].url;状态为 failed 时,按文档处理对应错误并展示合适的失败状态。想要一个能持久化进度的可运行示例,请看批量提交与轮询。

不要把 API 密钥附加到图像下载请求上。授权属于任务 API 调用,而不属于单独去抓取那个返回的资源 URL。

把参考图和遮罩改为 URL 输入

原本基于本地文件的流程,需要多一个准备步骤:把参考图放到一个你可控、可访问的 HTTP(S) URL 上。然后以 images: [{"image_url": "https://example.com/reference.png"}] 的形式传入,并把这个地址换成你自己的。不要传文件路径、blob: URL、base64 的 data URL 或 Files ID。

请确认这个 URL 在没有浏览器登录 cookie 的情况下也能打开。只有在你已登录的会话中才能访问的 URL,对这个请求来说不是可用的参考图。任务处理期间请保持图片可访问,不要一提交就撤销访问权限。

遮罩使用 mask: {"image_url": "https://example.com/mask.png"} 的形式,并且必须与参考图一起使用,尺寸要与第一张参考图一致。在迁移已有的编辑流程之前,请先通读全部媒体输入约束,尤其是文件格式和文件大小。

迁移的验收测试该覆盖什么?

请测试你的应用真正依赖的行为,包括被中断的情况。一张成功的图只能证明那一次请求成功了,它并不能证明你的「处理中」状态能挺过一次刷新,也不能证明下载失败时不会重复生成。

  • 提交一次纯文本请求,并在轮询之前先把返回的 ID 存下来。
  • 停止轮询,再用同一个 ID 重新开始,确认没有产生额外的 POST 请求。
  • 把 processing、completed 和 failed 当作三种彼此不同的状态来处理。
  • 在不发送 API 授权请求头的情况下,下载一张已完成的图像。
  • 用一个可访问的 URL 验证参考图编辑,再用一个无法访问的 URL 验证失败处理。
  • 用公开的 schema 校验可选字段,其中包括压缩值设为 0 的情况。
  • 确认账号扣费是从用量记录里读取的,而不是从一个凭空臆造的任务响应费用字段里读取的。

可重复的失败与超时测试,请使用模拟响应。只有在这些检查都通过之后,再有意识地做一次小规模的真实测试;真实生成是要消耗余额的。如果提交结果不确定,请先排查再重试。本地抛出的异常,并不能证明没有任务被受理。

常见问题

现有的提示词还能继续用吗?

可以,作为起点使用,前提是它们满足请求的各项约束。请保留几条有代表性的提示词用于对比,但不要指望重复生成会得到完全相同的图像。

我需要换一个客户端库吗?

就本文的示例而言不需要,标准的 HTTP 请求就够了。无论你选择哪个客户端,它都必须能处理任务提交与轮询,而不是期望立刻拿到一张成品图。

最终费用在哪里查看?

在账号用量记录中查看。已完成的任务可能会带上 token 用量,但它对外的响应中没有金额字段。估算方法见价格指南。

在应用边界上完成这次迁移

当应用能完整处理结果的整个生命周期——任务受理、处理中状态、最终输出、下载以及失败——这次图像 API 迁移才算完成。第一步改动要小,把被中断的场景测到位,等输入和输出的假设都核实过之后,再迁移剩下的请求。

相关指南