Lab 9 Solution: Building a "Calculator" Agent
Goal
This file contains the complete, step-by-step guide to creating the "Calculator" agent using modern ADK practices.
Step 1: Create the Calculator Agent Project
-
Initialize the project:
uv init calculator_agent --python 3.10
cd calculator_agent
uv add "google-adk>=2.1.0" python-dotenv -
Set up authentication: Create a
.envfile in yourcalculator_agentdirectory and add yourGOOGLE_API_KEY(or Agent Platform configuration).
Step 2: Write the Custom Tool Functions
-
Create a
toolsdirectory and package files:mkdir tools
touch tools/__init__.py -
Create the
calculator.pyfile: Createtools/calculator.pyand add the following code. In ADK 2.0, returning a Pydantic model is the best practice for type-safe tool outputs.from pydantic import BaseModel
class MathResult(BaseModel):
status: str
result: float = 0
message: str | None = None
def add(a: int, b: int) -> MathResult:
"""
Adds two numbers together.
Use this tool when the user asks to find the sum of two numbers.
"""
return MathResult(status="success", result=a + b)
def subtract(a: int, b: int) -> MathResult:
"""
Subtracts the second number from the first number.
"""
return MathResult(status="success", result=a - b)
def multiply(a: int, b: int) -> MathResult:
"""
Multiplies two numbers together.
"""
return MathResult(status="success", result=a * b)
def divide(a: int, b: int) -> MathResult:
"""
Divides the first number by the second number.
"""
if b == 0:
return MathResult(status="error", message="Cannot divide by zero.")
return MathResult(status="success", result=a / b)
Step 3: Configure the Agent Node
Open agent.py and replace its contents with the following. We use the modern Agent class and pass the raw Python functions directly into the tools list.
from google.adk import Agent
from tools.calculator import add, subtract, multiply, divide
root_agent = Agent(
name="calculator_agent",
model="gemini-3.5-flash",
description="An agent node that can perform arithmetic calculations.",
instruction="""
You are a helpful calculator assistant.
When the user asks you to perform a calculation, you MUST use the appropriate tool.
Clearly state the result to the user.
If the user asks something else, politely decline.
""",
tools=[add, subtract, multiply, divide]
)
Step 4: Test the Calculator Agent
You can now start the agent using the modern ADK CLI command:
uv run adk run .
Interact with the agent in the terminal and ask it to perform calculations:
- "What is 42 + 118?"
- "Multiply 15 by 3."
- "What is 10 divided by 0?"
- "What is the capital of France?" (Should be gracefully declined).
Self-Reflection Answers
-
What do you think would happen if you removed the docstrings from your calculator functions? Would the agent still be able to use them?
- Answer: If you remove the docstrings, the LLM receives an empty description for the tool. While it might occasionally guess what a tool named
adddoes based purely on the name and parameters, its behavior will become highly unpredictable. It might use the wrong tool, pass incorrect arguments, or refuse to use it entirely. The docstring is the LLM's only instruction manual for your function.
- Answer: If you remove the docstrings, the LLM receives an empty description for the tool. While it might occasionally guess what a tool named
-
Why is it a good practice to return a dictionary with a
statuskey from a tool function, especially for operations that can fail (like division)?- Answer: If
divide(10, 0)simply raised a PythonZeroDivisionError, your entire script (and the agent) would crash. By returning{"status": "error", "message": "..."}, you handle the error gracefully. The LLM receives this error message and can formulate a polite response to the user (e.g., "I'm sorry, but I cannot divide by zero.").
- Answer: If
-
How would you add a new tool to this agent, for example, a function to calculate the square root of a number? What steps would you need to take?
- Answer:
- Open
tools/calculator.pyand write the new function:def square_root(a: float) -> dict: - Add type hints and a clear docstring explaining its purpose.
- Implement the logic (e.g., using
math.sqrt(a)). - Return the structured dictionary.
- Open
agent.py, update the import statement to includesquare_root. - Add
square_rootto thetools=[]list in theroot_agentdefinition.
- Open
- Answer:
Lab Summary
You have successfully built an agent with custom capabilities, learning to:
- Organize tool code into a separate Python module.
- Write well-defined Python functions with type hints and docstrings to serve as tools.
- Register your custom tools directly in
agent.pywithout needing extra wrappers. - Write instructions that effectively guide the agent on how and when to use its new tools.