Inspiration

ContaBu was born from the daily work of a bookkeeper in the United States. Every tool in it answers a mistake that work keeps finding in small-business books: a gym booked as an office expense, payroll the bank only shows net, one merchant in two categories.

The people who catch those mistakes work in small offices. The US has 71,408 private bookkeeping and non-CPA accounting offices, averaging 4.0 employees each (BLS, QCEW 2024, NAICS 541219), and bookkeeping clerk jobs are projected to fall 6% (−85,600) from 2025 to 2035 (BLS, Occupational Outlook Handbook). Their clients are not shrinking: there are 36.4 million US businesses, and 5.8 million are Hispanic-owned (US Census Bureau, reference year 2023, released Nov 20, 2025). That is why ContaBu is built in English and Spanish.

ContaBu takes the architecture of the enterprise tools auditors trust — the model proposes in a restricted form, a person approves, a deterministic engine applies — and brings it to that small bookkeeper: big-firm AI, for the small bookkeeper.

What it does

ContaBu is a bookkeeper's daily console for many client books. Bank transactions come in (Plaid or a CSV/XLSX statement, through the same engine) → rules categorize them → whatever no rule covers stays Pending, in plain sight → a team of agents on NVIDIA Nemotron, served by Nebius Token Factory, reviews the book and proposes → the bookkeeper approves → the P&L comes out with Pending declared.

How ContaBu works: the bank goes into the rules with no AI; what no rule covers stays Pending; the AI agents on NVIDIA Nemotron review and propose; the bookkeeper decides; the P&L comes from the database.

The AI never categorizes and never computes. Each book is a formula — an ordered chain of rules, like a nested IF (text contains · date window · amount range · money in/out → P&L section + category). A deterministic auditor finds what fixed rules can find; the agents judge its findings, check merchants on the web with Tavily, and draft new rows of the formula; a deterministic engine applies only what the bookkeeper approves. Totals come from SQL.

Every AI claim comes with its evidence, and every action shows its effect before it runs. Select a row and its side panel tells its whole story: the rule, its correction history, the agents' findings with the web evidence and its link, the notes that apply. The owner's vacation note becomes one rule with a date window, and the history test shows the 9 rows it moves, and nothing else. What the bookkeeper writes by hand wins: no rule touches that row again.

The Bookkeeping sheet with the side panel open on a coffee bought in Rome: the bookkeeper's vacation note, the personal-spending agent's finding and the Tavily evidence.

What it finds: on a blind exam on the demo books, our fixed checks in code, without AI, find 8 of 22 planted errors; with the agents, 14 · 15 · 14. On a real book — the bank account of a small business, used with its owner's permission (an authorized client account), with 197 current transactions from 2026 — a practicing bookkeeper planted 12 errors: code without AI finds 0, the full system 7 in each of 3 runs, all hidden personal spending. And of the 15 Pending transactions (out of the book's 118) for which the rule drafter proposed rules, it got 7 right on its own and all 15 with one note from the bookkeeper. Reviewing that whole book takes about 30 seconds and costs less than a cent ($0.007–0.008); the three demo books take under two minutes and $0.012.

ContaBu is a bookkeeping tool, not tax advice: every account carries its IRS Schedule C line to guide the tax preparer.

How we built it

  • Stack: React 19 + Vite + TypeScript + Tailwind (the sheet is RevoGrid) · Python + FastAPI · PostgreSQL + SQLModel + Alembic · Plaid for bank feeds · Firebase Auth. Every screen in English and Spanish.
  • Every AI call goes to NVIDIA Nemotron on Nebius Token Factory through its OpenAI-compatible endpoint, from one small httpx client: strict json_schema, a per-agent reasoning switch, retries, and a metered row per call (model, tokens, dollars, latency), with daily caps per office.
  • One model per seat, chosen by measurement: the reviewer, Nemotron 3 Nano; the merchant verifier, Tavily + Nemotron 3 Super; the rule drafter, Nemotron 3.5 Super VL (text only); the personal-spending agent, Nano; the note translator, Super — none of them reasoning. For each seat we tried every Nemotron language model on Token Factory's public catalog: five (Nano, 3.5 Lightning, Super, Ultra, 3.5 Super VL), reasoning on and off, one seat at a time, three runs each. The rule to switch was written before running: a candidate wins only if its worst run beats the current model's best. Token Factory made that fast: all five models sit behind the same API, so changing an agent's model is changing one variable.
  • The book's formula: the drafter returns rows in strict JSON; a validator in code rejects rows outside the schema or the book's chart of accounts (26 cases, 0 failures); a deterministic engine interprets them (rule → transfer → Pending). Every proposed rule needs grounds — a note, a repeated hand correction, or medium/high web evidence — or the model is not even called. Nothing the model returns is executed.
  • The merchant verifier searches Tavily only for what the audit flagged and the most frequent Pending merchants, never people: basic search first (1 credit), advanced (2 credits) once if the confidence is not high. Web text reaches one model only, which can return only one business type from a closed list of 30, with no tools; the other agents see only the type and a confidence.
  • Privacy: person names are replaced with placeholders before each call, and we measure what was actually sent — 0 full transaction descriptions, 0 amounts and 0 person names, in every run.
  • A measurement harness: blind exams on the demo books and on a real book, with answer keys the agents never see, counted by code, on the code we ship (frozen by sha1).

Challenges we ran into

  • A provider outage that looked like a result. On Oct 24, between 06:06 and 06:47 PDT, Token Factory answered HTTP 503 to many calls. In the runs inside that window, an agent with a FIXED model (the rule drafter) dropped from 44 to 0–34 Pending transactions resolved, and the seat we were measuring seemed to lose to four candidates. We caught it only because that fixed agent dropped for no reason; runs affected by provider errors were discarded and repeated.
  • Strict JSON guarantees format, not truth: asked for an impossible value, the model returns a plausible false one ("7202-07-01" for a date). So every value is validated again in code against the book's chart of accounts and dates.
  • Reasoning was the biggest cost lever and the hardest to control: only chat_template_kwargs.enable_thinking turns it off; reasoning_budget and reasoning_effort are accepted with 200 and ignored; and reasoning counts against max_tokens, so an answer can arrive empty.
  • Live evidence is not saved evidence. With the merchant verifier live, the team dropped by our own rule (one D2 run gave 13, one R2 run gave 5). A control — our keyword table on the same fresh Tavily results — showed the drop came from the new evidence, not from Super.
  • On a real book with no notes or corrections, the first review rejected every rule the drafter proposed, for lack of grounds: the web verifier searched only flagged merchants, and a Pending merchant never is. Now it also searches the 10 merchants with the most Pending transactions.
  • Temperature 0 is not deterministic on long outputs, so every measurement is three runs, and we report all three.
  • The demo had to stay open to every judge while each review spends Nemotron and Tavily credits, and the first load took 7–11 s. We built two doors: a read-only guided tour with the review already saved, and a live office per judge, pre-seeded so it opens at once, with daily caps.

Accomplishments that we're proud of

  • On a blind exam the agents were never tuned on, the team takes the demo books from 8 of 22 errors (code without AI) to 14 · 15 · 14.
  • On a real book, of 12 errors planted by a practicing bookkeeper, code without AI finds 0 and the full system 7, in each of 3 runs — all hidden personal spending.
  • Of the 15 Pending transactions (out of 118) the rule drafter proposed rules for, a single one-line note from the bookkeeper takes it from 7 right to all 15 (×3).
  • A full review of the real book takes about 30 seconds and costs $0.007–0.008, about one second of a bookkeeper's wage; the three demo books take under two minutes and $0.012.
  • 0 full transaction descriptions, 0 amounts and 0 person names sent to the model, in every run.
  • A test that calls every route with every role: 86 routes, 0 leaks. The formula validator: 26 cases, 0 failures.
  • Pending is declared in all five P&L outputs (card, summary, PDF, closed period, saved list).
  • English and Spanish on every screen; the agents that explain a finding write it in both languages in the same call.

What we learned

  • The smallest model was the best judge. As reviewer, Super, Ultra and 3.5 Super VL dismissed 6 or 7 true errors as "legitimate" on one real-book exam, so judging stays on Nano.
  • One model can be the best in one seat and the worst in another: 3.5 Super VL, used with text only and no reasoning, is our best rule drafter — the same quality as Super with reasoning, 39% cheaper, 3 s per call instead of 15–40 — and as a reviewer it dismissed true errors.
  • Large models were less stable across prompts: as the personal-spending agent, the best large model changed just by rewriting the prompt, while Nano gave 7 of 12 in all 12 runs, with both prompt versions.
  • Reasoning rarely paid: no seat in the final team reasons.
  • A fix has to pass the rule, not just look right. On the real book, the personal-spending agent finds 7 of 12 hidden errors with Tavily's merchant types and 12 of 12 without them: a store type ("department store") says what the store is, not what was bought. But the bookkeeper labeled every extra alert, and all of them were false alarms: taking the type away from that agent alone added 8–10 per run, and giving it the booked category found only 0–6 of 12. Neither fix passed the rule we wrote before running, so the verifier stays on for every agent. On the demo, with and without Tavily nearly tie (14 · 14 · 14 against 14 · 14 · 13 of 22).
  • Write the rule for "better" before running, keep a control, and repeat. A fixed agent exposed a provider outage, and a control separated new evidence from a new model.

What's next for ContaBu

Bookkeeping is where ContaBu starts. A plan, not something ContaBu does today:

  • A platform that connects bookkeepers with business owners: the owner receives the P&L, answers the bookkeeper's questions and sees the book, while the bookkeeper keeps the books.
  • AI tools for the owner, in that same platform. Bookkeeping is the entry point: once the owner and their bookkeeper work in the same platform, we want to keep building AI tools for the owner — receipts kept with each transaction as evidence, bill payments and more — with the same rule: the AI proposes, and a person decides.
  • The statement reconciler, under construction: it will store bank statements and check images, reconcile every transaction against the PDF statement, and put the payee's name on every check, automatically.
  • At a general store, the personal-spending alert should not go away but move to "ask the client", measured with the same rule and the same labels.
  • The detectors we don't have yet — a wrong category on a single row, an ATM withdrawal booked as an expense, a loan or owner money booked as revenue — measured on the same exams.
  • Exams written by practicing bookkeepers, and more authorized client books, each with its own exam.
  • A cash-derived balance sheet, then double entry.

Built With

Share this project:

Updates

Submission history