Vercel AI SDK 5.0+ 与 OpenAI 集成:一些你可能不知道的细节
Vercel AI SDK 提供了一套统一的抽象与工具链,用于在前后端快速接入大模型、流式输出与工具调用等能力。本文从一次升级到 AI SDK 5.0 后遇到的报错出发,梳理 5.0 的默认行为变化,并补充一些与 OpenAI(尤其是 Responses API)集成时容易忽略的细节与迁移要点。
起因:一个令人困惑的错误
在将项目升级到 AI SDK 5.0 后,我们在使用它调用 GPT-5 模型时遇到了这样一个错误:
{
"error": {
"message": "Item 'rs_038b8175...' of type 'reasoning' was provided without its required following item.",
"type": "invalid_request_error",
"param": "input"
}
}
这个错误信息提到了 reasoning 类型的项目缺少必需的后续项目。但我们明明只是在做简单的聊天对话,为什么会涉及到 "reasoning" 呢?
调查:AI SDK 5.0 的默认行为变化
顺着这个报错往下查,我们发现了一个直接相关的变化:
在 AI SDK 5.0 中,默认的 OpenAI provider 已经从 Chat Completions API 切换到了 Responses API。
这意味着:
// AI SDK 4.x
openai('gpt-4o') // → 使用 Chat Completions API
// AI SDK 5.0+
openai('gpt-5') // → 使用 Responses API (新默认值!)
如果你需要继续使用 Chat Completions API,需要显式指定:
// 显式使用 Chat Completions API
openai.chat('gpt-5')
// 显式使用 Responses API
openai.responses('gpt-5')
// 默认 (AI SDK 5.0+) - 等同于 openai.responses()
openai('gpt-5')
什么是 Responses API?
理解了这个“默认切换”之后,再回头看 reasoning 报错,就可以从 Responses API 的消息结构来解释。
Responses API 是 OpenAI 在 2025 年 3 月推出的新一代 API。它提供一个统一接口,用于对话、工具调用、状态持久化等 Agent 相关能力。
核心特性对比
| 特性 | Chat Completions | Responses API |
|---|---|---|
| 内置 Web 搜索 | 需要外部工具 | 原生支持 web_search |
| 文件搜索 | 需要外部工具 | 原生支持 file_search |
| 代码解释器 | 不支持 | 内置支持 |
| 计算机操作 | 不支持 | 支持(用于 Agent) |
| 状态持久化 | 每次需重发历史 | store: true 自动持久化 |
| 推理上下文保留 | 不支持 | 可在多轮中保留推理上下文 |
| MCP 支持 | 不支持 | 支持远程 MCP |
为什么会有 reasoning 错误?
Responses API 支持推理模型(如 GPT-5 系列),这类模型在生成回复时会包含 reasoning(推理)片段。多轮对话时,如果你回传的历史里带了 reasoning,却缺了紧随其后的 output,就会触发这个错误。
常见触发场景:
- 对话历史被意外截断
- 序列化/反序列化过程中丢失了部分数据
- 手动处理消息时过滤不当
成本与性能
在明确接口差异与报错原因后,下面再看成本与性能。
定价
Responses API 不额外收费,与 Chat Completions 使用相同的 token 计价标准。
成本优势
根据官方资料:
"与 Chat Completions 相比,缓存利用率提升 40%-80%"
这意味着在多轮对话场景下,Responses API 可能更省钱。
性能提升
"在 SWE-bench 测试中,使用 Responses API 的 GPT-5 比 Chat Completions 提升 3%"
如何在 AI SDK 中使用
下面给出在 AI SDK 中的用法示例,包含最常见的 generateText/streamText 场景。
基础用法
import { generateText } from 'ai';
import { openai } from '@ai-sdk/openai';
// 默认使用 Responses API
const { text } = await generateText({
model: openai('gpt-5'),
prompt: '解释量子纠缠的概念。',
});
使用 Web 搜索工具
import { openai } from '@ai-sdk/openai';
import { generateText } from 'ai';
const result = await generateText({
model: openai('gpt-5'),
prompt: '上周旧金山发生了什么重要新闻?',
tools: {
web_search_preview: openai.tools.webSearchPreview(),
},
});
console.log(result.text);
console.log(result.sources); // 包含引用来源
控制推理力度
const result = await generateText({
model: openai('gpt-5'),
prompt: '分析这个复杂的数据集并提供见解。',
providerOptions: {
openai: {
reasoningEffort: 'high', // 'low' | 'medium' | 'high'
},
},
});
在 Next.js 中使用 (Chat Route)
// app/api/chat/route.ts
import { openai } from '@ai-sdk/openai';
import { convertToModelMessages, streamText, UIMessage } from 'ai';
export const maxDuration = 30;
export async function POST(req: Request) {
const { messages }: { messages: UIMessage[] } = await req.json();
const result = streamText({
model: openai('gpt-5.1'),
messages: convertToModelMessages(messages),
});
return result.toUIMessageStreamResponse();
}
如何选择?
看完上面的能力对比与代码示例,接下来往往需要回答一个问题:到底该用哪个接口、什么时候切换?下面按常见场景给出简要选型建议,便于快速判断。
| 场景 | 推荐 |
|---|---|
| 简单聊天,无工具调用 | 两者皆可(Chat Completions 更简单) |
| 需要实时网络信息 | Responses API |
| 多轮推理对话 | Responses API |
| 构建 AI Agent | Responses API |
| 需要兼容旧代码 | Chat Completions |
| 新项目 | Responses API(官方推荐) |
迁移建议
如果你正在从 AI SDK 4.x 升级到 5.x,建议按下面三步检查一遍:先确认实际调用的 API 与预期一致,再处理历史消息,最后再考虑引入 Responses API 的新特性。
-
检查你的 OpenAI provider 调用方式
- 如果希望继续走 Chat Completions(保持 4.x 行为),请显式使用
openai.chat('模型名') - 如果想强制使用 Responses API,请显式使用
openai.responses('模型名')(避免被默认行为变化影响)
- 如果希望继续走 Chat Completions(保持 4.x 行为),请显式使用
-
处理对话历史
- 确保
reasoning和output项目成对出现 - 或者在发送前过滤掉
reasoning类型的消息
- 确保
-
利用新特性
- 考虑使用内置的 web search 和 file search
- 探索状态持久化功能减少 token 使用
版本信息
为避免版本差异导致行为不一致,本文基于以下版本:
- AI SDK: 5.0.108+