AI Gateway Anthropic Reasoning
Anthropic Claude models support thinking, which lets the model reason through complex problems before producing a final answer. Claude 4.6 introduced adaptive thinking, where Claude dynamically decides when and how much to think based on an effort level. On Claude Opus 4.7 and later and the Claude 5 models (Claude Opus 5, Claude Sonnet 5, Claude Fable 5), adaptive thinking is the only way to turn thinking on. The legacy fixed-budget API is no longer accepted on those models.
See the AI SDK Anthropic provider reference for supported reasoning options and response metadata.
- Adaptive thinking: Set
thinking: { type: 'adaptive' }. Claude dynamically decides when and how much to think based on theeffortparameter. Available on Claude 4.6 and later. The only way to turn thinking on for Claude Opus 4.7 and later and the Claude 5 models. - Extended thinking with a token budget: Set
thinking: { type: 'enabled', budgetTokens: N }for a fixed token budget. Available on Claude 4.6 and earlier. Deprecated on Claude 4.6. Removed on Claude Opus 4.7 and later and the Claude 5 models: requests withtype: 'enabled'return a 400 error. Migrate to adaptive thinking.
Set thinking: { type: 'adaptive' } explicitly when you want adaptive thinking. Omitting thinking delegates to the model's default; it doesn't mean the same thing as enabling or disabling thinking. Check the Anthropic adaptive thinking documentation for defaults when migrating between models.
To turn thinking off, set thinking: { type: 'disabled' }. Two exceptions: Claude Fable 5 can't turn thinking off at all, and Claude Opus 5 accepts disabled only at an effort of high or lower. Pairing it with xhigh or max returns a 400.
Use GET /v1/models to find Anthropic models and their reasoning_options. Use effort.values for named levels and a budget_tokens entry for explicit budgets. See Two thinking modes for the native adaptive and legacy request shapes.
When you enable adaptive thinking, set providerOptions.anthropic.effort in the AI SDK or output_config.effort in the Messages API. Choose a value from the model's catalog entry that your client accepts. Don't assume a newer Claude model shares an older model's effort levels or default.
Use the shared effort option for portable configuration. AI SDK 7's shorthand stops at xhigh; native Anthropic max requires a provider-specific option or an HTTP format that accepts it.
For more details, see the Anthropic extended thinking docs, adaptive thinking docs, and effort parameter docs.
On Claude 4.6 and later, the AI SDK 7 top-level reasoning option enables adaptive thinking at the corresponding effort level, so you don't need provider-specific configuration for the common case:
import { generateText } from 'ai';
const result = await generateText({
model: 'anthropic/claude-sonnet-5',
prompt: 'Explain quantum entanglement in simple terms.',
reasoning: 'high', // Adaptive thinking with effort: 'high'
});
console.log('Thinking:', result.reasoningText);
console.log('Response:', result.text);Use providerOptions.anthropic when you need Anthropic-specific features like a fixed token budget on older models, the display parameter, or interleaved thinking beta headers. If you set thinking in providerOptions, it takes precedence over the top-level reasoning value.
Configure adaptive thinking through providerOptions. Claude dynamically decides when and how much to think:
import { generateText } from 'ai';
const result = await generateText({
model: 'anthropic/claude-sonnet-5',
prompt: 'Explain quantum entanglement in simple terms.',
providerOptions: {
anthropic: {
thinking: { type: 'adaptive' },
},
},
});
console.log('Thinking:', result.reasoningText);
console.log('Response:', result.text);On Claude Opus 4.7 and later, set display: 'summarized' to receive reasoning text, which is omitted by default. See Thinking display.
import { streamText } from 'ai';
const result = streamText({
model: 'anthropic/claude-opus-5',
prompt: 'Explain quantum entanglement in simple terms.',
providerOptions: {
anthropic: {
thinking: { type: 'adaptive', display: 'summarized' },
},
},
});
for await (const part of result.stream) {
if (part.type === 'reasoning-delta') {
process.stdout.write(part.text);
} else if (part.type === 'text-delta') {
process.stdout.write(part.text);
}
}import { streamText } from 'ai';
const result = streamText({
model: 'anthropic/claude-opus-5',
prompt: 'Explain quantum entanglement in simple terms.',
providerOptions: {
anthropic: {
thinking: { type: 'adaptive', display: 'summarized' },
},
},
});
for await (const part of result.fullStream) {
if (part.type === 'reasoning-delta') {
process.stdout.write(part.text);
} else if (part.type === 'text-delta') {
process.stdout.write(part.text);
}
}For pre-4.7 models, use type: 'enabled' with a budgetTokens value. This is the only thinking mode supported on Claude 4, 4.1, 4.5, and Haiku 4.5; on Claude 4.6 it works but is deprecated; on Claude Opus 4.7 and later it returns a 400 error.
import { generateText } from 'ai';
const result = await generateText({
model: 'anthropic/claude-opus-4',
prompt: 'Explain quantum entanglement in simple terms.',
providerOptions: {
anthropic: {
thinking: {
type: 'enabled',
budgetTokens: 5000,
},
},
},
});
console.log('Thinking:', result.reasoningText);
console.log('Response:', result.text);You can configure thinking without the AI SDK through the gateway's /v1/messages endpoint using the Anthropic SDK in any language. The OpenAI-compatible formats also work with Claude models: their reasoning parameter is mapped to Claude's thinking configuration.
import Anthropic from '@anthropic-ai/sdk';
const anthropic = new Anthropic({
apiKey: process.env.AI_GATEWAY_API_KEY,
baseURL: 'https://ai-gateway.vercel.sh',
});
const message = await anthropic.messages.create({
model: 'anthropic/claude-sonnet-4.5',
max_tokens: 8192,
thinking: {
type: 'enabled',
budget_tokens: 5000,
},
messages: [
{
role: 'user',
content: 'Explain quantum entanglement in simple terms.',
},
],
});
for (const block of message.content) {
if (block.type === 'thinking') {
console.log('Thinking:', block.thinking);
} else if (block.type === 'text') {
console.log('Response:', block.text);
}
}import os
import anthropic
client = anthropic.Anthropic(
api_key=os.getenv('AI_GATEWAY_API_KEY'),
base_url='https://ai-gateway.vercel.sh'
)
message = client.messages.create(
model='anthropic/claude-sonnet-4.5',
max_tokens=8192,
thinking={
'type': 'enabled',
'budget_tokens': 5000,
},
messages=[
{
'role': 'user',
'content': 'Explain quantum entanglement in simple terms.'
}
],
)
for block in message.content:
if block.type == 'thinking':
print('Thinking:', block.thinking)
elif block.type == 'text':
print('Response:', block.text)curl https://ai-gateway.vercel.sh/v1/messages \
-H "Authorization: Bearer $AI_GATEWAY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "anthropic/claude-sonnet-4.5",
"max_tokens": 8192,
"thinking": {
"type": "enabled",
"budget_tokens": 5000
},
"messages": [
{
"role": "user",
"content": "Explain quantum entanglement in simple terms."
}
]
}'| Parameter | Type | Description |
|---|---|---|
type | string | Set to 'adaptive' |
effort | string | A model-supported value from reasoning_options in the catalog; set it as providerOptions.anthropic.effort |
display | string | 'summarized' to include reasoning text in the response, 'omitted' (default on Claude Opus 4.7 and later) for empty thinking blocks. See Thinking display. |
| Parameter | Type | Description |
|---|---|---|
type | string | Set to 'enabled' |
budgetTokens | number | Maximum number of tokens to allocate for thinking |
Starting with Claude Opus 4.7, thinking content is omitted from the response by default. Thinking blocks are still present in the stream, but their text is empty. To receive the model's reasoning output, set display: 'summarized':
import { generateText } from 'ai';
const result = await generateText({
model: 'anthropic/claude-opus-5',
prompt: 'Explain quantum entanglement in simple terms.',
providerOptions: {
anthropic: {
thinking: { type: 'adaptive', display: 'summarized' },
},
},
});
console.log('Thinking:', result.reasoningText); // populated
console.log('Response:', result.text);Without display: 'summarized', result.reasoningText is empty on Claude Opus 4.7 and later. You're still billed for thinking tokens whether or not they're returned.
This applies to Claude Opus 4.7 and later and the Claude 5 models (Claude Sonnet 5, Claude Fable 5). Claude Opus 4.6 and Claude Sonnet 4.6 continue to return reasoning text by default.
Interleaved thinking lets Claude think between tool calls, producing better reasoning in multi-step workflows.
- Claude Opus 4.6 and later: Automatically enabled with adaptive thinking. No header needed.
- Earlier models with extended thinking (Claude Sonnet 4.6, Claude 4.5, Claude 4, Claude 4.1): Pass the
interleaved-thinking-2025-05-14beta header whentype: 'enabled'is set.
import { generateText } from 'ai';
const result = await generateText({
model: 'anthropic/claude-sonnet-4.5',
prompt: 'Search for the weather and summarize it.',
providerOptions: {
anthropic: {
thinking: { type: 'enabled', budgetTokens: 5000 },
headers: {
'anthropic-beta': 'interleaved-thinking-2025-05-14',
},
},
},
tools: {
// your tools here
},
});With interleaved thinking, budgetTokens can exceed the model's max output tokens since it represents the total budget across all thinking blocks in a single turn.
For more details, see the Anthropic extended thinking docs.
Claude 4 and later models return summarized thinking output, not full thinking tokens. You're charged for the full thinking tokens, but the response contains a condensed summary.
Was this helpful?