Technical
The Agent I Built Last Week (Week Two Of Year Two)
On April ninth I shipped a small agent for a client. I want to walk through it because it is a good example of the kind of agent that actually earns its keep.
The business problem was invoice reconciliation. The client receives PDFs from suppliers every week. Someone has to match line items to purchase orders. That someone was spending four hours a week on it.
The scope
- Read invoice PDFs from a shared drive
- Extract line items
- Match them against an existing purchase orders CSV
- Output a reconciliation sheet with confidence scores
- Stop when the queue is empty
That is the whole goal. One input. One output. One stop condition.
The shape
def reconcile_agent(pdf_dir, po_csv):
invoices = [extract(p) for p in list_pdfs(pdf_dir)]
pos = load_pos(po_csv)
matches = []
for inv in invoices:
result = llm_match(inv, pos)
matches.append(result)
write_sheet(matches)No loop of loops. No recursive planning. One pass over the invoices. One call per invoice.
What makes it an agent
The LLM decides which purchase order line matches an invoice line and gives a reason. It has one tool, which is a fuzzy search against the PO dataset. It stops when the queue is empty.
What the client got
Four hours a week down to fifteen minutes of review. Confidence scores route the low-confidence matches to a human queue. High confidence auto-approved.
What I did not build
- No vector database. A fuzzy string match was enough.
- No agent framework. A Python script.
- No queue system. A folder.
- No UI. A Google Sheet output.
Why the shape matters
Agents that fail in production are usually the ones trying to do too much in one run. Narrow scope and a clean stop condition are more valuable than fancy planning. The Anthropic agents writeup says this better. I am saying it again because it keeps getting forgotten.
RELATED READING
The Consulting Shift I Am Making In Year Two
After a year of writing and building, my consulting practice is changing shape. Shorter engagements. Sharper outcomes.
ReadThe Frontend Shift: Shipping Less JavaScript In Year Two
A year ago I reached for Next.js for everything. This year I often reach for nothing.
ReadThe Serverless Lesson I Would Write On A Sticky Note
After a year of shipping serverless projects, one rule explains most of the wins and all of the losses.
Read