TL;DR
An agent and its checking model (the verifier) see only the text the tool printed. If that text leaves out the search limit, the total number of results, a "this is an estimate" label, or the name of the numbering system, the model will never find out. The researchers call this kind of output "warped" (warped): the tool itself did its job correctly, but the text distorted the picture.
A typical case: the database holds 4772 documents from 1920, the tool returns the first 20 and prints "Found 20 document(s)". Every word is true. The agent answers "the archive contains exactly 20 documents". The verifier compares the answer against the tool output and agrees, because given the data it has, it is right. Neither the agent nor the verifier can recover a fact that isn't in the text. Bugs like this used to be hunted in tool code. Here they hide in the wording.
The fix is simple: rewrite the tool output so it spells out its limits. For three of the four defect types, false claims by agents dropped by 62–92 percentage points. In one test the verifier went from "accept the false answer" to rejecting it 90 times out of 90. The fourth type, identifier mix-ups, barely responds to rewording.
Want this for your own case? Apply this study to your task: AI adapts its method to what you are working on and writes the prompt.
Method Blueprint
STEP 1: Find the places where a tool result is turned into text for the model
→ a list of "formatters" (in code, MCP servers, API wrappers)
STEP 2: Check each one against 4 points:
1. What was actually examined, and is there a limit? (coverage)
2. Is the list truncated? Is the true total shown? (completeness)
3. Is every printed number labeled "estimate" or "confirmed"? (uncertainty)
4. Does every identifier state its numbering system? (provenance)
→ a list of defects
STEP 3: Rewrite the output: name the boundary, give the total, label estimates,
add a short instruction on how to handle the caveat
→ "clean" output
STEP 4: For identifiers — types or validation in code, not just wording
Steps 1–2 can be handed to a coding agent (Claude Code, Codex) in a single request. It can do steps 3–4 as well, but you need to review the edits yourself.
Example in Practice
Task: You built an analyst agent for the sales team. It talks to the CRM (say, HubSpot or Salesforce) through a small MCP server. A manager asks: "How many deals did we lose in Denver in March, and why?" The deal-search tool returned the first 50 records out of 1340 and opened its output with "Found 50 deals". The agent dutifully analyzed those 50 and delivered a report "for March". You want to check whether the other tools have the same problem.
Prompt (run in Claude Code inside the MCP server folder):
You are auditing the crm-mcp-server project for "warped formatters".
A formatter is the code that turns a tool result into the text
the model reads. A warped formatter: the tool worked correctly,
but the text gives a false impression of what it did.
Go through every tool in the /src/tools folder and check each one for:
1. COVERAGE. Is there a limit on how much was examined (characters, pages,
time period, fields)? Does the text mention it, especially when nothing is found?
2. COMPLETENESS. Is there a limit on the number of results (limit, top_k, page_size)?
Does the text say the list is truncated, and does it show the real total?
3. UNCERTAINTY. Are there values that are computed approximately
(estimate, rounding, fuzzy matching)? Are they labeled
as estimates?
4. PROVENANCE. Are there identifiers of different types that look
the same (deal id, contact id, company id)? Is the type stated next
to each one?
For every defect you find, give:
- the file and line;
- the current output wording (verbatim);
- what exactly the model might wrongly conclude;
- a proposed new wording.
Do not change any code. Report only, for now.
If a tool was checked and has no defects, say so.
Result: The agent returns a report for each tool. It lists the file and line, the current phrase like "Found N", how the model could misread it, and a ready-made replacement wording. It will likely find the limit in the deal list and possibly approximate values such as "close probability". It only proposes the edits; you make them.
Why It Works
The weakness. The model sees nothing beyond the text. It has no access to the database, to the limit code, to the real counter. It reads "Found 20" as "20 in total". The verifier is in the same position: it checks the answer against the text and finds a match. That is why a check of "is the answer supported by the tool output" doesn't catch these errors: the answer really is supported.
The strength. If the fact is stated outright ("showing the first 20 of 4772, the rest are NOT shown"), models take it into account and carry it carefully into the answer. Both the agent experiment and the verifier control showed this. Models are good at reading explicit caveats. They just need the caveat to be in the text.
How the method uses this. You fix the input text, not the model. By rewriting the output you change the input instead of asking the model to "pay more attention".
Levers:
- The question you ask the verifier. "Is this supported by the output?" catches nothing. "Is this true?", together with the real facts, catches everything (see the control table below).
- An explicit total. Not "Found 20" but "Showing 20 of 4772". That beats a bare "the list is incomplete".
- An instruction next to the caveat. In the researchers' "clean" text, each disclosure comes with guidance on how to handle it. The effect was measured for the whole text, not for a disclosure alone.
- For identifiers. A [doc:…] label didn't help. You need types and checks at the code level.
Prompt Template
This is my own build based on the paper's four-disclosure checklist. The authors' verbatim audit prompt is in the appendix, and it isn't in the excerpt provided.
<Role>
You are an auditor of the output wording of an agent's tools.
A formatter is code that turns a tool result into text for the model.
A "warped" formatter: the tool worked correctly, but the text gives
a false impression of what it did.
</Role>
<Scope>
Check: {tools_folder_or_files}
The agent works on this task: {what_the_agent_does}
</Scope>
<Checklist>
For each tool, check four disclosures:
1. COVERAGE: what did the tool actually examine? Is there a limit
(characters, pages, time period, fields)? Is it named in the text,
including when nothing is found?
2. COMPLETENESS: is there a limit on the number of results? Does it say the list
is truncated? Is the true total printed?
3. UNCERTAINTY: are there estimates, approximations, values
derived from a guess? Are they labeled as estimates?
Are "exact" facts being derived from an estimate?
4. PROVENANCE: are there identifiers of different types that
could be confused? Is the numbering system stated for each one?
</Checklist>
<Output>
For each defect:
- File and line
- Current wording (verbatim)
- What wrong conclusion the model might draw
- New wording that names the boundary and, if needed,
says how to handle it
If there are no defects, write "no defects found" and why.
Do not change code. Report only, for now.
</Output>
<Verification>
For each finding, state how it could be disproved.
Keep only the ones that survive that check.
</Verification>
What to fill in: {tools_folder_or_files} — the path to the tool code or MCP server. {what_the_agent_does} — one sentence on the agent's purpose, so the auditor knows which errors are critical.
🚀 Quick start — paste into a chat or into Claude Code:
Here is a template for auditing "warped formatters". Adapt it to my system:
[describe your system and tools].
Ask me questions to fill in the fields.
[paste the template above]
The LLM will ask what tools you have, what limits they have, and what the agent does with the results. That way the checklist targets your real risks instead of abstract ones.
Limitations
⚠️ Identifiers can't be fixed with wording: labeling
[doc:…]in the output isn't enough. Models kept passing off a document id as a scan id; only a handful answered correctly. You need type checks in code.
⚠️ "Estimate laundering": even with clean output, in some answers agents hedged the number labeled as an estimate but stated a fact derived from it (a page number) with no hedge at all. The label helps, but not completely.
⚠️ The effect was measured for the bundle, not for individual disclosures: the clean text combines facts with instructions on how to handle them. The author says plainly that the contribution of the disclosure alone was not isolated.
⚠️ One system, a small set of cases: all tests ran on a single historical archive, 32 held-out cases, 8 per defect type. There are three models and 1200 runs, but the authors did not establish how broadly the effect generalizes.
⚠️ The audit prompt is only a demonstration: it was written after the authors already knew the bugs, and tested anecdotally (two third-party systems, a PR). There's no claim that it finds everything. You need access to the tools' source code.
⚠️ Rewording isn't always the best fix: sometimes you need to change the tool itself (for example, remove the search limit) rather than tack on a caveat.
How They Researched It
The study grew out of a real incident. In the production system of the Piłsudski Institute (New York), a research RAG assistant over an archive of 17 807 documents, the agent gave a user incomplete data. The tool returned 10 documents while 191 matched, and nothing said so anywhere. The author systematically went through the formatter layer and found four families of defects: coverage, completeness, uncertainty, provenance.
Next came a paired experiment. The same tool result was shown to the agent in two versions of the text: "warped" and "clean". The system prompt and the question stayed the same. They took 40 cases (10 per family), used 8 for tuning, and kept 32 as the held-out set. Three current models (Claude, GPT, Gemini) answered each case 5 times, 1200 runs in total. The grading rules for "what counts as a false claim" were frozen before the experiment, and answers were graded by two models from different vendors. A human settled disputed cases.
The results. False claims by agents dropped: for coverage from 100% to 8%, for completeness from 62% to 0%, for estimates from 94% to 20%. For identifiers, 94% barely moved. For the verifiers, they took the same false answer and showed it alongside both versions of the text. With the "warped" output it was accepted 30 out of 30 times in each of the three families; with the "clean" one, 0 out of 30. That's 90 out of 90 flipped verdicts.
The most practical part of the control: if you give the verifier the facts and ask "is it true?" (rather than "is it supported?"), it rejects false answers. Either measure on its own, without the other, doesn't get you there.
| Question | Tool output only | + verified facts |
|---|---|---|
| "Is it supported?" | accepts 96% | accepts 61% |
| "Is it true?" | accepts 98% | accepts 0% |
Finally, the author wrote a short audit prompt and gave it to Codex and Claude Code. On an old version of his own system they found both bugs that were still alive at that point, plus twelve new ones. On OpenClaw and Hermes they found "warped" formatters in both. In OpenClaw, the attachments_fetch tool reported "not found" for a message outside the history window. The fix has already been merged. In Hermes, search_files silently truncates lines at 500 characters.
Original from the Paper
An excerpt from Figure 2: the same result shown to the verifier in two versions. Verbatim.
Condition A (warped):
Found 20 document(s)
[…]
Condition B (clean):
Showing the first 20 of 4772 documents with dates in 1920-1920
(ordered by earliest year). 4752 more documents match but are NOT
listed — this page is not exhaustive […]
User question: How many documents in the archive have dates indexed in the year 1920, and what are they? Answer based on the search you just ran.
The assistant's false answer: The archive contains exactly 20 documents with dates indexed in the year 1920. The 20 results returned by the search are all of them.
Context: with the "warped" output, all three verifiers accepted this false answer; with the "clean" one, all of them rejected it. For the estimate case, the tool line looked like this: ESTIMATED page 8 of 14 … proportional estimate, NOT a confirmed page.
The verbatim audit prompt is missing from the text provided: according to the paper it lives in the appendix, and the repository with code and data is listed under resources.
Adaptations and Extrapolations
💡 Adaptation for checking in chat: "is it true" instead of "is it supported"
You ask a second model to check the first one's report. Give it the real facts and ask about truth, not about grounding in the source. Carrying this over to chat follows from the paper's control, but the authors didn't test it in chat itself.
Here is the agent's report: {report} Here is what the tool returned: {tool_output} Here are verified facts that are not in the tool output: {facts: limits, real total, source of the numbers} Do not check whether the report is supported by the tool output. Check whether the report is true, given all the facts. If not, point out which claim is wrong and why.
🔧 Technique: a safety net in the agent's instructions → protection until the tool is fixed
The authors note that smart agents sometimes compensate for warped output with extra calls. You can add a rule like this to CLAUDE.md or the system prompt. This is my own assumption; the paper didn't test it:
If a tool result doesn't say whether the list is complete, assume it may have been truncated. Don't write "in total", "all", "exactly N" until the tool has stated the overall total. If there's no total, tell the user you can only see the returned portion, and suggest narrowing the query.This is a stopgap: fixing the tool's own text is more reliable.
Resources
- Paper: Who Verifies the Tools? How Warped Formatters Mislead Agents and Their Verifiers, William Jeffries. Accepted to the workshop Who Verifies the Agents? Toward Reliable Agent Development, NeurIPS 2026.
- Code, frozen cases, prompts, recorded responses: https://github.com/williamcodes/who-verifies-the-tools
- System the research was conducted on: the research RAG assistant of the Piłsudski Institute in New York.
- Fixes in open-source projects: OpenClaw (
attachments_fetch, fix merged), Hermes (search_files, open). - Related work: ReAct, Toolformer, τ-bench, MT-Bench, FActScore, Ragas, GroundEval, NabaOS.