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 type | Example | Minimum record | Usual gap |
|---|---|---|---|
| Structured system read | CRM customer lookup, core-banking balance, SQL query through a connector | Tool ID and version, arguments digest, record references, result digest, source record version or as-of time | Only the tool name is logged; the result is discarded after the step |
| Document read | Passport scan, bank statement, signed mandate | Document ID, SHA-256 checksum, storage object version, received time, page and region of each cited value | The file is replaced in place under the same name, so the checksum no longer resolves |
| Retrieval | Policy-manual passages from a vector index | Index ID and build version, query digest, returned chunk IDs, scores and chunk content digests, top_k | The index is rebuilt and old chunk IDs no longer exist |
| Model or memory | A value the model wrote without a cited source; a fact recalled from agent memory | An explicit model or memory source label; for memory, the memory item ID and when it was written | Unsourced 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.
{
"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.
"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.
| Decision input | Value used | Source | Provenance evidence | Auditor check and result |
|---|---|---|---|---|
| Residence country | FR | Tool: crm.customer.get | call_syn_0193_02, result digest, record version v41 | CRM history shows v41 current at 08:12:03Z; value matches. Pass |
| ID document expiry | 2031-04-30 | Document: doc_syn_771 | Checksum, page 1, region located by text layer | Stored object version matches checksum; printed date matches. Pass |
| Cash deposits, last 90 days | EUR 18,400 | Tool: txn.summary.get | call_syn_0193_03, result digest | Core-banking ledger re-run for the same window gives EUR 18,400. Pass |
| Occupation | Self-employed | Tool: crm.customer.get | call_syn_0193_02, record version v41 | CRM 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 summary | Narrative paragraph | Model | source: model | No 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
modellabel. 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.
