第 10 章 · 推理模型
本章目标:
- 理解语言模型的内部「推理」(thinking)阶段及其对回答质量的影响
- 掌握跨 provider 可移植的顶层
reasoning参数及六个档位- 学会在
streamText中分别处理 reasoning 与 text-delta 流片段- 理解
reasoning参数与providerOptions的优先级规则- 了解如何从 provider 专属配置迁移到可移植的
reasoning参数
10.1 什么是推理阶段
许多语言模型在产出最终回复之前,会先进行一个内部的「推理」阶段(有时也称为 "thinking")。AI SDK 在 generateText 和 streamText 上提供了顶层的 reasoning 参数,用一个可移植的设置控制所有 provider 的这种行为。
10.2 基本用法
import { generateText, createGateway } from 'ai';
// 方式一:Vercel AI Gateway
const gateway = createGateway({ apiKey: process.env.AI_GATEWAY_API_KEY ?? '' });
const { text, reasoning, reasoningText } = await generateText({
model: gateway('anthropic/claude-sonnet-4.6'),
reasoning: 'medium',
prompt: 'How many people will live in the world in 2040?',
});
// 方式二:自定义 OpenAI 兼容 Provider(二选一即可,同样适用于自定义 provider)
// import { createOpenAICompatible } from '@ai-sdk/openai-compatible';
// const myProvider = createOpenAICompatible({
// name: 'my-provider',
// baseURL: process.env.OPENAI_COMPATIBLE_BASE_URL ?? '',
// apiKey: process.env.OPENAI_COMPATIBLE_API_KEY ?? '',
// });
// const model = myProvider('claude-sonnet-4.6'); // 按服务端实际模型名填写reasoning 参数接受以下取值:
| 取值 | 行为 |
|---|---|
'provider-default' | 使用 provider 的默认推理行为(省略时的默认值) |
'none' | 关闭推理 |
'minimal' | 最少量推理 |
'low' | 快速、简洁的推理 |
'medium' | 平衡的推理 |
'high' | 充分的推理 |
'xhigh' | 最大程度推理 |
10.3 流式输出
reasoning 参数在 streamText 中的用法完全相同。流片段分为 reasoning 与 text-delta 两类,可以分开处理:
import { streamText, createGateway } from 'ai';
const gateway = createGateway({ apiKey: process.env.AI_GATEWAY_API_KEY ?? '' });
const result = streamText({
model: gateway('google/gemini-3-flash-preview'),
reasoning: 'high',
prompt: 'Explain the Riemann hypothesis in simple terms.',
});
for await (const part of result.stream) {
if (part.type === 'reasoning') {
process.stdout.write(part.textDelta);
} else if (part.type === 'text-delta') {
process.stdout.write(part.textDelta);
}
}10.4 优先级规则
顶层 reasoning 参数与 provider 专属的 providerOptions 永远不会合并。如果你在 providerOptions 中设置了推理相关选项,它们完全生效,顶层 reasoning 参数被忽略:
import { generateText, createGateway } from 'ai';
const gateway = createGateway({ apiKey: process.env.AI_GATEWAY_API_KEY ?? '' });
const { text } = await generateText({
model: gateway('openai/gpt-5.4'),
reasoning: 'low', // 被忽略,因为设置了 providerOptions.openai.reasoningEffort
providerOptions: {
openai: {
reasoningEffort: 'high', // 这个优先生效
},
},
prompt: 'Explain quantum entanglement.',
});这一设计让你默认使用可移植的 reasoning 参数,只在需要 provider 专属特性(如精确的 token 预算)时才退回 providerOptions。
10.5 Provider 支持情况
reasoning 参数由以下 provider 支持:OpenAI、Anthropic、Google、xAI、Groq、DeepSeek、Fireworks 和 Amazon Bedrock。每个 provider 把该值翻译成自己的原生推理 API:
- 有些 provider 原生支持全部六档;另一些会收敛到更少的档位(发生收敛时会发出 warning)
- 有些 provider 用数值 token 预算而非枚举来控制推理;此时顶层
reasoning值会被映射为按模型最大输出 token 百分比计算的预算 - 不支持推理的 provider(如 Mistral、Perplexity、Cohere)发出
unsupportedwarning 并忽略该参数
💡 无论你用 Vercel AI Gateway 还是自定义 OpenAI 兼容 Provider,
reasoning参数的语义保持一致——是否真正生效取决于底层模型与网关背后的 provider 能力。
10.6 从 providerOptions 迁移
如果你目前通过 providerOptions 控制推理,可以迁移到顶层 reasoning 参数以获得跨 provider 的可移植性。
Anthropic
之前:
const { text } = await generateText({
model,
providerOptions: {
anthropic: {
thinking: { type: 'adaptive', effort: 'high' },
},
},
prompt: 'How many people will live in the world in 2040?',
});之后:
const { text } = await generateText({
model: gateway('anthropic/claude-opus-4.6'), // gateway 实例见 10.2;同样适用于自定义 provider
reasoning: 'high',
prompt: 'How many people will live in the world in 2040?',
});对于较旧的 Anthropic 模型:
const { text } = await generateText({
model: gateway('anthropic/claude-sonnet-4-20250514'),
reasoning: 'medium', // 替代 budgetTokens: 12000
prompt: 'How many people will live in the world in 2040?',
});如果需要强制精确的 token 预算(如恰好 12000 tokens),继续使用 providerOptions 而不是顶层 reasoning 参数。
Google
之前通过 includeThoughts 配置:
const { text } = await generateText({
model: gateway('google/gemini-3-flash-preview'),
reasoning: 'medium',
providerOptions: {
google: { thinkingConfig: { includeThoughts: true } }, // 与 reasoning 无关的选项保留在 providerOptions
},
prompt: 'Explain the Riemann hypothesis in simple terms.',
});OpenAI
之前同时设置 reasoningEffort 和 reasoningSummary:
const { text } = await generateText({
model: gateway('openai/o3'),
reasoning: 'high', // 替代 providerOptions.openai.reasoningEffort
providerOptions: {
openai: { reasoningSummary: 'auto' }, // 与推理力度无关的专属特性仍可用 providerOptions
},
prompt: 'Explain quantum entanglement.',
});注意:providerOptions 仍然可以和 reasoning 并用于推理力度之外的 provider 专属功能。但如果 providerOptions 中包含推理力度/预算类设置(如 reasoningEffort、thinking、thinkingConfig.thinkingBudget),它们完全优先,顶层 reasoning 参数被忽略。
本章小结
- 许多模型在生成最终回复前有内部「推理」阶段;AI SDK 用顶层
reasoning参数统一控制 - 六个档位:
none/minimal/low/medium/high/xhigh,外加provider-default - 流式输出中
reasoning片段与text-delta片段可分别处理 providerOptions中的推理设置完全优先于顶层reasoning,二者不合并- 各 provider 将
reasoning映射到各自的原生 API;不支持的 provider 发出unsupportedwarning - 迁移时保留 provider 专属的非推理选项在
providerOptions,推理力度改用可移植参数
🛠️ 动手实践
- 分别用
reasoning: 'low'、'medium'、'high'对同一道数学题调用generateText,对比返回的reasoning文本长度与答案质量。 - 用
streamText+reasoning: 'high'实现一个终端程序:把 reasoning 部分打印为灰色前缀,正文正常输出(参考 10.3 的流片段处理)。 - 把一段使用
providerOptions.anthropic.thinking.budgetTokens的旧代码迁移为顶层reasoning参数,并写一条注释说明什么场景下必须保留providerOptions。