In Part 1, we built a Study Buddy agent from scratch using Google ADK. Now it's time to give our agent real power — tools.
Think about it this way: you could open a bottle with your teeth, but why would you when a bottle opener exists? The same logic applies to AI agents. Without tools, your Study Buddy can only respond using its pre-trained knowledge. It cannot look up current information, perform precise calculations, or interact with external systems.
The solution? Equip it with the right tools — like google_search for real-time information and custom calculators for precise computations.
How Agents Actually Use Tools
When an agent encounters a request, it follows a structured reasoning loop:
- Reason — The agent analyzes the user's request and determines what's needed.
- Select — It decides whether a tool is needed and picks the right one.
- Parameterize — It figures out the correct parameters and invokes the tool.
- Observe — It reads and interprets the tool's output.
- Respond — It uses the results to continue reasoning or produce a final answer.
This is exactly how humans operate — you assess what you need, pick the right tool, use it, and act on the result.
Tool Types in ADK
ADK provides two main categories of tools:
Function Tools (user-built)
- Standard Python functions/methods — Regular functions you write and register.
- Agents-as-Tools — Other agents that serve as tools for your primary agent.
- Long Running Function Tools — Asynchronous tasks that may take time to complete.
Built-in Tools (pre-made by ADK)
- Google Search — For real-time web search capabilities.
- Code Executor — For running code dynamically.
Let's start with built-in tools first.
Adding Google Search to Your Agent
Here's how to add the google_search tool to your Study Buddy agent:
import os
from pathlib import Path
import yaml
from google.adk import Agent
from google.adk.tools import google_search
def create_study_buddy_agent() -> Agent:
current_dir = Path(__file__).parent
config_path = current_dir / 'agent_config.yml'
config = yaml.safe_load(open(config_path, 'r', encoding='utf-8'))
prompt_path = current_dir / config['agent']['prompt_file']
instruction = open(prompt_path, 'r', encoding='utf-8').read().strip()
agent = Agent(
name=config['agent']['name'],
description=config['agent']['description'],
model=config['agent']['model'],
instruction=instruction,
tools=[google_search],
)
return agent
root_agent = create_study_buddy_agent() The code loads your agent's configuration and prompt from files, then creates the agent with the google_search tool included. That single line — tools=[google_search] — gives your agent the ability to search the web in real time.
Update Your Prompt
Once you add tools, your prompt needs to be updated to tell the agent when and how to use them. A good prompt update includes:
- Clear Tool Instructions — Tell the agent exactly when to reach for Google Search vs. relying on its knowledge.
- Reasoning Steps — Guide the agent through thinking before acting.
- Error Handling — What to do if a tool call fails or returns unexpected results.
Your prompt is the agent's personality blueprint. It should cover identity, capabilities, behavior guidelines, information sourcing rules, and constraints like academic integrity. For the Study Buddy, this means:
- Being patient, encouraging, and supportive in tone.
- Using Google Search for fact-checking and current events.
- Never giving direct homework answers — guide the student instead.
- Using mathematical notation for formulas.
- Maintaining clear boundaries (no personal, medical, or mental health advice).
Creating Custom Tools for Study Buddy
What Are Custom Function Tools?
Custom function tools are regular Python functions that you write and ADK automatically wraps them so your agent can call them. The key is writing clear function signatures with type hints and comprehensive docstrings — ADK inspects these to understand how to use the tool.
def calculate_grade(scores: list) -> str:
"""
Calculate a student's grade based on their test scores.
Args:
scores (list): A list of numerical test scores.
Returns:
str: The calculated grade (e.g., 'A', 'B', 'C').
"""
average = sum(scores) / len(scores) if scores else 0
if average >= 90:
return 'A'
elif average >= 80:
return 'B'
elif average >= 70:
return 'C'
else:
return 'D or below' ADK inspects the function's signature, type hints, and docstring to understand what the tool does and how to call it. This is why clear documentation is critical.
Adding the Custom Tool to Your Agent
Simply add the function to your tools list alongside the built-in tools:
agent = Agent(
name=config['agent']['name'],
description=config['agent']['description'],
model=config['agent']['model'],
instruction=instruction,
tools=[google_search, calculate_grade], # Adding the custom tool
) Best Practices for Custom Tools
- Clear Function Signatures — Always use type hints and detailed docstrings.
- Required vs. Optional Parameters — Use defaults or
typing.Optionalfor optional params. - Keep It Simple — Break complex tasks into small, focused functions.
- Test Thoroughly — Test the function standalone before integrating with the agent.
- Update Your Prompt — Tell the agent when and why to use the custom tool.
Leveling Up: Adding Personalization
A basic Study Buddy is helpful, but a personalized one is transformative. Imagine an agent that remembers your name, tracks your progress, knows your weak spots, and celebrates your wins. That's the difference between a tool and a true study companion.
Step 1: Identifying the Need
To make the agent truly personal, it needs to track:
- Student name, grade level, and preferred subjects
- Study session history and progress over time
- Goals and weak topics to focus on
Step 2: Planning the Custom Tool
We need functions to get and update student info, track study sessions, and manage goals. A JSON file works well for simple persistence:
def record_study_session(
subject: str,
duration_minutes: int,
topics_covered: List[str],
session_notes: Optional[str] = None
) -> Dict[str, str]:
"""Record a completed study session with progress tracking.
Args:
subject (str): Subject studied
duration_minutes (int): Session length
topics_covered (List[str]): Topics covered
session_notes (str, optional): Extra notes
Returns:
Dict[str, str]: Status with details
"""
# Logic to update JSON file... Step 3: Integrating It
Import the new tools and add them to the agent's tool list:
from .tools.student_manager import record_study_session, get_student_profile
agent = Agent(
# ...
tools=[google_search, record_study_session, get_student_profile],
) Step 4: Adjusting the Prompt
Update the prompt to instruct the agent to silently retrieve the student's profile at the start of each session and record the session after each meaningful interaction.
A Quick Note on Tool Limitations
The current single-agent setup can effectively use one built-in tool at a time, though you can add as many custom function tools as you need. This limitation will be addressed in future posts when we explore multi-agent systems — where specialized agents collaborate, each with their own tool sets.
The Power of the Prompt
The prompt is arguably the most critical component of your agent. Here's why:
- Defines Personality and Behavior — It shapes how the agent communicates and interacts.
- Guides Tool Usage — It tells the agent when and how to use its tools.
- Ensures Consistency — It keeps responses aligned with your goals.
- Handles Edge Cases — It provides fallback behavior for unexpected inputs.
Code and tools build the body, but the prompt breathes life into your agent.
XML Tag Prompting: Structuring for Clarity
One powerful technique is wrapping instructions in XML-like tags. This makes the prompt easier for the LLM to parse and significantly improves comprehension.
<Persona>
Identity: You are a patient, encouraging, and supportive Study Buddy.
Tone: Always maintain a friendly, positive, and enthusiastic tone.
...
</Persona> Using consistent, descriptive tags helps the model focus on the right context at the right time, leading to more reliable behavior.