reasoning_effort field to control reasoning in new integrations. Accepted values are none, minimal, low, medium, and high. These guides use high when enabling reasoning and none when disabling it. Evaluate answer quality and latency on your task.
none requests an answer without reasoning; any other tier enables reasoning without an additional flag. minimal currently maps to low. Send the exact lowercase values: an unsupported tier is rejected by the SDK before sending. A raw API request with an unsupported tier returns HTTP 400 with invalid_request_error and a message naming reasoning_effort.
message.content. When returned, reasoning is in the separate message.reasoning_content extension. In the Perceptron SDK, read the final answer from response.text and optional reasoning from response.reasoning. Streaming chunks use delta.reasoning_content separately from delta.content.
The field location depends on the endpoint:
Choose effort for your task
- Use
nonefor a baseline without reasoning, including straightforward captions, direct questions, or transcription. - Set
reasoning_effort="high"when enabling reasoning for comparisons, counting with ambiguous overlaps, or questions that combine several observations. Evaluate the answer against examples with known results. - Measure the added token and latency cost. Higher effort does not guarantee a more accurate answer.
max_completion_tokens on reasoning. A budget of only a few hundred tokens may leave an empty final answer with finish_reason: "length". Start with a larger budget, such as 2,048 tokens in the example below, and adjust to your task within the model’s context and output limits.
Evaluate spatial and temporal tasks with the same approach: check the returned geometry, labels, timestamps, and asset references. Do not assume that every task benefits from the same effort level.
Read a completed answer
Installperceptron>=0.4.0 and set PERCEPTRON_API_KEY. This example keeps reasoning separate from the answer and checks that generation completed:
response.reasoning is None. Use response.text as the final answer instead of joining the two fields.
Consume reasoning in a stream
Run this after definingclient and messages above. It collects the two fields independently and consumes the entire stream, including a possible final usage chunk with no choices:
get_final_completion(). It raises on streamed API errors or a stream that ends before its completion marker. If iteration raises or the final completion is unsuccessful, treat the accumulated text as incomplete. A length finish reason can mean reasoning used the available budget before the answer was finished.
Retain reasoning in conversation history
For tool conversations, preservereasoning_content on assistant messages when sending the history back. Append response.message or response.message.to_dict() to history after checking that a message was returned; both retain the reasoning and tool-call fields. The tool-calling guide demonstrates this alongside call IDs and tool results.
Migrating the older flag
For chat completions and Multilook,vision_config.enable_thinking is a deprecated compatibility control. If present, it overrides whether reasoning is enabled, even when you also send reasoning_effort:
falsekeeps reasoning off, including withreasoning_effort: "high".trueenables reasoning. An enabled tier still sets the effort;reasoning_effort: "none"does not turn reasoning off in this combination and leaves the tier unpinned.
reasoning_effort so there is one source of control. Detect has different precedence: its explicit config.reasoning_effort wins over config.enable_thinking.
Reasoning text consumes output budget. Leave room for the final answer or tool arguments, and check finish_reason before using the result. Increasing effort does not replace validation of annotations, extracted facts, or function arguments.
See the tokenization guide for output budgeting and usage accounting.