This lesson brings everything together: a small, complete agent that can look up information and perform a simple calculation, with proper error handling.

The scenario

An agent that answers questions requiring a calculation - "what is 15% of 340?" - by using a real calculation tool rather than trying to compute it via the language model itself (recall from AI Fundamentals: models are unreliable at exact arithmetic).

Defining the tool

def calculate(expression):
    try:
        # A real implementation would use a safe expression parser,
        # never Python's eval() on untrusted input.
        result = safe_eval(expression)
        return {"success": True, "result": result}
    except Exception as e:
        return {"success": False, "error": str(e)}

The agent loop

def run_agent(user_question):
    messages = [{"role": "user", "content": user_question}]
    tools = [{"name": "calculate", "description": "Evaluate a math expression"}]

    for step in range(5):   # hard cap - never loop forever
        response = model.generate(messages, tools=tools)

        if response.wants_tool_call:
            tool_result = calculate(response.tool_call.arguments["expression"])
            messages.append({"role": "tool", "content": tool_result})
        else:
            return response.text   # model decided it has the final answer

    return "Could not complete the task within the step limit."

Testing an agent properly

Test with the happy path first (a question that clearly needs one calculation), then deliberately test failure cases: an ambiguous question, a request for something with no matching tool, and a case where the tool itself fails - an agent that only works when everything goes right is not actually ready to ship.

What you have actually learned across this course

This small example uses every concept from the course: the agent-vs-chatbot distinction, function calling, step-by-step reasoning, and failure handling. Real production agents add more tools and more safeguards, but the fundamental shape - describe tools, let the model request calls, execute them safely, feed results back - stays exactly this simple underneath.