Observability for autonomous workflows: tracing decisions, not just requests
Standard APM tooling will tell you an agent system is healthy while it quietly makes the wrong calls all day. After two years of running agents inside finance, revenue, and logistics operations, we have settled on a different unit of telemetry: the decision. Here is what we instrument by default, and why.
The week the dashboards lied
Early in a finance ops engagement, we had an invoice-coding agent running against the client's NetSuite instance. It handled about 1,100 invoices a week: read the document, matched it to a PO, assigned GL codes, routed exceptions to a human queue. The observability stack was textbook APM: request latency, error rates, throughput, token spend. Every panel was green for eleven straight days.
During that stretch, a supplier changed their invoice template. The agent kept parsing the documents without a single exception, but it started reading the freight line as a product line and coded roughly 240 invoices to the wrong account. Nothing timed out. Nothing threw. Cost per run was actually slightly lower because the new template was shorter. The month-end close surfaced it, which is to say a human accountant surfaced it, three weeks late.
That incident reshaped how we build. The lesson was not that we needed more monitoring. We had plenty. The lesson was that we were monitoring the wrong noun. Latency charts stay green when an agent misclassifies an invoice, because misclassifying an invoice takes exactly as long as classifying it correctly. Request-level telemetry measures whether the system ran. It says nothing about whether the system was right.
The unit of work is a decision, not a request
Traditional software is deterministic enough that request health is a decent proxy for correctness. If the code path executed and returned 200, the business logic did what it was written to do. Agent systems break that proxy. The same input can legitimately produce different outputs, the reasoning depends on retrieved context that changes daily, and the failure mode is rarely a crash. It is a confident, well-formed, wrong answer.
So we trace decisions. In our vocabulary, a decision is any point where the agent commits to something that has operational consequences downstream: matching an invoice to a PO, choosing a carrier for a shipment, deciding a renewal opportunity is at risk, deciding NOT to escalate. One workflow run in a logistics deployment might contain thirty requests but only four decisions, and those four are where all the risk lives.
This distinction sounds academic until you try to answer the questions that actually come up in production. Why did the agent pick this vendor record over that one? What did it know at the moment it chose? Would it choose differently today? None of those are answerable from a request trace, no matter how detailed your spans are.
What a decision record contains
Every agent we ship writes a decision record by default. It is not optional, not a premium tier, and not something we bolt on after go-live. The record has seven fields that we have converged on across deployments: the decision type and its schema version, the full input snapshot including every ERP or CRM record the agent retrieved, the policy version the agent was operating under, the tool calls it made and their raw results, the alternatives it considered and rejected, a calibrated confidence score, and the disposition, meaning whether it auto-executed, went to a human review gate, or was abstained on.
The input snapshot is the field people push back on because it is heavy. A single decision record in our revenue ops deployments averages around 40KB. We keep them anyway, hot for 90 days and cold for seven years in regulated environments, because the snapshot is what makes a decision replayable. When a controller asks why the agent approved a payment run in March, we do not want to reconstruct what the vendor master looked like in March. We want to open the record and see it.
The alternatives field earns its keep during audits and during debugging in equal measure. An agent that chose carrier A should be able to show that carrier B was considered and rejected on transit time, not silently ignored because a lookup failed. Roughly a third of the real bugs we find in production are visible only in the rejected-alternatives list: the right answer was never in the candidate set to begin with.
Metrics that predict trouble before finance finds it
Once decisions are first-class records, you can compute metrics that actually lead incidents instead of trailing them. Four have proven themselves repeatedly. First, override rate: the fraction of gated decisions where the human reviewer changed the agent's answer. In a healthy deployment this sits between 2 and 6 percent. When it drifts above 10 percent for any single decision type, something upstream changed, usually source data, and we page on it the same way an SRE pages on error budgets.
Second, confidence calibration drift. We continuously compare stated confidence against observed correctness on the reviewed sample. An agent that says 90 percent and is right 90 percent of the time is trustworthy even when it is wrong. An agent that says 90 percent and is right 70 percent of the time is dangerous precisely because its automation gates are keyed to that number. Calibration drift caught the invoice template change in a later deployment within 36 hours, against the three weeks it took us the first time.
Third, input distribution shift per decision type: cheap statistical checks on the shape of what the agent is being asked to decide about. New supplier, new document format, new deal structure. Fourth, abstention rate. Agents that stop saying I am not sure are usually not getting smarter. Something has flattened their uncertainty, and that is worth a look before the quarter closes, not after.
Every latency chart was green the week an agent misclassified 240 invoices, because misclassifying an invoice takes exactly as long as classifying it correctly.
Decision traces are eval fodder, and that loop is the point
The most underrated property of decision-level telemetry is that every reviewed decision is a labeled example. When a human at a review gate approves, edits, or rejects an agent's call, that outcome flows straight into the eval suite for the next policy version. Our rollouts are month-by-month partly for organizational reasons, but mostly because each month of gated production traffic yields a few thousand labeled decisions, and that corpus is what lets us widen the automation gates with evidence instead of optimism.
Replay is the other half of the loop. Because input snapshots are complete, we can run a candidate policy against the last 60 days of real decisions before it touches production, and diff the outcomes decision by decision. In a recent revenue ops engagement, a prompt change that looked strictly better on our synthetic evals flipped 4 percent of historical renewal-risk calls in a direction the CRO would not have signed off on. It never shipped. Without replayable decisions, we would have found that out in the pipeline numbers a quarter later.
This is also where the initial audit pays off. When we map a client's workflows before writing any agent code, we are effectively writing the decision schema: what the commit points are, what a human currently looks at when making each call, what the ERP fields of record are. Teams that skip that mapping end up logging what was convenient rather than what the decision actually depended on, and their traces cannot answer the question that matters.
Where to start if you are retrofitting
If you already have agents in production with only APM-grade telemetry, resist the urge to instrument everything at once. Rank your decision types by blast radius, which in ops environments usually means dollars moved times detection delay, and instrument the top three first. A misrouted shipment is caught in hours. A miscoded invoice is caught at month end. The invoice wins even if the shipment is more frequent.
Then get one human review gate emitting structured outcomes rather than free-text comments. Approved, edited, rejected, and if edited, what changed. That single stream gives you override rate and calibration data within a couple of weeks, and those two metrics alone would have caught the majority of the production incidents we have seen across clients.
The deeper point is a stance, not a stack. Request observability asks whether the machine is up. Decision observability asks whether the machine deserves the autonomy you have given it, and answers with evidence you can show a controller, an auditor, or your own engineers at 2am. Agents earn wider gates by being provably right, and you cannot prove what you never recorded. Trace the decisions. The requests were never the interesting part.