Skip to content

多模态

概述

多模态(Multimodal)是指 AI 模型能够同时处理和生成多种类型的媒体——文本、图片、音频等。AI SDK 提供了一整套多模态 API:generateImage 用于生成图片,generateSpeech 用于文本转语音,transcribe 用于语音转文字,同时还支持在对话消息中发送图片和音频让模型理解分析。

前端类比

多模态 API 类似于前端中的 Media API 家族。就像浏览器提供 Canvas API 处理图片、Web Audio API 处理音频、MediaRecorder 录制媒体一样,AI SDK 通过统一的函数签名提供了对图片、语音的生成和分析能力。每个函数都遵循相同的模式:传入 model + 输入内容,返回结果。

AI SDK 原生语义generateSpeechtranscribe 目前还是实验性 API(需要通过 experimental_generateSpeechexperimental_transcribe 导入),接口可能在未来版本中调整。generateImage 已经是稳定 API。

图片生成:generateImage

使用 generateImage 根据文本提示生成图片:

🔗 generateImage API 参考

typescript
import { generateImage } from 'ai'
import { openai } from '@ai-sdk/openai'

const { images } = await generateImage({
  model: openai.image('dall-e-3'),
  prompt: '一只戴着程序员眼镜在电脑前写代码的猫,像素风格',
  size: '1024x1024',
})

// images 是一个数组,包含生成的图片数据
const image = images[0]
console.log(image) // 包含图片的 base64 数据或 URL

生成多张图片

typescript
import { generateImage } from 'ai'
import { openai } from '@ai-sdk/openai'

const { images } = await generateImage({
  model: openai.image('dall-e-3'),
  prompt: '日落时分的城市天际线,赛博朋克风格',
  n: 3, // 生成 3 张
  size: '1024x1024',
})

images.forEach((image, index) => {
  console.log(`图片 ${index + 1} 已生成`)
})

常用参数

参数类型说明
modelImageModelV3图片模型,如 openai.image('dall-e-3')
promptstring图片描述提示词
nnumber生成图片数量
sizestring图片尺寸,如 '1024x1024'
aspectRatiostring宽高比,如 '16:9'
seednumber随机种子,用于可复现的生成

语音合成:generateSpeech

使用 generateSpeech(实验性 API)将文本转换为语音音频:

🔗 generateSpeech API 参考

typescript
import { experimental_generateSpeech as generateSpeech } from 'ai'
import { openai } from '@ai-sdk/openai'

const { audio } = await generateSpeech({
  model: openai.speech('tts-1'),
  text: '你好,欢迎使用 AI SDK!这是一段由 AI 生成的语音。',
  voice: 'alloy',
})

// audio 是 Uint8Array 格式的音频数据
console.log(`音频大小: ${audio.length} bytes`)

可用声音和参数

typescript
import { experimental_generateSpeech as generateSpeech } from 'ai'
import { openai } from '@ai-sdk/openai'
import { writeFile } from 'fs/promises'

const { audio } = await generateSpeech({
  model: openai.speech('tts-1'),
  text: '这是一段演示文本。',
  voice: 'nova', // 可选: alloy, echo, fable, onyx, nova, shimmer
  outputFormat: 'mp3', // 输出格式: mp3, wav 等
  speed: 1.0, // 语速: 0.25 - 4.0
})

// 保存为音频文件
await writeFile('output.mp3', Buffer.from(audio))
console.log('音频已保存为 output.mp3')

语音转文字:transcribe

使用 transcribe(实验性 API)将音频文件转换为文本:

🔗 transcribe API 参考

typescript
import { experimental_transcribe as transcribe } from 'ai'
import { openai } from '@ai-sdk/openai'
import { readFile } from 'fs/promises'

const { text, segments, language, durationInSeconds } = await transcribe({
  model: openai.transcription('whisper-1'),
  audio: await readFile('meeting-recording.mp3'),
})

console.log(`语言: ${language}`) // "zh"
console.log(`时长: ${durationInSeconds} 秒`)
console.log(`转录文本: ${text}`)

// segments 包含带时间戳的分段信息
segments?.forEach((segment) => {
  console.log(
    `[${segment.startSecond}s - ${segment.endSecond}s] ${segment.text}`
  )
})

从 URL 转录

typescript
import { experimental_transcribe as transcribe } from 'ai'
import { openai } from '@ai-sdk/openai'

const { text } = await transcribe({
  model: openai.transcription('whisper-1'),
  audio: new URL('https://example.com/audio/recording.mp3'),
})

console.log(text)

多模态提示:在消息中发送图片

许多模型(如 GPT-4o、Claude 3.5)支持直接在对话中发送图片,让模型"看懂"图片内容:

通过 URL 发送图片

typescript
import { generateText } from 'ai'
import { openai } from '@ai-sdk/openai'

const { text } = await generateText({
  model: openai('gpt-4o'),
  messages: [
    {
      role: 'user',
      content: [
        { type: 'text', text: '描述这张图片的内容。' },
        {
          type: 'file',
          mediaType: 'image/png',
          url: 'https://example.com/photo.png',
        },
      ],
    },
  ],
})

console.log(text) // 模型对图片内容的描述

通过 Base64 发送图片

typescript
import { generateText } from 'ai'
import { openai } from '@ai-sdk/openai'
import { readFileSync } from 'fs'

const imageBuffer = readFileSync('./screenshot.png')

const { text } = await generateText({
  model: openai('gpt-4o'),
  messages: [
    {
      role: 'user',
      content: [
        { type: 'text', text: '这个截图中有什么 UI 问题?' },
        {
          type: 'file',
          mediaType: 'image/png',
          data: imageBuffer,
        },
      ],
    },
  ],
})

console.log(text)

发送音频文件

部分模型(如 gpt-4o-audio-preview)还支持直接分析音频内容:

typescript
import { generateText } from 'ai'
import { openai } from '@ai-sdk/openai'
import { readFileSync } from 'fs'

const { text } = await generateText({
  model: openai('gpt-4o-audio-preview'),
  messages: [
    {
      role: 'user',
      content: [
        { type: 'text', text: '这段音频在说什么?' },
        {
          type: 'file',
          mediaType: 'audio/mpeg',
          data: readFileSync('./recording.mp3'),
        },
      ],
    },
  ],
})

console.log(text)

多模态能力一览

能力函数输入输出状态
文本 → 图片generateImage文本提示图片数据稳定
文本 → 语音generateSpeech文本音频数据实验性
语音 → 文本transcribe音频文件文本 + 时间戳实验性
图片 → 文本generateText (多模态消息)图片 + 提示文本描述稳定
音频 → 文本generateText (多模态消息)音频 + 提示文本分析稳定

在 Next.js 中处理多模态

图片分析聊天界面

前端组件可以通过 useChat 发送包含图片的消息:

typescript
// app/api/chat/route.ts
import { streamText } from 'ai'
import { openai } from '@ai-sdk/openai'

export async function POST(req: Request) {
  const { messages } = await req.json()

  const result = streamText({
    model: openai('gpt-4o'),
    messages,
  })

  return result.toUIMessageStreamResponse()
}
typescript
// app/page.tsx
'use client'

import { useChat } from '@ai-sdk/react'
import { useState } from 'react'

export default function Chat() {
  const [imageUrl, setImageUrl] = useState('')
  const { messages, input, setInput, sendMessage } = useChat()

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault()
    sendMessage({
      role: 'user',
      parts: [
        ...(imageUrl
          ? [{ type: 'file' as const, mediaType: 'image/png', url: imageUrl }]
          : []),
        { type: 'text' as const, text: input },
      ],
    })
    setInput('')
    setImageUrl('')
  }

  return (
    <div>
      {messages.map((m) => (
        <div key={m.id}>
          <strong>{m.role === 'user' ? '你' : 'AI'}:</strong>
          {m.parts.map((part, i) => {
            if (part.type === 'text') return <p key={i}>{part.text}</p>
            if (part.type === 'file')
              return <img key={i} src={part.url} alt="uploaded" />
            return null
          })}
        </div>
      ))}
      <form onSubmit={handleSubmit}>
        <input
          value={imageUrl}
          onChange={(e) => setImageUrl(e.target.value)}
          placeholder="图片 URL(可选)"
        />
        <input
          value={input}
          onChange={(e) => setInput(e.target.value)}
          placeholder="描述你想了解的内容..."
        />
        <button type="submit">发送</button>
      </form>
    </div>
  )
}

最佳实践

  1. 图片提示词要具体generateImage 的提示词越详细,生成效果越好。包含风格、色调、构图等描述
  2. 音频格式匹配:不同模型支持的音频格式不同,OpenAI Whisper 支持 mp3、mp4、wav 等
  3. 图片大小控制:发送图片给模型时注意文件大小,过大的图片会增加 token 消耗和延迟
  4. 实验性 API 注意事项generateSpeechtranscribe 是实验性 API,需要通过 experimental_ 前缀导入,接口可能在未来版本变更
  5. 多模态消息的 content 格式:发送多模态消息时,content 必须是数组格式(包含 type: 'text'type: 'file' 等 part)

下一步

学习文档整合站点