Testing and Debugging AI Agents
Agents are non-deterministic, so traditional "input X gives exactly output Y" tests only go so far. A solid testing strategy combines normal tests for your code with task-level evaluations of the agent's behaviour.
1. Unit-test the tools
Tools are ordinary functions. Test them like any other code, including permissions and error messages.
test('getInvoice refuses other customers\' invoices', async () => {
await expect(getInvoice({ invoice_id: 'INV-2' }, { user: { customerId: 1 } })).rejects.toThrow('Not found');
});
2. Record traces
Log every step: model request, response, tool name, arguments, result, tokens and latency, all under one run ID. Most agent bugs become obvious when you read the trace.
{ "run": "r_81f", "step": 3, "tool": "search_orders", "input": {"email": "a@x.com"},
"result_preview": "0 orders", "ms": 182 }
3. Task-based evaluations
Write realistic tasks with a checkable outcome, then run the agent on each several times.
TASKS = [
{"prompt": "Refund the damaged item on ORD-1042", "check": lambda db: db.refunds.exists("ORD-1042")},
{"prompt": "What's the status of ORD-7?", "check": lambda out: "shipped" in out.lower()},
]
pass_rate = sum(task["check"](run_agent(task["prompt"])) for task in TASKS for _ in range(3)) / (len(TASKS) * 3)
4. Common failure patterns
- Wrong tool chosen - improve tool descriptions or merge overlapping tools.
- Loops (same call repeated) - make errors more informative and add a step limit.
- Gives up too early - state the success criteria clearly in the system prompt.
- Hallucinated results - check the trace; was a tool actually called?
5. Test against a fake world
Point tools at a seeded test database or mocked APIs so evaluation runs are repeatable and can't touch production.
Was this article helpful?
Comments
No comments yet. Have a question or a tip? Be the first to share it.