第 14 章 · 图像生成与多模态输入
本章目标:
- 掌握
generateImage生成图像的基本用法与尺寸/宽高比设置- 学会批量生成、指定 seed、providerOptions 等高级配置
- 了解
wrapImageModel图像模型中间件与错误处理- 掌握
uploadFile上传文件并通过ProviderReference引用的机制- 理解多 provider 场景下的文件引用合并策略
14.1 用 generateImage 生成图像
AI SDK 提供 generateImage 函数,基于给定 prompt 使用 image model 生成图像。
import { generateImage, createGateway } from 'ai';
import 'dotenv/config';
const gateway = createGateway({ apiKey: process.env.AI_GATEWAY_API_KEY ?? '' });
// 字符串模型 ID 会经全局默认 provider(AI Gateway)解析;
// 自定义 OpenAI 兼容 provider 可用 myProvider.image('your-image-model')
const { image } = await generateImage({
model: gateway.image('openai/dall-e-3'),
prompt: 'Santa Claus driving a Cadillac',
});你可以通过 base64 或 uint8Array 属性访问图像数据:
const base64 = image.base64; // base64 图像数据
const uint8Array = image.uint8Array; // Uint8Array 二进制数据14.2 基础设置
尺寸(Size)与宽高比(Aspect Ratio)
根据模型不同,你可以指定 size 或 aspect ratio。size 以 {width}x{height} 格式的字符串表示——模型仅支持少数几种尺寸,且不同模型和 provider 各不相同:
import { generateImage } from 'ai';
import 'dotenv/config';
const { image } = await generateImage({
model: 'openai/dall-e-3',
prompt: 'Santa Claus driving a Cadillac',
size: '1024x1024',
});aspect ratio 则以 {width}:{height} 格式表示,同样只有部分取值可用:
import { generateImage } from 'ai';
import 'dotenv/config';
const { image } = await generateImage({
model: 'openai/dall-e-3',
prompt: 'Santa Claus driving a Cadillac',
aspectRatio: '16:9',
});批量生成多张图
generateImage 支持一次生成多张图像:
import { generateImage } from 'ai';
import 'dotenv/config';
const { images } = await generateImage({
model: 'openai/dall-e-3',
prompt: 'Santa Claus driving a Cadillac',
n: 4, // number of images to generate
});generateImage 会自动按需(并行)调用模型以生成请求数量的图像。每个 image model 对单次 API 调用能生成的图片数有内部上限,SDK 会自动合理分批(例如 DALL-E 3 单次只能生成 1 张,DALL-E 2 单次最多 10 张)。
如有需要,可通过 maxImagesPerCall 覆盖默认批量大小——这对新增或自定义模型尤其有用:
const { images } = await generateImage({
model: 'openai/dall-e-2',
prompt: 'Santa Claus driving a Cadillac',
maxImagesPerCall: 5, // Override the default batch size
n: 10, // Will make 2 calls of 5 images each
});指定 Seed
提供 seed 可以控制图像生成的输出。如果模型支持,相同 seed 总是产出相同图像:
import { generateImage } from 'ai';
import 'dotenv/config';
const { image } = await generateImage({
model: 'openai/dall-e-3',
prompt: 'Santa Claus driving a Cadillac',
seed: 1234567890,
});Provider 专属设置
image model 通常有 provider 甚至模型专属的设置,通过 providerOptions 参数传入即可(选项会成为请求体属性)。下面的示例沿用官方文档中 OpenAI 的写法展示 providerOptions 的结构:
import { generateImage, createGateway } from 'ai';
import 'dotenv/config';
const gateway = createGateway({ apiKey: process.env.AI_GATEWAY_API_KEY ?? '' });
const { image } = await generateImage({
model: gateway.image('openai/dall-e-3'),
prompt: 'Santa Claus driving a Cadillac',
size: '1024x1024',
providerOptions: {
openai: {
style: 'vivid',
quality: 'hd',
},
},
});中止信号与超时
generateImage 接受可选的 AbortSignal 类型 abortSignal 参数,可用于中止图像生成或设置超时:
import { generateImage } from 'ai';
import 'dotenv/config';
const { image } = await generateImage({
model: 'openai/dall-e-3',
prompt: 'Santa Claus driving a Cadillac',
abortSignal: AbortSignal.timeout(1000), // Abort after 1 second
});自定义 Headers 与警告
可选的 headers 参数(类型 Record<string, string>)可为图像生成请求添加自定义 header;若模型返回警告(例如不支持的参数),可在结果的 warnings 属性中获取:
const { image, warnings } = await generateImage({
model: 'openai/dall-e-3',
prompt: 'Santa Claus driving a Cadillac',
});Provider 附加元数据
一些 provider 会在结果整体或每张图上暴露额外的元数据。返回的 providerMetadata 外层键是 provider 名,内层是元数据;其中总有一个 images 键,是与顶层 images 数组等长的数组:
const prompt = 'Santa Claus driving a Cadillac';
const { image, providerMetadata } = await generateImage({
model: 'openai/dall-e-3',
prompt,
});
const revisedPrompt = providerMetadata.openai.images[0]?.revisedPrompt;
console.log({
prompt,
revisedPrompt,
});14.3 错误处理
当 generateImage 无法生成有效图像时,会抛出 AI_NoImageGeneratedError。该错误的可能原因:模型未能生成响应,或生成了无法解析的响应。
错误对象保留了以下信息便于记录问题:responses(图像模型响应元数据,含时间戳、模型、headers)和 cause(根因,可用于更细粒度的错误处理):
import { generateImage, NoImageGeneratedError } from 'ai';
try {
await generateImage({ model: 'openai/dall-e-3', prompt: 'A futuristic city' });
} catch (error) {
if (NoImageGeneratedError.isInstance(error)) {
console.log('NoImageGeneratedError');
console.log('Cause:', error.cause);
console.log('Responses:', error.responses);
}
}14.4 图像中间件(Image Middleware)
可以使用 wrapImageModel 和 ImageModelV4Middleware 增强 image model,比如设置默认值或实现日志。下面是一个在未提供 size 时设置默认值的示例:
import { generateImage, wrapImageModel, createGateway } from 'ai';
import 'dotenv/config';
const gateway = createGateway({ apiKey: process.env.AI_GATEWAY_API_KEY ?? '' });
const model = wrapImageModel({
model: gateway.image('openai/dall-e-3'),
middleware: {
specificationVersion: 'v3',
transformParams: async ({ params }) => ({
...params,
size: params.size ?? '1024x1024',
}),
},
});
const { image } = await generateImage({
model,
prompt: 'Santa Claus driving a Cadillac',
});14.5 用语言模型生成图像
一些语言模型(如 Google gemini-2.5-flash-image)支持包含图像的多模态输出。使用这类模型时,可以通过响应的 files 属性访问生成的图像:
import { generateText, createGateway } from 'ai';
import 'dotenv/config';
const gateway = createGateway({ apiKey: process.env.AI_GATEWAY_API_KEY ?? '' });
const result = await generateText({
model: gateway('google/gemini-2.5-flash-image'),
prompt: 'Generate an image of a comic cat',
});
for (const file of result.files) {
if (file.mediaType.startsWith('image/')) {
// The file object provides multiple data formats:
// Access images as base64 string, Uint8Array binary data, or check type
// - file.base64: string (data URL format)
// - file.uint8Array: Uint8Array (binary data)
// - file.mediaType: string (e.g. "image/png")
}
}官方文档维护了各 provider 的 image models 及其支持尺寸/宽高比的清单(xAI Grok、OpenAI gpt-image-2/dall-e 系列、Amazon Nova Canvas、Fal FLUX 系列、Google Gemini Image、Black Forest Labs flux-kontext 等),详见 Image Generation 页面的 Image Models 表格。
14.6 文件上传(File Uploads)
AI SDK 提供 uploadFile 函数,把文件上传到 provider 并拿回一个 ProviderReference 用于后续 API 调用。
在 AI SDK 中,上传后的文件由一个 ProviderReference 标识——它是把 provider 名映射到 provider 专属标识符的 Record<string, string>。这一概念也用于其他 provider 专属资源引用(如已上传的 skills):
import { uploadFile, generateText, createGateway } from 'ai';
import fs from 'node:fs';
import 'dotenv/config';
const gateway = createGateway({ apiKey: process.env.AI_GATEWAY_API_KEY ?? '' });
const { providerReference } = await uploadFile({
api: gateway,
data: fs.readFileSync('./photo.png'),
filename: 'photo.png',
});
const { text } = await generateText({
model: gateway('openai/gpt-5'),
messages: [
{
role: 'user',
content: [
{ type: 'text', text: 'Describe what you see in this image.' },
{ type: 'file', mediaType: 'image', data: providerReference },
],
},
],
});作为简写,可以直接把 provider 实例传给 api 而不必显式调用 .files()——SDK 会替你调用:
const { providerReference } = await uploadFile({
api: gateway, // shorthand for gateway.files()
data: fs.readFileSync('./photo.png'),
filename: 'photo.png',
});支持的文件类型
依据 provider 的不同,可以上传图片、PDF、文本文件和其他文档。未显式指定时会从文件字节自动探测 media type:
const { providerReference } = await uploadFile({
api: gateway,
data: fs.readFileSync('./document.pdf'),
mediaType: 'application/pdf', // optional, auto-detected if omitted
filename: 'document.pdf',
});在文件 content part 中使用 providerReference 时带上 media type:
{
role: 'user',
content: [
{ type: 'text', text: 'Summarize this document.' },
{ type: 'file', data: providerReference, mediaType: 'application/pdf' },
],
}Provider 专属选项
一些 provider 通过 providerOptions 接受额外选项,例如 OpenAI 要求 purpose 字段:
const { providerReference } = await uploadFile({
api: gateway,
data: fs.readFileSync('./photo.png'),
providerOptions: {
openai: {
purpose: 'assistants',
},
},
});Provider References 的结构
ProviderReference 是把 provider 名映射到 provider 专属文件标识的 Record<string, string>:
// Example ProviderReference
{
openai: 'file-abc123',
}当把 ProviderReference 作为消息 content part 的 data 或 image 字段传入时,当前 provider 会从中查找自己的文件 ID;如果引用里没有当前 provider 的条目,就会抛出错误。
多 Provider 使用
如果在对话中途切换 provider(比如把 OpenAI 开启的对话续接到 Anthropic),需要把文件上传到两个 provider 并合并引用:
const openaiResult = await uploadFile({
api: gateway,
data: imageBytes,
filename: 'photo.png',
});
const anthropicResult = await uploadFile({
api: gateway,
data: imageBytes,
filename: 'photo.png',
});
const mergedProviderReference = {
...openaiResult.providerReference,
...anthropicResult.providerReference,
};这样合并后的引用对两个 provider 都有效——这也正是「同一份文件跨网关与自定义 provider 复用」的关键技巧。
本章小结
generateImage是图像生成的统一入口,支持size/aspectRatio/n/seed/abortSignal/headers;- 多图生成由 SDK 自动并行分批,
maxImagesPerCall可覆盖单次调用上限; - provider 专属参数与元数据分别走
providerOptions与providerMetadata; - 失败抛出
NoImageGeneratedError,用isInstance判定并读取cause/responses; wrapImageModel可以给 image model 加中间件(如默认尺寸);支持图像输出的语言模型通过result.files取图;uploadFile返回ProviderReference(provider 名 → 文件 ID 的映射),跨 provider 复用时需上传到各 provider 后合并引用。
🛠️ 动手实践
- 用
generateImage分别以size: '1024x1024'与aspectRatio: '16:9'各生成一张图,把uint8Array写入本地 png 文件并对比效果。 - 实现「同 prompt + 同 seed 两次调用结果一致」的验证脚本;再尝试
n: 3批量生成并打印images.length。 - 编写脚本:上传一张本地 PDF 到 AI Gateway,然后用文件 content part 发起
generateText让模型总结内容;再把返回的providerReference打印出来观察其键值结构。