Work sample 08 / 14AI agent integration
Private Ollama bill coding into Xero or QuickBooks Online
How I'd approach supplier bills for a multi-branch service group whose owner will not send financial documents to an outside AI service: a model running on the group's own hardware proposes the coding, a person approves it, and nothing posts on its own.
Worked example on representative data.
- Area
- AI agent integration
- Tools
- Ollama (Qwen, Nemotron) · Xero · QuickBooks Online
- Typical scope
- US$3,500–5,000
- Timeline
- About 6 weeks · 4 fixed milestones
01Context
A multi-branch service group whose owner will not send financial documents to an outside AI service. Supplier bills arrive by email and as scans, and are keyed into the ledger by hand.
The systems in play
In the example each operating company has its own ledger, in Xero or QuickBooks Online. A bookkeeper enters the bills, branch managers approve them, and an outside accountant reviews the books.
| System | What it does for the business |
|---|---|
| Bill inbox or shared folder | Where supplier bills arrive, as PDFs, photos and scans. |
| Ollama on the group’s own hardware | Runs the language models locally. No bill, supplier detail or bank detail is sent to an outside AI service. |
| Approval queue | A page where a person sees the bill beside the proposed coding, then approves or edits it. |
| Xero or QuickBooks Online | The ledger. Receives a bill only after approval. |
02Problem
What the owner sees
- Hours spent keying bills by hand
- Bills coded to the wrong account or branch
- The same bill paid twice
- Bills that wait for the one person who understands them
Faster bill entry is easy to promise. The harder part is that every number and every code has to be right, and a person has to stay accountable for what posts.
| Everyday situation | What goes wrong |
|---|---|
| Re-keyed amounts | A typo changes the total or the tax |
| Duplicate bills | The same bill is emailed twice, or arrives again with a statement |
| Wrong account or tax code | The same supplier is coded differently by different people |
| Missing job or branch | Cost cannot be traced to where it was incurred |
| Credit notes entered as bills | A credit increases what is owed |
| Split bills | One bill covers two jobs or two branches |
| Poor scans | Fields are unreadable and are guessed |
03Approach
Four steps, in this order. The model only proposes. Checks in code and a person decide.
- LookA sample of past bills is collected with how each was coded. The supplier list, chart of accounts and coding rules are reviewed.
- BuildA local pipeline reads each bill, checks it in code and proposes coding. The model may only choose from your existing accounts, tax codes and branches.
- Shadow runThe pipeline runs beside manual entry for a few weeks. Each field is compared with what the bookkeeper entered, and every difference is reviewed.
- Go live with approvalProposals go to the approval queue. Nothing posts without an approver, and anything the checks flag goes to a person first.
How a bill moves
- Bill arrives
- Text read, or scan read by a vision model
- Fields saved in a fixed format
- Checks in code
- Coding proposed
- Approval queue
- Posted with the PDF attached
- Audit log
04What the setup includes
What the setup includes, and why each piece is there. The detail of how it is configured is agreed in the scoping call.
Show the setup, layer by layer
| Layer | What is set up and why |
|---|---|
| Hosting and models | One workstation or small server on the group’s network runs Ollama. Qwen is used for reading and Nemotron is compared for proposals, and the shadow run decides which is kept. Models and bills stay on the group’s hardware. |
| Intake | A mailbox or shared folder. Each file is hashed on arrival, so the same file is never processed twice. |
| Reading | The text layer of the PDF first. A vision model for scans. Output goes into fixed fields in a strict format, and anything that does not fit the format is rejected. |
| Checks in code | Lines plus tax equal the total. The date is plausible. The supplier matches the contact list, including bank details. The duplicate key is supplier, bill number and total. Credit notes are detected. These are code, not the model. |
| Coding proposal | Supplier, account, tax code, and branch or job, based on how that supplier was coded before and the chart of accounts. The model can only choose from existing lists. |
| Approval queue | The PDF beside the proposal, the reasons, and any flags. An approver edits or approves. Role limits apply, so bills above a set amount need a second approver. |
| Posting | A Xero bill, or a QuickBooks Online bill, with the PDF attached, created only after approval. A retry key means a failed attempt can never post twice. |
| Audit log | Who approved, what they changed from the proposal, the model and prompt version, and a hash of the original file. |
| Rules from edits | Edits made by approvers are reviewed monthly and turned into written rules. There is no automatic retraining. |
05Edge cases
These are agreed with the bookkeeper and tested on real past bills during the shadow run.
| Situation | How it is handled |
|---|---|
| Credit note | Detected from the document and the sign. Posted as a supplier credit and never as a bill. |
| Bill split across jobs or branches | The split is proposed and shown. A manager approves the split. |
| Supplier not in the contact list | Goes to the queue. A contact is never created automatically. |
| Same bill twice | The file hash or the supplier, number and total match. It is flagged and rejected as a duplicate. |
| Poor scan or totals that do not add up | Marked as not read. Entered by hand, and kept as a test case. |
| Bill addressed to another company in the group | Detected from the bill-to name and routed to that company’s queue, or flagged if unsure. |
| Tax-inclusive and tax-exclusive totals | Both are checked against the lines. A mismatch is flagged. |
| Model is offline | The queue shows bills as not read and manual entry continues. Nothing is lost. |
| Approver edits the proposal | The change is saved in the audit log with the user and the reason. |
06Worked example
The tables below use representative data. They show the shape of the queue and the shadow run, not a client result. No accuracy figure is claimed.
| Bill | Total | Proposed coding | Flag | Result |
|---|---|---|---|---|
| Supply house, INV-20418 | 1,284.50 | Parts and materials, North branch, standard rate | None | Approved as proposed |
| Equipment hire, H-7731 | 612.00 | Equipment hire, job 4821, standard rate | Job taken from the bill notes | Approved, branch corrected to South |
| Supply house, INV-20418 (again) | 1,284.50 | Same as above | Duplicate: same supplier, number and total | Rejected as a duplicate |
| Subcontractor, 0093 | 3,900.00 | Subcontractors, split across two jobs | Split bill | Split approved by the branch manager |
| Supply house, CN-552 | -240.00 | Parts and materials, North branch | Credit note | Posted as a supplier credit |
| Unnamed scan | Not proposed | Low quality, totals do not add up | Entered by hand | |
| New supplier | Not proposed | Not in the contact list | Contact created by the bookkeeper, then re-run |
| Bill | Field | Bookkeeper entered | Model proposed | Match |
|---|---|---|---|---|
| INV-20418 | Account | Parts and materials | Parts and materials | Yes |
| 0093 | Account | Subcontractors | Subcontractors | Yes |
| 0093 | Job | 4821 and 4830 | 4821 only | No: reviewed, split rule added |
| H-7731 | Tax code | Standard rate | No tax | No: reviewed, supplier rule added |
07How the result is checked
The checks that matter are the ones in code, because a model can be confidently wrong. A person approves everything that posts.
| Check | How | Pass condition |
|---|---|---|
| Totals | Recomputed in code from the lines and tax | Equal to the stated total |
| Duplicates | The same bill sent twice, and a statement copy | Second copy rejected |
| Shadow run | Field-by-field comparison beside manual entry over a few weeks | Every difference reviewed and either a rule is added or the field stays with a person |
| Permissions | Approvers tested against the role limits | A bill over the limit cannot post on one approval |
| Failure | Model switched off | Queue shows not read and manual entry continues |
| After go-live | Every flagged bill plus a regular sample of the rest | Reviewed and logged |
08Scope and milestones
A fixed scope agreed in writing before anything starts. Each milestone is paid when you sign off its deliverable.
| Area | Included |
|---|---|
| Health Check | Review of bill flow, the chart of accounts and the hardware available, a 45-minute call, written findings and a fixed quote |
| Reading pipeline | Intake, reading, fixed fields and the checks in code |
| Coding proposal | Proposal from your own lists, with reasons |
| Approval queue | A page for approvers, with role limits and the audit log |
| Posting | Xero or QuickBooks Online bills created after approval, with the PDF attached |
| Shadow run | A few weeks beside manual entry, with a written review of every difference |
| Handover | Written SOPs, a recorded walkthrough and files you own, plus 14 days of fixes after go-live |
| Not included | Tax filing or payroll. |
| Also outside the scope | Buying and hosting the hardware. Accounting software subscriptions (billed to you by the vendors). Training a custom model. |
| Milestone | Deliverable | Timing | Share |
|---|---|---|---|
| M1 Health Check and sample set | Findings, rules and a sample set of past bills | Week 1 | 20% |
| M2 Pipeline reads bills | Checks pass on the sample set | Weeks 2 to 3 | 30% |
| M3 Shadow run | Compared with manual entry, differences reviewed | Weeks 4 to 5 | 30% |
| M4 Approval queue live and handover | Queue live, SOPs, walkthrough, 14 days of fixes | Week 6 | 20% |
Typical scope for this kind of project: US$3,500–5,000
About 6 weeks across 4 fixed milestones. The Systems Health Check (US$300, fixed) comes first and confirms the scope.
Describe the process you want handled, and I'll say where I'd start.
Send a short note through the form on the home page. I will reply with where I would start, and whether the US$300 Systems Health Check is the right first step.