Build a Tool-Using AI Agent with Gemini
Build a Python AI agent that calls tools to answer questions accurately.
Introduction
30 Second Summary
When you ask a virtual assistant about the weather or to solve a quick math problem, it doesn't just guess. It picks the right tool behind the scenes, gets the answer, and brings it back to you.
In this project, you will build your own AI agent in Python that works the same way. You'll connect it to Google Gemini and teach it to choose between different tools to answer your questions accurately.
What You'll Build
You'll type a question in plain English into your terminal, and your agent will figure out whether to check the weather, run a calculation, or answer from its own knowledge.
By the end of this project, you'll have:
- A working Python chatbot powered by Google Gemini that you can talk to directly in your terminal.
- An agent that autonomously decides when to use a tool and which tool to use, without you telling it.
- A visible agentic loop where you watch the agent think, pick a tool, call it, and respond with grounded answers instead of made-up ones.
- Secret Mission: Add a timezone tool that returns the real current time in any city, giving your agent a third skill powered by live data.
Are there any prerequisites?
This project assumes you have Python 3.10+ and VS Code installed on your computer. You do not need any prior AI experience.
Step 1 walks you through everything else, including getting a free Google Gemini API key.
Before We Start
Before we dive in, let's lock in what you're about to build and why it matters.
Set Up Your Gemini API Key and Project
Every AI agent needs a brain. Your agent's brain will be Google Gemini, a large language model you can talk to through an API. The best part? Gemini's API has a free tier that costs nothing to use.
In this step, you'll grab a free API key from Google AI Studio, install the Python SDK, and write a quick test script to make sure everything connects.
In this step, get ready to:
- Get a free API key from Google AI Studio.
- Install the google-genai Python SDK.
- Create agent.py and verify your connection to Gemini.
Get your free Gemini API key
Your agent needs an API key to authenticate with Google's servers. Google AI Studio gives you a free key with no credit card required.
- Open your browser and go to https://aistudio.google.com/apikey.
- Sign in with your Google account.
- Click Create API Key.
- If prompted to select a Google Cloud project, choose the default project that AI Studio created for you.
- Copy the API key that appears and save it somewhere safe (like a text file on your Desktop).
Keep your key safe
Your API key is like a password. Do not share it publicly or commit it to GitHub. You'll paste it directly into your code for this learning project.
Seeing a permission denied error?
Make sure you are signed into your personal Google account, not a work or school account. Some organizations restrict API key creation.
Also confirm you are in a supported region for the Gemini API. If the issue persists, try opening the page in an incognito browser window.
Help me fix a permission error when creating my Gemini API key.
Install the SDK and create your project file
The google-genai SDK is the Python library that lets your code talk to Gemini. You'll install it with pip, then set up a project folder and file.
- Press Cmd+Space (macOS) or the Windows key (Windows) to open your search bar.
- Type VS Code and press Enter to open it.
- Open a terminal inside VS Code by pressing Ctrl+` (the backtick key, next to the number 1 on your keyboard). This shortcut works on both macOS and Windows.
- Move to your Desktop by running this command:
cd ~/Desktop
- Create your project folder and move into it by running these commands:
mkdir gemini-agent
cd gemini-agent
- Install the google-genai SDK by running:
pip install google-genai
You should see pip downloading and installing the package. Look for a line that says "Successfully installed" near the end of the output.
Seeing 'command not found' for pip?
Try running pip3 install google-genai instead. Some systems use pip3 for Python 3.
Help me fix a pip install error for google-genai.
Now open the gemini-agent folder in VS Code so that your file explorer and terminal are both pointed at the right place.
- Click File in the VS Code menu bar.
- Click Open Folder.
- Select the gemini-agent folder on your Desktop, then click Open.
Why open the folder?
Opening the folder sets VS Code's workspace to your project. Your terminal will automatically start in the gemini-agent directory, and any files you create will appear in the Explorer sidebar on the left.
- Click the New File icon at the top of the Explorer sidebar (it looks like a page with a plus sign).
- Type agent.py and press Enter.
Your new file opens in the editor. This is where your agent will live for the entire project.
- Add the following code to agent.py:
import json
from google import genai
from google.genai import types
# Create a client to communicate with Google Gemini
client = genai.Client(api_key="your-api-key-here")
# Send a simple question to Gemini
response = client.models.generate_content(
model="gemini-3.5-flash",
contents=["Hello! What can you help me with?"],
)
# Print the model's response
print(response.text)
- Replace "your-api-key-here" with the API key you copied from Google AI Studio. Keep the quotes around it.
What does this code do?
- import json and from google.genai import types are imports you'll need in later steps. They're included now so you don't have to add them later.
- genai.Client(api_key=...) creates a connection to Google's servers using your API key.
- client.models.generate_content() sends your question to the gemini-3.5-flash model and returns Gemini's answer.
- response.text pulls out the text of Gemini's reply so you can print it.
- Save agent.py by pressing Cmd+S (macOS) or Ctrl+S (Windows).
Run your script and verify your connection
Before you run this, what do you think Gemini will respond with? It received "Hello! What can you help me with?" as its input.
- Open the terminal in VS Code by pressing Ctrl+`.
- Run your script by entering this command:
python agent.py
You should see a text response from Gemini printed in your terminal. The exact wording will vary each time, but Gemini will describe the kinds of tasks it can help with.
Seeing an error?
- If you see ModuleNotFoundError, the SDK is not installed in the Python your terminal is using. Try running pip3 install google-genai and then python3 agent.py.
- If you see an API key error, double-check that you replaced "your-api-key-here" with your actual key from Google AI Studio. Make sure the key is inside the quotes.
- If you see a 403 or region error, your Google account may not be in a supported region for the Gemini API free tier.
Help me fix an error when running agent.py with the Gemini API.
✔️ Awesome, I've got everything!
Great. Make sure you've saved agent.py and you're ready to move on.
ⓧ I'd like to double check the full code
Here is the full agent.py at this point. Make sure your file matches this exactly (with your own API key in place of the placeholder).
import json
from google import genai
from google.genai import types
client = genai.Client(api_key="your-api-key-here")
response = client.models.generate_content(
model="gemini-3.5-flash",
contents=["Hello! What can you help me with?"],
)
print(response.text)
Your connection to Gemini is live. Next up, you'll turn this simple script into an interactive chatbot you can have a conversation with.
Build a Basic Chatbot
Your script can talk to Gemini, but right now it sends a single question and exits. A real assistant needs to hold a conversation.
In this step, you will turn your script into an interactive chatbot that keeps talking until you tell it to stop. This version can only generate text from its training data. It cannot look up real information or do calculations accurately. You will see this limitation firsthand.
In this step, get ready to:
- Turn your one-shot script into an interactive chatbot with a conversation loop.
- Add a system instruction that shapes how the model responds.
- Test the chatbot and discover what it cannot do.
Turn your script into an interactive chatbot
Right now agent.py fires off one question and exits. You need a loop that keeps reading your input, sending it to Gemini, and printing the response.
- In agent.py, find these lines below the three imports:
client = genai.Client(api_key="your-api-key-here")
response = client.models.generate_content(
model="gemini-3.5-flash",
contents=["Hello! What can you help me with?"],
)
print(response.text)
- Select all of that code (everything below the three import lines) and delete it.
- Replace it with the following code:
def main():
# Create the Gemini client
client = genai.Client(api_key="your-api-key-here")
# Set up a system instruction for the model
config = types.GenerateContentConfig(
system_instruction="You are a helpful personal assistant.",
)
print("Personal Assistant Agent")
print("Type your questions below. Type 'quit' to exit.\n")
while True:
user_input = input("You: ")
if user_input.lower() == "quit":
print("Goodbye!")
break
# Send the user's question to Gemini
response = client.models.generate_content(
model="gemini-3.5-flash",
contents=[user_input],
config=config,
)
print(f"Agent: {response.text}\n")
if __name__ == "__main__":
main()
What does this code do?
- def main(): wraps everything in a function. The if __name__ == "__main__": block at the bottom calls it when you run the script directly.
- types.GenerateContentConfig(system_instruction=...) gives the model a personality. The system instruction tells Gemini how to behave before the user even asks a question.
- The while True loop is the conversation engine. It reads your input, sends it to Gemini with generate_content(), and prints the response. Typing quit breaks out of the loop and ends the program.
- Save agent.py.
- Run your chatbot by entering this command in your terminal:
python agent.py
You should see the header Personal Assistant Agent followed by a You: prompt waiting for your input.
- Type a question like What is the capital of France? and press Enter.
Gemini responds with an answer, and the You: prompt appears again. You have a working conversation loop.
- Type quit and press Enter to exit the chatbot.
Chatbot not starting?
- Check that you deleted ALL of the old code below the imports. Leftover lines from the previous version will cause errors.
- Make sure the if __name__ == "__main__": line is at the very bottom of the file with no indentation.
- Confirm your API key is still in the genai.Client(api_key=...) line. The new code uses the same key from Step 1.
Help me debug why my chatbot won't start.
✔️ Awesome, I've got everything!
Great. Double check you have saved agent.py before moving on.
ⓧ I'd like to double check the full code
Here is the full agent.py file at this point. Compare yours against it line by line.
import json
from google import genai
from google.genai import types
def main():
client = genai.Client(api_key="your-api-key-here")
config = types.GenerateContentConfig(
system_instruction="You are a helpful personal assistant.",
)
print("Personal Assistant Agent")
print("Type your questions below. Type 'quit' to exit.\n")
while True:
user_input = input("You: ")
if user_input.lower() == "quit":
print("Goodbye!")
break
response = client.models.generate_content(
model="gemini-3.5-flash",
contents=[user_input],
config=config,
)
print(f"Agent: {response.text}\n")
if __name__ == "__main__":
main()
Test the chatbot and discover its limits
Your chatbot handles general knowledge questions well. But what happens when you ask it something that requires real-time information?
- Start the chatbot again by running:
python agent.py
Before you ask your next question, think about this: do you think the chatbot can give you accurate, real-time weather data for Tokyo?
- Type What is the weather in Tokyo right now? and press Enter.
The model either makes up weather data that sounds plausible or admits it cannot access real-time information. Either way, the answer is not grounded in reality. This is the limitation you expected.
- Now type What is 847 * 293? and press Enter.
The correct answer is 248,171. The model may get it right, get it wrong, or give a confident answer that is slightly off. Large language models predict text. They do not actually compute math.
- Type quit to exit the chatbot.
Why did the chatbot fail?
The chatbot only has access to its training data. It has no way to look up live weather, perform reliable calculations, or access any external system.
This is exactly why AI agents need tools. A tool gives the model the ability to call a real function, get a real result, and use that result in its answer. That is the gap you will close in the next step.
You have seen the problem firsthand. Your chatbot sounds confident, but it has no connection to the real world. In the next step, you will give it a tool that lets it call a real function and return grounded answers.
Give Your Agent a Tool
Your chatbot just made up weather data because it has no way to access real information. It can only generate text from its training data, which means it guesses instead of looking things up.
Function calling fixes this. You define a tool with a name, description, and parameters. The model then decides when to call that tool instead of guessing.
In this step, get ready to:
- Define a weather function and a tool descriptor that tells Gemini how to use it.
- Wire up the agentic loop so the model can detect, call, and use tool results.
- Test that your agent calls the weather tool instead of making up an answer.
Define the weather function and tool descriptor
Your agent needs two things to use a tool: a Python function that does the actual work, and a descriptor that tells Gemini what the function does and what parameters it expects.
- In agent.py, add the following get_weather function above the def main(): line:
# --- Your Tools ---
def get_weather(location: str) -> str:
"""Returns mock weather data for a given location."""
weather_data = {
"paris": "22C and sunny",
"london": "15C and cloudy",
"tokyo": "28C and humid",
"new york": "18C and windy",
}
location_lower = location.lower()
for city, weather in weather_data.items():
if city in location_lower:
return json.dumps({"location": location, "weather": weather})
return json.dumps({"location": location, "weather": "20C and partly cloudy"})
What does this code do?
The get_weather function takes a city name and returns mock weather data as a JSON string. It uses a dictionary of hardcoded cities and a fallback for any city not in the list.
This is mock data on purpose. The point of this project is learning how agents call tools, not building a real weather API integration. The pattern works the same way with real data.
Now Gemini needs to know this function exists. A tool descriptor is a structured definition that tells the model what the function does and what arguments it accepts.
- Add the following tool descriptor and function registry directly below the get_weather function (still above def main():):
# --- Tool Descriptors ---
weather_tool = types.FunctionDeclaration(
name="get_weather",
description="Gets the current weather for a given location. Call this when the user asks about weather or temperature in a city.",
parameters_json_schema={
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "The city name, e.g. Paris, London, Tokyo",
}
},
"required": ["location"],
},
)
# --- Available Functions Registry ---
available_functions = {
"get_weather": get_weather,
}
What is a tool descriptor?
The FunctionDeclaration tells Gemini three things: the function's name, a plain-English description of when to use it, and the expected parameters with their types. Gemini reads this description to decide whether to call the function for a given question.
The available_functions dictionary maps function names to their actual Python functions. When Gemini says "call get_weather", your code looks up the real function here.
- Save agent.py.
- Run your chatbot to confirm everything still starts up by running:
python agent.py
The chatbot should start as normal. The new code you added is defined but not wired into the chat loop yet. Type quit to exit.
Seeing a syntax error?
Make sure the get_weather function and weather_tool descriptor are placed above the def main(): line, not inside it. Check for missing commas inside the parameters_json_schema dictionary.
Help me fix a syntax error in my agent.py tool descriptor
Wire up the agentic loop
The agentic loop is the core pattern behind every AI agent. Instead of just printing the model's text, your code checks whether the model wants to call a tool, executes the tool, and feeds the result back.
- In agent.py, find the config block inside def main()::
config = types.GenerateContentConfig(
system_instruction="You are a helpful personal assistant.",
)
- Replace it with this updated version that registers your tool and gives the model smarter instructions:
tools = types.Tool(function_declarations=[weather_tool])
config = types.GenerateContentConfig(
tools=[tools],
system_instruction="You are a helpful personal assistant. Use the available tools when appropriate to give accurate answers. For weather questions, use the get_weather tool. For general knowledge questions, answer directly.",
)
What changed in the config?
You wrapped your weather_tool descriptor in a types.Tool object and passed it to the config. Now Gemini knows it has a weather function available.
The system instruction also got more specific. It tells the model exactly when to use the tool and when to answer directly.
Next, you need to update the response handling inside the while True loop. Right now, every response is printed as plain text. You need to check whether Gemini wants to call a function first.
- Find these lines inside the while True loop (below the quit check):
response = client.models.generate_content(
model="gemini-3.5-flash",
contents=[user_input],
config=config,
)
print(f"Agent: {response.text}\n")
- Replace them with this code that detects tool calls, executes the function, and handles non-tool responses:
contents = [user_input]
response = client.models.generate_content(
model="gemini-3.5-flash",
contents=contents,
config=config,
)
# Check if the model wants to call a function
if response.function_calls:
fc = response.function_calls[0]
print(f" [Agent is calling tool: {fc.name}({fc.args})]")
# Execute the function
func = available_functions[fc.name]
result = func(**fc.args)
print(f" [Tool returned: {result}]")
else:
print(f"Agent: {response.text}\n")
What does this code do?
The user's input goes into a contents list (you will build on this list shortly). After calling generate_content, you check response.function_calls to see if Gemini wants to use a tool.
If it does, you grab the first function call, look up the matching Python function in available_functions, and run it with the arguments Gemini provided. If Gemini did not request a tool, the response is printed as plain text.
- Save agent.py and run the script:
python agent.py
Ask: What is the weather in Paris?. You should see two lines printed showing the tool being called and its raw return value. The agent does not give you a conversational answer yet because you have not sent the tool result back to Gemini.
Why is there no conversational answer?
Right now the loop stops after executing the function. The model asked for data. Your code fetched it. But nobody told Gemini what the data says. The next chunk completes the loop by feeding the tool result back to Gemini so it can write a natural-language answer.
Type quit to exit the chatbot.
The final piece of the agentic loop is sending the tool's result back to Gemini so it can compose a real answer. This is the "close the loop" step that makes function calling useful.
- In agent.py, find the line print(f" [Tool returned: {result}]") inside the if response.function_calls: block.
- Add the following code directly below that line (still inside the if block, above the else):
# Send the result back to the model
contents.append(response.candidates[0].content)
fn_response_part = types.Part.from_function_response(
name=fc.name,
response=json.loads(result),
id=fc.id,
)
contents.append(types.Content(role="user", parts=[fn_response_part]))
# Get the final response
final_response = client.models.generate_content(
model="gemini-3.5-flash",
contents=contents,
config=config,
)
print(f"Agent: {final_response.text}\n")
What does this code do?
First, you append the model's original response (which contains its function call request) to the contents list. This preserves the conversation history.
Next, types.Part.from_function_response() wraps your function's result into a format Gemini understands. The id parameter links this response back to the exact function call Gemini made.
Finally, you call generate_content again with the full conversation (user question, model's tool request, your tool result). Gemini reads the tool result and writes a conversational answer.
Test your tool-using agent
Before you run this, think about what you expect to see. When you ask about the weather, do you think the agent will make up an answer like before, or do something different?
- Save agent.py and run the script:
python agent.py
- Type: What is the weather in Paris?
You should see three things in your terminal: a line showing the agent calling the get_weather tool, a line showing the tool's return value, and a conversational response that uses the tool's data instead of making something up.
What should I see?
Your terminal output should look something like this:
- [Agent is calling tool: get_weather({...})]
- [Tool returned: {"location": "Paris", "weather": "22C and sunny"}]
- Agent: The weather in Paris is 22C and sunny.
The exact wording of the agent's final answer varies each time because Gemini generates it fresh. The key is that the data comes from your tool, not from the model guessing.
- Try asking a general knowledge question like Who invented the telephone? to confirm the agent responds directly without calling a tool.
- Type quit to exit.
Agent not calling the tool?
Make sure you passed tools=[tools] inside your GenerateContentConfig. Without it, Gemini does not know any tools exist.
If you see an error about function responses, check that contents.append(response.candidates[0].content) comes before the types.Part.from_function_response() call. The model's original response must be in the conversation history first.
Help me debug why my agent is not calling the weather tool
✔️ Awesome, I've got everything!
Great. Double check you have saved agent.py.
ⓧ I'd like to double check the full code
Here is the complete agent.py at this point. Compare it against yours section by section:
- The imports (json, genai, types) at the top.
- The get_weather function under the # --- Your Tools --- comment.
- The weather_tool descriptor under # --- Tool Descriptors ---.
- The available_functions dictionary under # --- Available Functions Registry ---.
- The main() function with the tools setup, updated config, and the full if response.function_calls block.
Scroll up and confirm each section is present and in order.
Your agent now uses real data instead of guessing. Next up, you will add a second tool and watch the model intelligently route each question to the right one.
Add a Second Tool and Multi-Tool Routing
Your agent can now call a weather tool instead of making up answers. That is a huge upgrade from the basic chatbot.
A real agent needs more than one trick. Right now, if you ask your agent a math question, it still guesses. By adding a second tool, you will see something powerful: the model automatically routes each question to the correct tool, or skips tools entirely when it can answer on its own.
In this step, get ready to:
- Build a calculator tool that evaluates math expressions.
- Wire up both tools so the model picks the right one for each question.
- Test multi-tool routing with weather, math, and general knowledge questions.
Define the calculator function
Your agent needs a Python function it can call when someone asks a math question. This function takes an expression like 847 * 293 as a string, evaluates it, and returns the result as JSON.
- In agent.py, find the # --- Tool Descriptors --- comment.
- Add the following calculate function directly above that comment, with a blank line between it and the get_weather function:
def calculate(expression: str) -> str:
"""Evaluates a math expression and returns the result."""
try:
result = eval(expression)
return json.dumps({"expression": expression, "result": str(result)})
except Exception as e:
return json.dumps({"expression": expression, "error": str(e)})
What does this code do?
- eval(expression) takes a math string like "847 * 293" and runs it as Python code, returning the numeric result.
- The try/except block catches invalid expressions (like "abc + 2") and returns the error message instead of crashing.
- The result is returned as a JSON string, matching the same format as get_weather.
A note on eval() in production
eval() runs any Python expression, which is a security risk if you ever accept input from untrusted users. For this learning project running locally, it is perfectly safe. In production, you would use a dedicated math parser instead.
- Save agent.py.
- Test the function directly by running this command in your terminal:
python -c "from agent import calculate; print(calculate('847 * 293'))"
You should see {"expression": "847 * 293", "result": "248171"} printed in your terminal.
Seeing a SyntaxError or ImportError?
- Make sure you saved agent.py before running the command.
- Check that the calculate function is at the top level of the file (same indentation as get_weather), not accidentally nested inside another function.
- Make sure you are running the command from the same folder that contains agent.py.
Still stuck? Ask for help.
Create the tool descriptor and connect everything
Your function works, but Gemini does not know it exists yet. You need a tool descriptor that tells the model what the function does, when to call it, and what parameters it expects.
- In agent.py, find the # --- Available Functions Registry --- comment.
- Add the following calculator_tool descriptor directly above that comment, after the existing weather_tool:
calculator_tool = types.FunctionDeclaration(
name="calculate",
description="Evaluates a mathematical expression and returns the result. Call this when the user asks to calculate, compute, or solve a math problem.",
parameters_json_schema={
"type": "object",
"properties": {
"expression": {
"type": "string",
"description": "The math expression to evaluate, e.g. 847 * 293",
}
},
"required": ["expression"],
},
)
What does this descriptor do?
This follows the same structure as your weather_tool descriptor. The description field is the key: it tells Gemini when to reach for this tool ("calculate, compute, or solve a math problem").
The model reads these descriptions at runtime to decide which tool fits the user's question. A clear, specific description means better routing.
Now you need to connect the new tool in three places: the functions registry, the tools list, and the system instruction.
- In agent.py, find the available_functions dictionary. It currently looks like this:
available_functions = {
"get_weather": get_weather,
}
- Add "calculate": calculate to the dictionary so it looks like this:
available_functions = {
"get_weather": get_weather,
"calculate": calculate,
}
- Next, find the tools line inside the main() function. It currently looks like this:
tools = types.Tool(function_declarations=[weather_tool])
- Add calculator_tool to the list so it looks like this:
tools = types.Tool(function_declarations=[weather_tool, calculator_tool])
- Finally, find the system_instruction string inside config. It currently looks like this:
system_instruction="You are a helpful personal assistant. Use the available tools when appropriate to give accurate answers. For weather questions, use the get_weather tool. For general knowledge questions, answer directly.",
- Replace it with this updated version that mentions the calculator tool:
system_instruction="You are a helpful personal assistant. Use the available tools when appropriate to give accurate answers. For weather questions, use the get_weather tool. For math questions, use the calculate tool. For general knowledge questions, answer directly.",
- Save agent.py.
Test multi-tool routing
Everything is connected. Your agent now has two tools and a system instruction that describes both. The agentic loop already looks up whichever function the model requests by name, so it works with any number of tools without changing the loop code.
Before you run this, think: if you ask about the weather, a math problem, and a general knowledge question, what do you expect the agent to do differently for each one?
- Start the agent by running this command:
python agent.py
- Type What is the weather in London? and press Enter.
You should see [Agent is calling tool: get_weather(...)] in the output, followed by the weather data from your mock function.
- Now type What is 847 * 293? and press Enter.
This time you should see [Agent is calling tool: calculate(...)] in the output. The agent picked a different tool. The result should be 248171.
- Finally, type Who invented the telephone? and press Enter.
No [Agent is calling tool: ...] message this time. The model answered directly from its training data because no tool was needed.
- Type quit to exit the agent.
Why is this so powerful?
You did not write any routing logic. There is no if "weather" in question or if "calculate" in question in your code. The model reads the tool descriptions and decides on its own which tool fits each question.
This is the same pattern behind every AI agent framework. Adding a third or fourth tool is just adding another function and descriptor. The loop stays the same.
Agent not calling the calculator tool?
- Check that calculator_tool appears in the function_declarations list alongside weather_tool.
- Make sure "calculate": calculate is in your available_functions dictionary. If it is missing, the agent will crash with a KeyError when it tries to look up the function.
- Verify the system_instruction mentions "For math questions, use the calculate tool." so the model knows when to reach for it.
Need help debugging? Ask here.
✔️ Awesome, I've got everything!
Great. Double check you have saved agent.py and that all three question types routed correctly.
ⓧ I'd like to double check the full code
Your agent.py should now contain these sections in order. Scroll up and confirm each one is present:
- Imports: json, genai, and types.
- Your Tools: get_weather() function, then calculate() function.
- Tool Descriptors: weather_tool FunctionDeclaration, then calculator_tool FunctionDeclaration.
- Available Functions Registry: available_functions dictionary with both "get_weather" and "calculate".
- Agent Loop: main() function with both tools in function_declarations, updated system_instruction mentioning the calculate tool, and the agentic loop.
Your agent now intelligently routes questions to the right tool all on its own. Next up, you will tackle an optional Secret Mission to add a third tool that returns real, live data.
Secret mission
Add a Timezone Tool
Your agent handles weather and math, but it has no idea what time it is anywhere in the world. In this mission, you will add a third tool that returns real, live time data using Python's standard library.
Clean Up Your Resources
Clean Up Your Resources
This project runs entirely locally and uses the Gemini API free tier, so there are no ongoing costs. Decide whether to keep your resources for future experimentation, pause them, or delete them entirely.
Resources you used:
- Your agent.py project file.
- Your Google Gemini API key (created in Google AI Studio).
- The google-genai Python SDK installed via pip.
Keep everything running
No action needed. Choose this if you want to keep experimenting with your agent or add more tools.
- Your agent.py file stays on your machine, ready to run anytime.
- Your Gemini API key remains active at no cost. The free tier has no billing account and no charges.
- The google-genai SDK stays installed in your Python environment for future projects.
Pause - I'll come back to this later
Since this project has no running processes or paid resources, there is nothing to pause. Your files and API key will be waiting for you when you come back.
- Your API key stays active at no cost. You can return to your project and run agent.py again anytime.
- No processes are running in the background, so there is nothing to shut down.
Delete - I don't want to use this again
Remove all project files, revoke your API key, and uninstall the SDK to start completely fresh.
- Delete your project file by running this command in the terminal from the folder where agent.py lives:
- Revoke your Gemini API key. Go to https://aistudio.google.com/apikey, find the key you created for this project, and delete it.
- Uninstall the SDK by running:
- When prompted to confirm, enter y and press Enter.
That's a Wrap!
That's a Wrap!
Nice work! You just built a working AI agent from scratch in Python using the Google Gemini API. Your agent doesn't just chat. It thinks about your question, picks the right tool, calls it, and weaves the result into a natural response.
You've learned how to:
- Built the agentic loop pattern from scratch: prompt the model, detect function calls, execute your Python functions, and feed results back to the model for a final answer.
- Implemented multi-tool routing where the model intelligently picks the right tool for each question, or skips tools entirely for general knowledge.
- Saw firsthand why agents need tools by watching a plain chatbot make up answers to weather and math questions, then fixing it with tool descriptors that ground the model's responses in real data.
- Secret Mission: Added a timezone tool that returns real live data using Python's datetime and zoneinfo modules.
Ready to quiz yourself?