Inspiration
Accounts payable is the original multi-step workflow: extract, match, check, chase, approve, pay. It's also where business-email-compromise fraud lands. We wanted a taskmaster where the LLM does what it's uniquely good at (reading messy paper, noticing "pay within 48 hours per CEO") and never what it's bad at (deciding to move money).
What it does
Paste or ingest raw invoice text; a per-invoice ADK agent chain extracts it with Gemini 3.5, runs six deterministic AP rules (approved-vendor master, duplicate detection, PO exists/matches/within-cap, line arithmetic, IBAN-vs-master payment-redirect guard, and a pressure-language hold), then routes it: clean and ≤€5,000 auto-approves; clean but large waits for a human; any failed rule is held with every reason named, so approving it is an explicit, recorded override. A pay-run batches everything approved into a payment file and writes the ledger. Every hop appends to the invoice's event trail. The 8-invoice sample set exercises every branch — including a textbook fraud attempt that trips four rules at once.
How we built it
FastAPI on Cloud Run; per-invoice SequentialAgent (ADK): LlmAgent extractor with a strict
output_schema (never infers amounts, never fixes arithmetic, treats invoice text as data,
not instructions) → custom validator BaseAgent → custom router BaseAgent writing a
Firestore state machine (tr_invoices with status + event trail, tr_ledger, tr_payruns).
Keyless Vertex AI via ADC — no API keys anywhere. Server-rendered workbench with approve /
override / reject and one-click pay-run.
Challenges
Making the LLM/rules boundary crisp: extraction quality tempts you to let the model judge. We kept judgment fully deterministic and made the model's one soft signal (pressure language) feed a hard rule, so the fraud invoice is held by policy, not vibes. Second: duplicate detection across resends needed vendor+number identity rather than text similarity — the resent invoice says "please disregard if already received" and still must be caught.
Accomplishments
End-to-end in an afternoon: 8 branches, all correctly routed on the first full run — the fraud attempt held with four named reasons; the €6,996 clean invoice correctly parked for a human; the arithmetic error caught to the cent.
What we learned
Taskmasters earn trust by routing, not by autonomy: auto-approve the boring 80%, and make the risky 20% arrive with reasons a human can act on in seconds.
What's next
Gmail/Drive intake connectors; two-person approval above a threshold; vendor-master change control; export to real payment rails (SEPA pain.001).
Disclosure
Built solo during the submission window with AI coding assistance (Claude). All vendors, invoices, IBANs and the fraud attempt are fictional. Same author as the separate entry "Proofline" (Fortified Enterprise Fleet track); the two share no code.
Log in or sign up for Devpost to join the conversation.