Tool Result Formatting: Shaping What the Model Reads Back
AI Agents

Tool Result Formatting: Shaping What the Model Reads Back

Tool output is the largest block of prompt content you never wrote. How to shape it so agents stay accurate, cheap and able to decide what to do next.

You write the system prompt carefully. You review the tool descriptions. Then a file reader returns eight thousand tokens of source and a test runner returns the entire build log, and by turn ten the majority of the model's input is text nobody chose.

Tool results are prompt content. They compete for attention with your instructions, they persist for the rest of the session, and they are resent on every subsequent turn. Formatting them is one of the highest-leverage things you can do to an agent, and it is almost always cheaper than upgrading the model.

Every result has a budget

Decide, per tool, roughly how many tokens a single call is allowed to put into the conversation. Then enforce it in the tool, not in a prompt asking the model to be careful.

The number does not need to be precise. What matters is that no tool can unilaterally consume a large share of the window. An unbounded result is a latent incident: it works fine on your test repository and then someone points it at a generated file with forty thousand lines.

Budgets also make cost predictable. Since the entire transcript is resent every turn, a result that is oversized once is oversized for the remainder of the session. Agent token budgets covers how to set the per-session ceiling that these per-call budgets roll up into.

Truncate at the source and admit it

When output exceeds the budget, cut it — but never cut silently. A truncated result the model believes is complete produces confident conclusions drawn from half the evidence.

Say what happened and how to get the rest: [truncated: showing lines 1-120 of 4,318; call read_file with offset to continue]. That single line converts a data-loss bug into a navigable interface, and it costs a handful of tokens.

Where you cut matters as much as that you cut. The head of a stack trace is usually the useful part; the tail of a test run usually is. Log files often want the last N lines plus any lines matching an error pattern. Choose the truncation strategy per tool rather than applying one rule everywhere.

Format for the decision, not for completeness

The question to ask of every result is: what does the model need in order to choose its next action? Everything beyond that is cost.

A search that returns full file contents for twenty matches has answered a question nobody asked. The same search returning path, line number and a two-line excerpt gives the model exactly what it needs to pick which file to open, at a fraction of the size. If it wants more, it can ask — that is what the loop is for.

The same applies to command output. A test runner should return the failures with their messages, not the passing tests. A build tool should return the errors, not the compiler's progress chatter. Tool schema design covers the input side of the same discipline.

Plain text usually beats JSON

Structured output feels safer, and for machine consumers it is. For a model reading the result, JSON spends a substantial fraction of its tokens on braces, quotes and repeated key names.

A table of ten search results as JSON objects repeats every field name ten times. The same data as aligned lines — path, colon, line number, colon, excerpt — carries identical information in far fewer tokens and is at least as easy for the model to parse.

Keep JSON where the shape genuinely matters: nested data, optional fields, anything the model needs to echo back verbatim. For flat lists and logs, plain text with consistent delimiters is the better default.

Include the coordinates for the next call

A good result is not just information, it is a handle. If the model might want to act on part of the output, the identifier it needs must be in the output.

Search results carry file paths and line numbers so the next read is precise. A list of records carries IDs so the next update targets one. A directory listing distinguishes files from directories so the model does not try to read a folder.

Without these, the agent guesses, and guessing produces the wasted turns that dominate cost in long sessions. This is one of the most common differences between an agent that finishes in six turns and one that takes twenty. Agent loop anatomy covers why turn count drives everything else.

Errors are results too

The error path deserves more care than the success path, because the model reads it at the exact moment it needs to change behaviour.

State what failed, why, and what would work instead. "File not found: src/uti1s.ts. Did you mean src/utils.ts?" gets corrected immediately. A bare exception dump gets an identical retry, and possibly three of them.

Keep errors short. A stack trace from your own tooling is rarely useful to the model and frequently very long — log it for yourself and return the one line that tells the agent what to do differently.

Compaction is a formatting problem too

Even with disciplined results, a long session accumulates. Old tool output that has already been acted on is dead weight, and it is the first thing worth removing when the transcript approaches its limits.

The practical pattern is to replace a superseded result with a one-line stub recording that the call happened and what it concluded, rather than deleting it outright. The model keeps the thread of what it has already tried and stops repeating itself. Summarisation in agent loops and context compaction strategies cover the mechanics.

A working checklist

For each tool, answer four questions. What is the token budget for one call? Where does it truncate, and does the truncation announce itself? What identifiers does the result carry for the next action? And what does the error message tell the model to do differently?

Then instrument it. Log the token size of every tool result and look at the distribution, not the mean — the tail is where the incidents live. One badly behaved tool usually accounts for most of the waste, and fixing it is an afternoon of work that no model upgrade would have matched.

Common questions

Should tool results be JSON or plain text?

Plain text for flat lists and logs, since JSON spends many tokens on braces and repeated key names. Keep JSON where the shape genuinely matters, such as nested data or values the model must echo back verbatim.

How should truncation be handled?

Never silently. Say what was cut and how to get the rest, such as showing lines 1-120 of 4,318 with an instruction to call the reader again with an offset. Silent truncation produces confident conclusions from half the evidence.

Why does tool output affect cost so much?

Because the transcript is resent on every turn. A result that is oversized once stays oversized for the remainder of the session, and each subsequent turn pays for it again.

Similar articles

Tool Call Retries: Retry the Transport, Not the Judgement
AI Agents
AI Agents·8 min read

Tool Call Retries: Retry the Transport, Not the Judgement

Agents retry constantly, and most of it is wasted. How to tell a transport failure from a wrong decision, and what each one actually needs.

Read
Tool Schema Design: The Prompt You Forgot You Were Writing
AI Agents
AI Agents·8 min read

Tool Schema Design: The Prompt You Forgot You Were Writing

Tool definitions are prompt content the model reads on every turn. Design choices there change agent reliability more than model selection does.

Read
Agent Checkpointing: Saving Work a Long Session Can Lose
AI Agents
AI Agents·8 min read

Agent Checkpointing: Saving Work a Long Session Can Lose

Long agent runs die halfway. What to checkpoint, where the boundaries belong, and why external side effects break the snapshot model entirely.

Read