An agent that clears the purchase-invoice queue
Supplier invoices are read, matched against the purchase order and the goods receipt, and either proposed for posting or handed to a person with the reason attached.
- Invoices read each month
- 2,000
- The queue is worked
- Same day
- Postings without a match or an approval
- 0
The client
A mid-sized industrial manufacturer
Named clients are withheld under the confidentiality agreements we work to. Sector, scale and system detail are published with permission.
- Sector
- Discrete manufacturing, multi-plant
- Scale
- Around 2,000 supplier invoices a month, three finance staff
- Duration
- 10 weeks to production, then four weeks running under supervision
- Team
- AI engineer, Backend engineer, Frontend engineer, Finance process analyst, Project manager
What was wrong.
Invoices arrived as email attachments, scans and the occasional photograph. A clerk opened each one, found the purchase order, compared line items and quantities against the goods receipt, and keyed the result into the ERP. The backlog was cleared in a Monday push, so early-payment terms were missed most weeks.
The finance team had already been shown a tool that promised full automation, and they did not trust it. Their objection was reasonable: an invoice posted against the wrong order costs more to unpick than one that was never posted. The system had to be able to say that it did not know.
The approach, step by step.
- 01
Start from the exceptions
We took 400 historical invoices and sorted them by why a human had to intervene. Three causes covered most of the queue: short deliveries, price revisions and freight charged separately. The agent was designed around those three before anything else was built.
- 02
Extract, then verify
A vision-capable model reads each document into a typed structure. Every field it produces is checked rather than trusted: supplier against the master, order number against open orders, and totals recomputed from the line items.
- 03
Give it tools, not a chat box
The agent calls a small set of typed functions — look up the order, fetch the goods receipt, propose a posting, raise an exception. It has no write access to the ledger. It can only propose.
- 04
Route the doubt to a person
Anything outside tolerance goes to a review screen holding the invoice image, the matched order and one sentence explaining the mismatch. The reviewer approves or corrects in a single action.
- 05
Score every release
A fixed evaluation set of invoices runs before each deploy. If field accuracy or match precision drops, the deploy stops, the same way a failing test stops a release.
The architecture we shipped.
Every layer below exists in the running system. Nothing here is a reference diagram.
- Intake
- A monitored mailbox and a scan folder. Attachments are deduplicated by hash, so a resent invoice is not processed twice.
- Document understanding
- Page classification, then structured extraction into a typed invoice schema with a confidence value per field.
- Ground truth lookup
- Read-only ERP connectors fetch the supplier master, the open purchase order and the goods receipt note.
- Matching engine
- A deterministic three-way match with configurable tolerance. The model proposes; the rules decide what counts as a match.
- Agent loop
- A planner with typed tools handles cases rules alone cannot close, such as one invoice covering two partial deliveries.
- Approval gate
- Nothing reaches the ledger without either a rules match inside tolerance or a named human approval.
- Evaluation and audit
- Every run is stored with its inputs, tool calls and outcome, and replayed against the evaluation set before each release.
What it does now.
Read from the system itself. No revenue claims, no multiples.
Invoices read each month
Email, scans and photographs, all through one intake.
The queue is worked
Invoices are processed on arrival rather than in a Monday batch.
Postings without a match or an approval
The agent proposes; a rule inside tolerance or a person decides.
For every exception
Invoice image, matched order and the reason, in a single view.
What it runs on.
- Python
- LLM function calling
- Schema-validated extraction
- PostgreSQL
- Redis queue
- n8n
- ERP REST connectors
- Next.js review console
- OpenTelemetry
It does the reading and the chasing. We do the judgement calls, and there are far fewer of those left by the time it reaches us.
Attributed by role and sector only, at the client's request.
What happens next.
The same matching engine applied to freight bills, where the tolerance rules differ but the shape of the work is identical.
Services behind this build
Sector
ManufacturingAround 2,000 supplier invoices a month, three finance staff. The pattern transfers; the domain detail is rebuilt for every client.
Have a system that should work like this one?
We will walk your process, tell you what is worth automating, and scope the first version that can be measured.