Part 2 · One Agent, Five Platforms
In Part 1 I said I'd build the same invoice-exception agent on five platforms. Before building anything, it's worth being precise about the job, because the most common mistake with agents is giving them work that rules or people should do.
Invoice exceptions are half rules and half judgement. That mix is exactly where an agent either earns its place or does damage, which is why it makes a good test.
The six exception types
When an invoice fails the three-way match against the purchase order (PO) and the goods receipt, it usually falls into one of six types. At Arden Medical Supply, our fictional distributor, they look like this:
- Price variance. The supplier charged $12.40 a unit, the PO says $11.90. Sometimes it's an error, sometimes an agreed price increase that never reached the PO.
- Quantity variance. 500 units invoiced, 480 received. Maybe a short delivery, maybe the last 20 are still on a truck.
- Missing goods receipt. The invoice is fine, but nobody has booked the receipt. The goods may be sitting in the warehouse.
- Duplicate invoice. The same invoice arrives twice. Easy when the number matches, harder when the supplier resends it with a new number or a slightly different date.
- Closed purchase order. The PO was closed before the invoice arrived, so there's nothing to match against.
- Tax mismatch. The tax amount or rate doesn't match what's expected for that supplier, item or location.
They look similar in the exception queue. They are very different problems.
Two questions for every type
For each type I ask two questions, the same ones I used in series 1's 2x2 for deciding what to automate:
- Rules or judgement? Can a deterministic check decide this, or does it need context, such as supplier history, documents or a pattern across invoices?
- Low or high risk? If the answer is wrong, is it cheap to correct, or does it cost money, a supplier relationship or a compliance problem?
That gives four ways to handle an exception.
Rules only: no agent
Exact duplicates and price variances within tolerance are pure rules. If the supplier, invoice number and amount match an invoice you've already paid, it's a duplicate. If the price is within the agreed tolerance, say 2%, policy says accept it.
There's nothing for an LLM to add here except cost, latency and a small chance of being wrong about something a rule gets right every time. These cases never reach the agent. The deterministic check_duplicate_invoice and run_three_way_match tools exist so that rules run first.
Agent proposes, quick approval
A missing goods receipt needs context: was there a delivery note, did the supplier confirm shipment, does this supplier often deliver before the receipt is booked? An agent can gather that and propose "hold and ask the warehouse to confirm the receipt". If the proposal is wrong, the cost is a short delay.
A near-duplicate, with a new invoice number but the same amount, items and week, is similar. The agent can line the two invoices up and propose "reject as duplicate", but a person still confirms, because rejecting a real invoice annoys a supplier.
These are the cases where an agent saves the most time with the least risk.
Rules detect, person decides
A closed PO is trivial to detect. What to do about it isn't. Reopen the PO? Raise a new one? Reject the invoice? That's a procurement decision with budget and contract consequences. The agent can summarise what happened, but the decision belongs to a person, and the agent shouldn't propose a fix it can't justify.
Agent investigates, person decides
Price variances over tolerance and quantity variances are where judgement matters most and errors cost most. The agent's job is to investigate: check the supplier's price agreements, recent invoices, partial deliveries, open receipts, and propose a specific fix with its evidence. A person with the right authority approves or rejects it.
Tax mismatches sit here too, with a stricter rule: the agent gathers evidence only. Tax treatment is a compliance question. An agent that "fixes" tax is a finding waiting to happen.
What a wrong answer costs
It's worth being concrete, because these costs drive the design:
- Paying twice. A missed duplicate is money out the door, and recovering it takes time.
- Overpaying. Accepting a wrong price or quantity, repeated across hundreds of invoices.
- Paying late. Over-cautious holds can mean missed early-payment discounts or late fees.
- Damaging a supplier relationship. Wrongly rejecting a valid invoice, or sending a supplier an incorrect query.
- Audit and tax findings. An adjustment nobody can explain later.
None of these come from the agent being slow. They come from the agent being confidently wrong, or from it being allowed to act without a check.
How this shapes all five builds
This analysis turns into design rules that every build in the series follows:
- Rules run first. Every invoice goes through the deterministic match and duplicate check before the agent sees it. The agent only gets the cases rules can't settle.
-
Read-only by default. Investigation uses read tools: invoice, PO, goods receipt, supplier history. The two tools that change anything outside the approval workflow,
post_invoice_adjustmentandnotify_supplier, both require anapproval_id. -
Approval tiers.
request_approvalroutes by quadrant: a quick approval for low-risk proposals, an approver with authority for high-risk ones, and the tax team for tax. - Every proposal carries evidence. The approver sees why, not just what.
- The golden set covers every quadrant. The 30 test invoices include the easy cases the agent should never see, not only the hard ones, so we can check the routing too.
None of this is platform-specific, which is the point. In Part 3 I'll draw the platform-neutral architecture that every build will follow, before any vendor gets a say.
Which exception type would you never automate?
This series describes a reference build on a fictional company. All figures are illustrative. Product capabilities are based on vendor documentation as of October 2026; check current docs before you build.

Top comments (0)