Options and Reasoning Effort

The most important thing you set on a model today is how much it should think through before it starts answering. It shapes quality, speed and price alike. We will look at how one dial controls that across all providers, where to find the rest of the settings, and at the end at what happened to the temperature parameter you may have read about elsewhere.

How Much the Model Thinks Before Answering

Newer models can do something the older ones could not: before they start writing the answer, they write themselves a kind of draft reasoning. They take the task apart, try an approach, find a mistake in it, fix it, and only then answer. This draft is called reasoning or thinking.

There are two things you need to know about it. It does not reach the answer itself, so getText() never contains it; some providers do return it separately, some only as a summary, and you can read it with getReasoning(). And above all you pay for it, because it counts as output tokens, and on a harder task there are more of them than in the answer itself.

How much the model should think through is what setEffort() says:

use AIAccess\Chat\Effort;

$chat = $client->createChat('gpt-5.6-luna');
$chat->setEffort(Effort::Low);

echo $chat->sendMessage('Which category does this complaint belong to?')->getText();

There are six levels: None, Low, Medium, High, XHigh and Max. None means the model should not think at all and should answer straight away.

Each provider translates the value into its own, because they do not even agree on the naming:

Provider What it is called there
Claude output_config.effort, and None also disables thinking
OpenAI reasoning.effort
Gemini thinkingConfig.thinkingLevel, None is a zero budget
DeepSeek thinking.reasoning_effort
Grok reasoning_effort

Some providers do not know all six levels, so those map to the nearest one. Gemini has only three, which is why High, XHigh and Max all end up the same there.

Two principles are worth saying out loud. First, nothing is sent until you call setEffort() and the provider's own default applies. That is exactly why DeepSeek thinks even though you never asked. Second, the library keeps no table of model capabilities. When a model lacks the dial, the provider answers with an error, and that is right; maintaining a list of what each model currently supports would mean documentation that ages before it is finished.

Which Level to Pick

The choice of level is not cosmetic, because it directly decides how long you wait for the answer and what it costs.

  • None for tasks with nothing to think through: classification, extracting data from text, rephrasing a sentence, translation. The answer arrives fastest and cheapest.
  • Low and Medium for ordinary work where the model needs a moment but not long: summarizing a longer text, drafting a reply, simpler decisions.
  • High and above for tasks with several steps: analyzing code, mathematics, planning, reasoning over contradictory information. Expect the answer later and markedly more expensive.

The cheapest optimization is usually discovering that the task does fine with None. The price difference between thinking turned off and turned up to maximum tends to be larger than the difference between two models.

Settings Each Provider Keeps to Itself

The rest of the settings is not unified, because it cannot be: only OpenAI has store, only Gemini has safetySettings, only Grok has seed. So they are named arguments of the setOptions() method on the specific provider class, not keys in a shared array.

// Claude
$chat->setOptions(maxOutputTokens: 1024, stopSequences: ['END']);

// OpenAI
$chat->setOptions(maxOutputTokens: 1024, store: false, parallelToolCalls: true);

You feel the difference from an array as you type. The IDE offers exactly what that provider knows, and PHP itself catches a typo. A shared array would quietly swallow a key that belongs nowhere, and you would find out only by nothing happening.

The most useful of them is maxOutputTokens, the cap on the answer's length. It has the same name with every provider because everyone needs it; on the wire it is called something different each time, max_tokens here and max_completion_tokens there, but that is the library's business.

The complete list for each provider is in the setOptions() signature in src/Provider/*/Chat.php, or your IDE will show it. And if you use the generic client for a third-party endpoint, it has an extra custom argument for pushing through anything that endpoint knows and the library does not.

What Happened to Temperature

When you read about configuring models elsewhere, you will almost certainly run into the temperature parameter. It is worth knowing what it did and why this documentation does not recommend it.

A model does not pick one single correct continuation of a sentence. At every moment it holds a list of words that could come next, each with a probability, and draws one of them. That is exactly why the same question gives you a slightly different answer every time. temperature decided how risky that draw would be: a value near zero meant a sober, predictable writer that almost always reaches for the most likely word, higher values meant more inventive text but also more inaccuracies. top_p and top_k did a similar thing in a different way.

Reasoning models abandoned this way of steering. If you send them temperature anyway, some answer with HTTP 400, which is what Claude does on its newest models and OpenAI from GPT-5.1 on, and others silently ignore it, which is what Gemini does and DeepSeek does whenever it is thinking.

The dangerous one is the second. An error at least tells you; a silently ignored parameter means the application looks like it works, you keep tuning values, and nothing happens at all.

The library does not forbid temperature and on older models you are welcome to use it through setOptions(). Just do not build anything lasting on it: on the models shipping next year it will very likely not work at all.

Where to Go Next

  • Streaming – read the answer while the model is still writing it
  • Tool calling – when the model should reach into your application
  • Structured output – when you need data, not prose
  • Providers – what each one can do and how they differ