Reasoning
Read Olive's reasoning apart from its answer, and set how much it reasons.
Olive returns its reasoning in reasoning_content, separate from the answer in content. Set reasoning_effort to change how much it reasons.
When to use it
- A clinician reviews how Olive reached an answer.
- You log reasoning to trace an answer that looks wrong.
- A hard case needs more room, or a simple question should return sooner.
The SDK samples assume the client from the Quickstart.
curl https://api.avey.ai/llm/chat/completions \
-H "Authorization: Bearer $AVEY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "olive",
"reasoning_effort": "low",
"messages": [
{ "role": "user", "content": "62-year-old with exertional chest pain relieved by rest. What is the differential?" }
]
}'The Go samples reuse the Quickstart client. Add the imports each sample uses.
The response carries both fields on the message:
{
"choices": [
{
"index": 0,
"finish_reason": "stop",
"message": {
"role": "assistant",
"reasoning_content": "Exertional pain relieved by rest suggests a demand-related...",
"content": "The most likely diagnosis is stable angina..."
}
}
]
}Effort
reasoning_effort sets a thinking budget. Olive is told to think for at most
that many tokens before it answers. On the Responses API, send the same values
as reasoning.effort.
reasoning_effort | Thinking budget |
|---|---|
none | 256 tokens |
minimal | 512 tokens |
low | 1,024 tokens |
medium | 2,048 tokens |
high | 4,096 tokens |
xhigh | 6,144 tokens |
| Not set | No budget. Olive reasons as long as the output limit allows |
noneis the smallest budget, not "off". Olive always reasons before it answers.- The budget is an instruction, not a hard cap. Use
max_tokensfor a hard limit. - Any other value returns
400:Invalid value: 'x'. Supported values are: 'none', 'minimal', 'low', 'medium', 'high', 'xhigh'. reasoning.max_tokenswith no effort picks the largest level whose budget fits under it. An explicit effort wins.reasoning.summaryon Responses returns400.
Reasoning uses the output budget
Reasoning counts toward max_tokens with the answer. If it uses the whole
budget, a chat completion ends with finish_reason length and content can
be empty. A Responses request ends with status incomplete. Leave room for
both. On chat completions you can leave max_tokens unset. On Responses, set
max_output_tokens.
Multi-turn conversations
Chat completions keep no state. Send the whole conversation on every call. For
each earlier assistant turn, send its content. Keep the reasoning in your own
logs.
messages = [{"role": "user", "content": "62-year-old with exertional chest pain relieved by rest. What is the differential?"}]
first = client.chat.completions.create(model="olive", messages=messages, reasoning_effort="medium")
messages.append({"role": "assistant", "content": first.choices[0].message.content})
messages.append({"role": "user", "content": "Which test would you order first, and why?"})
second = client.chat.completions.create(model="olive", messages=messages, reasoning_effort="medium")Keep reasoning_effort the same for the whole conversation. The budget is
written into every user message, so changing it on a later turn changes the
whole prompt. The cached prefix then misses, and that turn is slower.
To keep the conversation on the server instead, use the Responses API with
previous_response_id. See Conversation state.
Things to know
- Reasoning is output. It counts in
usage.completion_tokens, oroutput_tokenson Responses, and is billed as output. - Only chat completions return the reasoning text. Responses and completions do not return it as a separate field.
- Each effort budget adds a short instruction to every user message. Those tokens count as input.
- Reasoning streams before the answer. See Streaming.
- Show reasoning to clinicians, not patients. A clinician reviews the answer, with its reasoning, before it affects care.
- Reasoning is free text. Read
contentfor the answer, and see Structured outputs before you parse anything.