A demo voice agent and a production one are different animals. The demo can ramble. The production one has a customer on the line, an account to look up, and a calendar slot that either exists or does not.

At Automatdo I built the inbound agent that handled that traffic — Python and Django on AWS, foundation models with per-client tool-calling. The tools were the product: read account data, schedule an appointment, kick off a workflow the client already ran by hand. If the model could not call those tools reliably, it was just a polite voicemail.

A few things I would not skip again:

Tool-calling is a contract. Each client got a small, explicit set of tools rather than a grab bag. Fewer tools, stricter schemas, and boring fallbacks beat a clever agent that invents a function name at 2am.

The dashboard is part of the agent. Clients needed to see handled calls, voicemails, booked appointments, and SMS in one place. We shipped that as Django + React, with role-based access, because nobody trusts a black box that talks to their customers.

QA cannot be a spreadsheet. Once volume crossed a few thousand calls a month, listening to a sample by hand did not scale. The scoring service — performance, sentiment, risk, purpose — was how we kept a human in the loop without making a human the loop.

The interesting work was not “we used an LLM.” It was the unglamorous path from a live call to a side effect in someone else’s system, with logs you can audit later.