Skip to content

server: support "reasoning_effort": "none" in OAI API#26045

Merged
ngxson merged 4 commits into
ggml-org:masterfrom
pnb:reasoning_effort_none
Jul 24, 2026
Merged

server: support "reasoning_effort": "none" in OAI API#26045
ngxson merged 4 commits into
ggml-org:masterfrom
pnb:reasoning_effort_none

Conversation

@pnb

@pnb pnb commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Overview

The server already has a way to disable reasoning in the OpenAI-compatible chat completions API, via chat_template_kwargs, but this is a bit annoying because it is non-canonical so it works for llama.cpp and not for other software, and vice versa. The OAI API already has a defined way to disable reasoning, via "reasoning_effort": "none".

Of course, reasoning_effort can also do low/medium/etc. model-specific things, which free models generally do not support as far as I can tell, but it is relatively trivial to support the special case of none at least. This will make it easier to support software that uses the OAI chat completions endpoint for super low-latency tasks without adding a special case for llama.cpp.

Additional information

Example how to test:

curl -X POST http://127.0.0.1:8080/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "Qwen3.5-4B-Q8_0",
    "messages": [{"role": "user", "content": "What is the exact value of 1729 * 463 - 89234 / 17? Just give the number."}],
    "reasoning_effort": "none"
  }'

Observe without reasoning_effort or with reasoning_effort set to anything other than "none", it will reason for a while.

Responses API example

It also works with the responses API now, which uses a nested reasoning.effort variable instead. For example

curl -X POST http://127.0.0.1:8080/v1/responses \
  -H "Content-Type: application/json" \
  -d '{
    "model": "Qwen3.5-4B-Q8_0",
    "input": "What is the exact value of 1729 * 463 - 89234 / 17? Just give the number.",
    "reasoning": {
      "effort": "none"
    }
  }'

Requirements

  • I have read and agree with the contributing guidelines
  • AI usage disclosure: YES, pi + llama.cpp + Qwen 3.6-27B for exploration and writing some test scripts to make sure behavior matched across other providers. Final code written by me because it turned out to be super simple.

@pnb
pnb requested a review from a team as a code owner July 23, 2026 14:48
@MaxKruse

Copy link
Copy Markdown

For what its worth, the UI has the concept of None/Low/Medium/High/Max, which is different reasoning budgets. maybe it makes sense to look there as well?

@github-actions github-actions Bot added documentation Improvements or additions to documentation server labels Jul 23, 2026
@pnb

pnb commented Jul 23, 2026

Copy link
Copy Markdown
Contributor Author

For what its worth, the UI has the concept of None/Low/Medium/High/Max, which is different reasoning budgets. maybe it makes sense to look there as well?

@MaxKruse From what I can tell this is handled client-side (maybe with /v1/chat/completions/control?) and the "budget" isn't quite the same idea as "effort" (the latter being a trained model behavior rather than a post-hoc limit imposed on generation). I hope some free models will support reasoning effort levels in the future, when it might be good to revisit this.

the official doc also support max which means unlimited reasoning budget, it's worth adding too: https://developers.openai.com/api/reference/resources/chat/subresources/completions/methods/create#(resource)%20chat.completions%20%3E%20(method)%20create%20%3E%20(params)%200.non_streaming%20%3E%20(param)%20reasoning_effort%20%3E%20(schema)

@ngxson I might be asking a dumb question here but isn't "max" just unlimited, which is already the default? In this PR all values except "none" are ignored, so the user could pass in "max" and it would have the expected result of the model just doing as much as it wants.

and it should also be handled by response API: https://developers.openai.com/api/reference/resources/responses/methods/create#(resource)%20responses%20%3E%20(method)%20create%20%3E%20(params)%200.non_streaming%20%3E%20(param)%20reasoning%20%3E%20(schema)%20%2B%20(resource)%20%24shared%20%3E%20(model)%20reasoning%20%3E%20(schema)%20%3E%20(property)%20effort

Good point, I will explore adding this too.

Comment thread tools/server/README.md Outdated

`chat_template_kwargs`: Allows sending additional parameters to the json templating system. For example: `{"enable_thinking": false}`

`reasoning_effort`: If set to `none`, reasoning will be disabled for this request. Other values (e.g., `low`, `high`) are not yet supported.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the current behavior seems like: anything other than none will be defaulted to max, probably better document this

the "not yet supported" is a bit ambiguous, it can be interpreted as "throwing an error"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense, thanks. I just updated the documentation to hopefully avoid this interpretation.

@pnb

pnb commented Jul 23, 2026

Copy link
Copy Markdown
Contributor Author

It works with the responses API now too. I added an example of that.

Comment thread tools/server/server-common.cpp Outdated

// Parse also the OAI "reasoning_effort": "none" specific value
if (body.contains("reasoning_effort")) {
std::string reasoning_effort = body.at("reasoning_effort").get<std::string>();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

better to use json_value to make it similar to all other fields

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

@ngxson
ngxson merged commit 27209a5 into ggml-org:master Jul 24, 2026
21 of 25 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation server

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants