公告: GPT Image 2.6 Flare 与 Sunburst 上新限时 8 折,立即体验
HiAPI
博客

教程

如何通过 HiAPI API 使用 gemini-omni-1.2-flash:curl 与 Python

2026年11月12日
Abstract flat cover art with marbled celadon liquid forms folding over a dark ink background, for a tutorial blog post.
本页内容

gemini-omni-1.2-flash 请求长什么样

在写第一行代码之前,先理解一次 gemini-omni-1.2-flash 调用在 HiAPI 上究竟由什么组成,会很有帮助。你发送的每个请求都是一个 JSON 对象,投递到单一端点,并使用你的 HiAPI API 密钥进行认证。这一结构在各模型之间保持一致,也就是说,一旦你为本模型掌握了它,就能在其他地方复用同样的模式。

从高层次看,一个请求包含四类信息:

  • 模型标识符 —— 字符串 gemini-omni-1.2-flash,告诉 HiAPI 把你的任务路由到哪个模型。
  • 输入 —— 你希望模型处理的内容。取决于你面向的模态,它表现为提示词或结构化输入字段。
  • 生成参数 —— 塑造输出的选项,例如时长和分辨率。这些是你将在本指南后续调校的旋钮。
  • 请求元数据 —— 平台识别和追踪你任务所需的任何信息,例如可用于关联的客户端侧引用。

响应结构

响应的可预测性同样高。同步调用会直接在结果字段中返回结果。异步调用则返回一个任务句柄——一个用于查询状态并最终获取输出的标识符。提前弄清你面对的是这两种中的哪一种,能省下大量后续调试时间。

为什么结构很重要

大多数首次集成失败都源于请求结构:缺少字段、参数类型错误,或误以为调用是同步的而实际并非如此。如果你在写代码前就内化这一解剖结构,后面的 curl 和 Python 示例就只是直白的翻译,而不是神秘的咒语。

一个实用习惯:把你发送的确切 JSON 主体保存在变量或文件中。当出错时,你希望能看到究竟发出去的是什么,而不是凭记忆重建。

一行完成认证

每个请求都在授权头中携带你的 API 密钥。把密钥当作机密:从环境变量加载而不是硬编码,并且绝不提交到版本控制。这一条纪律就能避免 API 集成中最常见的安全错误。

用 curl 发出你的第一个可用请求

确认密钥、端点和请求结构都正确的最快方式是 curl 调用。它消除了你和 API 之间的每一层抽象,所以如果它能工作,你就知道问题(如果有)出在你的代码,而不是你的环境配置。

第 1 步:保存你的密钥

把 HiAPI API 密钥放进环境变量,这样它就不会出现在你的 shell 历史或共享脚本中:

export HIAPI_API_KEY="your_key_here"

第 2 步:构造请求主体

把 JSON 主体写入文件。这让 curl 命令保持可读,并给你一个可复用的产物:

cat > request.json <<'EOF'
{
  "model": "gemini-omni-1.2-flash",
  "input": {
    "prompt": "描述你希望模型生成的内容。"
  },
  "parameters": {
    "duration": 5,
    "resolution": "720p"
  }
}
EOF

具体的参数值取决于你的用例;这里重要的是结构。第一次调用时把 duration 和 resolution 保持适中,这样你能快速、低成本地获得流水线可用的信号。

第 3 步:发送它

curl -sS -X POST "https://api.hiapi.ai/v1/generate" \
  -H "Authorization: Bearer $HIAPI_API_KEY" \
  -H "Content-Type: application/json" \
  --data @request.json

第 4 步:读取响应

如果请求是同步的,你会在响应体中看到生成的结果。如果是异步的,你会收到一个任务句柄——一个任务 ID 加一个状态字段。记下这个 ID;轮询时你会需要它。

如果你的终端支持,把输出通过 JSON 格式化器处理,或者保存到文件以便仔细检查:

curl -sS -X POST "https://api.hiapi.ai/v1/generate" \
  -H "Authorization: Bearer $HIAPI_API_KEY" \
  -H "Content-Type: application/json" \
  --data @request.json > response.json

第 5 步:扩展前先确认

在这个裸调用成功并且你能读懂输出之前,不要开始调校时长、分辨率或批处理。第一次绿色的请求就是你的基线;之后的一切都是可以与之对比的增量变更。

把调用移植到 Python

一旦 curl 能工作,移植到 Python 就是机械性的工作。目标是写一个小的、可读的客户端,精确镜像该请求,这样如果 Python 调用失败,你就能逐字段地与 curl 版本做 diff。

一个最小客户端

import json
import os
import requests

API_KEY = os.environ["HIAPI_API_KEY"]
ENDPOINT = "https://api.hiapi.ai/v1/generate"

payload = {
    "model": "gemini-omni-1.2-flash",
    "input": {
        "prompt": "描述你希望模型生成的内容。"
    },
    "parameters": {
        "duration": 5,
        "resolution": "720p"
    },
}

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

response = requests.post(ENDPOINT, headers=headers, json=payload, timeout=60)
response.raise_for_status()

data = response.json()
print(json.dumps(data, indent=2))

需要注意的地方

  • json=payload 会为你序列化字典,这就是为什么主体与 curl 文件一致,而不是手工拼接的字符串。
  • raise_for_status() 把非 2xx 响应变成异常,这样失败会立即暴露,而不是静默返回一个你随后试图当作结果解析的错误体。
  • timeout=60 防止脚本在连接停滞时无限挂起。根据你预期生成需要多长时间来选取一个值。

处理两种响应结构

由于一次调用可能返回结果或任务句柄,要对响应做分支判断,而不是假定某一种结构:

if "job_id" in data:
    print("异步任务已启动:", data["job_id"])
else:
    print("结果已就绪")

这个小小的检查,就是客户端在两种模式下都能工作、与平台第一次决定你的任务需要异步运行时却崩溃之间的差别。

把它放在一个函数里

把调用包装成一个以提示词、时长和分辨率为参数的函数。这样在你开始调校时,用不同参数运行同一份代码就变得轻而易举,并且请求结构只在一个地方定义。

异步任务与结果轮询

有些 gemini-omni-1.2-flash 请求完成得足够快,可以内联返回结果。另一些则需要更长时间,HiAPI 会改为返回任务句柄。你的集成必须同时处理这两种情况,而异步路径正是大多数脆弱客户端崩溃的地方。

识别异步响应

异步响应包含一个任务标识符和一个状态。你得到的不是已完成的输出,而是一个承诺:工作已被接受并将被处理。你的任务是回来查看。

正确轮询

朴素的做法——在紧凑的 while True 循环中猛击状态端点——有两个坏处:它浪费你的速率限制预算,并且给平台带来不必要的负载,却不会让你更快拿到结果。

更好的模式使用带上限的间隔退避:

import time

def poll_job(job_id, base_delay=1.0, max_delay=10.0, max_wait=300.0):
    elapsed = 0.0
    delay = base_delay
    while elapsed < max_wait:
        status = get_job_status(job_id)
        if status["state"] == "succeeded":
            return status
        if status["state"] == "failed":
            raise RuntimeError(status.get("error", "job failed"))
        time.sleep(delay)
        elapsed += delay
        delay = min(delay * 2, max_delay)
    raise TimeoutError(f"job {job_id} did not finish in time")

轮询的三条规则

  • 从小开始,缓慢增长。 较短的初始间隔能以低成本捕获快速任务;加倍增长直至上限,可避免慢任务被检查得过于频繁。
  • 始终设置最长等待时间。 没有它,卡住的任务会永远挂起你的进程。抛异常的超时远好于静默挂起。
  • 区分成功、失败和待处理。 其中只有两种应停止循环,且只有一种应返回结果。

可用时优先使用 webhook

如果你的负载很重,对每个任务轮询扩展性不佳。在 HiAPI 提供完成回调的地方,使用它们来接收结果,而不是反复询问。对于交互式工具和低量脚本,带退避的轮询完全够用。

无论哪种方式,都把任务句柄当作工作的持久标识符。存储它、记录它,并用它稍后对账结果。

选择时长和分辨率

时长和分辨率是最直接影响你输出的两个参数——也影响你的账单和等待时间。两者都没有唯一正确的值;正确的选择取决于你在构建什么。重要的是你有意识地选择它们,而不是从示例中复制数字。

时长

时长控制生成输出的运行长度。更长的时长给你更多内容,但需要更多算力来生成,这既影响延迟,也影响请求如何计费(计费基于输出时长)。一些实用指导:

  • 测试时从短开始。 简短的时长能端到端证明流水线可用,而不必在每次迭代上浪费时间。
  • 让时长匹配用途。 用于预览或缩略图的短片段不需要完整交付物的长度。
  • 不要投机性地加长。 生成你实际会使用的长度;事后裁剪不会给你带来任何好处。

分辨率

分辨率控制输出保真度。更高分辨率意味着更多细节和更大的负载,并相应增加处理时间和成本。需要权衡的取舍:

  • 预览和草稿工作 不需要高分辨率——它是正确性检查,不是最终产品。
  • 最终交付物 可能值得更高的设置,尤其是当输出以完整尺寸展示时。
  • 带宽和存储 也很重要:高分辨率输出传输和保留起来都更重。

一次只调一个变量

调整参数时,一次只改一个,并与你的基线 curl 调用对比。同时改变时长和分辨率,就无法把质量、延迟或成本的变化归因于其中任何一个。维护一个小型矩阵,记录你测试过的设置及其观察到的行为。

把成本当作公式而不是数字来推理

因为定价位于站点的定价面板中,所以把成本当作一个函数:总成本随输出时长缩放,对于更高分辨率,还随最终输出大小和处理量缩放。你的工作是知道哪些参数驱动该函数,然后在承诺生产量之前查看当前定价。这样即使价格变化,你的估算也能保持正确。

常见错误及修复方法

大多数首次集成失败都可归入少数几类。按这个顺序逐项排查——每一步都依赖前一步正确,所以跳着检查会让你追逐表面症状。

1. 请求结构

症状:验证错误,或关于字段缺失或意外的消息。

修复:确认主体是有效 JSON(尾随逗号是经典罪魁祸首),确认 model 字段恰好是 gemini-omni-1.2-flash,并逐行把你的负载与可工作的 curl 示例对比。如果 curl 能工作而 Python 不能,就 diff 两个请求主体。

2. 参数

症状:报错点名 duration 或 resolution,或输出大小意外。

修复:检查类型(该是数字的地方是数字,该是字符串的地方是字符串),并检查值在可接受范围内。如果某个参数被静默忽略,确认它嵌套在 API 期望的位置,而不是放在顶层。

3. 认证

症状:401 或 403 响应。

修复:确认密钥存在于 Authorization 头中并带有 Bearer 前缀,确认环境变量确实包含值(空字符串看起来很像错误密钥),并确认你没有把周围的空白或引号复制进密钥。如果你怀疑密钥泄露,重新生成它。

4. 任务状态

症状:你轮询却永远看不到成功,或你把待处理任务当作失败。

修复:确认你在轮询正确的任务 ID,确认循环识别所有状态(pending、running、succeeded、failed),并确认最大等待时间对于现实任务足够长。记录每次状态转换,这样你能看到它卡在哪里。

5. 速率限制和瞬时故障

症状:429 响应或间歇性 5xx 错误。

修复:退避并带抖动重试,而不是立即重试。如果你在轮询许多任务,降低并发。瞬时错误是正常的;智能重试的客户端能挺过去。

一条调试纪律

当某处出错时,一次只改一个东西,并重新运行尽可能小的请求。保留原始响应体——错误消息通常会点名确切的字段或条件,仔细阅读它们比任何猜测都更省时间。

生产集成检查清单

一个在你笔记本上跑通一次的脚本不算集成。上线前,补齐这些缺口。

带退避的重试

把网络调用包装在能处理瞬时故障的重试策略中——超时、连接重置、429 和 5xx 响应。使用带抖动的指数退避,限制尝试次数,并且绝不要重试验证失败的请求;重试格式错误的主体只会更慢地再次失败。

处处设置超时

为每个 HTTP 调用设置显式超时。区分连接超时和读取超时,并确保生成请求的超时至少与真实生成所需时间一样长——但有上限。

围绕任务实现幂等

网络抖动可能发生在服务器已接受你的请求、但你还没看到响应之间。如果你盲目重试,可能会创建重复任务。为每个逻辑请求附加客户端生成的引用,这样你可以检测并复用已有任务,而不是创建新任务,并以该引用为键把任务句柄存入持久存储。

能回答问题的日志

为每个请求记录模型名称、参数值(时长、分辨率)、任务句柄、状态转换和延迟。绝不要记录 API 密钥或可能包含敏感数据的完整提示词内容。当凌晨 3 点出问题时,这些日志正是让你精确重建所发生之事的东西。

可观测性与告警

追踪请求和任务生命周期两者的成功率、按类型划分的错误分布以及端到端延迟。对持续错误率告警,而不是单次失败。把验证错误与瞬时错误分开的仪表盘能立即告诉你,你是有 bug,还是网络状况不佳。

配置卫生

把端点、模型名称和默认参数放在配置中,而不是散落在代码各处。从密钥管理器或环境变量加载 API 密钥。如果定价和限制对你的规划相关,查阅定价面板而不是硬编码数字,因为这些会变化。

把这份清单走一遍,你的 gemini-omni-1.2-flash 集成就能处理真实流量,而不只是第一次测试。从可工作的 curl 调用开始,移植到 Python,然后从那里向外构建。

立即开始构建持久 AI 产物

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

阅读 API 文档