Log the decision, not the prompt: a trace schema for AI agents
A practical trace schema for agent runs that records identity, tool effects, approvals, state changes, and costs—without storing secrets or full prompts.
DECISION TOPICAgent architecture↗Read with one real task in mind, then complete the workbench. The lesson is done when another person can review what you made.
Most agent logs are either a chat transcript or a pile of model timings. Neither answers the question an incident asks: who approved which action, over which data, with what result, and what did the system do when the result was unknown?
A trace is a decision record. It links a user request to the steps the agent took, the tools it called, the state it changed, and the human who allowed it. It is not a copy of the prompt.
Prompt logs are not traces
A prompt log shows what the model saw. It does not show:
- which tenant or record the action targeted;
- whether a tool call actually executed or timed out;
- who approved a consequential step;
- what state changed in the external system;
- whether a retry created a duplicate effect.
Prompt text is also the wrong thing to retain by default. It contains customer messages, retrieved documents, credentials accidentally pasted into a field, and personal data. Storing it for every run creates a second, ungoverned copy of the data.
A trace can include a hash or a short redacted summary of the input, but its primary job is to reconstruct the decision path.
The decision record
Think in spans. One run has a root span; each model turn, tool call, approval, and state transition is a child span. The schema should answer five questions:
| Question | Trace fields |
|---|---|
| Who acted? | User ID, tenant, service identity, session |
| What was the task? | Task ID, run ID, task type, policy version |
| What did the agent do? | Model/version, step number, tool name, argument hash, result status |
| Who allowed it? | Approval ID, approver, scope, timestamp |
| What changed? | External effect status, resource ID, before/after state hash |
| What did it cost? | Input/output tokens, tool charge, latency, retry count |
The fields are intentionally about decisions and effects, not prose. They are small enough to retain longer and specific enough to answer an incident review.
What to log (and not log)
Log:
- run and task identifiers;
- user and tenant identifiers, or a pseudonymous key;
- model and agent version;
- tool name, argument hash, result status, duration;
- approval ID, approver, and approved scope;
- state transitions and external effect status;
- retry count and reason;
- cost and latency;
- error class and recovery action.
Do not log:
- full prompts or full retrieved documents by default;
- credentials, tokens, cookies, or connection strings;
- customer names, emails, phone numbers, or free-text notes unless a specific, reviewed need exists;
- raw tool arguments when they contain personal data;
- model chain-of-thought.
If a team needs prompt text for debugging, use a sampled, time-limited, access-controlled store with redaction. Do not make it the default trace.
Example: the refund agent’s unknown payment
A refund agent calls a payment tool. The call times out. The agent’s run status says “failed,” but the payment may have succeeded.
A useful trace shows:
- the tool call span with an idempotency key and a timeout error;
- the external-effect status: unknown, not failed;
- the follow-up query span that checks the payment provider by key;
- the resolution: confirmed, rejected, or still unknown;
- the human owner who was notified if it stayed unknown.
Without the external-effect status, the dashboard counts a failure while the customer may have received a refund. Without the idempotency key, the operator cannot query the provider. Without the approval ID, no one knows who authorized the attempt.
The trace does not need the customer’s message. It needs the payment reference and the state.
Counterexample: the trace that stored the full prompt
A team enables verbose tracing to debug a retrieval problem. The trace stores the full prompt, including a customer email address and an internal policy excerpt, in a third-party observability tool.
The debugging works. Three months later, the team cannot answer which customer data is in the tool, how long it is retained, or who can search it. A privacy request becomes an engineering project.
The fix is not “turn off tracing.” It is to separate debug context from decision record:
- the decision record keeps hashes, IDs, statuses, and approvals;
- the debug context is sampled, redacted, access-controlled, and retained for days, not months;
- the trace links to the debug record by ID, not by copying the content.
This keeps the incident-review capability without building a shadow data warehouse.
A minimal schema
A JSON-shaped record for one tool call can start like this:
| Field | Type | Example |
|---|---|---|
run_id | string | run_01J... |
task_id | string | refund-1042 |
tenant_id | string | tenant_a |
step | integer | 7 |
tool | string | payments.refund |
args_hash | string | sha256:... |
idempotency_key | string | refund-1042-v1 |
approval_id | string | apr_88 |
status | enum | ok, error, timeout, denied |
effect_status | enum | confirmed, rejected, unknown |
resource_id | string | re_123 |
duration_ms | integer | 842 |
cost_usd | number | 0.004 |
The exact names do not matter. The distinctions do: a timeout is not a failure, an approval is not a log line, and an external effect has a status separate from the run.
Replay and retention
A trace supports two different replays:
- Decision replay: reconstruct what happened, who approved it, and what changed. This should work from the trace alone.
- Execution replay: re-run the workflow against a sandbox. This requires saved inputs and a safe environment; it must never re-trigger external effects.
Set retention by purpose. Decision records may need 90 days or more; debug context should be shorter. Access should be role-based: support can see the customer’s case, but not every tenant’s trace. Redact at write time, not at export time.
Boundary
This schema fits tool-using agents that read, write, notify, or pay. It is not a full observability platform, a compliance archive, or a replacement for application logs and audit trails. It does not capture model reasoning and should not try to. If the team cannot separate decision records from prompt text, start with the tool-call and approval spans; those are the minimum for an incident review. A trace that cannot answer “who approved this effect?” is not a trace yet.
SOURCES CHECKED
Which first-party sources informed this guide?
Sources anchor definitions, risk boundaries, or operational facts. The decision framework and workbench are original to AI Vista.
- OpenTelemetry — Generative AI semantic conventionsChecked 2026-10-29
- W3C — PROV OverviewChecked 2026-10-29
- OpenAI Agents SDK — TracingChecked 2026-10-29
AI tools may assist with research, outlining, and language editing. Facts, cases, and final wording are reviewed by the editor. Report an error through the contact page.
TAKEAWAY TOOL
Single-run agent trace review
Connect observed decisions to executed calls, approvals, and authoritative outcomes.
This workbench saves a draft in this browser. Use synthetic run IDs, sanitized summaries, and controlled evidence pointers; do not paste user text, credentials, confidential tool results, or hidden reasoning.
- 01Describe the taskDescribe the result with a sanitized summary.
- 02Fill the decision fieldsRecord input categories, risk, evidence pointers, and handoff.
- 03Ask a colleague to reviewThe tool is ready when someone else can restate the decision.
LESSON READ
Finish the workbench, then mark it read.
The read state updates the syllabus and your course progress.
- 01Fields filled
- 02Case tested
- 03Reviewable
GUIDE PRACTICE NOTES
Leave a judgment you can review later.
The fictional examples below show the format. Your own notes stay in this browser. Record what worked, which boundary failed, or one question worth testing.
This guide has no example or local note yet. Record the first concrete observation.