Reasoning and thinking
Control and read model reasoning on BigModel.io. Pass reasoning_effort or thinking, read reasoning_content and thinking blocks, and keep multi-turn history valid.
On this page
Reasoning models think before they answer. Depending on the endpoint, you control this with reasoning_effort or thinking, and you get the thinking back as reasoning_content or as thinking blocks.
| Endpoint | Control | Thinking in the response |
|---|---|---|
/v1/chat/completions |
reasoning_effort, or the vendor's own field such as thinking |
message.reasoning_content (stream: delta.reasoning_content) |
/v1/messages |
thinking: {"type": "enabled", "budget_tokens": N}, output_config.effort |
thinking content blocks |
/v1/responses |
reasoning: {"effort": "..."} |
reasoning output items |
What a model accepts is model-specific. Some models always reason, some switch it on with a parameter, some do not reason. Read the vendor's documentation for the model you use; reasoning models in the catalog may carry a Reasoning tag.
#Chat Completions: read reasoning_content
On GLM and DeepSeek groups the body is passed through unchanged, so reasoning_effort, thinking and any other vendor field reach the model as you send them. reasoning_content in the response is passed back unchanged too. On converted groups, reasoning_effort is kept; other vendor fields are dropped.
import os
from openai import OpenAI
client = OpenAI(base_url="https://bigmodel.io/v1", api_key=os.environ["BIGMODEL_API_KEY"])
completion = client.chat.completions.create(
model="deepseek-v4-pro",
messages=[{"role": "user", "content": "Is 1001 a prime number?"}],
reasoning_effort="high", # only if the model supports it
)
msg = completion.choices[0].message
print("thinking:", getattr(msg, "reasoning_content", None))
print("answer:", msg.content)import OpenAI from "openai";
const client = new OpenAI({ baseURL: "https://bigmodel.io/v1", apiKey: process.env.BIGMODEL_API_KEY });
const completion = await client.chat.completions.create({
model: "deepseek-v4-pro",
messages: [{ role: "user", content: "Is 1001 a prime number?" }],
reasoning_effort: "high", // only if the model supports it
});
const msg = completion.choices[0].message;
console.log("thinking:", msg.reasoning_content);
console.log("answer:", msg.content);curl https://bigmodel.io/v1/chat/completions \
-H "Authorization: Bearer $BIGMODEL_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"deepseek-v4-pro","messages":[{"role":"user","content":"Is 1001 a prime number?"}]}'reasoning_content is not part of the OpenAI schema, so SDK types do not declare it. The OpenAI SDKs keep unknown fields, so you can read it as above. When streaming, read chunk.choices[0].delta.reasoning_content next to delta.content.
To send a vendor field the SDK does not know, use extra_body in Python, for example extra_body={"thinking": {"type": "enabled"}}. Use the exact shape from the vendor's documentation.
#LangChain
LangChain's ChatOpenAI does not surface reasoning_content; the thinking text is lost. If you need it, call the OpenAI SDK directly as above, or use the model through the Messages API with ChatAnthropic on a group that serves Messages. See LangChain.
#Messages API: thinking blocks
On groups that serve /v1/messages, use Anthropic's thinking parameter. budget_tokens must be lower than max_tokens.
import os
from anthropic import Anthropic
client = Anthropic(base_url="https://bigmodel.io", api_key=os.environ["BIGMODEL_API_KEY"])
message = client.messages.create(
model="glm-5.3",
max_tokens=4096,
thinking={"type": "enabled", "budget_tokens": 2048},
messages=[{"role": "user", "content": "Is 1001 a prime number?"}],
)
for block in message.content:
if block.type == "thinking":
print("thinking:", block.thinking)
elif block.type == "text":
print("answer:", block.text)On Anthropic-platform groups, a Responses reasoning.effort is translated into a thinking budget.
#Multi-turn conversations
- Chat Completions. Vendors differ on whether
reasoning_contentfrom earlier turns may be sent back. Some reject it, some require it during tool calls. Follow the vendor's rule; when in doubt, send onlycontent. - Messages. Send earlier assistant content back exactly as you received it, including thinking blocks and their signatures. Edited, reordered or partly removed thinking blocks cause a 409
malformed_session_state.
#Cost
Thinking tokens make replies slower and longer. They are counted in the usage the provider reports. The Usage page shows the reasoning effort of each request.
Reasoning tokens are billed as reported by the provider in the usage fields: the gateway charges the output tokens the provider returns (completion_tokens or output_tokens) at the output price, and doesn't count thinking separately.
#Verify the setup
Run the Python Chat Completions example with a reasoning model. thinking: should print text, not None. If it prints None, the model either does not return its reasoning or needs a parameter to turn it on.
#Troubleshooting
reasoning_content is always empty or None. The model does not reason, needs a vendor parameter (for example thinking) to start, or your library drops the field (LangChain ChatOpenAI). Test with the OpenAI SDK first.
400 about reasoning_effort or thinking. The model does not accept the parameter or value. Remove it, or use the value names from the vendor's documentation.
409 malformed_session_state. The Messages history has altered thinking blocks or mismatched tool ids. Pass assistant turns back unchanged, or start a new conversation.
The reply is cut off and content is empty. The model spent max_tokens on thinking. Raise max_tokens, or lower the effort or budget_tokens.
404 on /v1/messages. The key's group serves Chat Completions only. Use reasoning_content on /v1/chat/completions.
#Related
- Streaming for
reasoning_contentdeltas. - Tool calling with reasoning models.
- Chat Completions API reference and Messages API reference.
Updated · View as Markdown