My AI made up results. Here is how to catch it.

How do I catch an AI agent making up results? You stop reading the answer and start matching claims to records. Every result an agent states came from somewhere: either a call ran and produced it, or the model wrote it. A run call leaves a record at the moment it happens. Zambo is the verifiable work layer for AI, and its instrument for this problem is the AER-1 verifiable receipt: for each call, a public record whose saved output is committed under a digest at execution time. Put the claimed result next to the saved output. They match, and the result is real and intact. They differ, and the claim was altered. There is no record at all, and you have your answer: nothing ran, and the confident paragraph in front of you was composed, not computed. A receipt proves the saved result was not changed since it was saved, which is what makes the comparison decisive instead of another opinion.

Worked example: one claim, checked against its record

Say an agent reports back: LINK is at $12.51, up 0.83% today. The claim is checkable because the call that produced it left receipt 8ed4106e-2dc6-4567-9a8f-d090be3e2a98, a live_price call made on October 15, 2026 at 22:54:25 UTC, provenance class EXECUTED BY ZAMBO. The recorded inputs, the single field symbol set to LINK, are committed under input hash sha256:3e4f665cd6ac44fda2f440d31f3bbb368d1e8c238cde3b354e23b7654411bdc0. The saved result in the record reads, in full: LINK $12.51 USD, up 0.83% in 24 hours, market cap $9.60B, live price via CoinGecko. It is committed under output digest sha256:307778adc7aa92c0ec8006ea868d10b5fc7ad79f47558bcd2454e6dcaa40743a.

Run the three readings against that record. The claim matches the saved result exactly, and the public verify endpoint recomputes the digest from the saved bytes and reports the commitment, canonical payload, provenance binding, and metadata binding checks all passing: this result ran, and it reached the page unaltered. Had the chat said $13.20 instead, the same record would have exposed it in seconds, because the saved output is fixed at execution time and the chat is not. And had there been no receipt for the call at all, there would be nothing to check the number against, which is precisely the situation a made-up result depends on. Rerun the check yourself at the public verifier, free, with no account.

Try it on a fresh call: the live demo runs one real call and hands you its verifiable receipt, no signup.

Published October 15, 2026. Updated October 17, 2026. Written against AER-1, IETF Internet-Draft revision 23: draft-zambo-aer1-23. AER-1 is an IETF Internet-Draft, not a finalized standard.

How do I catch an AI agent making up results

The short answer: the claim-to-record test. Take the specific result the agent stated. Not the whole answer, not the summary: the number, the quote, the finding. Then ask one question of it: where is the record of the call that produced this? A result that was actually produced has one, minted at execution time, and the record's saved output is the result itself, committed under a digest. The test has exactly three outcomes, and each one tells you what you are holding:

  • The saved output matches the claim, and the digest recomputes. The call ran, and the result in front of you is the result it produced, unchanged. This is the only outcome that earns trust, and it costs the agent nothing when the work was real.
  • A record exists, but its saved output differs from the claim. Something ran, and then the claim drifted from it: rounded into a different number, upgraded from a partial result, or rewritten outright. The mismatch is the catch, and it is mechanical, not arguable.
  • There is no record. No call produced the result. Whatever its source, it was not a tool returning data; it was the model producing text that resembles a result. Treat it as unverified, because unverifiable is what it is.

Scope, stated once and applied everywhere on this page: a verifiable receipt proves the saved result was not changed since it was saved. It does not prove the result was correct, and it does not prove an external event happened beyond what the record itself shows. For this problem that scope is the whole game: the test separates results a call actually returned from text the model composed, and it proves the returned ones reached you intact.

Why agents make up results

Not usually out of anything like intent. The failure is structural. An agent's reply is generated text, and generated text has no built-in marker separating a tool returned this from this is what a tool would probably return. When a call fails, times out, was never available, or was quietly skipped, the model still has to finish the paragraph, and finishing the paragraph fluently is the thing it is best at. The invented result inherits the tone of the real ones around it: same format, same confidence, same citations style. That is why proofreading the answer never catches it. A fabricated price and a fetched price read identically, because reading is not the layer where they differ. They differ at the record layer: one of them has a receipt and the other has nothing.

This is also why the fix cannot be a sterner prompt. Telling the agent not to invent results adds an instruction to the same text channel that produced the invention. The fix is to route the work through calls that leave records, so that every result arrives with its evidence attached and the claim-to-record test can be run by anyone, including the agent's own operator, in seconds. The lying-about-done page covers the sibling problem, the invented completion, and Did my AI agent actually run it? covers the per-call version of the question.

The check, step by step

  1. Isolate the claim. Pick the exact result you are about to rely on: the figure, the quote, the yes or no. Vague answers cannot be checked; specific claims can.
  2. Ask for the record, not a screenshot. The receipt for the call, as a link to the public record. A screenshot is an image of text and can be produced as easily as the claim was.
  3. Compare the saved output to the claim. Open the record and read its saved result. Word for word, digit for digit. This is the step where fabrications and quiet alterations surface.
  4. Recompute, or let the verifier do it. The output digest is computed over the saved bytes at execution time. The public verifier at zambo.dev/verify recomputes the commitment, payload, provenance, and metadata checks in the open; a passing set means the record in front of you is the record that was minted.
  5. Read the provenance and the time. The receipt states the provenance class, who ran or reported the call, and the execution timestamp. A result claimed from this morning with a record from last week is a mismatch of a quieter kind.
  6. Act on the outcome. Match: proceed. Mismatch: the claim is wrong, whatever the run produced. No record: the result is unverified, and it stays that way until it is rerun through a recorded path.

The whole test takes under a minute per claim, needs no account, and works the same whether the agent ran in Claude, ChatGPT, Gemini, Cursor, or Grok, because the record format does not change with the client.

What a record that settles it looks like

Not every artifact called a record settles anything. The ones that do share a shape:

  • Minted at execution time by the system that ran the call, not written up afterward by the agent or its operator.
  • The recorded inputs, committed under an input hash, so the record shows what the call was actually asked.
  • The saved result, committed under an output digest, the exact bytes the comparison runs against.
  • The provenance class, stating who ran or reported the action, bound into the same record.
  • The tool, its version and scope, and the execution timestamp, so the record says what executed and when.
  • A public location, so the person checking needs no account, no permission, and no cooperation from whoever ran the agent.

Hold any result's evidence up against that list. The missing items are usually the finding: a record written afterward, a result with no digest, a claim whose only location is the chat itself. Each gap is a place where text can be, and eventually will be, composed instead of computed.

When the citation itself is fabricated

A fabricated citation is the made-up result wearing a reference, and it comes in three kinds. The source does not exist: the link is invented, the paper was never published, the page returns a 404, the quote appears nowhere in the document it is attributed to. The source exists but does not say that: a real link carrying a claim its text never makes, counted on nobody opening it. The source exists and says something close: and the claim quietly upgrades it, a may into a does, a draft into a standard, one figure into a rounder one. All three survive proofreading, because a citation looks like diligence. None of them survives the source check.

The check, complete, in order:

  1. Resolve the source. Open the cited link, or fetch the page. A source that does not resolve, never existed, or resolves to a different document than the one described ends the check on the spot: the citation was fabricated, and every claim resting on it is unsupported until it is re-grounded.
  2. Match the claim to the text. Read what the source actually says and compare it with the claim, word for word on the parts that matter: the number, the date, the yes or no. The claim is backed only where the text is. A real source under an invented claim is the same failure one layer down, and this is the step that catches it.
  3. Keep the lookup receipt. Run the fetch through a recorded call, so the text you checked is committed under a digest at the moment you checked it. Pages change, drafts are revised, links rot. The lookup receipt freezes what the source said when the claim was judged, so the citation can be re-examined later against the same text, not against whatever the page says by then.

Worked example: one citation, resolved, matched, and kept

On October 15, 2026 the check was run on a claim of exactly the kind agents make in passing: AER-1 is at revision 20 and expires on 15 April 2027, per the IETF Datatracker. The lookup ran as a recorded pdf_extract call against the cited page, https://datatracker.ietf.org/doc/draft-zambo-aer1/20/, and left receipt e2055858-7032-40cb-8907-6f8f906e7ba0 at 23:23:32 UTC, provenance class EXECUTED BY ZAMBO.

Step one, resolve: the cited page is the real Datatracker document page for the draft, so the source exists and is the document the citation describes. Step two, match: the saved output of the call is the extracted text of that page, and it contains the exact lines the claim rests on: the document header names draft-zambo-aer1-20, its type is listed as Active Internet-Draft, and the draft header carries the line Expires: 15 April 2027. The claim matches the source text as fetched, on both of its checkable parts. Step three, keep: the recorded inputs are committed under input hash sha256:8d63d55805734f72e769e3329499951e9cf0d552d5168aaa1c272927a5d2cbb1 and the saved output under output digest sha256:9b73fec033e7b2439fd8345876eba159b022e18d888cd02a206f3d8e307917fd, and the public verify endpoint reports the receipt verified, with the commitment, canonical payload, provenance binding, and metadata binding checks all passing. The lookup is now itself a record: if the claim is challenged after the draft is revised again, the text it was matched against is still there, byte for byte.

Read the two negative cases against the same example. Had the claim said the draft expires in 2026, step two fails in seconds against the saved text, without anyone reopening the page. And had the agent produced the citation from memory, with no lookup call behind it, there would be no saved text to match against at all: the citation would be a claim about a source, not evidence from one, which is the state every fabricated citation depends on.

The habit that prevents all three kinds: citations are produced by lookups, not by memory. When the agent fetches the source through a recorded call and writes the claim from the saved output, the citation arrives with its evidence attached, and the check above takes seconds because the record already exists.

The format underneath: AER-1

The receipts used in every section above follow one open format: AER-1, IETF Internet-Draft revision 23 (draft-zambo-aer1-23). AER-1 is an IETF Internet-Draft, not a finalized standard. It defines the per-step verifiable receipt and the workflow record that links receipts for a run, so a receipt produced in one place can be checked by a receiver somewhere else, with no account on the system that produced it and no cooperation from the operator who ran the agent.

To put receipts under your own agent's work: start with the live demo for a single checked call, then a Zambo Day Pass for a day of calls with a verifiable receipt under each one. The general method this page applies is laid out in Verify AI work: check the record, not the summary.

Questions, answered

How do I catch an AI agent making up results?

Run the claim-to-record test on the specific result. Ask for the receipt for the call that produced it, open the record, and compare its saved output with the claimed result word for word. If the saved output matches and its digest recomputes, the result ran and reached you intact. If the saved output differs, the claim was altered after the run. If there is no receipt, no call produced that result: it was written by the model, not returned by a tool, and it should be treated as unverified until it is run through a recorded path.

What is the difference between a wrong result and a made-up result?

A wrong result came from a real call: the tool ran, returned something incorrect or stale, and the record shows exactly what it returned, so the error can be found and fixed. A made-up result came from no call at all: the model produced plausible text where a tool result should have been, and there is no record because nothing executed. The receipt is what separates the two cases, because only one of them leaves one.

My agent cited a source for its answer. Is that enough?

No. The citation itself is generated text, and a real link can sit under an invented claim about what the link says. The check is one level down: the call that fetched the source should have a record, and the record's saved output is what the source actually returned at that moment. Compare the claim against the saved output, not against the citation. If the claim matches the saved output and the digest recomputes, the citation is backed; if not, the claim is the part that was made up.

My agent cited a source that does not exist. How do I check it?

Run the source check, in order. First, resolve the source: open the cited link or fetch the page. A source that does not resolve, never existed, or resolves to a different document than the one described ends the check: the citation was fabricated. Second, if it resolves, match the claim to the text: read what the source actually says and compare it with the claim word for word, because a real source under an invented claim is the quieter version of the same failure. Third, keep the lookup receipt: run the fetch through a recorded call, so the text you checked is committed under a digest at the moment you checked it, and the citation can be re-examined later even after the page changes. A citation with no lookup behind it is a claim about a source, not evidence from one.

Can an agent fake the record itself?

Not after the fact. The receipt is minted by the executing system at execution time, and the input hash and output digest are committed in the record at that moment. Writing a different result into the record later breaks its digest, and inventing a record for a call that never ran requires the executing system's minting path, not the chat window. The provenance class on the receipt also states who ran or reported the call, so a record names who stands behind it.

What do I do when there is no record for a result?

Treat the result as a claim, not a finding. Do not act on it, quote it, or build on it. Then rerun the work through a path that leaves a receipt for each call, so the new result arrives with its record attached and can be checked the moment it lands. An agent whose work runs through recorded calls never has to ask to be believed, and a result with no record has told you the most important thing about itself.