GPT-6 Sol、Claude Opus 5.5 已上线GPT-6 Sol 价格仅为 5.6 Sol 的一半

Seedream 5.0 Pro API:用 Python 生成图片

一个 POST、model 填 Dola-Seedream-5.0-pro 就建好出图任务。下面是能直接抄的请求代码、尺寸和标签的实际表现,以及我们 2026 年 10 月 29 日跑出来的两张图。

Kiki, OmniaKey COO7 分钟阅读
本页内容

发一个 POST 到 https://api.omniakey.com/v1/media/tasks,model 填 Dola-Seedream-5.0-pro,operation 填 generate,拿到任务 id 就轮询。状态变成 succeeded,再下载 assets[0].url。默认出图在角落带一个「AI generated」标签。2026 年 10 月 29 日,我们用同一份请求生成一张、改一张。尺寸都写 1024x1024,两个文件量出来都是 1024×1024 PNG。

下面依次是 id 和两种操作、一行没改的请求代码、请求尺寸和文件像素的对照列表、标签和关掉它的设置(这项还没跑过),以及会让建任务失败的两个报错。两张图都是那天我们自己跑出来的。

用哪个模型 id、能做什么

用 Dola-Seedream-5.0-pro,这就是 Seedream 5.0 Pro 模型页(2026 年 10 月 29 日核对)上示例请求里的 id。页面写了两种操作:文生图和改图。生成和改图按同一个价格算,选的尺寸、附带的参考图都不额外收费。当前费率看 价格页。

请求的形状由下面几个字段决定,提示词另放:

  • model: Dola-Seedream-5.0-pro
  • operation: generate 或 edit
  • parameters.size: 1K、1.5K、2K,或 widthxheight 中间写一个小写 x
  • output_format: png 或 jpeg,默认是 jpeg

parameters.size 和 output_format 都放在 parameters 里。尺寸最高到 2K,模型页(2026 年 10 月 29 日核对)没有 4K。Seedream 的宽高之间写小写 x,Qwen 和 Wan 写星号,同一个客户端调两家时别弄混。我们两次都写 widthxheight 形式的 1024x1024、用 PNG,1K、1.5K、2K 这三档没跑过。

ByteDance 在 BytePlus ModelArk 上卖同一个模型,id 是 dola-seedream-5-0-pro-260628。那是 BytePlus 的 id,调 OmniaKey 要用上面那个。

请求代码

下面这份脚本就是 2026 年 10 月 29 日跑的那份,一行没改:两个辅助函数,一次生成调用,一次改图调用。只用 Python 标准库,key 从 OMNIAKEY_API_KEY 读,图片写进你运行脚本的文件夹。图片接口文档 写的是同样三步。生成和改图只差两处:源图字段和 operation 的取值,其余字段一样。

python
import base64
import json
import os
import time
import urllib.error
import urllib.request
import uuid

API = "https://api.omniakey.com/v1/media/tasks"
KEY = os.environ["OMNIAKEY_API_KEY"]
MODEL = "Dola-Seedream-5.0-pro"

def request(method, url, body=None, extra_headers=None):
    headers = {"Authorization": f"Bearer {KEY}", "User-Agent": "omniakey-example/1"}
    data = None
    if body is not None:
        headers["Content-Type"] = "application/json"
        data = json.dumps(body).encode()
    headers.update(extra_headers or {})
    req = urllib.request.Request(url, data=data, headers=headers, method=method)
    with urllib.request.urlopen(req, timeout=120) as resp:
        return json.load(resp)

def poll(url, attempts=5):
    for attempt in range(attempts):
        try:
            return request("GET", url)
        except urllib.error.HTTPError as err:
            if err.code < 500 or attempt == attempts - 1:
                raise
        except urllib.error.URLError:
            if attempt == attempts - 1:
                raise
        time.sleep(5 * (attempt + 1))

def run_task(body, out_path):
    task = request("POST", API, body, {"Idempotency-Key": str(uuid.uuid4())})["id"]
    print("task", task, flush=True)
    for _ in range(150):
        time.sleep(4)
        state = poll(f"{API}/{task}")
        if state["status"] not in ("queued", "processing"):
            break
    if state["status"] != "succeeded":
        raise RuntimeError(state.get("error") or state["status"])
    asset_url = state["assets"][0]["url"]  # signed link: short-lived, so download now
    req = urllib.request.Request(asset_url, headers={"User-Agent": "omniakey-example/1"})
    with urllib.request.urlopen(req, timeout=120) as resp, open(out_path, "wb") as f:
        f.write(resp.read())
    return task

def generate_image(prompt, out_path, size="1024x1024"):
    body = {
        "model": MODEL,
        "type": "image",
        "operation": "generate",
        "input": {"prompt": prompt},
        "parameters": {"size": size, "output_format": "png"},
    }
    return run_task(body, out_path)

def edit_image(source_path, prompt, out_path, size="1024x1024"):
    with open(source_path, "rb") as f:
        image = base64.b64encode(f.read()).decode()
    body = {
        "model": MODEL,
        "type": "image",
        "operation": "edit",
        "input": {"prompt": prompt, "image": {"data": image, "mime_type": "image/jpeg"}},
        "parameters": {"size": size, "output_format": "png"},
    }
    return run_task(body, out_path)

if __name__ == "__main__":
    task = generate_image(
        "A glass bottle of cold-pressed orange juice on a pale stone counter, morning light from the left, "
        "a single orange slice beside it, shallow depth of field, no text, no logos.",
        "juice-bottle.png",
    )
    print("generate task", task)
    task = edit_image(
        "cafe-base.jpg",
        "Change the red bicycle to matte black. Keep everything else exactly the same: "
        "the table, the cup, the window frame and the daylight. Photorealistic, no text, no logos.",
        "cafe-edited.png",
    )
    print("edit task", task)

三步都在 run_task 里。先用一个新幂等键建任务,轮询到状态离开 queued 和 processing,再下载第一个产物的地址。建任务返回 HTTP 202,id 以 task_ 开头。状态一开始是 queued,文档里一共四种:queued、processing、succeeded、failed(2026 年 10 月 29 日核对)。状态落到 failed 时,脚本把返回里的错误抛出来,原因直接打在终端。

我们跑的尺寸和格式,拿回什么文件

两次请求的尺寸和格式一样,两个文件都是 1024×1024 PNG。

  • 生成 — 请求的尺寸: 1024x1024; 文件里的像素: 1024×1024; 格式: PNG; 日期: 2026-10-29
  • 改图 — 请求的尺寸: 1024x1024; 文件里的像素: 1024×1024; 格式: PNG; 日期: 2026-10-29

像素要去下载下来的文件里读。尺寸是你请求的,文件才是你拿到的,拿去排版的也是文件里的数字。每个 PNG 我们都打开量了宽高,也对照提示词看过画面。

改图那次更值得看。我们发了一张 1024×683 的咖啡馆照片,加一句要求,返回的是正方形。自行车变成深色,桌子、杯子和绿植都还在画面里;因为输出是正方形,窗户和桌沿的取景跟原图不一样。

prompt
Change the red bicycle to matte black. Keep everything else exactly the same: the table, the cup, the window frame and the daylight. Photorealistic, no text, no logos.
Left: a café window with a red bicycle outside. Right: the same window after the edit, with the bicycle now dark, in a square frame.
Left: the source photo we sent, 1024×683. Right: the output of one edit on October 29, 2026, size 1024x1024. The bicycle is now dark. The output is a square, so the window and the table edge are framed differently from the source.

「AI generated」标签怎么关掉

按模型页(2026 年 10 月 29 日核对)的说法,每个输出的角落都带「AI generated」标签。要把标签去掉,在 parameters 里把 watermark 设成 false。页面写的位置是右下角,下面这张默认出图的标签就在右下角:很淡、很小。请求里不写 watermark,出来的就是带标签的图。

prompt
A glass bottle of cold-pressed orange juice on a pale stone counter, morning light from the left, a single orange slice beside it, shallow depth of field, no text, no logos.

这张就是用默认设置出的图:

A glass bottle of orange juice with an orange slice on a pale stone counter, with a faint AI-generated label in the corner.
Generated with Seedream 5.0 Pro via the OmniaKey API on October 29, 2026, size 1024x1024, default settings. The faint 'AI generated' label sits in the bottom-right corner.

水印关掉的那一版我们没跑。博客工具的每次运行花费上限在请求发出之前就拦下了,所以还没有见过不带标签的 Seedream 出图。

报错和限制

建任务能不能过,看两个请求头:Bearer token 和 Idempotency-Key。

你发的内容返回什么
建任务不带幂等键400 missing_idempotency_key
同一个键、同一份 body,再发一次200,返回原任务,不重复扣费
同一个键、改了 body409 idempotency_key_reused

同一个键配同一份 body 才是安全的重复发送:拿回原来的任务,不会多扣一次费。同一个键改了提示词或尺寸就返回 409,所以每次新请求都换一个新键。键最长 255 个字符(文档,2026 年 10 月 29 日核对)。

请求体控制在 1 MiB 以内,Base64 的图也算在里面,源图大就先压小再发。重试时把原来那份 body 一起带上,幂等键才有意义。任务成功后,返回里的下载地址是签名链接,文档说有效期大约一小时。链接过期后文件不会自己保存下来,所以马上把文件拉下来,或者再轮询一次换新链接。

2026 年 10 月 29 日还有一个请求头让我们意外。用 Python 默认的 urllib User-Agent 发 POST,返回 HTTP 403。返回内容是 Cloudflare 的 error code: 1010。换我们自己的 User-Agent 请求头就到达了接口,也没有扣费。

自己带一个 User-Agent 请求头,例如 omniakey-example/1。2026 年 10 月 29 日 Python 默认的那个就被挡在上面那个 403 上。

做 API 该选 Seedream 还是 GPT Image 2.5

看活是什么。这次改图,Seedream 5.0 Pro 改掉的是我们点名的那辆自行车,大部分场景还在,但画面换成了正方形,窗框和桌沿的位置和原图不一样。产品图我们没有测过。请求只是一个 body,operation 填 generate 或 edit。源图可以给公开 URL,也可以内联 Base64(文档,2026 年 10 月 29 日核对)。

想先看同一句提示词下它和 GPT Image 2 的差别?Seedream 5.0 Pro 对比 GPT Image 2 把两边的输出放在一起。想在另一个模型上照同样的「生成加改图」写法走一遍,GPT Image 2.5 API 教程 有它的请求和尺寸。换之前先用你自己最难的那句提示词跑一次,再按费率决定。

FAQ

调接口时 model 该填什么?

填 Dola-Seedream-5.0-pro,这是模型页示例请求里的 id(2026 年 10 月 29 日核对)。ByteDance 自己的 dola-seedream-5-0-pro-260628 属于 BytePlus ModelArk,OmniaKey 要的不是它。

为什么我的图上有「AI generated」标签?

模型页(2026 年 10 月 29 日核对)写着每个输出都带这个标签,除非把 watermark 设成 false。我们 10 月 29 日用默认设置出的那张,标签就在右下角。

接口支持哪些尺寸?

尺寸有 1K、1.5K、2K 三档,也可以写 widthxheight、中间用小写 x(模型页,2026 年 10 月 29 日核对)。最高到 2K,我们两次都要的 1024x1024。

能要 PNG 不要 JPEG 吗?

可以。output_format 填 png 或 jpeg,默认是 JPEG(文档,2026 年 10 月 29 日核对)。我们两次都用 PNG,拿回来的也是 PNG。

能用 Seedream 改已有图片吗?

可以:operation 填 edit,带上提示词和源图,源图可以是内联 Base64 加 mime 类型,也可以是一个公开 URL。上面尺寸那节的咖啡馆改图就是一次完整的例子。

文中提到的模型

Seedream 5.0 Proimage APIPythontext-to-imageAPI

相关文章

最新文章