AI SDK Core

Reasoning

Learn how to control reasoning across providers with the top-level reasoning parameter.

Many language models support an internal "reasoning" phase (sometimes also called "thinking") before producing a response. The AI SDK provides a top-level reasoning parameter on generateText and streamText that controls this behavior across providers with a single, portable setting.

Basic Usage

import { generateText } from 'ai';

const { text, reasoning, reasoningText } = await generateText({
  model: 'anthropic/claude-sonnet-5.5',
  reasoning: 'medium',
  prompt: 'How many people will live in the world in 2040?',
});

The reasoning parameter accepts the following values:

ValueBehavior
'provider-default'Use the provider's default reasoning behavior (default when omitted)
'none'Disable reasoning
'minimal'Bare-minimum reasoning
'low'Fast, concise reasoning
'medium'Balanced reasoning
'high'Thorough reasoning
'xhigh'Extra-high reasoning
'max'Maximum reasoning

Streaming

The reasoning parameter works the same way with streamText:

import { streamText } from 'ai';

const result = streamText({
  model: 'google/gemini-3.8-flash',
  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);
  }
}

Precedence Rules

Provider-specific settings take precedence over the corresponding fields derived from reasoning. Partial configurations may still use portable reasoning to fill missing fields; summary and display settings can be used alongside it.

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

const { text } = await generateText({
  model: openai.responses('gpt-6-astra'),
  reasoning: 'low', // ignored because providerOptions.openai.reasoningEffort is set
  providerOptions: {
    openai: {
      reasoningEffort: 'high', // this wins
    },
  },
  prompt: 'Explain quantum entanglement.',
});

This design lets you use the portable reasoning parameter by default and fall back to providerOptions only when you need provider-specific features like exact token budgets.

Provider Support

The reasoning parameter is supported by providers including OpenAI, Anthropic, Google, xAI, Groq, DeepSeek, Moonshot AI, Fireworks, Amazon Bedrock, Mistral, Cohere, Alibaba, Open Responses, OpenAI Compatible, and Perplexity. Each provider translates the value to its native reasoning API.

Providers with a distinct native maximum tier, such as supported OpenAI, Anthropic, DeepSeek, and Moonshot AI models, receive 'max' directly. Amazon Bedrock preserves 'max' for its Anthropic and OpenAI effort mappings, while Amazon Nova 2 maps 'xhigh' and 'max' to 'high' with a compatibility warning. Providers whose highest native tier is lower coerce 'max' to their closest supported tier and emit a compatibility warning when their adapter supports warning propagation. OpenAI-compatible and Open Responses endpoints receive 'max' directly so compatible servers can interpret it.

Some providers use a numeric token budget instead of an enum for reasoning control. In those cases, 'max' maps to 95% of the model's maximum output tokens by default, subject to the provider's minimum and maximum reasoning budget limits.

Maximum reasoning can substantially increase token usage, latency, cost, and the chance of reaching request or output limits. Use it when the model's additional reasoning depth is worth those tradeoffs.

Providers and models that do not support reasoning configuration emit an unsupported warning and ignore the parameter.

Migrating from providerOptions

If you currently control reasoning via providerOptions, you can migrate to the top-level reasoning parameter for portability across providers.

Before (Anthropic)

const { text } = await generateText({
  model: anthropic('claude-opus-5-5'),
  providerOptions: {
    anthropic: {
      thinking: { type: 'adaptive' },
      effort: 'high',
    },
  },
  prompt: 'How many people will live in the world in 2040?',
});

After (Anthropic)

const { text } = await generateText({
  model: anthropic('claude-opus-5-5'),
  reasoning: 'high',
  prompt: 'How many people will live in the world in 2040?',
});

Before (Anthropic with older model)

const { text } = await generateText({
  model: anthropic('claude-sonnet-4-20250514'),
  providerOptions: {
    anthropic: {
      thinking: { type: 'enabled', budgetTokens: 12000 },
    },
  },
  prompt: 'How many people will live in the world in 2040?',
});

After (Anthropic with older model)

const { text } = await generateText({
  model: anthropic('claude-sonnet-4-20250514'),
  reasoning: 'medium',
  prompt: 'How many people will live in the world in 2040?',
});

If you need to enforce an exact token budget (e.g. exactly 12000 tokens), keep using providerOptions instead of the top-level reasoning parameter.

Before (Google with includeThoughts)

const { text } = await generateText({
  model: google('gemini-3.8-flash'),
  providerOptions: {
    google: {
      thinkingConfig: { thinkingLevel: 'high', includeThoughts: true },
    },
  },
  prompt: 'Explain the Riemann hypothesis in simple terms.',
});

After (Google with includeThoughts)

const { text } = await generateText({
  model: google('gemini-3.8-flash'),
  reasoning: 'high',
  providerOptions: {
    google: { thinkingConfig: { includeThoughts: true } },
  },
  prompt: 'Explain the Riemann hypothesis in simple terms.',
});

Before (OpenAI with reasoningSummary)

const { text } = await generateText({
  model: openai.responses('gpt-6-astra'),
  providerOptions: {
    openai: { reasoningEffort: 'high', reasoningSummary: 'auto' },
  },
  prompt: 'Explain quantum entanglement.',
});

After (OpenAI with reasoningSummary)

const { text } = await generateText({
  model: openai.responses('gpt-6-astra'),
  reasoning: 'high',
  providerOptions: {
    openai: { reasoningSummary: 'auto' },
  },
  prompt: 'Explain quantum entanglement.',
});

You can combine providerOptions with reasoning for provider-specific features such as reasoning summaries or display settings. Explicit effort or budget values override the corresponding mapped fields; partial configurations may still use portable reasoning to fill missing fields. See Precedence Rules for details.