HiAPI
博客

教程

如何通过 HiAPI API 调用 seedream-5.0-lite/text-to-image:curl 与 Python 指南

面向开发者的可运行请求演练:通过 HiAPI 集成文本到图像

2026年10月31日
极简建筑感封面图:暖灰混凝土平面与斜切的青灰蓝色块、一道细鼠尾草绿接缝,构成安静的布里库特风格几何构图。

这个集成实际做什么

在 HiAPI 上发起文本到图像调用,是你的代码与一个异步任务队列之间的一次简短对话。你发送一个请求,描述你想要的图像;平台验证请求、接受任务,并返回一个标识符。图像并不在首次响应中——它在之后生成。随后你的代码监视该任务,直到它报告完成,最后从任务暴露的 URL 下载图像。

这个形态很重要,因为它决定了你如何编写集成。有三个不同的时刻:提交、轮询和获取。每个都有各自的失败模式。提交会在载荷格式错误或模型路径无效时失败。轮询在循环写错时失败——太快、太短,或无法区分“仍在运行”与“已完成”。获取会在你把输出 URL 当作永久地址或忘记将字节写入磁盘时失败。

底层来看,seedream-5.0-lite/text-to-image 是 HiAPI 平台上的一个通用文本到图像模型。你通过该精确的模型标识符来调用它。你发送的参数是这类调用的普通参数:模型名称、提示词,以及端点文档中说明的任意输出尺寸或数量控制参数。你不需要任何特殊 SDK;一个普通的 HTTPS 客户端就足够了。

读完本演练,你将拥有一个可以用 curl 复现的请求、一个围绕它的 Python 函数、如何措辞提示词以使渲染文本清晰可读的技巧,以及一个真正会终止的轮询循环。所有内容都通过同一个 HiAPI 端点运行,因此一旦一个调用成功,剩下的就是参数调优。

用 curl 构建请求

从命令行开始。一个可运行的 curl 调用是载荷的基准——一旦它成功,其他每种语言都只是翻译练习。

首次调用前你需要两样东西:你的 HiAPI API 密钥和 API 的基础 URL。密钥以 bearer 令牌的形式放在 Authorization 头中。尽可能让它不进入你的 shell 历史记录;环境变量是最简单的习惯。

export HIAPI_API_KEY="your_api_key_here"

请求本身是一个带 JSON 正文的 POST。模型标识符是你要调用的路径段,提示词描述图像:

curl -sS -X POST "$HIAPI_BASE_URL" \
  -H "Authorization: Bearer $HIAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "seedream-5.0-lite/text-to-image",
    "prompt": "A minimalist poster for a coffee shop called North Roast, warm cream background, bold dark lettering"
  }'

将 HIAPI_BASE_URL 设置为平台文档中显示的文本到图像提交端点;路径因产品界面而异,所以请复制而不是猜测。

在编写更多代码之前,先阅读响应。成功的提交会返回一个 JSON 对象,包含任务标识符和一个状态字段。状态通常会表明任务已排队或处理中——尚未完成。这是预期行为。准确记下返回的字段名;你将在接下来的两节中引用它们。

curl 层面的两个错误造成了大多数首次失败。第一个是密钥缺失或作用域错误:响应是认证错误,而不是模型错误。第二个是正文格式错误——提示词内引号未转义、末尾逗号、JSON 要求双引号处使用了单引号。如果平台拒绝载荷,用 jq 美化打印并单独验证它,然后再归咎于模型。

当提交返回标识符时,你就有了一个有效的请求。此后的一切都是等待和获取。

移植到 Python

Python 版本应该是一个小而可复用的函数——而不是一个硬编码单个提示词的脚本。使用 requests(或 httpx,如果你更喜欢);调用本身不需要特殊客户端。

import os
import requests

API_KEY = os.environ["HIAPI_API_KEY"]
BASE_URL = os.environ["HIAPI_BASE_URL"]

HEADERS = {
    "Authorization": f"Bearer {API_KEY}",
    "Content-Type": "application/json",
}

def submit_image(prompt: str, **params) -> dict:
    payload = {
        "model": "seedream-5.0-lite/text-to-image",
        "prompt": prompt,
        **params,
    }
    response = requests.post(BASE_URL, headers=HEADERS, json=payload, timeout=30)
    response.raise_for_status()
    return response.json()

这里有三个有意的选择。密钥和基础 URL 来自环境,因此该函数可以安全地提交。 **params 万能参数让你可以传递输出尺寸或其他文档化选项,而无需编辑函数。而 raise_for_status() 会立即将 HTTP 错误转为异常,这正是你想要的——提交时的 4xx 永远不会成为有效任务,因此快速失败胜过检查令人困惑的响应正文。

返回的字典就是你的任务记录。在开发期间打印一次,以便了解标识符和状态的确切键名。不要盲目索引它;一个小访问器可以让其余代码保持可读:

job = submit_image("A flat illustration of a paper plane over a city map")
print(job)

如果它打印出已排队的任务,则从 curl 的移植是正确的。如果它抛出异常,来自 raise_for_status() 的异常消息会告诉你遇到的是认证问题还是载荷问题——与你在 shell 中会遇到的相同两类问题。

为网络知识和渲染文本编写提示词

文本到图像模型在提示词描述应该可见的内容时最强,在暗示模型必须推断的知识时最弱。 seedream-5.0-lite/text-to-image 可以利用一般世界上下文——可识别的物体、常见设计惯例、排版风格——但你仍然需要给它足够的内容来锚定该上下文。

对于场景提示词,描述主体、构图和视觉风格。 'A cozy reading nook by a window, soft afternoon light, three-quarter view, muted earth tones' 告诉模型既画什么,也如何设计风格。模糊的提示词产生普通的图像;具体的提示词产生可用的图像。

渲染文本是提示词通常失败的地方。如果你需要图像内包含文字,请遵循几条规则:

  • 引用确切的字符串。 将你想要的文本写在引号中,使其明确是字面量,而非描述。
  • 保持简短。 短标题或品牌名可以可靠渲染;段落则不行。
  • 说明位置和样式。 'The word "North" centered at the top in a bold sans-serif' 胜过 'some text at the top'。
  • 避免竞争性文本。 一张图像中包含多个不同的文本元素容易导致乱码。如果你需要多个,请保持简短并彼此远离。
  • 每次只迭代一个变量。 改变措辞,而不是同时改变措辞、布局和样式,否则你将无法了解是什么解决了问题。

对于涉及可识别上下文的任何内容——产品类别、海报类型、标牌类型——请明确命名。当提示词给它一个钩子时,模型的先验知识最有用。 'A vintage travel poster for a coastal town' 比 'a poster' 携带更多可用上下文。

不要发明参数。如果提示词没有产生你想要的文本位置,请先调整提示词本身的措辞,然后再尝试你未见文档说明的选项。

处理异步任务并下载输出

轮询是集成悄悄出错的地方。任务是异步的,因此你需要一个循环来检查状态、在检查之间等待、最终放弃,并确切知道哪些状态值意味着“完成”。

import time

def wait_for_job(job_id: str, poll_interval: float = 3.0, timeout: float = 180.0) -> dict:
    deadline = time.monotonic() + timeout
    while time.monotonic() < deadline:
        response = requests.get(
            f"{BASE_URL}/{job_id}", headers=HEADERS, timeout=30
        )
        response.raise_for_status()
        job = response.json()

        status = job.get("status")
        if status in {"succeeded", "completed"}:
            return job
        if status in {"failed", "error", "cancelled"}:
            raise RuntimeError(f"Job {job_id} ended with status {status}")

        time.sleep(poll_interval)
    raise TimeoutError(f"Job {job_id} did not finish within {timeout}s")

根据平台文档显示的内容调整轮询路径和状态字符串——这两个细节最可能与上述草图不同。结构才是关键:一个单调截止时间、检查之间的睡眠、明确的成功和失败集合,以及抛出异常而非返回半完成任务的超时。

一旦任务报告成功,响应会包含输出的 URL。将该 URL 视为临时的。立即下载字节,而不是存储链接:

def download_image(url: str, path: str) -> None:
    response = requests.get(url, timeout=60)
    response.raise_for_status()
    with open(path, "wb") as f:
        f.write(response.content)

job = wait_for_job(job_id)
download_image(job["output"]["url"], "out.png")

在继续之前,确认文件是真实图像——打开它、检查尺寸,或至少检查字节长度是否异常小。如果服务器正常关闭,截断的下载在 requests 看来就像成功。

常见错误及其修复方法

首次集成中的大多数失败分为四类。按顺序处理它们。

提交被拒绝

如果首次调用返回 4xx,打印响应正文。认证错误意味着密钥缺失、过期或未作为 bearer 令牌发送。模式错误意味着载荷格式错误——模型字段错误、提示词缺失或文档化参数拼写错误。单独验证 JSON,并与可运行的 curl 示例进行差异对比。

任务永不完成

循环无限旋转或超时。先检查轮询间隔:无睡眠地猛击端点可能触发速率限制,使健康任务看起来卡住。然后检查你的状态比较——如果平台返回 success 而你匹配的是 succeeded,每个任务看起来都未完成。记录一次原始状态值,而不是猜测。

输出 URL 返回 404 或 403

输出 URL 是签名且有时间限制的。如果你轮询了很长时间然后才获取,链接可能已过期。完成后立即获取,如果你需要保留结果,请保存文件而不是链接。

图像渲染但文本乱码

这是提示词问题,不是代码问题。缩短文本、精确引用、减少文本元素数量,并使样式指令更明确。每次只做一个更改重新运行,以便知道哪个调整有帮助。

请求挂起或超时

始终在提交和轮询调用上设置显式超时。没有超时的请求可能无限期阻塞工作进程,而没有截止时间的轮询循环会将瞬态中断变成卡住的进程。

当出现意外行为时,将其缩减为仍然失败的最小 curl 调用。如果原始 HTTP 请求行为异常,Python 层不是问题——一旦 curl 再次工作,移植回 Python 就是机械性的。 seedream-5.0-lite/text-to-image 的模型页面列出了当前参数和响应形态,因此在假设字段名之前请先查看那里。

立即开始构建持久 AI 产物

获取 API 密钥,通过一个基于任务(task)的 API 调用图像、视频和音频模型。

阅读 API 文档