媒体 Schema 机制
通过 /v2/media-tool-configs 获取各模型的媒体工具参数 Schema,客户端据此动态生成表单,并用 sidecar 完成强校验调用。
设计意图
不同图像/视频模型的参数差异极大:尺寸枚举、画质档位、参考图数量、厂商特有字段各不相同。 传统做法是客户端硬编码每个模型的参数表单,模型一多就无法维护。
积木的解法是把参数 Schema 作为平台数据下发:
- 平台为每个媒体模型维护一份工具参数 Schema(
input_schema),按模型实时更新 - 客户端调用
GET /v2/media-tool-configs拉取当前令牌可用模型的 Schema - 客户端按 Schema 动态渲染表单(必填项、枚举下拉、数值范围、正则校验都由 Schema 描述)
- 提交媒体请求时携带 sidecar(
jimu_media_tool),网关按同一份 Schema 做服务端强校验
这样新模型上架、参数调整都不需要客户端发版。
获取媒体工具配置
/v2/media-tool-configsmodelstring可选。筛选指定模型,可重复(?model=a&model=b)或逗号分隔(?model=a,b)。不传则返回当前令牌可用且有媒体配置的全部模型
只返回当前令牌有权访问、已启用媒体能力且配置有效的模型,其余自动省略。
响应结构
{
"success": true,
"data": [
{
"model": "g-image-2",
"revision": "3273a2a67e0e639a9ba9f5dc65f9f637d3e4348dc78e64af58a71667a50a41ac",
"tools": {
"jimu_image_generation": {
"provider": "openai",
"input_schema": {
"type": "OBJECT",
"properties": { ... },
"required": ["prompt"],
"additionalProperties": false
}
}
},
"image_fields": {
"jimu_image_generation": [
{ "name": "image_uris", "array": true }
]
}
}
]
}
modelstring模型 ID
revisionstring该模型当前工具配置的 SHA-256。配置变化时 revision 必然变化,客户端据此判断是否需要刷新表单
toolsobject工具名 → 工具配置。工具名为 jimu_image_generation(图像)或 jimu_video_generation(视频)
tools.*.providerstring请求协议(视频工具不支持 open_responses)
openai · gemini · open_responsestools.*.input_schemaobject参数 Schema(JSON object),描述该模型支持的参数全集
image_fieldsobject与 tools 同级的可选字段,指出各工具中哪些参数承载图片输入。仅当 Schema 声明了图片输入字段时出现,不参与 revision 计算
image_fields.*[].namestring承载图片输入的属性名
image_fields.*[].arrayboolean该字段是否接受图片数组。为 false 时表示承载单张图片的标量字段,需要多张时填写多个此类字段
provider 决定入口路径
provider 不只是一个标记,它决定了你必须从哪条路径发请求。
服务端按「路径 + 工具名」匹配 provider,只有匹配上的组合才会走 sidecar 校验与原样透传;
路径与 provider 不匹配时 sidecar 不生效,请求会按普通请求处理。
| provider | 工具 | 可用入口路径 |
|---|---|---|
openai | jimu_image_generation | /v1/chat/completions、/v1/completions、/v1/images/generations、/v1/images/edits、/v1/edits |
gemini | jimu_image_generation | /v1beta/models/{模型}:generateContent、/v1beta/models/{模型}:streamGenerateContent |
| 不限 | jimu_video_generation | /v1/video/generations、/v1/videos |
用 Schema 动态生成表单
input_schema 遵循一套受控的 JSON Schema 子集:
- 根节点
type语义上必须是 object;匹配大小写不敏感,响应字面量可能是OBJECT也可能是object - 支持七种语义类型:object、array、string、number、integer、boolean、null——同样不保证响应中的大小写形式
properties中每个参数必带非空description(可直接用作表单 label/帮助文案)required数组列出必填参数,其余均为可选- 约束关键字:
enum(枚举值)、pattern(正则)、minimum/maximum、maxLength、items(数组元素定义) - 支持
anyOf/oneOf/allOf嵌套,不含$ref - 未显式声明
additionalProperties时按false处理——不要提交 Schema 之外的字段
type 前必须先做大小写归一。 Schema 校验大小写不敏感,本接口又原样回传存储的 Schema,
因此同一语义类型可能以 OBJECT 或 object 返回,取决于配置当初是怎么存的。
严格比对 OBJECT 的客户端会在配置存为 object 时失败——请先统一转小写(或转大写)再匹配。真实示例:g-image-2
以下为生产环境实测返回(节选关键属性):
{
"model": "g-image-2",
"revision": "3273a2a67e0e639a9ba9f5dc65f9f637d3e4348dc78e64af58a71667a50a41ac",
"tools": {
"jimu_image_generation": {
"provider": "openai",
"input_schema": {
"type": "OBJECT",
"required": ["prompt"],
"additionalProperties": false,
"properties": {
"prompt": {
"type": "STRING",
"description": "The desired image description. Maximum 32000 characters for GPT image models.",
"maxLength": 32000
},
"size": {
"type": "STRING",
"description": "Use auto or WIDTHxHEIGHT. For gpt-image-2 both dimensions must be divisible by 16, aspect ratio must be between 1:3 and 3:1, and the maximum is 3840x2160.",
"pattern": "^(auto|[1-9][0-9]*x[1-9][0-9]*)$"
},
"quality": {
"type": "STRING",
"description": "The generated image quality. Defaults to auto.",
"enum": ["low", "medium", "high", "auto"]
},
"image_uris": {
"type": "ARRAY",
"description": "Optional reference images for editing. Maximum 10 images.",
"items": { "type": "STRING", "description": "A local image file path or an HTTP/HTTPS image URL." }
}
}
}
}
}
}
声明图片输入字段
Schema 的属性名直接采用上游原生协议的字段名,中间没有翻译层。因此「参考图」 这一语义在不同模型上的字段名并不统一,平台上同时存在三种形态:
| 形态 | 字段名 | 示例模型 |
|---|---|---|
| 数组 | image_uris | g-image-2 |
| 数组(另一种命名) | reference_images | nova-g-image-2 |
| 多个独立标量 | input_image、input_image_2 … input_image_8 | flux-2-pro、flux-2-max |
客户端需要把用户选择的本地图片转成 base64 再填回这些字段,因此必须知道哪些属性
承载图片输入。字段名无法穷举上游的命名空间,所以由 Schema 在 description 中
显式标记:
| 标记 | 含义 |
|---|---|
[jimu:image] | 该字段承载图片输入 |
[jimu:image:array] | 显式声明为图片数组(通常不必写,是否为数组由 type 推导) |
[jimu:image:single] | 显式声明为单张图片 |
配置示例:
"input_image": {
"type": "STRING",
"description": "[jimu:image] The input image used as a generation or editing reference."
}
平台的处理保证:
- 标记在下发前会从
description中剥除,客户端与模型看到的描述是干净的; - 标记的增删不改变
revision,不会导致已有客户端出现 revision 失配; - 图片字段清单以
image_fields顶层字段下发,与tools同级——它不进入input_schema,因此不改变 Schema 的 JSON 结构,也不参与revision计算。
响应中的形态:
{
"model": "flux-2-pro",
"revision": "50d7f31b...",
"tools": { "jimu_image_generation": { "provider": "openai", "input_schema": {} } },
"image_fields": {
"jimu_image_generation": [
{ "name": "input_image", "array": false },
{ "name": "input_image_2", "array": false }
]
}
}
每项含 name(属性名)与 array。array 为 false 表示这是承载单张图片的标量
字段,需要传多张时填写多个这样的字段;标量字段按名称排序下发,
input_image → input_image_2 → input_image_3 的顺序是稳定的。
image_fields 中,客户端也就不会把本地路径转成
base64,而是把原始路径字符串直接发给上游,导致上游 base64 解码失败
(如 Incorrect padding)或静默忽略该参数。为图片字段配置 Schema 时务必检查标记。/v1/images/edits)会拒绝
携带 sidecar 的请求。因此参考图必须以 HTTP(S) URL 或 base64 data URI 通过 JSON 下发。控件映射建议
| Schema 特征 | 建议控件 |
|---|---|
STRING + enum | 下拉选择 |
STRING + pattern / maxLength | 文本输入 + 前端校验 |
STRING 无约束(如 prompt) | 多行文本域 |
INTEGER / NUMBER + minimum/maximum | 数字输入或滑块 |
BOOLEAN | 开关 |
ARRAY + items | 多值输入(如多图上传/URL 列表) |
参数在 required 中 | 标记必填并做提交前校验 |
客户端应缓存 revision:启动时或发现 revision 变化时重新拉取 Schema 并重建表单,
避免平台侧更新参数后客户端还在提交旧字段。
Sidecar 运行时契约
对配置了 Schema 的模型,媒体请求(如 /v1/images/generations)顶层可携带
jimu_media_tool sidecar,让网关执行严格校验:
{
"model": "g-image-2",
"prompt": "一座雪山下的湖泊,清晨光线",
"size": "1536x864",
"quality": "high",
"jimu_media_tool": {
"name": "jimu_image_generation",
"revision": "3273a2a67e0e639a9ba9f5dc65f9f637d3e4348dc78e64af58a71667a50a41ac",
"arguments": {
"prompt": "一座雪山下的湖泊,清晨光线",
"size": "1536x864",
"quality": "high"
}
}
}
运行时规则(务必逐条遵守):
revision必须与当前配置一致,不一致直接在请求上游前返回 HTTP 400arguments中的字段必须全部在 Schema 中声明,且通过全部约束校验- 请求顶层的同名媒体参数必须与
arguments中的值 JSON 等值(两边都传且一致) - 校验通过后网关删除
jimu_media_tool再转发,上游永远不会看到 sidecar - 经 Schema 校验的请求不做跨渠道重试,失败直接返回
- 反过来,已配置 Schema 的模型必须携带 sidecar:请求缺少
jimu_media_tool时直接返回 HTTP 400(jimu_media_tool is required for model <模型名>),不会按宽松模式放行 - 只有未配置 Schema 的模型才能不带 sidecar 调用;对这类模型携带 sidecar 同样会 400
(
media tool schema is not configured for model <模型名>) - sidecar 仅支持 JSON 请求体入口。multipart 端点(
/v1/images/edits)不接受jimu_media_tool,已配置 Schema 的模型因此无法经 multipart 链路调用
Additional property n is not allowed)。
这同时意味着接这类模型前必须先从 /v2/media-tool-configs 拉到实时 Schema——
Schema 声明的参数集合可能与模型的通用文档不同(例如 g-image-2 的 Schema 不含 n、stream)。完整调用示例
# 1. 拉取 Schema
curl "https://api.jimu.chat/v2/media-tool-configs?model=g-image-2" \
-H "Authorization: Bearer $JIMU_API_KEY"
# 2. 携带 sidecar 提交(revision 替换为上一步的返回值)
curl https://api.jimu.chat/v1/images/generations \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $JIMU_API_KEY" \
-d '{
"model": "g-image-2",
"prompt": "一座雪山下的湖泊,清晨光线",
"size": "1536x864",
"quality": "high",
"jimu_media_tool": {
"name": "jimu_image_generation",
"revision": "<上一步返回的 revision>",
"arguments": {
"prompt": "一座雪山下的湖泊,清晨光线",
"size": "1536x864",
"quality": "high"
}
}
}'
管理侧说明
媒体 Schema 由平台管理员在模型管理中维护(media_tool_configs 字段),
没有独立的公开写接口。普通接入方只需要读 /v2/media-tool-configs 并遵守 sidecar 契约。