Inference API
Reasoning models
The GLM and DeepSeek V4 models think before they answer, and show you the thinking in a separate field.
On a reasoning model the assistant message has two parts: reasoning (the chain of thought) and content (the answer). The split means you can log, display, or discard the thinking without ever parsing it out of the reply:
import os
from openai import OpenAI
client = OpenAI(
base_url="https://inference.pearlresearch.ai/v1",
api_key=os.environ.get("PEARL_API_KEY"),
)
response = client.chat.completions.create(
model="deepseek-ai/DeepSeek-V4-Pro",
messages=[
{
"role": "user",
"content": "A bat and a ball cost $1.10. The bat costs $1 more than the ball. What does the ball cost?",
}
],
)
msg = response.choices[0].message
reasoning = getattr(msg, "reasoning", None)
if reasoning is None and hasattr(msg, "model_extra"):
reasoning = (msg.model_extra or {}).get("reasoning")
if reasoning:
print("— thinking —\n", reasoning)
print("— answer —\n", msg.content)The thinking is adaptive, trivial prompts produce little or no reasoning, hard ones produce a lot. When streaming, reasoning arrives as deltas before content does, which makes long thinking phases feel alive instead of stalled.
Migrating? The trace used to arrive as reasoning_content. That field is no longer emitted anywhere: read message.reasoning on a buffered reply and delta.reasoning on a streamed one. On the request side, the flat reasoning_effort is gone too, replaced by the reasoning object below.
Reasoning effort
Every reasoning control rides one object, reasoning, with three optional members: enabled (a plain on/off), effort, and max_tokens (a thinking-token budget). Effort is one of none, minimal, low, medium, high, xhigh, or max; each model maps those seven levels onto the modes it actually serves, so neighboring levels can resolve to the same mode. Omit the object for the model's default. In the OpenAI Python SDK pass it via extra_body:
response = client.chat.completions.create(
model="deepseek/deepseek-v4-flash-0731",
messages=[{"role": "user", "content": "Plan a 3-step refactor for this module: ..."}],
extra_body={"reasoning": {"effort": "high"}},
)Provider-native reasoning switches are rejected, not ignored: sending reasoning_effort, thinking, chat_template_kwargs.enable_thinking, thinking_budget, or any of their siblings returns 400 on the key alone, whatever its value. Use reasoning.
Turning thinking off
Omitting reasoning keeps the model's default, and on GLM-5.2 the default is adaptive thinking, so it will still reason when it deems the prompt worth it. To suppress reasoning entirely, send effort: "none" (or enabled: false); the reply then carries no reasoning and you stop paying for thinking tokens:
response = client.chat.completions.create(
model="zai-org/GLM-5.2",
messages=[{"role": "user", "content": "hi"}],
extra_body={"reasoning": {"effort": "none"}}, # no reasoning trace
)Multi-turn conversations
Treat reasoning as output for humans, not input for models: when you build the next turn's history, append the assistant's content only. The model re-thinks each turn, echoing old reasoning back just spends input tokens on text the model neither expects nor needs.
# Feed only the answer back into history, drop the reasoning trace.
messages.append({"role": "assistant", "content": msg.content})If you do replay a trace, put it on the assistant message as reasoning. An assistant message carrying reasoning_content is rejected with 400: presence is enough, so an explicit null fails too.
What thinking costs
- Reasoning tokens are output tokens, billed at the model's output rate and counted inside
completion_tokens. Some workers itemize them ascompletion_tokens_details.reasoning_tokensin usage. - Thinking consumes the
max_tokensbudget before the answer does. If you seefinish_reason: "length"with lots of reasoning and a cut-off answer, raisemax_tokensor lower the reasoning effort. - For high-volume pipelines, benchmark V4 Flash at
loweffort against V4 Pro at default, the answer-quality-per-dollar ordering depends on your task, and the playground makes the comparison quick.
Chain-of-thought is a working scratchpad, not a guaranteed explanation, audit decisions from the answer and your own evaluations, not from the narrative in reasoning.