Skip to content

Planning and Reasoning in Agents

13 min read
same task · two decoding budgets
prompt
a farmer has 17 sheep, all but 9 run away. how many are left?
no thinking budget
think: 0 tok · answer: 0 tok
model jumps straight to the obvious arithmetic
with thinking budget
think: 10 tok · answer: 0 tok
think"all but 9 run away" means 9 do NOT run.
thinking tokens are hidden from the user in production

Same model, same prompt. The budgeted run spends a handful of tokens catching the trap in the wording before committing to an answer. That spend happens before the action, not inside it.

The agent loop we built a few posts back has one obvious weak spot. Between the moment the model reads the user's message and the moment it fires off a tool call, there's almost no time for it to think. It has one forward pass of decoding to pick an action, commit to it, and move on. For easy tasks that's fine. For anything that requires catching a subtle wording trap, weighing two plausible next moves, or noticing that the problem is harder than it looks at first, one pass isn't enough.

This post is about what happens when we give the model more decoding-time compute before it acts. That compute has a name in the literature (chain-of-thought, extended thinking, test-time search) and a shape in practice that's worth getting concrete about. The sticky version of the mental model I want you to walk away with:

Thinking is a budget. Spend it where the search is, not where the action is.

Everything in this post is a variation on that idea.


One decoding pass is not enough

Language models generate text one token at a time, left to right. Once a token is committed, it's in the context, and every later token is conditioned on it. That's fine when the first token is obvious, and disastrous when the first token is wrong.

The sheep problem in the hero is a miniature version of this. "All but 9" is a phrase that looks like an arithmetic signal but is really a trap. If the model's first output token commits to "8", no amount of later tokens can pull it back without an explicit self-correction, and base models trained on next-token prediction don't do that reliably.

The escape hatch is to let the model produce tokens that don't count as the answer. Scratch work, interior monologue, tokens it can revise, contradict, and discard before it writes the final line. That's the content of "reasoning" as the field uses the term. When I first heard "the model reasons" I expected some new cognitive faculty. It turns out to be more decoding, earlier, in a region the user doesn't see.


The minimal math: a compute-accuracy curve

If you fix a task and a model and vary the number of thinking tokens the model is allowed to emit before committing to an answer, you get a curve. On easy tasks it's flat near the ceiling. On medium tasks it's a sigmoid that saturates somewhere in the middle. On hard tasks it still saturates, but below 100%, because the model is missing world knowledge that reasoning can't invent.

accuracy vs thinking budget · hover to inspect
0%25%50%75%100%0642561k4k16kthinking-token budgeteasy taskmedium taskhard task
budget ≈ 84 tok
full reasoning · real search happens here
easy task: 96% medium task: 64% hard task: 21%

Three tasks, three shapes. Easy tasks sit near the ceiling regardless of budget. Medium tasks reward thinking but saturate quickly. Hard tasks have a ceiling below 100% because the model is missing world knowledge no amount of reasoning will invent.

Accuracy as a function of thinking-token budget, on three task difficulties. Easy tasks are flat near the ceiling. Medium tasks ride a sigmoid up to a saturation point. Hard tasks rise but plateau below the ceiling. Past saturation, more thinking tokens cost money and sometimes hurt accuracy.

The marginal return on thinking tokens is almost never monotonic. There's a regime where more tokens help a lot, a regime where they help a little, and a regime where they cost real money and hurt accuracy. And that last regime is real. Models can and do talk themselves out of correct answers when given too much rope, especially on tasks that were easy to begin with.

So the practical question stops being "should I enable reasoning?" and becomes "how much budget, for this task?" The answer depends on where on the curve you are.


What extended thinking actually is at runtime

The 2023-era trick was chain-of-thought prompting: add "let's think step by step" to your prompt, and the model would emit a reasoning trace before the final answer. It worked well for a prompting trick: it improved hard tasks noticeably while costing extra tokens, and by 2024 it was the default for any benchmark that involved arithmetic or multi-step logic.

The 2026 version is different in a way that matters. Anthropic's extended thinking, OpenAI's o-series, DeepSeek-R1, Gemini's thought signatures: these are trained capabilities, not prompting tricks. The model has learned, during post-training, to allocate an internal budget of thinking tokens, reason inside a structured block, and emit a final answer at the end. You control the budget via an API parameter (Anthropic calls it budget_tokens, OpenAI calls it reasoning_effort) and the model is expected to spend up to that much on interior work before it commits to the visible output.

A few runtime details that matter for the mental model:

  • The thinking block is separate from the final response in the transcript format. Users typically don't see it. Providers sometimes redact, summarize, or compress it on the way back to the client.
  • Thinking tokens are real tokens that go through the normal decoding loop, cost money, and fill the KV cache. A 32k thinking budget on a 50-turn agent run is real money.
  • When the agent calls a tool, the thinking block frequently appears between the prompt and the tool_use output. The model is thinking about which tool to call, not just about what to say.
  • Thought signatures preserve the thinking across turns in some providers, so the model can refer back to its own reasoning on a later call without re-deriving it.

So "reasoning" in the 2026 sense is: more decoding, inside a dedicated block, trained for, preserved across turns, and priced as tokens.


Worked example

Here's a small multi-step puzzle, the kind of thing reasoning models were trained to do well on.

You have a 3-liter jug and a 5-liter jug. Measure exactly 4 liters.

Run it with no thinking budget and a reasonable model will sometimes produce a correct sequence and sometimes drop a step. The failure mode isn't "obviously wrong"; it's that the plan sounds fluent but doesn't add up. Run it with a moderate thinking budget and the model will enumerate a couple of candidate paths, discard the one that loops, and return the canonical solution.

The interesting part isn't that thinking helped. It's where the thinking went.

tree of thoughts · game of 24 · target = 24
nums: 4 6 8 94 + 6 → 109 − 8 → 18 × 9 → 72
step 1/7expand 3 candidate first moves

Tree of Thoughts expands a handful of candidates at each step, asks the same model to score each one, and keeps only the best. A greedy single-path decode would have committed to 4 + 6 at the first step and never found the 4 × 6 route. The cost is that you run the model many more times per task.

Explicit tree search over reasoning branches. The model proposes several candidate next moves, scores each one with itself as the evaluator, prunes losers, and expands the survivors. In practice, modern reasoning models do something like this implicitly inside one long thinking block.

Tree of Thoughts is the research-grade version of this: expand multiple candidate next moves, score each one with the same model acting as its own evaluator, prune to the best, repeat. It's a real speedup on puzzle-shaped tasks in papers. In production agents, it's rare. The dominant pattern is closer to "let the model think longer in a single block and call tools" than "orchestrate explicit tree search over the model's own outputs." Tools give you information the model doesn't have, which is usually a better lever than more internal search.

I'm showing the tree anyway because it makes the search concrete. When a reasoning model thinks about a hard problem, something close to this tree is happening inside the thinking block, implicitly. The branching and pruning are just not broken out into separate API calls.


The plan-execution gap

Here's the gap that shows up in practice. A model can write a genuinely excellent plan and still fall over when it's time to execute.

plan vs execution · task: fix the auth bug
planned
step 1
search repo for 'auth middleware'
step 2
open src/auth/middleware.py
step 3
patch the session validator at line 42
step 4
run pytest tests/auth/
executed
step 1
search repo for 'auth middleware'
step 2
open src/auth/middleware.ts
step 3
patch the session validator at line 61
step 4
run npm test -- auth

The plan was reasonable. The world was not. Every non-trivial agent task produces a trace like this: the first step matches, and then state drift accumulates. An agent's real skill is noticing the divergence and replanning, not writing the original plan.

A clean plan in the model's head, drifting from the world step by step as the actual file paths, test runners, and line numbers turn out not to match. Recovery — noticing the divergence and replanning — is the skill long-horizon agents actually need.

The pattern is familiar if you've watched an agent actually run. The plan assumes a file at a certain path, but the file moved. The plan assumes a test runner, but the repo uses a different one. The plan assumes a line number, but the line shifted after a refactor two weeks ago that isn't in training data. At each step, the model's belief about the world diverges a little from the world, and the divergences compound.

This is why "just plan better" doesn't solve agent reliability. Long-horizon tasks don't fail because the plan is wrong. They fail because the world is surprising, and the agent doesn't notice in time to replan.

The skill you want is recovery: detect the divergence, abandon the failing branch, replan from what the tools returned. Reflexion-style loops are the research-grade version of this.

reflexion loop · attempt → critique → reflect → retry
attempt 1act in the worldexecution · critiquewhat went wrongreflectionone-line lessonattempt 2 (context: reflection)retry + memoryepisodic memoryappended to next prompt
attempt 1
i will open the fridge and read the label on the milk carton.
waiting for the loop to complete

Reflexion turns a failed episode into a short lesson and prepends that lesson to the next attempt. The loop matters because the plan-execution gap is where real agents lose; recovering from it is a skill you can teach in the same way you'd teach any other.

Reflexion's outer loop. After a failed attempt, the agent writes a one-line natural-language reflection and prepends it to the next attempt's context. Verbal self-critique stands in for gradient updates, and the next try gets a head start.

Reflexion keeps a short "episodic memory" of one-line lessons from failed attempts and prepends it to the next attempt's prompt. Production systems rarely implement it literally; what they do instead is build the same structure into the agent loop: after a tool returns an unexpected result, the model is given the result, asked to critique its own plan, and re-enter the loop with the critique in context. Same idea, different packaging.


Implementation sketch

A minimal extended-thinking call against the Anthropic SDK, parsing the thinking block out of the response. Nothing exotic. The same shape works for the OpenAI o-series with reasoning_effort in place of thinking.

import anthropic
 
client = anthropic.Anthropic()
 
resp = client.messages.create(
    model="claude-opus-4-7",
    max_tokens=4096,
    thinking={
        "type": "enabled",
        "budget_tokens": 8000,   # spend up to 8k on interior reasoning
    },
    messages=[
        {
            "role": "user",
            "content": (
                "A farmer has 17 sheep. All but 9 run away. "
                "How many sheep are left? Think carefully."
            ),
        }
    ],
)
 
# The response is a list of blocks. Thinking blocks come before the text.
for block in resp.content:
    if block.type == "thinking":
        print("--- interior monologue ---")
        print(block.thinking[:400], "...")
    elif block.type == "text":
        print("--- final answer ---")
        print(block.text)
 
# usage.thinking_tokens and usage.output_tokens are billed separately
print(f"think: {resp.usage.thinking_tokens} · answer: {resp.usage.output_tokens}")

Two things to notice. The thinking block comes back as its own block type, distinct from the text block, so you can log it, inspect it, or drop it. And thinking tokens are billed. The budget is an upper bound, not a target; the model may stop early if it believes it has enough. If you crank the budget to 32k on every call, you'll pay for up to 32k on every call whether the task needed it or not.


Misconceptions

"More reasoning tokens always help." Past a threshold that depends on the task, they don't. Past the saturation point, extra thinking either does nothing or actively hurts by amplifying whatever direction the model was already committed to. The right policy is to tune the budget per task type, not to max it out globally. Anthropic and OpenAI both ship separate parameters precisely because one budget doesn't fit all workloads.

"Chain-of-thought is the same as a reasoning model." Chain-of-thought is a prompting trick that asks a general model to produce intermediate reasoning tokens. Reasoning models are trained to allocate a budget of those tokens well, inside a dedicated block, with post-training specifically for self-correction. Using "let's think step by step" on a reasoning model is usually redundant and sometimes harmful, because it double-prompts the behavior the training already installed.

"Tree of Thoughts is what production agents do." Mostly research. Production agents lean on tool use, retries, and a single long thinking block far more than on explicit tree search over self-scored outputs. The cost ratio makes ToT hard to justify: you're paying for a handful of extra forward passes per decision to get a correctness lift that a single round of tool use would usually produce for less.

"Thinking blocks are what the user sees." Usually no. Providers hide thinking from end users by default, sometimes redact or summarize it for safety, and sometimes return it only as a signed "thought signature" that lets the model refer back to its own reasoning on the next turn without exposing the raw tokens. If you want to display reasoning to a user, you're almost always showing a summary the provider generated for display, not the thinking block verbatim.

What's next

Reasoning gives the agent longer decoding before action. What it doesn't give the agent is new senses. Many of the tasks agents are now asked to do (navigating a web page, reading a screen, filling out a form) require looking at pixels, not just thinking harder about text. The next post covers Computer Use and Browser Agents, how screenshot-driven agents work and where their reliability still breaks.


Additional reading (and watching)