Skip to main content

Clearing a bank statement: what to automate, what to flag

· 2 min read
Vivek Gudapuri
Building Distri in public

The hard judgement in bank reconciliation isn't matching, it's knowing what to leave alone. A one-cent difference is card-processor rounding; a fifty-dollar difference is a question for a human. A good agent draws that line consistently and shows you only what deserves attention.

This recorded run works a real statement grid: it categorises the lines that are missing a category, and flags the amounts that are genuinely off, without touching the rest.

Recorded run, categorise via update_bank_records_batch, then flag the real gaps one row at a time. Every change lands as a reviewable draft.

Two things happen, and both stay visible on the grid:

  1. Categorise the uncategorised. Three statement lines match an invoice by reference but have no category yet. The agent sets each one from its matched invoice (Zeta → Sales, Electric Bill → Expense, Theta → Sales) in a single batch call, each row picks up a category, an AI comment, and a DRAFT badge.
  2. Flag what matters. Ten lines tie out to the cent; five are off by a penny or two and are left as rounding noise. Three are meaningfully over invoice, OMEGA ($50 over), SIGMA ($25 over), SALESFORCE ($20 over), and each gets an explanatory comment. That's $95.00 surfaced for a human instead of silently absorbed.

Every write is a draft, not a commit. The "AI changes pending" toolbar lets a person confirm or reject the whole batch, the agent proposes, the human disposes.

Batching, and the human gate

Two design choices make this production-shaped. First, batched writes, the agent updates many rows in one call instead of one-at-a-time, which keeps large runs fast:

{
name: 'update_bank_records_batch',
description: 'Update several bank records in one call',
handler: async ({ updates }) => {
gridRef.current.updateBankRecordsBatch(updates);
return `${updates.length} records updated`;
},
}

Second, the grid records every agent change as a draft with its previous values, so nothing is destructive until a human confirms. The agent's job is to get the queue down to just the decisions that need a person, and to explain each one.

Try it

Open the live sample to drive the grid yourself, or read the docs. Last in the series: consolidating subsidiary reports.