# 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.

Web version: https://bigmodel.io/docs/reasoning · Updated 2026-10-18

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.

```python [Python]
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)
```

```js [Node.js]
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);
```

```bash [cURL]
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](https://bigmodel.io/docs/langchain).

## Messages API: thinking blocks

On groups that serve `/v1/messages`, use Anthropic's `thinking` parameter. `budget_tokens` must be lower than `max_tokens`.

```python [Python]
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_content` from earlier turns may be sent back. Some reject it, some require it during tool calls. Follow the vendor's rule; when in doubt, send only `content`.
- **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](https://bigmodel.io/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](https://bigmodel.io/docs/streaming) for `reasoning_content` deltas.
- [Tool calling](https://bigmodel.io/docs/tool-calling) with reasoning models.
- [Chat Completions API reference](https://bigmodel.io/docs/api-chat-completions) and [Messages API reference](https://bigmodel.io/docs/api-messages).
