本地模型网关 API 文档
| 项目 | 内容 |
|---|---|
| 文档版本 | v3.0 |
| 更新日期 | 2026-11-06 |
| 接口基址 | https://gw.bjgmai.com |
| 认证方式 | Bearer API Key(详见 §2) |
0. 快速接入
接入流程分三步:提交任务获取 task_id →
等待回调(或轮询)→ 下载产物。
curl -X POST https://gw.bjgmai.com/v1/tasks \
-H "Authorization: Bearer <你的key>" \
-H "Content-Type: application/json" \
-d '{
"task_type": "image",
"model": "image-generate",
"params": {"prompt": "一只青花瓷花瓶,白底", "size": "1K"},
"callback_url": "https://your-server.com/api/gateway/callback"
}'
# → {"code":0,"data":{"task_id":"a1b2c3d4-...","status":"queued",...}}
0.1 认证
所有请求均须携带 Authorization 请求头,格式如下:
Authorization: Bearer <your_api_key>
<your_api_key>
由工美负责人开通并分配,无有效期限制。如发生泄露,请立即联系工美负责人更换。
0.2 获取结果
任务执行完成后,网关会向提交时指定的 callback_url 发起
POST 请求,请求体包含 task_id、status 与
result 字段。
回调请求体的完整结构及签名验证方法见 §7。请依据 §7.1 定义的 JSON 结构实现接收端,不要依赖其他推测格式。
若不使用回调,可轮询 GET /v1/tasks/{task_id}
获取任务状态与结果。
0.3 下载产物
响应中的文件 URL 须携带 API Key 方可下载,支持请求头或查询参数两种方式。详见 §3.5.1。
1. 服务地址
所有接口均通过该基址调用,无需区分后端部署位置。
| 项目 | 值 |
|---|---|
| 接口基址 | https://gw.bjgmai.com |
1.1 模型的 server 字段
GET /v1/models 返回的每个模型含 server
字段,用于标识实际执行的计算节点。
该字段仅作信息展示,调用方无需关注,统一向上述基址提交即可,网关会自动路由。
1.2 关于响应中的文件 URL
任务响应中的文件 URL 形如
https://gw.bjgmai.com/files/...,可直接下载。详见
§3.5。
2. 认证
2.1 请求头
Authorization: Bearer <你的key>
API Key 由工美负责人按调用方单独开通,每个调用方分配独立 Key,互不通用。如需获取,请联系工美负责人开通。
2.2 验证 key
curl https://gw.bjgmai.com/v1/auth/me -H "Authorization: Bearer <你的key>"
{
"code": 0,
"data": {
"key_id": "{your_key_id}",
"bound_server": "node-a",
"capabilities": ["image", "text", "local"],
"models": ["image-generate", "text-small", "..."]
}
}
2.3 认证错误
| HTTP | code | 含义 |
|---|---|---|
| 401 | UNAUTHORIZED |
没传 key,或 key 不存在 |
| 403 | KEY_WRONG_SERVER |
该 API Key 与当前访问节点不匹配 |
| 403 | FORBIDDEN |
key 没有这个 task_type 的能力 |
3. 通用约定
3.1 时间与 ID
- 所有时间是 UTC,格式
2026-11-06T11:16:56Z task_id是 UUID v4,全局唯一,结果保留 7 天
3.2 状态机
queued ──→ running ──→ succeeded
│ │
├───────────┴──────→ failed
└──────────────────→ canceled
| 状态 | 含义 | 你该做什么 |
|---|---|---|
queued |
排队中 | 等 |
running |
执行中 | 等(progress 字段有百分比) |
succeeded |
成功 | 读 result |
failed |
失败 | 读 error.code /
error.message;retryable=true 可重试 |
canceled |
已取消 | — |
3.2.1 各类型任务典型耗时(决定你的轮询超时)
实测数据(2026-11-06):
| 模型 | 典型耗时 | 建议轮询超时 |
|---|---|---|
image-generate |
2~15 秒(缓存命中可 2 秒) | 60 秒 |
image-edit |
48 秒 | 180 秒 |
image-layered |
30 秒 | 180 秒 |
text-small / text-vision |
3~10 秒 | 60 秒 |
text-large |
32 秒(含冷加载) | 120 秒 |
music-fast |
25 秒 | 120 秒 |
music-hq |
74 秒 | 300 秒 |
voice-clone |
6 秒 | 60 秒 |
video-generate |
104 秒 | 600 秒 |
video-reference |
221 秒 | 600 秒 |
slice-3d |
79 秒 | 600 秒 |
pantone-report |
110 秒 | 300 秒 |
| 其它 local 节点 | 2~30 秒 | 120 秒 |
⚠️ 轮询超时不要设太短。 视频 221 秒、3D 切片 79 秒, 如果按 60 秒超时判断失败,将导致大量任务被误判为失败,实际仍在执行中。
建议轮询间隔 3~5 秒(§7.4 也提了)。
3.3 统一响应包
所有接口均使用统一响应外壳:
{"code": 0, "message": "ok", "data": { ... }}
失败时 code != 0:
{"code": "BAD_REQUEST", "message": "params.prompt 必填", "data": null}
3.4 幂等
同一个任务重复提交会重复执行、重复计费。
网络超时不确定是否成功时,先 GET /v1/tasks?limit=10
查最近任务,确认后再决定是否重新提交。
3.5 产物 URL 与输出目录
产物 URL 形态:
https://gw.bjgmai.com/files/{caller}/{task_type}/{model}_{task_id前8位}_{文件名}
示例:
https://gw.bjgmai.com/files/{your_caller}/image/image-generate_a1b2c3d4_img_00001_.png
其中 {caller} 为调用方标识,由工美负责人开通时分配,与
API Key 一一对应。不同调用方的产物目录相互隔离。
3.5.1 下载产物需要认证
下载产物必须携带 API Key,三种传法任选其一:
| 传法 | 适用场景 |
|---|---|
Authorization: Bearer <key> |
程序调用(推荐) |
X-Gateway-Auth: <key> |
前端无法设置 Authorization 头时 |
?key=<key> |
浏览器直接打开链接 |
# 方式一:请求头(推荐)
curl -H "Authorization: Bearer <your_api_key>" \
https://gw.bjgmai.com/files/{your_caller}/image/{filename}
# 方式二:查询参数(浏览器可直接打开)
https://gw.bjgmai.com/files/{your_caller}/image/{filename}?key=<your_api_key>
未携带 Key 或 Key 无效时返回:
HTTP 401
{"code": "UNAUTHORIZED", "message": "缺少 token:直连用 Authorization: Bearer <key>,经 nginx Basic Auth 时用 X-Gateway-Auth: <key>", "data": null}
3.5.2 下载频率限制
为防止带宽被占满,文件下载受以下限制(按来源 IP 计算):
| 限制项 | 阈值 | 超出返回 |
|---|---|---|
| 并发下载连接数 | 单 IP 最多 5 个 | HTTP 429 |
| 新建下载请求速率 | 单 IP 每秒 2 个,允许突发 10 个 | HTTP 429 |
💡 正常业务不会触发。 建议串行下载,一次下一个文件; 若需批量取产物,并发请求数不超过 5,并在批次之间留出间隔。
触发 429 后等待 1~2 秒即可恢复,不需要重新提交任务。
⚠️ 请在任务完成后及时下载并转存至自有存储(产物保留 7 天,见 §3.5.3)。 涉及敏感内容时,请勿将产物 URL 发布至公开页面、日志或截图中。
3.5.3 产物保留 7 天后会怎样?
保留期从任务创建时间算起,满 7 天由网关清理。
| 情况 | 返回 |
|---|---|
| 还没被清理 | HTTP 200,正常下载 |
| 已过期被清理 | HTTP 404,响应体是 nginx/网关的 404 页 |
💡 建议:拿到产物 URL 后立刻下载并转存到你自己的存储,不要依赖网关的 7 天。 尤其是业务系统,用户可能一个月后才回看订单。
4. 提交任务
4.1 请求
POST /v1/tasks
4.2 请求体字段
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
task_type |
string | 是 | image / video / text /
music / voice / local |
model |
string | 是 | 模型名,见 §5。只能填 §5 里列出的名字 |
params |
object | 是 | 参数,结构随 task_type 而变 |
callback_url |
string | 否 | 完成后 POST 到这里。不填就自己轮询 |
⚠️ 所有参数必须嵌在
params里。 把prompt直接放最外层会返回 422(缺params字段), 响应体是 FastAPI 的原生格式{"detail":[...]},不是网关的{"code":...}。详见 §8.3。
正确 / 错误对照:
// ✅ 正确
{"task_type":"image","model":"image-generate","params":{"prompt":"一只花瓶"}}
// ❌ 错误:prompt 放外层 → 422,缺 params
{"task_type":"image","model":"image-generate","prompt":"一只花瓶"}
4.3 响应
{
"code": 0,
"message": "ok",
"data": {
"task_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": "queued",
"task_type": "image",
"model": "image-generate",
"queue_position": 1,
"estimated_wait_sec": 120,
"created_at": "2026-11-06T11:16:56Z"
}
}
| 字段 | 说明 |
|---|---|
task_id |
任务 ID,查结果/取消都用它 |
status |
提交后固定是 queued |
queue_position |
前面还有几个任务(1 = 下一个就轮到你) |
estimated_wait_sec |
预估等待秒数(按队列估算,仅供参考) |
💡 给用户显示进度:直接拿
queue_position和estimated_wait_sec显示「前面还有 N 个任务,预计等 M 秒」, 不用自己猜。这两个字段只在queued状态有意义,开始执行后看progress(0~100)。
4.4 并发与排队
- 提交是并发的 —— 可以同时提交多个任务,不会阻塞
- 执行是串行的 —— 并发提交的任务将排队执行
- 每个 key 有
max_pending上限(默认 20),超了返回 429
| HTTP | code | 含义 |
|---|---|---|
| 429 | TOO_MANY_PENDING |
你有太多任务在排队,等几个完成再提交 |
| 429 | DAILY_QUOTA_EXCEEDED |
今日配额用完 |
5. 模型清单与参数
5.0 全部 38 个模型速查
| # | 模型名 | 类型 | 用途 | 一句话说明 |
|---|---|---|---|---|
| 1 | image-generate |
image | 文生图 | 给一句描述,出一张图 |
| 2 | image-edit |
image | 图生图 / 编辑 | 必须给输入图,按描述改图 |
| 3 | image-layered |
image | 分层生图 | 生成带图层的图,用于后期拆解 |
| 4 | text-small |
text | 纯文本对话 | 最轻,写作/改写/摘要 |
| 5 | text-vision |
text | 看图对话 | 传图 + 问它图里有什么 |
| 6 | text-large |
text | 大模型对话 | 复杂推理、长文、精细看图 |
| 7 | video-generate |
video | 文生 / 首尾帧视频 | 5 秒约 104 秒 |
| 8 | video-reference |
video | 多参考图视频 | 5 秒约 221 秒 |
| 9 | music-fast |
music | 生音乐(轻量) | 快,适合草稿 |
| 10 | music-hq |
music | 生音乐(高质量) | 慢,成品级 |
| 11 | voice-clone |
voice | 语音合成 | 指定音色把文字读出来 |
| 12 | cutout |
local | 指定目标抠图 | 按指定目标抠图,需传具体名词 |
| 13 | remove-bg |
local | 去背景 | 自动识别主体,不用传提示词 |
| 14 | upscale |
local | 超清放大 | 2/3/4 倍放大 |
| 15 | depth |
local | 深度图 | 出灰度深度图 |
| 16 | ocr |
local | 文字提取 | 把图里的字读成文本 |
| 17 | lineart |
local | 线稿提取 | 出黑白线稿 |
| 18 | normal-map |
local | 法线图 | 出法线贴图(游戏/PBR 用) |
| 19 | whitemodel |
local | 白模 | 出石膏/素模效果 |
| 20 | flat-color |
local | 平涂 | 写实图转色块化 |
| 21 | realistic |
local | 写实渲染 | 色块图转写实 |
| 22 | color-regions |
local | 色彩分区 | 按色彩区域分割 |
| 23 | color-map |
local | 颜色分布图 | 出色彩分布示意 |
| 24 | grade-cinema |
local | 电影调色 | 达芬奇风格调色 |
| 25 | style-anime |
local | 动画风格 | 新海诚风格转绘 |
| 26 | material |
local | 材质提取 | 提取表面材质纹理 |
| 27 | components |
local | 组件拆分 | 拆出图中各部件 |
| 28 | reference-color |
local | 参考配色 | 需 2 张图,按参考图配色 |
| 29 | reference-style |
local | 参考风格 | 需 2 张图,按参考图风格 |
| 30 | pantone |
local | 潘通色卡 | 标注图里的潘通色号 |
| 31 | pantone-report |
local | 潘通报告 | 出 HTML 色卡报告 |
| 32 | sellpoints |
local | 卖点文案 | 从图里提炼卖点文字 |
| 33 | reverse-prompt |
local | 反推提示词 | 看图反推一段生图提示词 |
| 34 | layers |
local | 智能分层 | 拆成多个可编辑图层 |
| 35 | model-3d-hunyuan |
local | 图生 3D | 通用型,细节表现均衡 |
| 36 | model-3d-pixal |
local | 图生 3D | 快速型,生成速度优先 |
| 37 | model-3d-trellis |
local | 图生 3D | 高精度型,适合复杂结构 |
| 38 | slice-3d |
local | 3D 切片 | 出 3D 打印 gcode |
5.1 image —— 生图 /
编辑(3 个)
| 模型 | 用途 | 最大 batch |
|---|---|---|
image-generate |
文生图 | 4 |
image-edit |
图生图 / 编辑(必须给输入图) | 4 |
image-layered |
分层生图 | 1 |
参数表
| 参数 | 类型 | 必填 | 默认 | 取值 / 范围 | 说明 |
|---|---|---|---|---|---|
prompt |
string | 是 | — | — | 正向提示词。中文可用,英文更稳 |
negative_prompt |
string | 否 | "" |
— | 反向提示词,描述【不要】出现的东西 |
images |
array | 条件 | [] |
URL / data URL | 仅 image-edit 必填,其余模型不用 |
mask |
string | 否 | — | data URL | 局部重绘蒙版,白色区域参与重绘 |
size |
string | 否 | 1K |
1K/2K/4K/WxH |
见下方详解 |
batch |
int | 否 | 1 |
1 ~ 4 | 一次生成几张。数值越大耗时越长 |
steps |
int | 否 | 8 |
1 ~ 60 | 采样步数。turbo 模型 8 步最优 |
seed |
int | 否 | 随机 | 0 ~ 2³²-1 | 固定 seed 可复现 |
⚠️
image-edit的prompt与images必须同时提供。 缺任一参数会返回 422BAD_REQUEST,错误信息中会指明缺少哪个字段。
size 取值
档位写法(推荐):
| 值 | 短边约 | 耗时 | 适用 |
|---|---|---|---|
1K |
1024 | 5~10 秒 | 草稿、预览 |
2K |
2048 | 15~25 秒 | 生产推荐 |
4K |
4096 | 40~90 秒 | 印刷级,耗时较长 |
精确像素写法: 832x1248(宽 x
高),宽高都必须 64 ~ 4096。
⚠️
image-layered例外:size只能是640或1024。 传1K/2K会返回 400。这是该模型的固定两档,不支持其它值。
调用示例
文生图:
curl -X POST https://gw.bjgmai.com/v1/tasks \
-H "Authorization: Bearer <key>" \
-H "Content-Type: application/json" \
-d '{
"task_type": "image",
"model": "image-generate",
"params": {
"prompt": "一只青花瓷花瓶,白色背景,产品摄影,柔和布光",
"negative_prompt": "模糊,低质量,水印,多余物体",
"size": "2K",
"batch": 2,
"steps": 8,
"seed": 12345
},
"callback_url": "https://your-server.com/api/gateway/callback"
}'
图生图 / 编辑(注意 images
是数组):
{
"task_type": "image",
"model": "image-edit",
"params": {
"prompt": "把背景换成纯白色,产品保持不变",
"images": ["https://your-server.com/input.jpg"],
"size": "2K"
}
}
分层生图:
{
"task_type": "image",
"model": "image-layered",
"params": {
"prompt": "一只青花瓷花瓶,白色背景",
"size": "1024"
}
}
响应结果
{
"status": "succeeded",
"result": {
"images": [
{"url": "https://gw.bjgmai.com/files/{your_caller}/image/image-generate_a1b2c3d4_img_00001_.png",
"width": 2048, "height": 2048, "seed": 12345}
],
"elapsed_sec": 18.3
}
}
batch=N 就有 N 个 url。
实测耗时
| 模型 | 场景 | 耗时 |
|---|---|---|
image-generate |
1K,8 步 | 约 15 秒 |
image-edit |
1K,8 步,1 张输入图 | 约 48 秒 |
image-layered |
1024 | 约 30 秒 |
5.2 video —— 生视频(2
个)
| 模型 | 用途 |
|---|---|
video-generate |
文生视频 / 首尾帧视频 |
video-reference |
多参考图视频 |
参数表(两个模型共用)
| 参数 | 类型 | 必填 | 默认 | 取值 / 范围 | 说明 |
|---|---|---|---|---|---|
prompt |
string | 是 | — | — | 画面描述 |
mode |
string | 否 | t2v |
t2v/i2v/flf/r2v |
生成模式,见下 |
duration |
float | 否 | 5 |
2 ~ 15 秒 | 视频时长 |
aspect |
string | 否 | 16:9 |
16:9 / 9:16 |
画面比例 |
steps |
int | 否 | 8 |
1 ~ 50 | 采样步数 |
seed |
int | 否 | 随机 | — | 固定可复现 |
use_lora |
bool | 否 | true |
— | 开 turbo LoRA,8 步出片 |
first_frame |
string | 条件 | — | URL / data URL | i2v / flf 模式必填 |
last_frame |
string | 条件 | — | URL / data URL | flf 模式必填 |
ref_images |
array | 条件 | — | 最多 2 张 | r2v 模式必填 |
四种模式
| mode | 含义 | 必填输入 | 用哪个模型 |
|---|---|---|---|
t2v |
纯文字生视频 | 只要 prompt |
video-generate |
i2v |
图生视频(首帧) | first_frame |
video-generate |
flf |
首尾帧生视频 | first_frame + last_frame |
video-generate |
r2v |
参考图生视频 | ref_images(1~2 张) |
video-reference |
⚠️
r2v必须用video-reference,其它模式必须用video-generate,不能混用。video-reference用t2v会返回 400;video-generate用r2v也会返回 400。
调用示例
文生视频:
curl -X POST https://gw.bjgmai.com/v1/tasks \
-H "Authorization: Bearer <key>" \
-H "Content-Type: application/json" \
-d '{
"task_type": "video",
"model": "video-generate",
"params": {
"prompt": "一只青花瓷花瓶在桌面上缓慢旋转,柔和光线",
"duration": 5,
"aspect": "16:9",
"seed": 12345
}
}'
首尾帧视频:
{
"task_type": "video",
"model": "video-generate",
"params": {
"mode": "flf",
"prompt": "平滑过渡,产品缓慢旋转",
"first_frame": "https://your-server.com/start.jpg",
"last_frame": "https://your-server.com/end.jpg",
"duration": 5
}
}
参考图视频:
{
"task_type": "video",
"model": "video-reference",
"params": {
"mode": "r2v",
"prompt": "花瓶缓慢旋转展示",
"ref_images": [
"https://your-server.com/ref1.jpg",
"https://your-server.com/ref2.jpg"
],
"duration": 5
}
}
ref_images传 1 张亦可执行,第 2 个参考位自动复用第 1 张。
响应结果
{
"status": "succeeded",
"result": {
"videos": [{
"url": "https://gw.bjgmai.com/files/{your_caller}/video/vid_2100469d_video-generate_00002_.mp4",
"duration": 5.0,
"width": 1344,
"height": 768,
"fps": 24,
"has_audio": true
}],
"elapsed_sec": 101.2
}
}
输出格式: MP4(h264 + aac),24 fps,自带音频轨(模型会生成环境音)。
实测耗时
| 模型 | 模式 | 时长 | 耗时 |
|---|---|---|---|
video-generate |
t2v |
5 秒 | 103.6 秒 |
video-reference |
r2v(1 张参考图) |
5 秒 | 221.4 秒 |
单卡串行执行,两个视频任务不能并行。 提交后请耐心等,
progress会在 50% 停留较久(采样阶段)。
资源说明
视频模型资源占用较高,执行视频任务期间不建议并发提交生图或 3D 任务,否则可能因资源不足导致任务失败。
5.3 text ——
文本生成 / 视觉理解(3 个)
| 模型 | 用途 | 特点 |
|---|---|---|
text-small |
纯文本对话 | 最快,不支持看图 |
text-vision |
看图对话 | 支持传图 |
text-large |
大模型对话 | 能力最强,首次调用要等加载(约 24 秒) |
参数表
| 参数 | 类型 | 必填 | 默认 | 取值 / 范围 | 说明 |
|---|---|---|---|---|---|
messages |
array | 是 | — | — | 对话数组,见下 |
messages[].role |
string | 是 | — | system / user /
assistant |
角色 |
messages[].content |
string | array | 是 | — | — | 纯文本给 string;带图给数组 |
temperature |
float | 否 | 0.7 | 0 ~ 2 | 越低越确定,越高越发散 |
max_tokens |
int | 否 | 模型默认 | — | 最多生成多少 token |
看图怎么传
content 传数组,图片用 image_url 类型:
{
"task_type": "text",
"model": "text-vision",
"params": {
"messages": [
{"role": "user", "content": [
{"type": "text", "text": "这张图里是什么器物?"},
{"type": "image_url", "image_url": {"url": "https://your-server.com/a.jpg"}}
]}
]
}
}
调用示例
curl -X POST https://gw.bjgmai.com/v1/tasks \
-H "Authorization: Bearer <key>" \
-H "Content-Type: application/json" \
-d '{
"task_type": "text",
"model": "text-small",
"params": {
"messages": [{"role": "user", "content": "用一句话介绍景泰蓝"}],
"temperature": 0.7
}
}'
响应结果
{
"status": "succeeded",
"result": {
"text": "景泰蓝,正名铜胎掐丝珐琅,是中国著名的传统手工艺品……",
"usage": {"prompt_tokens": 12, "completion_tokens": 48},
"load_duration_ms": 0,
"elapsed_sec": 2.1
}
}
load_duration_ms说明:
text-small/text-vision常驻,一般是 0text-large默认不加载,首次调用会看到 20000+ ms,之后 5 分钟内再调就是 0- 超过 5 分钟没调用,模型会释放,下次又要重新加载
实测耗时
| 模型 | 场景 | 耗时 |
|---|---|---|
text-small |
一句话提问 | 约 2 秒 |
text-vision |
看图问答 | 约 3 秒 |
text-large |
一句话提问(含冷加载) | 约 32 秒 |
5.4 music —— 生音乐 /
配乐(2 个)
| 模型 | 用途 | 特点 |
|---|---|---|
music-fast |
轻量版 | 约 25 秒出 15 秒音乐 |
music-hq |
高质量版 | 约 74 秒出 15 秒音乐 |
参数表
| 参数 | 类型 | 必填 | 默认 | 取值 / 范围 | 说明 |
|---|---|---|---|---|---|
caption |
string | 是 | — | — | 英文描述,风格/乐器/情绪写这里 |
duration |
float | 否 | 15 | 5 ~ 300 秒 | 音乐时长 |
batch |
int | 否 | 1 |
1 ~ 4 | 一次生成几首 |
bpm |
int | 否 | 模型默认 | 20 ~ 300 | 速度 |
seed |
int | 否 | 随机 | — | 固定可复现 |
⚠️
caption中不得出现vocal/vocals词汇。 就算写no vocals也会被判定为要人声,直接 400 拒绝。 需纯器乐时,prompt 中不得出现人声相关词汇,仅描述乐器。
错误示例(会被拒):
"gentle piano, no vocals" ← 含 vocals,400
"instrumental, without vocal" ← 含 vocal,400
正确示例:
"gentle piano melody, soft and warm, cinematic instrumental background music"
调用示例
curl -X POST https://gw.bjgmai.com/v1/tasks \
-H "Authorization: Bearer <key>" \
-H "Content-Type: application/json" \
-d '{
"task_type": "music",
"model": "music-hq",
"params": {
"caption": "gentle piano melody, soft and warm, cinematic instrumental background music",
"duration": 15
}
}'
响应结果
{
"status": "succeeded",
"result": {
"audios": [{
"url": "https://gw.bjgmai.com/files/{your_caller}/music/bgm_a0a108d0_bgm.wav",
"duration": 15.0,
"sample_rate": 48000,
"format": "wav",
"size": 2880044
}],
"elapsed_sec": 71.6
}
}
输出格式: WAV,48kHz 立体声。15 秒约 2.8 MB。
实测耗时
| 模型 | 时长 | 耗时 |
|---|---|---|
music-fast |
15 秒 | 约 25 秒 |
music-hq |
15 秒 | 约 74 秒 |
5.5 voice —— 语音合成(1
个)
| 模型 | 用途 |
|---|---|
voice-clone |
零样本音色复刻 |
参数表
| 参数 | 类型 | 必填 | 默认 | 取值 / 范围 | 说明 |
|---|---|---|---|---|---|
text |
string | 是 | — | ≤ 3000 字 | 要读出来的文字 |
ref |
string | 二选一 | — | 预置音色名称 | 使用平台预置音色 |
ref_audio |
string | 二选一 | — | URL / data URL | 传自己的一段音频做音色 |
speed |
float | 否 | 1.0 | 0.5 ~ 2.0 | 语速倍率 |
⚠️
ref和ref_audio必须给且只能给一个。 都不给或都给都返回 400。
预置音色列表
| 音色名 | 时长 | 采样率 |
|---|---|---|
clone_1 |
4.2 秒 | 16 kHz |
clone_2 |
8.08 秒 | 24 kHz(默认) |
调用示例
使用预置音色:
curl -X POST https://gw.bjgmai.com/v1/tasks \
-H "Authorization: Bearer <key>" \
-H "Content-Type: application/json" \
-d '{
"task_type": "voice",
"model": "voice-clone",
"params": {
"text": "这是一段语音合成的测试文本。",
"ref": "clone_2",
"speed": 1.0
}
}'
用自己传的音频复刻:
{
"task_type": "voice",
"model": "voice-clone",
"params": {
"text": "这是一段语音合成的测试文本。",
"ref_audio": "https://your-server.com/my-voice.wav"
}
}
响应结果
{
"status": "succeeded",
"result": {
"audios": [{
"url": "https://gw.bjgmai.com/files/{your_caller}/voice/tts_6b002e0e_tts.wav",
"duration": 4.96,
"sample_rate": 24000,
"format": "wav",
"size": 238124
}],
"elapsed_sec": 3.9
}
}
实测耗时
| 场景 | 耗时 |
|---|---|
28 字文本,clone_2 |
约 6 秒(音频 4.96 秒) |
5.6 local ——
本地化节点(27 个)
这是最复杂的一类:27 个模型,输入输出形态各不相同。
5.6.0 通用规则(必读)
请求结构:
{
"task_type": "local",
"model": "<模型名>",
"params": {
"image": "图片(必填)",
"image2": "第二张图(仅 reference-color / reference-style)",
"prompt": "提示词(仅 cutout / pantone-report)",
"options": {"节点专属参数": "见各模型说明"}
}
}
三个标准输入位:
| 键 | 说明 |
|---|---|
image |
所有 local 模型必填,主输入图 |
image2 |
仅 reference-color / reference-style
需要 |
prompt |
仅 cutout / pantone-report 用到 |
⚠️ 除这三个键以外,其它参数必须放进
params.options。 放外层不会报错,但会被忽略——看起来成功了,实际参数没生效。
图片怎么传(三种都行):
- HTTP(S) URL:
"https://your-server.com/a.jpg" - data URL:
"data:image/png;base64,iVBORw0KGgo..." - 网关可访问的文件路径
输出形态分 5 类:
| 形态 | 返回结构 | 模型 |
|---|---|---|
| 图片 | {"images":[{"url":"..."}]} |
20 个 |
| 文本 | {"text":"..."} |
3 个(ocr / sellpoints /
reverse-prompt) |
| HTML 报告 | {"url":"...","groups":{}} |
pantone-report |
| 多图层 | {"layers":[],"files":[{"name","url"}]} |
layers |
| 3D 文件 | {"files":[{"name","url"}]} |
model-3d-* / slice-3d |
只有 4 个模型有专属 options:
| 模型 | options |
|---|---|
depth |
model: small / base /
large |
upscale |
scale:
2/3/4;model:
real/anime;target:
4k/8k/浮点 |
slice-3d |
bed_x / bed_y /
bed_z(打印床尺寸 mm) |
| 其余 23 个 | 不接受任何 options |
5.5.1 抠图 / 去背景(2 个)
cutout ——
指定目标抠图(提示词应传具体名词)
用途: 按你指定的目标抠图,输出透明背景 PNG。
| 参数 | 必填 | 默认 | 说明 |
|---|---|---|---|
image |
是 | — | 输入图 |
prompt |
建议必传 | object |
要抠的目标。中文可用(「花瓶」「瓶子」「人物」「瓶耳」) |
⚠️
prompt必须是图里真实存在的具体名词。不传时默认使用
object(泛称),模型通常无法定位到具体物体,任务会失败并返回no object found。请务必传入具体名词,不要使用「产品」「物品」「东西」等泛称。
{"task_type":"local","model":"cutout","params":{"image":"https://.../a.jpg","prompt":"花瓶"}}
返回:
images[0].transparent = true,PNG 带 alpha 通道。
实测: 2048×2048 图,0.6 秒。找不到目标时报
failed,错误信息 no object found。
prompt 写法参考:
| 想抠的内容 | 推荐写法 |
|---|---|
| 整件器物 | 花瓶、茶壶、瓷盘 |
| 器物某部位 | 瓶耳、把手、瓶口、底座 |
| 人物 | 人物、模特、人像 |
| 图案纹样 | 花纹、图案、纹饰 |
cutout和remove-bg怎么选:
你的情况 用哪个 传 prompt 吗 白底/纯色底,图里就一个主体 remove-bg不用 背景复杂,或图里多个物体只要其中一个 cutout要传 想抠某个具体部件(瓶耳、底座) cutout要传
remove-bg ——
自动去背景(不用提示词)
用途: 自动识别画面主体,去掉背景,输出透明背景 PNG。
适用场景: 白底、浅色底、纯色底的产品图 —— 适用于单主体图片,抠图效果最佳。
| 参数 | 必填 | 说明 |
|---|---|---|
image |
是 | 输入图 |
prompt |
不接受 | 传了也会被忽略 |
{"task_type":"local","model":"remove-bg","params":{"image":"https://.../a.jpg"}}
返回:
{
"images": [{
"url": "http://.../remove-bg_xxxxxxxx_out.png",
"transparent": true,
"meta": {"engine": "birefnet", "seconds": 3.01}
}]
}
实测(2048×2048 白底花瓶): 透明区 81.12%,主体保留 18.60%,边缘无白边无断裂,耗时 2~3 秒。
⚠️ 小尺寸图片边缘精度下降。 实测 256×256 输入时过渡带宽 5.99%,2048×2048 时为 0.27%。 建议输入不小于 512×512,或先用
upscale放大再抠。
5.5.2 图像增强(4 个)
upscale —— 超清放大
用途: 2/3/4 倍分辨率放大,保留细节。
| 参数 | 必填 | 默认 | 取值 | 说明 |
|---|---|---|---|---|
image |
是 | — | — | 输入图 |
options.scale |
否 | 4 |
2 / 3 / 4 |
放大倍数 |
options.model |
否 | real |
real / anime |
real 适合实拍/产品,anime 适合二次元 |
options.target |
否 | — | 4k / 8k / 浮点数 |
目标长边像素,给了就按这个算倍数 |
{
"task_type": "local",
"model": "upscale",
"params": {
"image": "https://.../a.jpg",
"options": {"scale": 4, "model": "real"}
}
}
实测: 6.3 秒(2048 → 8192)。
⚠️ 放大倍数过高可能导致处理失败。4 倍 + 2048 输入 = 8192 输出,已接近处理上限。
depth —— 深度图
用途: 出灰度深度图,用于做 3D 或景深效果。
| 参数 | 必填 | 默认 | 取值 | 说明 |
|---|---|---|---|---|
image |
是 | — | — | 输入图 |
options.model |
否 | small |
small / base / large |
精度档位,越大越准也越慢 |
{
"task_type": "local",
"model": "depth",
"params": {"image": "https://.../a.jpg", "options": {"model": "large"}}
}
实测耗时:
| 档位 | 耗时 |
|---|---|
small |
0.30 秒 |
large |
1.34 秒 |
返回 meta: model /
inference_seconds / postprocess_ms /
stats
lineart —— 线稿提取
用途: 出黑白线稿,用于做填色图或矢量化的基础。
| 参数 | 必填 | 说明 |
|---|---|---|
image |
是 | 输入图 |
{"task_type":"local","model":"lineart","params":{"image":"https://.../a.jpg"}}
实测: 约 27 秒。
normal-map —— 法线图
用途: 出切线空间法线贴图,游戏引擎 / PBR 材质用。
| 参数 | 必填 | 说明 |
|---|---|---|
image |
是 | 输入图 |
{"task_type":"local","model":"normal-map","params":{"image":"https://.../a.jpg"}}
输出: RGB 法线图,R=X、G=Y、B=Z,蓝色通道主导。
5.5.3 图像转换(6 个)
whitemodel —— 白模
用途: 出石膏/素模效果,用于看造型结构。
{"task_type":"local","model":"whitemodel","params":{"image":"https://.../a.jpg"}}
flat-color ——
平涂(色块化)
用途: 写实图转色块化,用于做填色图底稿。
{"task_type":"local","model":"flat-color","params":{"image":"https://.../a.jpg"}}
realistic —— 写实渲染
用途: 色块图 / 线稿转写实效果。
{"task_type":"local","model":"realistic","params":{"image":"https://.../a.jpg"}}
color-regions ——
色彩分区
用途: 按色彩区域分割,便于做配色分析或分层上色。
{"task_type":"local","model":"color-regions","params":{"image":"https://.../a.jpg"}}
color-map —— 颜色分布图
用途: 出色彩分布示意图,看主色占比。
{"task_type":"local","model":"color-map","params":{"image":"https://.../a.jpg"}}
grade-cinema ——
电影调色
用途: 达芬奇风格电影调色。
{"task_type":"local","model":"grade-cinema","params":{"image":"https://.../a.jpg"}}
5.5.4 风格 / 材质 / 拆解(4 个)
style-anime —— 动画风格
用途: 新海诚风格转绘。
{"task_type":"local","model":"style-anime","params":{"image":"https://.../a.jpg"}}
实测: 约 30 秒。
material —— 材质提取
用途: 从图里提取表面材质纹理(如磨砂铝面、釉面),去色去光留纹理。
{"task_type":"local","model":"material","params":{"image":"https://.../a.jpg"}}
components —— 组件拆分
用途: 拆出图中各部件(瓶身、瓶盖、把手…),各自成图。
{"task_type":"local","model":"components","params":{"image":"https://.../a.jpg"}}
layers —— 智能分层
用途: 拆成多个可编辑图层,输出多个 PNG。
{"task_type":"local","model":"layers","params":{"image":"https://.../a.jpg"}}
返回:
{
"layers": [{"name": "主体", "index": 0}, {"name": "背景", "index": 1}],
"files": [
{"name": "layers_xxxxxxxx_00.png", "url": "http://.../..."},
{"name": "layers_xxxxxxxx_01.png", "url": "http://.../..."}
]
}
实测: 约 27 秒,出 5 个文件。
5.5.5 参考迁移(2 个,需要 2 张图)
reference-color ——
参考配色迁移
用途: 把图 2 的配色方案搬到图 1 上,保持图 1 的形状结构。
| 参数 | 必填 | 说明 |
|---|---|---|
image |
是 | 底图(要改配色的那张) |
image2 |
是 | 参考图(提供配色) |
{
"task_type": "local",
"model": "reference-color",
"params": {
"image": "https://.../product.jpg",
"image2": "https://.../reference.jpg"
}
}
reference-style ——
参考风格迁移
用途: 把图 2 的画面风格搬到图 1 上。
| 参数 | 必填 | 说明 |
|---|---|---|
image |
是 | 底图 |
image2 |
是 | 参考图(提供风格) |
{
"task_type": "local",
"model": "reference-style",
"params": {
"image": "https://.../product.jpg",
"image2": "https://.../style-ref.jpg"
}
}
5.5.6 潘通色卡(2 个)
pantone —— 潘通色卡匹配
用途: 分析图里的主要颜色,标注最接近的潘通色号。
不需要 prompt。
{"task_type":"local","model":"pantone","params":{"image":"https://.../a.jpg"}}
pantone-report ——
潘通色卡报告(HTML)
用途: 出完整的 HTML 色卡报告,含色块、色号、占比、中文颜色名。
| 参数 | 必填 | 默认 | 说明 |
|---|---|---|---|
image |
是 | — | 输入图 |
prompt |
否 | object |
主体名称,用于聚焦分析范围(如「花瓶」) |
{
"task_type": "local",
"model": "pantone-report",
"params": {"image": "https://.../a.jpg", "prompt": "花瓶"}
}
返回:
{
"groups": {"主色": [...], "辅色": [...]},
"url": "http://.../pantone-report_xxxxxxxx_report.html",
"elapsed_sec": 108.2
}
实测: 约 110 秒(含抠图与自动命名环节)。
5.5.7 文本类(3 个)
ocr —— 文字提取
用途: 把图里的文字读成文本。
| 参数 | 必填 | 说明 |
|---|---|---|
image |
是 | 输入图 |
{"task_type":"local","model":"ocr","params":{"image":"https://.../a.jpg"}}
返回:
{"text": "识别出的全部文字"}
sellpoints ——
卖点文案提取
用途: 看图提炼产品卖点文字。
| 参数 | 必填 | 说明 |
|---|---|---|
image |
是 | 输入图 |
{"task_type":"local","model":"sellpoints","params":{"image":"https://.../a.jpg"}}
返回: {"text": "..."}
reverse-prompt ——
反推提示词
用途: 看图反推一段可直接用于生图的提示词。
| 参数 | 必填 | 说明 |
|---|---|---|
image |
是 | 输入图 |
{"task_type":"local","model":"reverse-prompt","params":{"image":"https://.../a.jpg"}}
返回:
{"text": "一段完整的英文提示词"}
5.5.8 3D 生成(3 个)
三个模型来自三家不同厂商,接口名各不相同,参数通用。
| 参数 | 必填 | 说明 |
|---|---|---|
image |
是 | 输入图(单张产品图) |
model-3d-hunyuan
—— 图生 3D(通用型)
{"task_type":"local","model":"model-3d-hunyuan","params":{"image":"https://.../a.jpg"}}
model-3d-pixal ——
图生 3D(快速型)
需要 MoGe 估算视野角(FOV),对透视要求较严。
{"task_type":"local","model":"model-3d-pixal","params":{"image":"https://.../a.jpg"}}
model-3d-trellis
—— 图生 3D(高精度型)
{"task_type":"local","model":"model-3d-trellis","params":{"image":"https://.../a.jpg"}}
三个模型的返回格式相同:
{
"files": [
{"name": "model_xxxxxxxx.glb", "url": "http://.../..."}
]
}
实测耗时:
| 模型 | 耗时 |
|---|---|
model-3d-hunyuan |
数分钟 |
model-3d-pixal |
数分钟 |
model-3d-trellis |
数分钟 |
⚠️ 3D 生成资源占用最高,同一时间仅可执行一个任务。
5.5.9 3D 切片(1 个)
slice-3d —— 3D 打印切片
用途: 把模型修复为封闭实体(manifold)→ 缩放居中 → 切片,输出可直接打印的 3MF(内含 gcode)。
| 参数 | 必填 | 默认 | 说明 |
|---|---|---|---|
image |
是 | — | 输入 3D 模型(.stl / .glb / .obj / .3mf),URL 或 base64,不接受本地路径 |
options.bed_x |
否 | 256 | 打印床宽 mm |
options.bed_y |
否 | 256 | 打印床深 mm |
options.bed_z |
否 | 100 | 打印床高 mm(注意默认 100,不是 256) |
⚠️ 必须用
params.image,不能只传options。 传 URL 即可,网关会自己下载。 ⚠️bed_z默认 100mm,模型高度超过 100mm 又没显式指定bed_z的话,会被判定超出打印区。
{
"task_type": "local",
"model": "slice-3d",
"params": {
"image": "https://your-server.com/model.stl",
"options": {"bed_x": 256, "bed_y": 256, "bed_z": 256}
}
}
返回: 两个产物,.stl
是修复后的模型,.3mf 是切片结果(内含
gcode,可直接导入常见切片软件打印)。
{
"files": [
{"name": "xxx_print.stl", "url": "..."},
{"name": "xxx_print.3mf", "url": "..."}
]
}
实测: 25.77 MB 的 STL(515,386 面,243mm)→ 78.6 秒,产出 8.56 MB 的 3MF, 内含 18.5 MB gcode(819,332 行),预计打印 1 小时 59 分。
行为说明:
| 情况 | 处理 |
|---|---|
| 模型本来就健康(水密+单体) | 跳过体素重建,直接用原网格(重建反而会把它变坏) |
| 模型坏了 | 迭代体素重建,选面数最多的水密候选 |
| 模型比床小 | 保持原尺寸,不放大(之前会硬放大到床的 95%,导致切片越界) |
| 模型比床大 | 等比缩小到床的 85%,留出 skirt/边缘补偿 |
6. 查询任务
6.1 单条查询
GET /v1/tasks/{task_id}
响应:
{
"code": 0,
"data": {
"task_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"task_type": "image",
"model": "image-generate",
"status": "succeeded",
"progress": 100,
"created_at": "2026-11-06T11:16:56Z",
"started_at": "2026-11-06T11:16:57Z",
"finished_at": "2026-11-06T11:17:15Z",
"elapsed_sec": 18.3,
"result": {
"images": [{"url": "http://..."}]
},
"error": null,
"callback_status": "sent"
}
}
progress 字段:
0~100。running 时会给个估计值,仅供展示,不是精确进度。
callback_status:
| 值 | 含义 |
|---|---|
pending |
还没发 |
sent |
已成功 POST 到你的 callback_url |
failed |
POST 失败(你的服务没响应或返回非 2xx) |
null |
未设置 callback_url |
6.2 列表查询
GET /v1/tasks?status=succeeded&limit=20&offset=0&model=image-generate
| 参数 | 默认 | 说明 |
|---|---|---|
status |
全部 | 过滤状态 |
task_type |
全部 | 过滤类型 |
model |
全部 | 过滤模型 |
limit |
20 | 1~100 |
offset |
0 | 分页 |
响应(字段名是 items,不是
tasks):
{
"code": 0,
"message": "ok",
"data": {
"total": 128,
"limit": 20,
"offset": 0,
"items": [
{
"task_id": "a1b2c3d4-...",
"task_type": "image",
"model": "image-generate",
"status": "succeeded",
"created_at": "2026-11-06T11:16:56Z",
"finished_at": "2026-11-06T11:17:11Z"
}
]
}
}
| 字段 | 说明 |
|---|---|
total |
符合条件的总条数(用于算总页数) |
limit / offset |
回显你传的分页参数 |
items |
任务数组在这里(不是 tasks) |
列表按创建时间倒序,服务端分页,不要拉全量。 算总页数:
ceil(total / limit)。
6.3 取消任务
DELETE /v1/tasks/{task_id}
只能取消 queued 状态的任务。已经 running
的取消不了(会返回 409)。
7. 回调(推荐)
7.1 回调请求
任务完成后,网关 POST 到你提交时给的 callback_url:
{
"task_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": "succeeded",
"task_type": "image",
"model": "image-generate",
"result": {
"images": [{"url": "https://gw.bjgmai.com/files/{your_caller}/image/..."}]
},
"error": null
}
请求头:
Content-Type: application/json
7.2 你的回调端点必须这样实现
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.post("/api/gateway/callback")
def callback():
data = request.json
task_id = data["task_id"]
status = data["status"]
if status == "succeeded":
urls = [img["url"] for img in data["result"].get("images", [])]
# 下载产物并落库
save_result(task_id, urls)
else:
mark_failed(task_id, data.get("error"))
# ⚠️ 须在此回调中立即返回 200
return jsonify({"ok": True}), 200
⚠️ 接收端实现注意事项:
- 响应超时 2 秒 — 接收端须在 2 秒内返回 HTTP 200,超时视为回调失败
- 须实现幂等 — 网关在回调失败时会重试,同一
task_id可能被投递多次- 先响应后处理 — 应先返回 200,再将文件下载、数据入库等耗时操作交由后台队列处理,避免同步阻塞
7.3 回调签名
回调请求携带 HMAC-SHA256 签名,接收端须完成验签,否则网关返回 401。
请求头
Content-Type: application/json
X-Gateway-Signature: sha256=<HMAC-SHA256(原始 body, 共享密钥)>
验签要点
| 要点 | 说明 |
|---|---|
| 用原始 body | 不能用解析后的数组。JSON 字段顺序/空格/转义在序列化后会变,拿不到逐字节一致的就验不过 |
| sha256= 前缀 | 签名值前面带 sha256=,比较时别漏 |
| 常量时间比较 | 用 hash_equals /
hmac.compare_digest,不要用 == |
| 时间戳防重放 | 时间偏差超过 5 分钟视为重放,拒绝 |
验证方法
# 不带签名,应返回 401
curl -X POST https://your-server.com/api/gateway/callback \
-H "Content-Type: application/json" -d '{"ping":1}'
# → {"code":401,"message":"invalid signature"}
密钥配置要点
回调签名密钥由工美负责人与接收方各自配置,两端的密钥必须完全一致。
⚠️ 更换密钥时须两端同步更换。 若仅更换一端,所有回调将被 401 拒绝, 任务状态将停留在「网关已完成、接收方未知」状态。
7.4 回调 vs 轮询
| 回调 | 轮询 | |
|---|---|---|
| 实时性 | 完成即通知 | 取决于轮询间隔 |
| 服务器压力 | 低 | 高(每次都打接口) |
| 实现复杂度 | 要开公网端点 | 简单 |
| 适合 | 生产环境 | 调试、内网 |
推荐:生产用回调。 调试阶段想省事就轮询,间隔 3~5 秒。
8. 错误码
8.1 提交时(同步返回)
| HTTP | code | 含义 | 怎么改 |
|---|---|---|---|
| 400 | BAD_REQUEST |
参数值不合法 | 看 message,会指明哪个字段 |
| 422 | detail[](无 code) |
请求体结构错,通常是缺 params |
见 §8.3 情况 A |
| 422 | MODEL_NOT_AVAILABLE |
模型名不在 §5 里 | 见 §8.3 情况 B |
| 401 | UNAUTHORIZED |
key 无效 | 检查 key |
| 403 | FORBIDDEN |
该 Key 未开通此能力 | 联系工美负责人开通权限 |
| 403 | KEY_WRONG_SERVER |
API Key 与访问节点不匹配 | 使用工美负责人分配的对应 Key |
| 404 | MODEL_NOT_FOUND |
模型名不存在 | 查 §5 的模型名 |
| 429 | TOO_MANY_PENDING |
排队任务太多 | 等几个完成再提交 |
| 429 | DAILY_QUOTA_EXCEEDED |
今日配额用完 | 明天再试 |
| 500 | INTERNAL |
网关内部错误 | 重试;持续报错请联系工美负责人 |
8.2 执行时(任务变 failed)
| error.code | 含义 | retryable | 怎么改 |
|---|---|---|---|
MODEL_ERROR |
模型执行失败 | 通常 true |
重试;持续失败说明输入有问题 |
TIMEOUT |
执行超时 | true |
降低 size / batch / steps |
INPUT_INVALID |
输入图读不了 | false |
检查图片 URL 是否能访问、格式是否支持 |
NO_OUTPUT |
模型跑完但没产物 | true |
重试 |
retryable=true 就重试,false
改了再重试。
8.3 两种 422 的区分方式
HTTP 状态码都是 422,但响应体格式完全不同,调用方要分开处理:
情况 A:请求体结构错(缺
params)
HTTP 422
{
"detail": [
{
"type": "missing",
"loc": ["body", "params"],
"msg": "Field required",
"input": {"task_type": "image", "model": "image-generate", "prompt": "test"}
}
]
}
没有 code 字段,是数组
detail。 这是 FastAPI
原生校验拦下的,说明请求体形状不对。
常见触发:
- 忘了
params params传成了字符串而不是对象task_type/model完全没传
情况 B:模型名不对
HTTP 422
{
"code": "MODEL_NOT_AVAILABLE",
"message": "未知模型 不存在的模型",
"data": null
}
有 code 字段,是网关自己的格式。
说明请求体结构对,但模型名不在 §5 里。
怎么统一处理
if resp.status == 422:
body = resp.json()
if "detail" in body:
# 情况 A:结构错,看 loc 指出哪个字段缺
fields = [d["loc"][-1] for d in body["detail"]]
raise ValueError(f"请求体缺字段: {fields}")
else:
# 情况 B:模型名错
raise ValueError(f"模型不存在: {body.get('message')}")
判断口诀:有
detail是请求体形状错,有code是模型名错。
9. 错误信息速查
| 你看到的 message | 原因 | 怎么改 |
|---|---|---|
params.prompt 必填 |
没传 prompt | 补上 |
size 格式不对:1024 |
用了不支持的写法 | 用 1K/2K/4K 或
832x1248 |
image-layered 的 size 只能是 640 或 1024 |
该模型只有两档 | 改 640 或 1024 |
image-edit 必须给 params.images |
编辑没给图 | 加 params.images: [url] |
params.image 必填 |
local 模型没给图 | 加 params.image |
reference-color 需要 params.image2 |
缺参考图 | 加 params.image2 |
cutout 失败 ... no object found |
没找到 prompt 指定的目标 | 换个词,或改用 remove-bg |
caption 里有正向人声词 |
caption 含 vocal | 删掉那个词 |
params.caption 必填 |
音乐没给 caption | 加英文描述 |
没有音色 xxx,可用:['clone_1','clone_2'] |
音色名写错 | 用 clone_1 / clone_2 |
video-reference 只能用于 r2v 模式 |
模式错 | 见 §13 |
TOO_MANY_PENDING |
排太多 | 等 |
Field required +
loc: ["body","params"] |
忘了传 params | 加 params: {...} |
未知模型 xxx |
模型名写错 | 查 §5 的模型名 |
10. 模型发现
GET /v1/models
响应:
{
"code": 0,
"data": {
"server": "node-a",
"capabilities": ["image", "text", "local"],
"models": [
{
"model": "image-generate",
"task_type": "image",
"display_name": "图像生成(标准)",
"max_batch": 4,
"supported_sizes": ["1K", "2K"],
"default_timeout_sec": 300,
"server": "node-a,node-b"
}
]
}
}
display_name只是给人看的,不要用它当model参数。 后台升级模型时display_name可能变,model名不变。
11. 健康检查
GET /v1/health
不需要 key。
{
"code": 0,
"data": {
"status": "ok",
"server": "node-a",
"queue": {"queued": 2, "running": 1, "succeeded": 1523, "failed": 8},
"uptime_sec": 86400
}
}
接入方建议每 30
秒探一次,status != "ok" 就告警。
12. 完整接入示例(Python)
import json
import time
import urllib.request
import urllib.error
BASE = "https://gw.bjgmai.com"
KEY = "你的key"
def api(path, method="GET", body=None, timeout=900):
data = json.dumps(body).encode() if body else None
req = urllib.request.Request(
BASE + path, data=data, method=method,
headers={"Content-Type": "application/json",
"Authorization": "Bearer " + KEY})
try:
with urllib.request.urlopen(req, timeout=timeout) as r:
return json.loads(r.read().decode())
except urllib.error.HTTPError as e:
body = e.read().decode(errors="replace")
raise RuntimeError(f"HTTP {e.code}: {body}")
def submit_and_wait(task_type, model, params, max_wait=900):
"""提交任务并轮询到完成"""
resp = api("/v1/tasks", "POST", {
"task_type": task_type,
"model": model,
"params": params,
})
if resp.get("code") != 0:
raise RuntimeError(resp.get("message"))
task_id = resp["data"]["task_id"]
print(f"已提交 {task_id}")
deadline = time.time() + max_wait
while time.time() < deadline:
time.sleep(3)
d = api(f"/v1/tasks/{task_id}")["data"]
st = d["status"]
if st == "succeeded":
return d["result"]
if st == "failed":
raise RuntimeError(f"任务失败: {d.get('error')}")
print(f" {st} {d.get('progress', 0)}%")
raise TimeoutError(f"等了 {max_wait} 秒还没完成")
# ── 例子 1:生图 ──
result = submit_and_wait("image", "image-generate", {
"prompt": "一只青花瓷花瓶,白色背景,产品摄影",
"size": "1K",
})
for img in result["images"]:
print("图片:", img["url"])
# ── 例子 2:去背景 ──
result = submit_and_wait("local", "remove-bg", {
"image": "https://your-server.com/product.jpg",
})
print("透明图:", result["images"][0]["url"])
# ── 例子 3:抠图(要提示词)──
result = submit_and_wait("local", "cutout", {
"image": "https://your-server.com/product.jpg",
"prompt": "花瓶",
})
print("抠图:", result["images"][0]["url"])
# ── 例子 4:看图问答 ──
result = submit_and_wait("text", "text-vision", {
"messages": [{
"role": "user",
"content": [
{"type": "text", "text": "这张图里是什么器物?"},
{"type": "image_url",
"image_url": {"url": "https://your-server.com/a.jpg"}}
]
}]
})
print("回答:", result["text"])
# ── 例子 5:生音乐 ──
result = submit_and_wait("music", "music-hq", {
"caption": "gentle piano melody, soft and warm, instrumental",
"duration": 15,
})
print("音乐:", result["audios"][0]["url"])
13. 模型验收状态
全部 38 个模型已通过端到端验收。验收标准为「实际执行任务并取得产物」,而非「接口返回 200」。
| 类型 | 数量 | 状态 |
|---|---|---|
| image | 3 | ✅ 全部通过 |
| video | 2 | ✅ 全部通过 |
| text | 3 | ✅ 全部通过 |
| music | 2 | ✅ 全部通过 |
| voice | 1 | ✅ 全部通过 |
| local | 27 | ✅ 全部通过 |
14. 版本与兼容
14.1 当前版本
- API 版本:v1
- 文档版本:v3.0(2026-11-06)
14.2 变更记录
| 日期 | 变更 |
|---|---|
| 2026-11-06 | 模型命名规范调整,统一为按能力命名 |
| 2026-11-05 | 接口架构统一,全部模型经由同一入口提供服务 |
| 2026-11-04 | 引入异步任务 + 回调模式 |
| 2026-11-02 | API v1 初版 |
14.3 兼容性承诺
model名不会因为后台升级而变。 例如image-generate底层从 A 模型换到 B 模型,接口名不变- 已有的必填参数不会变可选、可选参数不会变必填
- 破坏性变更会提前 2 周通知
- 新增模型只增不改,不影响已有调用
15. 技术支持
| 问题类型 | 找谁 |
|---|---|
| Key 开通、配额、权限 | 工美负责人 |
| 接口报错、结果异常 | 附上 task_id 联系工美负责人 |
| 新增模型需求 | 联系工美负责人 |
报问题时请附:
task_id- 你发的完整请求体(去掉 key)
- 返回的完整响应(含
error) - 大概什么时间提的