本页目录(7 节)

图片生成 Provider

Spark Work 图片生成 Provider:图片 API 源与 imageApiType 字段、9 个内置图片预设、spark_image MCP 工具与 spark_media 统一栈的双链路判定、产物输出目录与 7 类渠道的参数归一规则。

阅读约 6 分钟最后核对 2026-06-29

图片生成有两条链路:旧的 spark_image(单 Provider、单工具、只生图)与统一的 spark_media(多 Provider 路由、覆盖生图 / 编辑 / 语音 / 视频)。二者的取舍规则 是确定的:只要能解析出统一媒体配置,就只注入 spark_media;spark_image 是兜底,不是主力。这篇讲清楚两条链路各管什么、字段怎么落、参数怎么被 归一。

1. 配置步骤与真实选项

  1. 打开 设置 → Provider,新建或编辑一条 Provider。
  2. 模型类型选生图模型(存储字面量 image)。 图片专属字段只有 modelType=image 时才会写入。
  3. 选图片 API 源。表单里是下面 9 个选项,括号内是真实枚举值、默认端点与默认调用方式:
    界面标签imageProvider默认端点默认 imageApiType
    OpenAI Imagesopenaihttps://api.openai.com/v1sync
    APIMartapimarthttps://api.apimart.ai/v1async
    OpenRouteropenrouterhttps://openrouter.ai/api/v1sync
    Gemini / Imagengeminihttps://generativelanguage.googleapis.com/v1betasync
    火山方舟 Seedream / Seedanceseeddancehttps://ark.cn-beijing.volces.com/api/v3sync
    阿里百炼bailianhttps://dashscope.aliyuncs.com/api/v1/services/aigcasync
    智谱 GLM Imagezhipuhttps://open.bigmodel.cn/api/paas/v4sync
    xAI Imaginexaihttps://api.x.ai/v1sync
    自定义兼容接口custom(空,自己填)sync
  4. 填 Model ID 与 API Key,保存。

注意枚举拼写:是 seeddance 而不是 seedance。保存时 Spark 会做兼容归一,seedance / volcengine 也会被映射成 volcengine-ark, 但表单与预设写的是 seeddance。

内置的生图预设共 9 条:openai-images(OpenAI,gpt-image-2)、apimart-images(APIMart,gpt-image-2)、xai-imagine-image(xAI, grok-imagine-image-quality)、bailian-images(阿里云百炼,wan2.7-image-pro)、volcengine-seedream-image(火山方舟,doubao-seedream-5-0-pro-260628)、google-gemini-images(Google Gemini,gemini-3.1-flash-image)、midjourney-gateway(Midjourney 网关,需改自建网关地址)、minimax-image(MiniMax 图片,image-01)、tencent-tokenhub-image(腾讯云,hy-image-v3.0)。

2. 运行时链路:spark_image 与 spark_media 的分界

每一轮对话开始时,Spark 按固定顺序解析:

1. resolveMediaGenerationContext()
     聚合所有 enabled 且凭据可用的图片 / 语音 / 视频 Provider
     → 有结果:注入 spark_media(14 个工具),不再注入 spark_image
2. 只有当上一步返回 null 时,才调用 resolveImageGenerationContext()
     找第一条 modelType=image 且凭据可用的 Provider
     → 注入 spark_image,只暴露 mcp__spark_image__generate_image

也就是说:一个 Provider 同时能生图、语音、视频时,图片请求也走 spark_media。 只有「配了图片 Provider 但统一媒体栈解析不出任何可用配置」这种旧环境,才会落到 spark_image。

两条链路的差异:

spark_mediaspark_image
工具14 个(生图 / 编辑 / 语音 / 视频 / 文件 / 任务)1 个(generate_image)
Provider 范围所有 enabled 的 image / voice / video Provider,可混用第一条可用的 image Provider
模型选择靠 model(selectionKey / manifest id / 模型 id)路由固定用该 Provider 的默认模型
产物目录.spark-artifacts/media/{images,audio,videos,text}.spark-artifacts/images
能力11 个统一能力仅文生图

图片编辑 / 变体 / 语音 / 视频不在 spark_image 的能力范围里,请看 多媒体 Provider。

3. spark_image 工具

注入时通过环境变量把配置传进本地 stdio 子进程:

SPARK_IMAGE_API_KEY      Provider 的 API Key(只在子进程里)
SPARK_IMAGE_MODEL        默认模型 id
SPARK_IMAGE_PROVIDER     imageProvider 值,缺省 openai
SPARK_IMAGE_API_TYPE     sync | async | auto,缺省 sync
SPARK_IMAGE_BASE_URL     仅当 Provider 配了 apiEndpoint 时传
SPARK_IMAGE_OUTPUT_DIR   固定为 <workspace>/.spark-artifacts/images

工具 mcp__spark_image__generate_image 的参数:

参数类型说明
promptstring(必填)详细提示词
sizestring像素尺寸或宽高比,如 1024x1024、1:1、16:9,也接受语义值 portrait / landscape / square
ninteger 1~4生成数量,默认 1,超出会被夹到 4
filenamestring输出文件名,不要带路径
extraJsonobject渠道私有参数

执行细节:

  • 默认尺寸 1024x1024;同步请求超时 10 分钟;异步轮询间隔 5 秒,轮询 GET {baseUrl}/tasks/{taskId}。
  • 结果解析会遍历整个响应体,抓 url / image_url / imageUrl、 data:image/*;base64, 以及长度大于 64 的 b64_json / base64, 按内容去重后下载落盘。
  • 默认文件名形如 img_<时间戳>_<随机串>;一次生成多张时会在基础名后追加 _001 这类三位序号,再拼扩展名。
  • 返回结构:{ success, provider, mode, files, urls },其中 provider 形如 apimart/gpt-image-2。只有配置了 URL 前缀时 urls 才会是外链,否则与 files 相同(都是本地路径)——应用当前不注入该 前缀变量,所以默认拿到本地路径。
  • Agent 侧 system prompt 要求:成功后必须调用 mcp__spark_files__present_files 把本地 图片文件交给应用渲染预览;返回纯 URL 不算完成;失败时不要自动重试,要报错并建议 调整模型 / 提示词 / 尺寸 / Provider 配置。

4. 各渠道参数归一

size 会按渠道被改写成该渠道真正接受的字段,这是最容易踩坑的地方:

imageProvider提交路径size / 比例处理
openai/images/generations比例映射成像素尺寸:1:1→1024x1024、3:2/16:9→1536x1024、2:3/3:4/9:16→1024x1536
xai/images/generations删除 size(xAI 会报 Argument not supported: size),比例改写成 aspect_ratio
apimart/images/generations,异步比例或尺寸原样传递
bailian同步 /multimodal-generation/generation;异步 /image-generation/generation(带 X-DashScope-Async: enable)用星号尺寸(1:1→1280*1280、3:4→1104*1472、4:3→1472*1104、9:16→960*1696、16:9→1696*960);body 改写成 input.messages + parameters
openrouter/chat/completions比例写进 image_config.aspect_ratio;body 是 chat 格式并带 modalities(默认 ["image","text"])
gemini / seeddance / zhipu/images/generations把 aspect_ratio 与 aspectRatio 同时写进 extraJson
custom/images/generations比例或尺寸原样传递,其余靠 extraJson

5. Provider 选择规则

spark_image 自动挑选 Provider 的条件,四条缺一不可:

  1. enabled = 1;
  2. config_json.modelType === "image";
  3. 有 keystore_ref,且能真的从密钥库里解出非空 API Key;
  4. 默认模型(defaultModel,回退 model)非空。

命中条件时取「第一条」。查询语句是 SELECT * FROM provider_profiles LIMIT 1000,没有 ORDER BY, 实际就是数据库自然顺序(通常是创建顺序)。所以想固定用哪条,最简单的做法是只保留一条可用的 图片 Provider。

选择过程不检查健康状态:不会去 ping 渠道。只要字段齐全就会注入,真实失败会在第一次 调用时暴露。

6. 与统一媒体栈的字段同步

保存 modelType=image 的 Provider 时,Spark 会同步三个统一字段:

imageProvider写回的 mediaProvider
openai / openai-compatibleopenai-compatible
apimart / xai / bailian / custom原值
seeddance / seedance / volcenginevolcengine-ark
gemini / googlegoogle-generative-ai
其它(如 zhipu、openrouter)custom 兜底

mediaApiType 取 imageApiType 的归一值;mediaCapabilities 保证至少包含 image.generate。运行时解析统一媒体配置时,遇到未知 mediaProvider 也会兜底成 openai-compatible。

7. 常见问题排查

现象排查
会话里没有图片生成工具先确认是否已有可用的统一媒体 Provider(有的话只会出现 spark_media,这是预期行为)。若两套都没有,逐条对照第 5 节的四个条件。
「测试连接」失败,但图片能生成正常。测试连接发的是文本 ping(OpenAI 兼容 /chat/completions),纯生图渠道通常没有 chat 端点。
xAI 报 Argument not supported: size说明 size 被透传了。走 spark_image 时会自动改写为 aspect_ratio;如果你自己拼 HTTP 请求,请只传 aspect_ratio + resolution。
异步渠道报「没有图片也没有 task id」渠道返回体结构与预期不符。代码按 task_id / taskId / job_id / jobId / request_id / requestId / id 顺序找任务号;都没有就只能报错。
图片生成成功但界面没有预览Agent 需要在成功后调用 mcp__spark_files__present_files 把本地文件交给应用。
想要图片编辑 / 变体 / 多图合成spark_image 只做文生图,配置统一媒体 Provider 后用 spark_media 的 generate_image / edit_image。

速查表

图片 API 源
openai / apimart / openrouter / gemini / seeddance / bailian / zhipu / xai / custom(注意是 seeddance)
调用方式
sync / async / auto(缺省 sync)
内建生图预设
9 条:openai-images、apimart-images、xai-imagine-image、bailian-images、volcengine-seedream-image、google-gemini-images、midjourney-gateway、minimax-image、tencent-tokenhub-image
spark_image 工具
mcp__spark_image__generate_image(参数:prompt、size、n 1-4、filename、extraJson)
spark_image 产物目录
<workspace>/.spark-artifacts/images
超时
同步 10 分钟;异步轮询间隔 5 秒
imageProvider → mediaProvider
openai→openai-compatible · seeddance/seedance/volcengine→volcengine-ark · gemini/google→google-generative-ai · 其它→custom

常见问题

展开 5 条常见问题
  • 图片生成到底走 spark_image 还是 spark_media?

    只要能解析出可用的统一媒体配置,就只注入 spark_media(图片也走它);spark_image 仅在统一媒体栈解析为空时作为兜底注入,避免两个工具争抢模型选择。

  • 图片模型和文本模型有什么区别?

    modelType=image 时会多写 imageProvider 与 imageApiType 两个字段,并把它们同步到 mediaProvider / mediaApiType / mediaCapabilities(至少含 image.generate)。非图片模型会清掉图片专属字段。

  • 生成的图存在哪里?

    spark_image 是 <workspace>/.spark-artifacts/images;spark_media 是 <workspace>/.spark-artifacts/media/images。落盘目录会被写进仓库本地忽略。

  • 可以同时挂多个图片 Provider 吗?

    可以。spark_media 会把所有可用 Provider 聚合起来,用 model 参数路由;但走旧的 spark_image 时只会取第一条满足条件的 Provider(数据库自然顺序,通常是创建顺序),且不检查健康状态。

  • 为什么「测试连接」通不过?

    测试连接发的是文本协议 ping(/chat/completions 或 Anthropic messages),不校验图片端点。纯生图渠道没有 chat 端点会失败,这不代表图片功能不可用。