TechnicalOctober 13, 2026Updated October 20, 202612 min read

How to prove what an AI agent read before it acted

Record each retrieval and tool read, bind it to the decision it fed, and show an auditor where an AI agent got its information about a customer.

Antonella Serine

Antonella Serine

Founder, KLA

Founder of KLA, building the independent runtime governance control plane for regulated AI agents under the EU AI Act.

The question

Where did the agent get the information it used about this customer, and was that the version that existed when it acted?

The record

One read event per tool call, document or retrieval: source, request digest, result digest, source version, time, boundary and the execution it belongs to.

The link

A field provenance map that ties every fact in the decision to a read event, a document or the model itself.

The limit

A digest proves a match only when someone can still produce the content. Keep the content, or a resolvable version of it, for as long as the record must be checked.

To prove what an AI agent read before it acted, record every read as its own event and link each fact in the decision to one of those events. A read event names the source system, the tool or retrieval that produced it, a digest of the request and of the result, the version of the source record, the time and the data boundary. A field provenance map then states, for each value the agent used, whether it came from a tool result, a document or the model. With both, an auditor can take one decision and resolve every input to a source record that existed at the time.

This post covers the four kinds of read an agent makes, a record shape for each, a synthetic KYC example, the choice between keeping content and keeping a digest, and what KLA records today. The AI agent audit trails guide covers the wider execution record. Deterministic replay depends on the same read records.

Why auditors ask where the information came from

An agent that reviews a customer file, drafts a credit memo or closes an alert acts on what it read. When the outcome is challenged, the first questions concern the inputs: which records the agent saw, whether they were current, whether it was allowed to read them, and which facts in its output it made up.

Privacy law asks a version of the same question. Under GDPR Article 15(1)(g), a data subject who asks for access is entitled, where the personal data were not collected from them, to "any available information as to their source". Article 14(2)(f) requires the controller to tell the data subject "from which source the personal data originate". An agent that pulls customer data from several systems makes those answers harder unless each read is recorded.

The EU AI Act names inputs in logs for one category. For remote biometric identification systems under Annex III point 1(a), Article 12(3) requires logging of "the reference database against which input data has been checked" and "the input data for which the search has led to a match". For other high-risk systems, Article 12(1) and 12(2) require automatic logging that supports traceability, risk identification and post-market monitoring, and leave the fields to the provider. Read records are one way to meet that traceability for an agent.

What a default trace shows about reads

Many teams start from their tracing data. The OpenTelemetry semantic conventions for generative AI, which carry Development status, define a retrieval span with gen_ai.data_source.id and gen_ai.retrieval.top_k, and a tool execution span with gen_ai.tool.name and gen_ai.tool.call.id.

The content attributes are Opt-In: gen_ai.retrieval.query.text, gen_ai.retrieval.documents, gen_ai.tool.call.arguments, gen_ai.tool.call.result and the model input in gen_ai.input.messages. A trace with default settings can show that a retrieval or tool call happened and how long it took, with no record of what it asked for or what came back. When content capture is on, the trace holds raw values in a store usually sized and retained for debugging, with no source version and no integrity protection.

Tracing stays useful for the read record. The trace_id and span_id join a read event to the span that timed it.

Four kinds of read and what each needs

Agents read in four ways. Each needs a slightly different record, and each has a typical gap that breaks the audit trail.

Read types, minimum provenance record, and the usual gap
Read typeExampleMinimum recordUsual gap
Structured system readCRM customer lookup, core-banking balance, SQL query through a connectorTool ID and version, arguments digest, record references, result digest, source record version or as-of timeOnly the tool name is logged; the result is discarded after the step
Document readPassport scan, bank statement, signed mandateDocument ID, SHA-256 checksum, storage object version, received time, page and region of each cited valueThe file is replaced in place under the same name, so the checksum no longer resolves
RetrievalPolicy-manual passages from a vector indexIndex ID and build version, query digest, returned chunk IDs, scores and chunk content digests, top_kThe index is rebuilt and old chunk IDs no longer exist
Model or memoryA value the model wrote without a cited source; a fact recalled from agent memoryAn explicit model or memory source label; for memory, the memory item ID and when it was writtenUnsourced values are stored next to sourced ones with nothing to tell them apart

A read record and a field provenance map

The read record below is synthetic and vendor-neutral. It describes one CRM lookup during a periodic KYC review. The digests are shortened.

Synthetic read event
{
  "read_id": "read_syn_0193_02",
  "execution_id": "run_syn_0193",
  "tool_call_id": "call_syn_0193_02",
  "occurred_at": "2026-10-09T08:12:03.418Z",
  "source": {
    "system": "crm-eu",
    "kind": "api",
    "tool_id": "crm.customer.get",
    "tool_version": "2026-09-30"
  },
  "request": {
    "arguments_digest": "sha256:3b9e…41d0",
    "record_refs": ["cust_syn_55120"]
  },
  "response": {
    "result_digest": "sha256:c07a…9e12",
    "source_record_version": "v41",
    "as_of": "2026-10-09T08:12:03.390Z"
  },
  "boundary": {
    "data_boundary_ref": "boundary_eu_kyc",
    "purpose": "kyc-periodic-review"
  },
  "retention": {
    "content_stored": "digest_only",
    "content_location": "crm-eu record history"
  }
}

Bind each fact to its source

Read records show what the agent could have used. The field provenance map shows what it did use. Attach it to the decision record so that each output field points to one source.

Synthetic field provenance map
"field_provenance": {
  "residence_country": {
    "source": "tool",
    "tool_call_id": "call_syn_0193_02",
    "path": "$.address.country"
  },
  "id_document_expiry": {
    "source": "document",
    "document_id": "doc_syn_771",
    "checksum_sha256": "8f14…a3c2",
    "page": 1
  },
  "source_of_funds_summary": {
    "source": "model"
  }
}
  • Tool source: the value is read from a path in a recorded tool result. The reviewer recomputes the result digest and checks the value at that path.
  • Document source: the value cites a document the agent received in that step, by ID and checksum, with a page and, where available, a region on the page.
  • Model source: the value has no external source. Label it so a reviewer treats it as the agent’s own statement and checks it as such.

Worked example: a synthetic KYC periodic review

A fictional EU bank runs a KYC refresh agent. The agent reads the customer profile, the latest identity document and the transaction summary, then proposes a risk rating for a KYC analyst to approve. Every identifier and value below is invented.

Tracing each decision input to its source (synthetic)
Decision inputValue usedSourceProvenance evidenceAuditor check and result
Residence countryFRTool: crm.customer.getcall_syn_0193_02, result digest, record version v41CRM history shows v41 current at 08:12:03Z; value matches. Pass
ID document expiry2031-04-30Document: doc_syn_771Checksum, page 1, region located by text layerStored object version matches checksum; printed date matches. Pass
Cash deposits, last 90 daysEUR 18,400Tool: txn.summary.getcall_syn_0193_03, result digestCore-banking ledger re-run for the same window gives EUR 18,400. Pass
OccupationSelf-employedTool: crm.customer.getcall_syn_0193_02, record version v41CRM changed to "Salaried" in v43 two days later. The agent used the value current at the time. Pass, with a note for the analyst
Source-of-funds summaryNarrative paragraphModelsource: modelNo source. The analyst’s approval record must show this paragraph was reviewed as agent-written text. Exception: the approval screen did not label it

Keep the content, or keep a digest

A digest is small, safe to store in a sealed record and enough to prove a match. It proves nothing on its own: the auditor needs the original bytes to recompute it. Decide per source where those bytes will live for the retention period.

  • Digest plus source version: use when the source system keeps record history for at least as long as the evidence must be checked. Record the version or as-of time so the read can be resolved later.
  • Digest plus copy in evidence storage: use when the source is mutable, has a shorter retention than the evidence, or sits with a third party.
  • Field-level capture: store only the values the decision used, with their paths. This keeps personal data in the evidence record to what the decision needs.
  • Redaction and access: apply the same classification and access policy to stored read content as to the source. Record the redaction profile with the read.

What KLA records about reads today

KLA records reads where they pass through a governed path. The points below describe current behaviour and its limits.

Governed tool calls. When an agent calls a tool through the KLA runtime, the signed receipts for the call carry a SHA-256 digest of the tool arguments and of the released result. The receipts are written to the per-tenant append-only evidence ledger and collected into the Sealed Evidence Bundle. The ledger holds the digest; the read content stays in the source system and runtime storage.

Process field provenance. A Process can declare a source for each produced field. For a tool source, KLA captures the value at a path of the released tool result and writes that value. For a document source, the agent cites a stage document, and the transition gate checks the citation against the documents the stage actually received with content. A declared source with no evidence blocks the transition with missing_field_provenance. The gate decision records the map as references only: {source: "tool", toolKey, callId}, {source: "document", documentId, documentType, checksumSha256, page, region} or {source: "model"}.

Document Intake. Each source document carries checksum_sha256, object_version_id and received_at. Extraction records a source-text hash per field, the extractor model and the field contract version, and intake events are append-only. When the worker locates a cited value, the record keeps the page and box coordinates and the method (text_layer or vision), and never the text.

Limits. KLA does not capture vector-retrieval chunks or the model’s full context window today. A retrieval an agent runs inside its own code, outside a governed tool call, leaves no KLA read record; route it through a governed tool to record it. Data Boundaries are recorded for the run as a whole, with no per-read boundary version.

What we learned building document-sourced fields

We built document-sourced fields for a merchant-onboarding proof of concept in September 2026. A field such as a company registration number had to cite the onboarding document it came from, and the Process gate refused the transition when the citation was missing.

Our review of the first implementation found that citations were checked against every document in the run. An agent could cite a document it had not been shown in that step, and the check would pass. We changed the check to the documents the stage actually received with content. The same review found that values captured from tool results were lost when a run paused to wait for an email reply; we fixed that so captures survive the wait.

We wrote down one limit and kept it. A citation proves that the step was shown the cited document. Whether the value appears in that document is a separate question. To make that second check fast, we added citation regions at the end of September: the worker locates the cited value on the page and the case page outlines it for the reviewer.

Locating text with a model raised its own problem. A model asked whether its own box is right tends to agree. We use a blind check: a second call transcribes the cropped box without seeing the expected text, and the box is kept only when the transcription matches. Regions are a reading aid built from untrusted page content, so they never decide a transition.

Audit procedure for read provenance

Run these steps on a risk-based sample of decisions. The AI agent audit workpaper shows the same method for authority, approval and outcome.

  • List the inputs: for each sampled decision, list every fact the agent used from its output and the decision record.
  • Resolve the source: match each fact to a read event, a document or a model label. A fact with no entry is an exception.
  • Recompute digests: fetch the source content at the recorded version and recompute the result digest or checksum.
  • Check timing: confirm each read precedes the decision and that the source version was current at read time.
  • Check authority: compare each source and record with the data boundary and purpose in force for the run.
  • Check labelling: confirm that model-sourced facts were shown to the human reviewer as agent-written.

Frequently Asked Questions

How can I audit where an AI agent got its information about a customer?

Take one decision, list every customer fact it used, and resolve each to a recorded read: the tool call or document, the source record version and a result digest. Recompute the digest from the source at that version. Any fact with no read record, or one labelled as model-written, is either an exception or a value the reviewer must check as the agent’s own statement.

How do I audit what content an AI agent used to make a decision?

Separate what the agent read from what it used. Read events show every retrieval and tool result; a field provenance map on the decision record links each output value to one of them. Sample decisions, recompute the digests, and confirm the content was within the approved data boundary.

Does an LLM trace show what an AI agent read?

Only if content capture is switched on. In the OpenTelemetry GenAI conventions, retrieved documents, tool arguments, tool results and model input messages are Opt-In attributes. A default trace shows that a read happened, with no record of the content, its source version or its integrity.

Should an audit record store the content an agent read or only a hash?

Store a digest in the sealed record and keep the content where it can be produced for the full retention period: in the source system with a version reference, or in evidence storage when the source is mutable. A digest without retrievable content cannot be checked.

Key Takeaways

Provenance for an agent decision comes down to two records: one event per read, and a map from each fact in the decision to a read, a document or the model. Keep the content resolvable for as long as the record must be checked, and route retrieval through governed calls so it is recorded. For the record format, start with the AI agent audit log schema and the AI agent execution record. For how KLA joins reads to decisions and effects, see Execution Lineage.

See It In Action

Ready to automate your compliance evidence?

Book a 20-minute demo to see how KLA helps you prove human oversight and export audit-ready Annex IV documentation.

How to prove what an AI agent read before it acted | KLA Blog