AI Agents in Production: A Practical Playbook for 2026
What separates an AI agent demo from one you can trust with customers: tool design, guardrails, human approval, evaluation and observability — with patterns we use in real deployments.

Ahsan Bilal
Principal Software Engineer
On this page
Every team can build an agent demo in an afternoon: give a model a few tools, a system prompt, and watch it book a meeting. Getting that same agent to behave on its thousandth conversation — with real customers, real data and real consequences — is a different job. This playbook covers the engineering that closes that gap.
Start with a job, not a chatbot
The most successful agents we've shipped do one well-defined job: answer order questions, qualify inbound leads, triage support tickets, extract data from invoices. A narrow job gives you three things a general assistant never will:
- A clear definition of _done_ for each conversation
- A small, auditable set of tools
- Test cases you can write before you write prompts
Write the job down as if you were hiring a person: what they can look up, what they can change, when they must ask a manager, and what they must never do. That document becomes your system prompt, your tool list and your evaluation suite.
Design tools like public APIs
An agent is only as reliable as its tools. The model decides _when_ to call a tool; your code decides _what actually happens_. Treat every tool like a public API exposed to an unpredictable client:
- Small and specific.
get_order_status(order_id)beatsrun_sql(query). Narrow tools are easier for the model to choose and impossible to abuse. - Validated inputs. Parse every argument with a schema (Zod, Pydantic) and return a helpful error the model can recover from.
- Scoped by the user, not the model. The current customer's ID comes from the authenticated session — never from the model's arguments.
- Idempotent writes. If the model retries
create_refund, nothing should happen twice. Use idempotency keys. - Readable results. Return compact JSON with only the fields the model needs. Large payloads waste tokens and confuse reasoning.
// Tools are created per request, closing over the authenticated session.
function orderTools(session: Session) {
return {
getOrderStatus: tool({
description: "Look up the status of one of the current customer's orders.",
inputSchema: z.object({ orderNumber: z.string().regex(/^ORD-\d{6}$/) }),
execute: async ({ orderNumber }) => {
const order = await db.order.findFirst({
where: { number: orderNumber, customerId: session.customerId }, // never from the model
select: { number: true, status: true, eta: true },
});
return order ?? { error: "No order with that number on this account." };
},
}),
};
}Put humans in the loop where it matters
Not every action needs approval, but some must have it. A simple rule that works well:
| Action type | Example | Policy |
|---|---|---|
| Read | Look up an order, search docs | Automatic |
| Reversible write | Add a CRM note, create a draft | Automatic, logged |
| Customer-visible | Send an email, post a reply | Approval at first, automatic once trusted |
| Financial or destructive | Refund, cancel, delete | Always requires approval |
Implement approval as a first-class state: the agent proposes an action, the system stores it as _pending_, a human approves or edits it in your admin panel, and only then does the tool execute. The agent can keep talking to the customer while it waits ("I've asked our team to confirm that refund").
Guardrails are layered, not a single prompt
Prompt instructions alone won't stop a determined user — or a malicious document — from steering the model. Layer your defenses:
- Input checks: block obviously off-topic or abusive requests early and cheaply.
- Retrieval hygiene: treat retrieved documents and web pages as _data_, never as instructions. Strip or neutralize text that tries to issue commands (prompt injection).
- Tool-level authorization: even if the model is tricked into calling a tool, the tool enforces permissions.
- Output checks: scan responses for leaked PII, internal URLs or policy violations before they reach the user.
- Budgets: cap tokens, tool calls and wall-clock time per conversation so a confused agent can't loop forever.
Memory: less is more
Long conversations and "remember everything" memory sound appealing but degrade quality and raise privacy questions. Prefer:
- Short-term context: the current conversation, trimmed or summarized when it grows.
- Structured long-term facts: preferences or account details stored in your database with explicit fields, not free-text memories the model wrote itself.
- Retrieval for knowledge: documents fetched on demand with citations, not pasted into every prompt.
Evaluate before and after you ship
You cannot improve what you don't measure, and you cannot measure an agent by chatting with it a few times. Build an evaluation set from day one:
- Collect 50–200 real or realistic requests, including tricky and adversarial ones.
- For each, record what a good outcome looks like: the right tool calls, the facts the answer must contain, and things it must not say.
- Score automatically — exact checks for tool calls, model-graded checks for answer quality — and run the suite on every prompt, tool or model change.
In production, sample real conversations into the same pipeline. Every escalation or thumbs-down is a new test case.
Observability: trace every step
When an agent misbehaves, "the AI did something weird" isn't a bug report. Log a trace per conversation: each model call with its prompt and output, each tool call with arguments and result, latency and token cost. OpenTelemetry-compatible tracing makes this searchable alongside the rest of your stack, and lets you answer the questions that matter: _Which tool fails most? Which requests escalate? What does a conversation cost?_
Choosing models and controlling cost
Use the strongest model where reasoning matters — planning, deciding which tool to call — and smaller, faster models for classification, summarization and extraction. Route through a gateway so you can switch providers, add fallbacks and track spend per feature without rewriting code. Cache stable prompt prefixes; most providers now discount cached input tokens significantly.
A launch checklist
- One clearly defined job with written policies
- Narrow, validated, session-scoped tools
- Approval flow for high-impact actions
- Layered guardrails and per-conversation budgets
- An evaluation suite that runs on every change
- Full tracing with cost and latency
- A graceful human handoff path
Agents are not magic and they're not a fad. They're software — and the teams that treat them with the same engineering discipline as payments or authentication are the ones getting real value from them.
_Planning an agent for support, sales or operations? See our AI agents & chatbots service or start a project._
Keep reading
All articles →Building a WhatsApp AI Assistant for Your Business: Architecture, Costs and Pitfalls
WhatsApp is where many customers already are. Here's how to build an AI assistant on the WhatsApp Business Platform that answers questions, takes orders and hands off to your team — the right way.
Model Context Protocol (MCP): Connecting AI Assistants to Your Business Systems
MCP has become the standard way to give AI assistants safe access to tools and data. Here's what it is, when to use it, and how to build a secure MCP server for your ERP, CRM or internal APIs.
Beyond Basic RAG: Hybrid Search, Reranking and Agentic Retrieval
Naive 'embed and retrieve top 5 chunks' RAG breaks on real documents. These are the upgrades that matter in production — better chunking, hybrid search, reranking, query rewriting, agentic retrieval and evaluation.