Back to blog

AI for beginnersGuide

Do agents need the model at every step? Put fixed steps in code

Why every tool result triggers another model call, which agent steps can be plain code, and what a 3-step loop costs with and without the extra call.

By CheapTokens TeamPublished 7 min read

Cover: a short agent loop where the build passed and the next step is a rule, not a model call
On this page
  1. Why one tool result means one more model call
  2. Which steps need a decision and which are fixed
  3. A 3-step loop, with and without the extra call
  4. What the HarnessMM authors report
  5. Check your own agent in ten minutes

Your agent ran for ten minutes, and the bill is bigger than the task. Very often the reason is boring: after every tool result the harness calls the model again, even when the next step was obvious.

So no, an agent does not need the model at every step. It needs the model where something has to be decided. A step that is always the same, like running the tests after a build that passed, can be a plain rule in your code.

There is a money reason to care. Each extra call re-reads the whole context as input tokens (the long-chat article shows why), so a skipped call saves more than its own short answer. If the loop itself is new to you, start with how an AI agent works and come back.

Why one tool result means one more model call#

The model never runs anything. It writes "please run make build", your harness (the program around the model) runs it, pastes the output into the conversation and calls the model again with everything so far. That is the whole loop. The model only learns what a tool returned when you call it.

Think of a new colleague who phones the manager after every single step to ask "and now?", even though the checklist says "after compiling, run the tests". The manager answers the same thing every time, and every call costs a minute of reading the whole story from the top.

Here is what that looks like in an agent log. Say the task is "fix the failing test":

An agent log with three model calls, where call 2 only repeats a fixed rule
Example agent log: call 2 is the same answer in every run

Call 2 is the interesting one. The build passed, the next step is always the tests, and the model spends a full read of the context to say "run the tests". Call 1 and call 3 are different: call 1 chooses how to start, call 3 reads the test results and writes the report. Those are real work.

Which steps need a decision and which are fixed#

Three questions sort most steps:

  • Is the next action decided by a clear signal, such as an exit code, an HTTP status or "found / not found"?
  • Is it the same action every time that signal appears?
  • Is a wrong guess cheap to undo?

Three yeses: write it as a rule. Otherwise the model keeps the step.

A second example, outside coding. Say you run a support script: a customer writes in, the script looks up the order, then replies. Looking the order up by its number is code. Filling "Your order {id} is {status}" from a template is code too. Reading "it arrived broken, what now?" and choosing between a refund, a replacement and an apology is a judgment, so that is one model call, not three.

Match the pairs

Who should handle each step?

  • Build finished with exit code 0, and the next step is always the testsCode: the next step is fixed
  • Tests failed with a stack trace; which file needs the change?Model: a new judgment
  • Order found by number, now put its status into the reply templateCode: fill the template
  • Customer writes "it arrived broken, what now?"Model: reading free text

One guard makes this safe: the rule covers only the happy path. Build failed with exit code 1? Tests red? A tool returned something the rule did not expect? Hand control back to the model, exactly as before. You are removing calls that had only one possible answer, not taking the model out of the loop.

A 3-step loop, with and without the extra call#

Let's put numbers on the "fix the failing test" log. The assumptions, all of them ours and easy to swap for yours:

  • system prompt plus task: 3,000 tokens
  • build log: 1,500 tokens; test log: 2,000 tokens
  • a reply that only asks for a tool: 60 tokens; the final report: 300 tokens

Guess the number

If the test run moves into code, how many model calls does the loop make?

Show answer

Answer: 2

Two: one to start the build, one to read both results and write the report. The test run no longer needs a decision.

Model at every step. Call 1 reads 3,000 tokens. Call 2 reads 3,000 + 60 + 1,500 = 4,560. Call 3 reads 4,560 + 60 + 2,000 = 6,620. Input in total: 3,000 + 4,560 + 6,620 = 14,180 tokens; output: 60 + 60 + 300 = 420.

Test run in code. Call 1 reads 3,000 tokens. The harness runs the build, then the tests by rule, and call 2 reads 3,000 + 60 + 1,500 + 2,000 = 6,560. Input in total: 3,000 + 6,560 = 9,560 tokens; output: 60 + 300 = 360.

The difference is 14,180 − 9,560 = 4,620 input tokens, about a third of the input, plus one small answer. On DeepSeek-V4-Flash one such task costs $0.00025 the first way and $0.00018 the second. One task is a rounding error. Say your agent does 500 of them a day (14,180 × 500 = 7,090,000 input tokens, 420 × 500 = 210,000 output tokens against 4,780,000 and 180,000):

500 tasks a day, same model
  • Model at every step$0.127
  • Test run in code$0.0897

The gap grows with the context: the longer the logs the model drags along, the more a skipped re-read is worth. Here is the same loop side by side:

Three model calls versus two when the test run is a rule in code
The same task: the middle model call disappears

In code, the rule is a few lines. This is pseudo-code, the helper names are yours:

python
result = run_tool(call)              # the model asked for: make build
messages.append(tool_message(result))

if call.name == "build" and result.exit_code == 0:
    tests = run_tool("make test")    # fixed rule, no model call
    messages.append(tool_message(tests))
# anything else (build failed, odd output) goes back to the model

reply = call_model(messages)         # the model reads everything once

What the HarnessMM authors report#

The idea is not only ours. HarnessMM is a preprint on arXiv (arXiv:2610.32813, submitted 23 October 2026, checked 2 November 2026) by Yuhua Jiang, Chang Xu, Feifei Gao and Li Zhao. Their observation: agent harnesses often call the model again after tool feedback even when an earlier call already determined the next action. Their fix, guarded decision reuse, replays that decision and falls back to the original model when a new semantic decision appears, the evidence is unsupported or the selector abstains. The if above is the hand-written version of the same idea; how their guard decides is in the paper.

The authors report these results on HumanEval:

  • Codex harness: 66.72k → 47.02k tokens per task (−29.54%), success unchanged at 90.82%.
  • DeepSeek Harness: 96.28k → 11.62k tokens per task (−87.93%), success 71.43% → 85.71%.

Read them with care. It is one benchmark, the authors' own harness, a preprint that is not peer-reviewed, and the arXiv page lists no code. You may see "88%" in retellings: that is the DeepSeek Harness figure only, the Codex one is about 30%. Treat both as a direction, not as a promise for your agent. Your own log tells you more.

Check your own agent in ten minutes#

Turn on a log of every model call, with the usage numbers from each response (tracking agent token cost in Python shows one way). Then read the last twenty runs and mark each call: decision or fixed. A call is a candidate when the next action never changed across those runs. What does your log show?

Pick your case

What does your log show?

The same pair of calls in every run

A fixed rule is hiding there. Write it as an if on a clear signal, such as the exit code, and keep the model as the fallback when the signal is anything unexpected.

Calls that only reformat or copy tool output

Move them into a template in code. If the text really needs a model, it is a small job for a cheap model, not for your biggest one.

Calls where the next step changes with the content

Keep the model here. This is what it is for, and a cheaper model often handles a plain classify-and-pick step; see model routing: cheap model first.

Every call re-reads a huge log

Trim what goes back into the conversation: keep tool output out of context. The same task gets cheaper without removing any call.

If you want to try this on a model with a long context, CheapTokens serves DeepSeek-V4-Flash (deepseek-ai/DeepSeek-V4-Flash-0731) for agent loops: one price at any hour, 380K context and up to 32,768 output tokens per answer. For the steps that still need a decision there is GLM-5.3-Flash (zai-org/GLM-5.3-Flash) with a 390K context. Both work through the OpenAI- and Anthropic-compatible API at https://api.cheaptokens.dev/v1, with one balance for all models. Setup is in the docs, prices are on the pricing page, and the model page is cheap DeepSeek.