Reasoning Models in Agent Loops
A reasoning model writes a private working-out before it answers. In a single-turn chat that costs you one wait. In an agent loop it costs you one wait per turn, and a loop that takes eight turns has paid for eight of them before anything useful happened.
By the end of this lesson you will be able to switch thinking on and off for every engine and model family in this course, decide which turns deserve a thinking budget, say what to do with reasoning text when you build the next request, and make the case for and against using a non-reasoning model as your agent.
What each family offers, and how to switch it
Section titled “What each family offers, and how to switch it”Four different mechanisms, and no two spell it the same way.
Qwen3 ships both modes in one model. The card describes “seamless switching between thinking
mode (for complex logical reasoning, math, and coding) and non-thinking mode (for efficient,
general-purpose dialogue)”, with thinking wrapped in <think>...</think> blocks and on by
default. It is turned off with enable_thinking=False at the template level, and there are soft
switches: /think and /no_think in the prompt, with the model following the most recent
instruction in a multi-turn conversation. The card also gives different sampling settings per
mode, which most people miss: temperature 0.6, top-p 0.95, top-k 20 and min-p 0 for thinking,
with an explicit “DO NOT use greedy decoding”, and temperature 0.7, top-p 0.8, top-k 20 and
min-p 0 for non-thinking.
gpt-oss has a dial rather than a switch. The card describes three levels of reasoning effort
and states that “the reasoning level can be set in the system prompts, e.g., ‘Reasoning: high’”.
Its thinking lives on the harmony format’s analysis channel, with function calls placed on the
commentary channel and the answer on final.
Qwen3-Coder does not think at all: the card says it “supports only non-thinking mode and does
not generate <think></think> blocks in its output”. That is a deliberate choice for a model
built for agentic coding, and it is the strongest hint in this lesson.
Everything else is per-model. Read the card before you assume, because the failure when you get it wrong is silent: a model that was trained to think and is prevented from doing so answers worse, and a model that was not trained to think and is asked to will produce something that looks like thinking and is not.
Per engine, the switches as documented on 2026-09-09:
| Engine | Turn thinking off | Where the thinking arrives |
|---|---|---|
| vLLM | chat_template_kwargs: {"enable_thinking": false} per request, or --default-chat-template-kwargs '{"enable_thinking": false}' at launch |
A reasoning field, when --reasoning-parser is set |
| llama-server | --reasoning-budget 0, documented as “immediate end” |
Controlled by --reasoning-format: unparsed in message.content, or in message.reasoning_content |
| Ollama | think: false in the request |
message.thinking |
The cost is per turn, and it compounds
Section titled “The cost is per turn, and it compounds”Think about where the time in a turn goes. The prefill reads the transcript, which grows every turn. The decode writes the thinking, then the call. The tool runs, which is usually fast. Then it all happens again with a longer transcript.
Where a turn goes, with and without thinking, over four turns of the same task
Two numbers set the scale, and both come from the model cards rather than from a stopwatch. Qwen3’s card recommends a maximum output length of 32,768 tokens, rising to 38,912 for complex maths and programming, and thinking is what fills that budget. A tool call is a few dozen tokens. So a thinking turn can decode two or three orders of magnitude more tokens than the call it eventually emits, and decode is bandwidth-bound on every track in this course.
| Configuration | Output tokens per turn | Turns to finish | Wall clock, whole task (s) |
|---|---|---|---|
| Thinking off | pending | pending | pending |
| Thinking on, every turn | pending | pending | pending |
| Thinking on first turn only | pending | pending | pending |
per track, recorded by the validation pass, per track · llama.cpp v0.4.0 · Qwen3-8B, Q4_K_M · 32,768 tokens of context · pending
The first lab's task set and transcript log produce all three rows: run agent-tasks.json with thinking off, on, and on for the first turn only, and read the totals out of the transcript. Fill this in on your own hardware before deciding.
Where a thinking budget is worth spending
Section titled “Where a thinking budget is worth spending”Not every turn is the same kind of turn. In practice an agent loop has three:
Planning turns, where the model decides what the task actually requires and in what order. There is real work here, the input is ambiguous, and a wrong decision costs several wasted turns. This is where thinking pays.
Dispatch turns, where the next step is obvious from the last observation: the file was found, now read it. There is nothing to reason about. Thinking here produces a paragraph explaining that reading the file is a good idea, and then reads the file.
Recovery turns, where something failed: a tool returned an error, a search found nothing, a test broke. The input is genuinely surprising and the right response is not obvious. Thinking often pays here too.
So the useful pattern is not “thinking on” or “thinking off” but thinking sometimes, decided by your loop:
Fragment — not complete on its own
# Spend thinking where a decision is actually being made, not on every dispatch.def wants_thinking(turn_index, last_observation): if turn_index == 0: return True # the planning turn if last_observation is None: return False return "error" in last_observation.lower() or "no results" in last_observation.lower()
payload["chat_template_kwargs"] = {"enable_thinking": wants_thinking(turn, last)}That is a policy you can measure. Run the first lab’s task set three ways, thinking always, never and selectively, and compare turns to completion and wall clock. The answer differs by model and by task, which is the whole point of measuring it.
Interleaved thinking, and what the engines actually do with it
Section titled “Interleaved thinking, and what the engines actually do with it”“Interleaved thinking” describes a loop where the model thinks, calls a tool, sees the result, thinks again about that result, and calls another. It is the natural shape for a recovery turn, and it is worth being precise about what happens to those thoughts because the engines differ.
On every engine in this course, each turn is an independent request. There is no thinking that persists between turns unless you put it there. So interleaving is not a mode you switch on; it is what you get by default when thinking is enabled and the loop runs more than once. What you choose is whether turn three can see what turn two was thinking, and that choice is one line in your loop.
Two things make the difference worth measuring rather than assuming. Keeping the thinking gives later turns the reasoning that led to the current state, which sometimes stops a model re-deciding something it already settled. Dropping it keeps the transcript short, keeps the prefix cache intact, and removes a large block of text that competes for attention with the observations. On the short, well-tooled tasks in this part’s first lab, dropping it is almost always the better trade; on a fifteen-turn task with an ambiguous goal, it is worth trying both and comparing turns to completion.
What to do with the reasoning text
Section titled “What to do with the reasoning text”Three choices, and the middle one is usually right.
Drop it. Read the reasoning field for your log, and build the next request from the assistant message and the tool results only. The transcript stays short, the cache stays warm, and no thinking token is ever charged twice. Most local agent loops should do this.
Keep a summary. Have the loop write one line into the transcript: what the model decided and why. This is a form of the compaction the next lesson covers, and it keeps continuity across turns without keeping thousands of tokens.
Keep everything. Only when the model’s own documentation says its multi-turn behaviour depends on seeing its previous thinking. Check the card; do not assume in either direction.
There is a fourth thing you should not do, which is feed reasoning back as if it were content. vLLM states that “tool calling only parses functions from the content field, not from the reasoning”, so reasoning text pasted into a content field is text the parser will read as an answer rather than a call.
When a non-reasoning model is the better agent
Section titled “When a non-reasoning model is the better agent”The case is stronger than it sounds, and Qwen3-Coder is the evidence: a model built specifically for agentic coding, with a 262,144-token native context, that does not think at all.
Prefer a non-reasoning model when the loop has these properties, which most tool loops do:
- The next step is determined by the last observation. Dispatch turns dominate. There is nothing for reasoning to add.
- Turn count matters more than single-turn quality. Ten cheap turns often beat three expensive ones, because each turn brings back real information from a tool rather than speculation.
- The tools are the intelligence. A search index, a test runner and a type checker each know something the model does not. Reasoning about what the tests might say is strictly worse than running them.
- The transcript is long. Anthropic’s context-engineering post describes an “attention budget” that thins as context grows, and thinking tokens spend that budget on text that is about to be discarded.
Prefer a reasoning model when the task genuinely needs a plan before any tool is useful, when the observations are ambiguous and need interpretation, or when a wrong first move is expensive to undo.
Spend reasoning effort where the outcome can improve
Section titled “Spend reasoning effort where the outcome can improve”An agent turn may require planning a difficult change, or merely reading a file whose path is already known. Using a long generation budget on every turn can increase latency and consume context without improving those routine steps. Compare a fixed task suite under deliberately chosen reasoning configurations and keep tool behaviour unchanged.
Record final success, tool errors, generated tokens and wall time. Inspect cases where extra generation changes the plan and cases where it only lengthens the transcript. A model that writes a convincing analysis but invokes the wrong tool has still failed the application contract.
Keep any provider-specific reasoning representation separate from the user-visible answer and tool messages according to the API contract. Do not assume a displayed explanation is a faithful causal account of internal computation. For correctness, rely on independent checks of actions and outputs. The useful setting is the one that improves verified outcomes within the task’s resource budget, with stopping conditions that prevent repeated deliberation from becoming an unbounded loop.
Qwen3 carries both modes with enable_thinking and the /think and /no_think switches and
different recommended sampling settings for each, gpt-oss takes a reasoning-effort level in the
system prompt and puts thinking on a harmony channel, and Qwen3-Coder does not think at all. Each
engine spells the switch differently: chat_template_kwargs on vLLM, --reasoning-budget 0 on
llama-server, think: false on Ollama, and the field the thinking comes back in has recently been
renamed on vLLM. In a loop the cost of thinking is paid once per turn and again on every following
turn if you keep it in the transcript, so the right question is which turns deserve it: planning
and recovery turns usually do, dispatch turns usually do not, and a loop can decide that per
request. Drop the reasoning text from the next request or keep one line of summary, never paste it
into a content field, and remember it can contain anything the context contained. And a
non-reasoning model is often the better agent, because in a well-tooled loop the tools carry the
knowledge and the transcript is the scarce resource.
Check your understanding
Sources for this lesson
8 verified · checked 2026-09-09
- 01Qwen3-8B model card§ Thinking and non-thinking modes; enable_thinking; sampling settings; output lengthhuggingface.co/Qwen/Qwen3-8B2026-09-09
- 02Qwen3-Coder-30B-A3B-Instruct model card§ Non-thinking mode; context length; sampling settingshuggingface.co/Qwen/Qwen3-Coder-30B-A3B-Instruct2026-09-09
- 03gpt-oss-20b model card§ Harmony format; reasoning effort; agentic capabilitieshuggingface.co/openai/gpt-oss-20b2026-09-09
- 04OpenAI — Harmony response format§ Channels; instruction hierarchygithub.com/openai/harmony2026-09-09
- 05vLLM — Reasoning outputs§ Reasoning parsers; the reasoning field; disabling thinking; tool callingdocs.vllm.ai/en/latest/features/reasoning_outputs.html2026-09-09
- 06llama.cpp — llama-server README§ --reasoning-format; --reasoning-budgetgithub.com/ggml-org/llama.cpp/blob/master/tools/server/README.md2026-09-09
- 07Ollama — Tool calling§ The think parameter; message.thinking; streamingdocs.ollama.com/capabilities/tool-calling2026-09-09
- 08Anthropic — Effective context engineering for AI agents§ Context as a finite resource; the attention budgetanthropic.com/engineering/effective-context-engineering-for-ai-agents2026-09-09
Every technical claim on this page was checked against the official documentation of the tool, vendor or model publisher on the date shown, at the version pinned for the course. Where the course disagrees with folklore, the source is how you can tell which one to trust.