feat: add comprehensive Google ADK tutorials and example agents for structured output, tool usage, and MCP integration

This commit is contained in:
ShubhamSaboo 2025-07-19 08:37:37 -07:00
parent a8c8dd835a
commit 98a20d67c1
57 changed files with 3545 additions and 24 deletions

View file

@ -0,0 +1,114 @@
# 🎯 Tutorial 1: Your First ADK Agent
Welcome to your first step in the Google ADK journey! This tutorial introduces you to the fundamental concept of creating a simple AI agent using Google's Agent Development Kit.
## 🎯 What You'll Learn
- **Basic Agent Creation**: How to create your first ADK agent
- **ADK Workflow**: Understanding the agent lifecycle
- **Simple Text Processing**: Basic input/output handling
- **Agent Configuration**: Essential parameters and settings
## 🧠 Core Concept: What is an ADK Agent?
An ADK agent is a **programmable AI assistant** that can:
- Process user inputs (text, images, etc.)
- Use AI models (like Gemini) to understand and respond
- Perform specific tasks based on your instructions
- Return structured or unstructured responses
Think of it as creating a **smart function** that uses AI to handle complex tasks.
## 🔧 Key Components
### 1. **LlmAgent Class**
The main building block for creating AI agents in ADK:
```python
from google.adk.agents import LlmAgent
```
### 2. **Essential Parameters**
- `name`: Unique identifier for your agent
- `model`: The AI model to use (e.g., "gemini-2.0-flash")
- `description`: What your agent does
- `instruction`: How your agent should behave
### 3. **Basic Workflow**
1. **Input**: User sends a message
2. **Processing**: Agent uses AI model to understand and respond
3. **Output**: Agent returns a response
## 🚀 Tutorial Overview
In this tutorial, we'll create a **Simple Greeting Agent** that:
- Takes user input (name, mood, etc.)
- Generates personalized greetings
- Demonstrates basic ADK functionality
## 📁 Project Structure
```
1_starter_agent/
├── README.md # This file - concept explanation
├── requirements.txt # Dependencies
└── greeting_agent/ # Agent implementation
├── __init__.py # Makes it a Python package
├── agent.py # Main agent code
└── env.example # Environment variables template
```
## 🎯 Learning Objectives
By the end of this tutorial, you'll understand:
- ✅ How to create a basic ADK agent
- ✅ Essential agent parameters and their purpose
- ✅ How to run and test your agent
- ✅ Basic ADK workflow and lifecycle
## 🚀 Getting Started
1. **Set up your environment**:
```bash
cd greeting_agent
# Copy the environment template
cp env.example .env
# Edit .env and add your Google AI API key
# Get your API key from: https://aistudio.google.com/
```
2. **Install dependencies**:
```bash
# Navigate back to the 1_starter_agent directory
cd ..
# Install required packages
pip install -r requirements.txt
```
3. **Run the greeting agent**:
```bash
# Start the ADK web interface
adk web
# In the web interface, select: greeting_agent
```
4. **Test your agent**:
- Try different greetings: "Hello, I'm John and I'm feeling great today!"
- Experiment with different moods and names
- See how the agent personalizes responses
## 🔗 Next Steps
After completing this tutorial, you'll be ready for:
- **[Tutorial 2: Structured Output Agent](../2_structured_output_agent/README.md)** - Learn to create type-safe, structured responses
- **[Tutorial 3: Tool Using Agent](../3_tool_using_agent/README.md)** - Add custom tools and functions to your agent
## 💡 Pro Tips
- **Start Simple**: Begin with basic functionality and add complexity gradually
- **Test Often**: Use the ADK web interface to test your agents
- **Read Instructions**: Clear instructions lead to better agent behavior
- **Experiment**: Try different models and parameters to see the differences

View file

@ -0,0 +1 @@
from .agent import root_agent

View file

@ -0,0 +1,22 @@
from google.adk.agents import LlmAgent
# Create a simple greeting agent
root_agent = LlmAgent(
name="greeting_agent",
model="gemini-2.0-flash",
description="A friendly agent that creates personalized greetings",
instruction="""
You are a friendly greeting assistant.
When users provide information about themselves (name, mood, occasion, etc.),
create warm, personalized greetings that make them feel welcome.
Be creative and consider:
- Their name (if provided)
- Their current mood or situation
- The time of day or occasion
- Adding a touch of humor or positivity
Keep responses friendly, concise, and personalized to the user's input.
"""
)

View file

@ -0,0 +1 @@
google-adk>=1.5.0

View file

@ -0,0 +1,138 @@
# 🎯 Tutorial 2: Model-Agnostic Agent
Learn how to create agents that work with **different AI models** using OpenRouter. This example shows how ADK can use OpenAI and Anthropic models through separate agent implementations.
## 🎯 What You'll Learn
- **OpenRouter Integration**: Use one API key for multiple model providers
- **Separate Agent Implementations**: Compare different models side-by-side
- **Tool Integration**: Add simple tools to your agents
- **Root Agent Pattern**: Proper ADK agent naming convention
## 🧠 Core Concept: One API, Many Models
[OpenRouter](https://openrouter.ai/) provides a unified API to access multiple AI models:
- ✅ **Single API Key**: Access OpenAI and Anthropic with one key
- ✅ **Easy Comparison**: Run different agents to compare responses
- ✅ **Cost Effective**: Pay-per-use pricing
- ✅ **No Vendor Lock-in**: Switch providers anytime
## 📁 Project Structure
```
2_model_agnostic_agent/
├── README.md # This overview
├── requirements.txt # Shared dependencies
├── openai_adk_agent/ # OpenAI GPT-4 agent
│ └── agent.py # Agent implementation
└── anthropic_adk_agent/ # Anthropic Claude agent
└── agent.py # Agent implementation
```
## 🔧 Available Agents
### **OpenAI Agent** (`openai_adk_agent/`)
- **Model**: GPT-4 via OpenRouter
- **Agent Name**: `root_agent` (required by ADK)
- **Features**: Fun fact tool with OpenAI personality
### **Anthropic Agent** (`anthropic_adk_agent/`)
- **Model**: Claude 4 Sonnet via OpenRouter
- **Agent Name**: `root_agent` (required by ADK)
- **Features**: Fun fact tool with Claude personality
## 🛠️ Setup & Usage
### 1. **Get OpenRouter API Key**
- Visit: [https://openrouter.ai/keys](https://openrouter.ai/keys)
- Sign up and get your API key
### 2. **Set Environment Variable**
Create a `.env` file in each agent folder:
**In `openai_adk_agent/.env`:**
```bash
OPENROUTER_API_KEY=your_openrouter_api_key_here
```
**In `anthropic_adk_agent/.env`:**
```bash
OPENROUTER_API_KEY=your_openrouter_api_key_here
```
### 3. **Install Dependencies**
```bash
# From the 2_model_agnostic_agent directory
pip install -r requirements.txt
```
### 4. **Test OpenAI Agent**
```bash
cd openai_adk_agent
adk web
```
- Try asking: "Tell me a fun fact!"
- Notice the OpenAI GPT-4 response style
### 5. **Test Anthropic Agent**
```bash
cd anthropic_adk_agent
adk web
```
- Try asking: "Tell me a fun fact!"
- Compare with the Claude response style
## 💡 Key Code Pattern
Each agent follows the same pattern:
```python
from google.adk.agents import Agent
from google.adk.models.lite_llm import LiteLlm
import os
# Create model via OpenRouter
model = LiteLlm(
model="openrouter/openai/gpt-4", # or claude model
api_key=os.getenv("OPENROUTER_API_KEY"),
base_url="https://openrouter.ai/api/v1"
)
# Create root_agent (required name for ADK)
root_agent = Agent(
name="agent_name",
model=model,
instruction="Your instructions here...",
tools=[your_tool_function],
)
```
## 🎯 Learning Objectives
By the end of this tutorial, you'll understand:
- ✅ How to use OpenRouter with ADK
- ✅ How to create separate agents for different models
- ✅ How to compare responses from different AI providers
- ✅ How to properly structure ADK agents with `root_agent`
## 🔄 Comparing Models
1. **Run the OpenAI agent** and ask questions
2. **Run the Anthropic agent** with the same questions
3. **Notice differences** in response style and approach
4. **Experiment** with different types of prompts
## 💰 Cost Information
- OpenRouter charges per token usage
- GPT-4o: More expensive but very capable
- Claude 4 Sonnet: Balanced cost and performance
- You can set spending limits in your OpenRouter dashboard
- Free tier available for testing
## 🚨 Important Notes
- **Root Agent**: Each agent must be named `root_agent` for ADK to recognize it
- **Environment Variables**: Each folder needs its own `.env` file
- **API Key**: The same OpenRouter key works for both agents
- **Comparison**: Run agents separately to compare model behaviors

View file

@ -0,0 +1 @@
OPENROUTER_API_KEY="your-api-key"

View file

@ -0,0 +1,37 @@
import os
import random
from google.adk.agents import Agent
from google.adk.models.lite_llm import LiteLlm
def get_fun_fact():
"""Return a random fun fact"""
facts = [
"Honey never spoils. Archaeologists have found pots of honey in ancient Egyptian tombs that are over 3,000 years old and still perfectly edible.",
"Octopuses have three hearts and blue blood.",
"A group of flamingos is called a 'flamboyance'.",
"Bananas are berries, but strawberries aren't.",
"A day on Venus is longer than its year.",
"Wombat poop is cube-shaped.",
"There are more possible games of chess than atoms in the observable universe.",
"Dolphins have names for each other.",
]
return random.choice(facts)
# Anthropic model via OpenRouter
model = LiteLlm(
model="openrouter/anthropic/claude-sonnet-4-20250514",
api_key=os.getenv("OPENROUTER_API_KEY")
)
root_agent = Agent(
name="anthropic_adk_agent",
model=model,
description="Fun fact agent using Anthropic Claude 4 Sonnet via OpenRouter",
instruction="""
You are a helpful assistant powered by Anthropic Claude 4 Sonnet that shares interesting fun facts.
Use the `get_fun_fact` tool when users ask for a fun fact or interesting information.
Be enthusiastic and friendly in your responses.
Always mention that you're powered by Anthropic Claude when introducing yourself.
""",
tools=[get_fun_fact],
)

View file

@ -0,0 +1 @@
OPENROUTER_API_KEY="your-api-key"

View file

@ -0,0 +1,37 @@
import os
import random
from google.adk.agents import Agent
from google.adk.models.lite_llm import LiteLlm
def get_fun_fact():
"""Return a random fun fact"""
facts = [
"Honey never spoils. Archaeologists have found pots of honey in ancient Egyptian tombs that are over 3,000 years old and still perfectly edible.",
"Octopuses have three hearts and blue blood.",
"A group of flamingos is called a 'flamboyance'.",
"Bananas are berries, but strawberries aren't.",
"A day on Venus is longer than its year.",
"Wombat poop is cube-shaped.",
"There are more possible games of chess than atoms in the observable universe.",
"Dolphins have names for each other.",
]
return random.choice(facts)
# OpenAI model via OpenRouter
model = LiteLlm(
model="openrouter/openai/gpt-4o",
api_key=os.getenv("OPENROUTER_API_KEY")
)
root_agent = Agent(
name="openai_adk_agent",
model=model,
description="Fun fact agent using OpenAI GPT-4 via OpenRouter",
instruction="""
You are a helpful assistant powered by OpenAI GPT-4 that shares interesting fun facts.
Use the `get_fun_fact` tool when users ask for a fun fact or interesting information.
Be enthusiastic and friendly in your responses.
Always mention that you're powered by OpenAI GPT-4 when introducing yourself.
""",
tools=[get_fun_fact],
)

View file

@ -0,0 +1,3 @@
google-adk>=1.5.0
litellm>=1.65.1
python-dotenv>=1.0.1

View file

@ -24,26 +24,31 @@ A tutorial demonstrating how to implement a structured customer support ticketin
- Automatic priority assignment based on issue description
- Category-based routing for different departments
## How to Run
## 🚀 Getting Started
1. **Setup Environment**
1. **Set up your environment**:
```bash
# Clone the repository
git clone https://github.com/Shubhamsaboo/awesome-llm-apps.git
cd awesome-llm-apps/google_adk_tutorials/structured_output_agent/customer_support_ticket_agent
cd 3_1_customer_support_ticket_agent
# Copy the environment template
cp env.example .env
# Edit .env and add your Google AI API key
# Get your API key from: https://aistudio.google.com/
```
# Install dependencies
2. **Install dependencies**:
```bash
# Navigate back to the directory
cd ..
# Install required packages
pip install -r requirements.txt
```
2. **Configure API Keys**
- Get Google AI API key from [Google AI Studio](https://aistudio.google.com/)
- Set up your API credentials for Gemini access
3. **Run the Agent**
```bash
# Start the ADK web interface from the root folder
cd google_adk_tutorials/structured_output_agent/customer_support_ticket_agent
# Start the ADK web interface
adk web
```
Then:

View file

@ -19,26 +19,31 @@ A tutorial demonstrating how to implement structured output using Google's ADK (
- Proper use of output schemas for reliable results
- Minimal codebase demonstrating core concepts
## How to Run
## 🚀 Getting Started
1. **Setup Environment**
1. **Set up your environment**:
```bash
# Clone the repository
git clone https://github.com/Shubhamsaboo/awesome-llm-apps.git
cd awesome-llm-apps/google_adk_tutorials/structured_output_agent/email_agent
cd 3_2_email_agent
# Copy the environment template
cp env.example .env
# Edit .env and add your Google AI API key
# Get your API key from: https://aistudio.google.com/
```
# Install dependencies
2. **Install dependencies**:
```bash
# Navigate back to the directory
cd ..
# Install required packages
pip install -r requirements.txt
```
2. **Configure API Keys**
- Get Google AI API key from [Google AI Studio](https://aistudio.google.com/)
- Set up your API credentials for Gemini access
3. **Run the Agent**
```bash
# Start the ADK web interface from the root folder
cd google_adk_tutorials/structured_output_agent/email_agent
# Start the ADK web interface
adk web
```
Then:

View file

@ -0,0 +1,3 @@
# If using Gemini via Google AI Studio
GOOGLE_GENAI_USE_VERTEXAI=False
GOOGLE_API_KEY="your-api-key"

View file

@ -0,0 +1,127 @@
# 🎯 Tutorial 3: Structured Output Agent
Welcome to structured output! This tutorial teaches you how to create agents that return **type-safe, structured data** instead of plain text. This is crucial for building reliable applications that need predictable data formats.
## 🎯 What You'll Learn
- **Pydantic Schemas**: Define data structures with validation
- **Type Safety**: Ensure your agents return expected data formats
- **Business Logic**: Process structured data reliably
- **Error Handling**: Graceful handling of validation errors
- **Real-world Applications**: Customer support and email generation
## 🧠 Core Concept: Structured Output
Structured output means your agent returns **validated data objects** instead of raw text:
- ✅ **Type Safety**: Know exactly what data format you'll receive
- ✅ **Validation**: Automatic checking of required fields and data types
- ✅ **Reliability**: No more parsing text responses manually
- ✅ **Integration**: Easy to use in applications and databases
### Why Structured Output?
- **Predictable**: Always get the same data structure
- **Validated**: Pydantic ensures data correctness
- **Typed**: Full IDE support and type checking
- **Scalable**: Easy to modify and extend schemas
## 🚀 Tutorial Structure
This tutorial contains **two comprehensive examples**:
### 📍 **Example 1: Customer Support Ticket Agent**
**Location**: `./3_1_customer_support_ticket_agent/`
- Extract structured ticket information from customer complaints
- Priority classification and urgency assessment
- Contact information extraction
- Department routing logic
### 📍 **Example 2: Email Generation Agent**
**Location**: `./3_2_email_agent/`
- Generate structured email content with metadata
- Subject line optimization
- Recipient classification
- Email template formatting
## 📁 Project Structure
```
3_structured_output_agent/
├── README.md # This tutorial overview
├── 3_1_customer_support_ticket_agent/ # Customer support example
└── 3_2_email_agent/ # Email generation example
```
Each example directory follows the standard structure:
- **Python file**: Contains the agent implementation and Streamlit app
- **README.md**: Setup and usage documentation
- **requirements.txt**: Dependencies list
## 🎯 Learning Objectives
By the end of this tutorial, you'll understand:
- ✅ How to define Pydantic schemas for structured output
- ✅ How to configure agents to return structured data
- ✅ How to handle validation errors gracefully
- ✅ When to use structured output vs plain text
- ✅ Best practices for schema design
## 💡 Key Patterns
### Basic Structured Output Pattern
```python
from pydantic import BaseModel
from google.adk.agents import Agent
class TicketInfo(BaseModel):
title: str
priority: str
category: str
urgency_level: int
agent = Agent(
name="support_agent",
model="gemini-2.0-flash",
instruction="Extract ticket information...",
response_format=TicketInfo, # This ensures structured output!
)
```
### Advanced Schema with Validation
```python
from pydantic import BaseModel, Field, validator
from typing import List, Optional
class EmailData(BaseModel):
subject: str = Field(..., min_length=5, max_length=100)
recipients: List[str] = Field(..., min_items=1)
priority: str = Field(..., regex="^(low|medium|high)$")
@validator('recipients')
def validate_emails(cls, v):
# Custom email validation logic
return v
```
## 🎯 Real-World Applications
Structured output agents are perfect for:
- **Customer Support**: Extracting ticket information from complaints
- **Data Processing**: Converting unstructured text to database records
- **Content Generation**: Creating structured content with metadata
- **Form Processing**: Extracting information from documents
- **API Integration**: Providing consistent data formats for other systems
## 💡 Pro Tips
- **Clear Schemas**: Use descriptive field names and add docstrings
- **Validation**: Add appropriate validators for your use case
- **Optional Fields**: Use `Optional` for fields that might be missing
- **Examples**: Provide example data in your schema documentation
- **Error Handling**: Always handle validation errors gracefully
## 🚨 Important Notes
- **Pydantic Required**: You need Pydantic for schema definitions
- **Model Support**: Not all models support structured output equally well
- **Validation Overhead**: Complex schemas may slow down responses
- **Schema Evolution**: Plan for schema changes in production systems

View file

@ -0,0 +1,3 @@
# If using Gemini via Google AI Studio
GOOGLE_GENAI_USE_VERTEXAI=False
GOOGLE_API_KEY="your-api-key"

View file

@ -0,0 +1,135 @@
# 🔍 Built-in Tools
Google ADK provides powerful **pre-built tools** that are optimized for performance and reliability. These tools integrate seamlessly with Gemini models and provide essential capabilities like web search and code execution.
## 🎯 What You'll Learn
- **Search Tool**: Web search capabilities for real-time information
- **Code Execution Tool**: Safe Python code execution environment
- **Tool Limitations**: Understanding when to use built-in vs custom tools
- **Best Practices**: Optimizing built-in tool usage
## 🧠 Core Concept: Built-in Tools
Built-in tools are **Google ADK's native capabilities** that provide:
- **High Performance**: Optimized for speed and reliability
- **Safety**: Built-in security and sandboxing
- **Gemini Integration**: Deep integration with Google's models
- **Maintenance-free**: No custom code to maintain
### Important Limitations
- ⚠️ **Gemini Models Only**: Built-in tools work only with Gemini models
- ⚠️ **Single Tool Type**: Cannot mix built-in and custom tools in same agent
- ⚠️ **Limited Customization**: Fixed functionality, cannot modify behavior
## 🔧 Available Built-in Tools
### 1. **Search Tool**
- **Purpose**: Web search for real-time information
- **Use Cases**: News, facts, current events, research
- **Benefits**: Fast, accurate, up-to-date results
### 2. **Code Execution Tool**
- **Purpose**: Execute Python code safely
- **Use Cases**: Calculations, data processing, algorithms
- **Benefits**: Secure sandbox environment
### 3. **RAG Tools** (Advanced)
- **Purpose**: Retrieval-augmented generation
- **Use Cases**: Document search, knowledge bases
- **Benefits**: Efficient information retrieval
## 🚀 Tutorial Examples
This sub-example includes two practical implementations:
### 📍 **Search Agent**
**Location**: `./search_agent/`
- Implements web search capabilities
- Handles real-time information queries
- Demonstrates search result processing
### 📍 **Code Execution Agent**
**Location**: `./code_exec_agent/`
- Executes Python code safely
- Performs mathematical calculations
- Processes data dynamically
## 📁 Project Structure
```
1_builtin_tools/
├── README.md # This file - built-in tools guide
├── search_agent/ # Web search implementation
│ ├── __init__.py # Makes it a Python package
│ ├── agent.py # Search agent with Search Tool
├── code_exec_agent/ # Code execution implementation
│ ├── __init__.py # Makes it a Python package
│ ├── agent.py # Code execution agent
└── requirements.txt # Dependencies for built-in tools
└── .env.example # Example API key configuration
```
## 🎯 Learning Objectives
By the end of this sub-example, you'll understand:
- ✅ How to use Google ADK's Search Tool effectively
- ✅ How to implement safe code execution with built-in tools
- ✅ When to choose built-in tools over custom solutions
- ✅ Limitations and best practices for built-in tools
## 🚀 Getting Started
1. **Set up your environment**:
```bash
cd 4_1_builtin_tools
# Copy the environment template
cp env.example .env
# Edit .env and add your Google AI API key
# Get your API key from: https://aistudio.google.com/
```
2. **Install dependencies**:
```bash
# Install required packages
pip install -r requirements.txt
```
3. **Run the agents**:
```bash
# Start the ADK web interface
adk web
# In the web interface, select either:
# - search_agent: For trying web search capabilities
# - code_exec_agent: For testing code execution features
```
## 💡 Pro Tips
- **Use for Real-time Data**: Perfect for current information needs
- **Leverage Gemini Integration**: Built-in tools are optimized for Gemini
- **Simple is Better**: Don't overcomplicate with custom tools if built-in works
- **Test Thoroughly**: Understand tool behavior before production use
## 🔧 Common Use Cases
### Search Tool Applications
- **News Updates**: Get latest news on topics
- **Fact Checking**: Verify information accuracy
- **Research**: Gather information on subjects
- **Market Data**: Current prices, trends
### Code Execution Applications
- **Mathematical Calculations**: Complex computations
- **Data Analysis**: Process and analyze data
- **Algorithm Implementation**: Test code logic
- **Visualization**: Generate charts and graphs
## 🚨 Important Notes
- **Model Dependency**: Only works with Gemini models
- **No Mixing**: Cannot combine with custom tools
- **Production Ready**: Built-in tools are enterprise-ready
- **Rate Limits**: Be aware of usage limits

View file

@ -0,0 +1,48 @@
from google.adk.agents import LlmAgent
from google.adk.code_executors import BuiltInCodeExecutor
# Create a code execution agent using Google ADK's built-in Code Execution Tool
root_agent = LlmAgent(
name="code_exec_agent",
model="gemini-2.0-flash",
description="A computational agent that can execute Python code safely",
instruction="""
You are a computational assistant with the ability to execute Python code safely.
Your role is to help users with:
- Mathematical calculations and computations
- Data analysis and processing
- Algorithm implementation and testing
- Code debugging and verification
- Data visualization and charting
Key capabilities:
- Execute Python code in a secure sandbox environment
- Perform complex mathematical calculations
- Process and analyze data
- Create visualizations and charts
- Test algorithms and logic
When users request computational tasks:
1. Write appropriate Python code to solve the problem
2. Execute the code using the code execution tool
3. Explain the results and any insights
4. Provide the code used for transparency
Examples of tasks you can handle:
- "Calculate the compound interest for $1000 at 5% for 10 years"
- "Sort this list of numbers: [64, 34, 25, 12, 22, 11, 90]"
- "Create a simple visualization of sales data"
- "Find the prime numbers between 1 and 100"
- "Calculate the Fibonacci sequence up to 20 terms"
Always:
- Show the code you're executing
- Explain the logic and approach
- Interpret results for the user
- Handle errors gracefully and suggest fixes
Safety note: Code execution happens in a secure sandbox environment.
""",
code_executor=BuiltInCodeExecutor()
)

View file

@ -0,0 +1,37 @@
from google.adk.agents import LlmAgent
from google.adk.tools import google_search
# Create a web search agent using Google ADK's built-in Search Tool
root_agent = LlmAgent(
name="search_agent",
model="gemini-2.0-flash",
description="A research agent that can search the web for real-time information",
instruction="""
You are a research assistant with access to real-time web search capabilities.
Your role is to help users find current, accurate information from the web.
Key capabilities:
- Search the web for recent news, facts, and information
- Provide accurate, up-to-date responses based on search results
- Cite sources when presenting information
- Clarify when information might be outdated or uncertain
When users ask for information:
1. Use the search tool to find relevant, current information
2. Synthesize the search results into a clear, comprehensive response
3. Include source links when possible
4. Mention if the information is from a specific time period
Examples of queries you can handle:
- "What's the latest news about artificial intelligence?"
- "Current stock price of Tesla"
- "Recent developments in renewable energy"
- "Today's weather in San Francisco"
- "Latest updates on space exploration"
Always prioritize accuracy and recency of information. If search results are
conflicting, present multiple perspectives and mention the discrepancy.
""",
tools=[google_search]
)

View file

@ -0,0 +1,249 @@
# ⚡ Function Tools
Function tools are **custom Python functions** that you create and integrate into your agents. This is the most flexible and commonly used approach for adding specific capabilities to your agents.
## 🎯 What You'll Learn
- **Function Tool Creation**: Build custom Python functions as tools
- **Tool Registration**: How to register functions with your agent
- **Parameter Handling**: Managing tool inputs and outputs
- **Error Handling**: Robust error management in tools
- **Best Practices**: Design patterns for effective function tools
## 🧠 Core Concept: Function Tools
Function tools are **Python functions with special characteristics**:
- **Descriptive docstrings**: Help the agent understand when to use them
- **Type annotations**: Clear input/output specifications
- **Return dictionaries**: Structured, informative responses
- **Error handling**: Graceful failure management
### Key Advantages
- ✅ **Maximum Flexibility**: Create any functionality you need
- ✅ **Easy Integration**: Simple Python functions
- ✅ **Full Control**: Complete control over behavior
- ✅ **Debugging**: Easy to test and debug
## 🔧 Function Tool Requirements
### 1. **Descriptive Docstrings**
```python
def calculate_compound_interest(principal: float, rate: float, years: int) -> dict:
"""
Calculate compound interest for an investment.
Use this function when users ask about investment growth,
compound interest calculations, or future value of investments.
Args:
principal: Initial investment amount
rate: Annual interest rate (as decimal, e.g., 0.05 for 5%)
years: Number of years to compound
Returns:
Dictionary with calculation results and breakdown
"""
```
### 2. **Type Annotations**
- Always specify parameter types
- Include return type annotations
- Use appropriate Python types (str, int, float, dict, list)
### 3. **Structured Returns**
```python
return {
"result": final_amount,
"calculation_breakdown": {
"principal": principal,
"rate": rate,
"years": years,
"total_interest": total_interest
},
"status": "success"
}
```
### 4. **Error Handling**
```python
try:
# Tool logic here
return {"result": result, "status": "success"}
except ValueError as e:
return {"error": str(e), "status": "error"}
```
## 🚀 Tutorial Examples
This sub-example includes two practical implementations:
### 📍 **Calculator Agent**
**Location**: `./calculator_agent/`
- **Mathematical Operations**: Basic arithmetic, compound interest, percentage calculations
- **Unit Conversions**: Temperature conversions (Celsius, Fahrenheit, Kelvin)
- **Statistical Analysis**: Mean, median, mode, standard deviation for data sets
- **Financial Calculations**: Investment growth, compound interest projections
- **Number Utilities**: Rounding, formatting, and mathematical expressions
### 📍 **Utility Agent**
**Location**: `./utility_agent/`
- **Text Processing**: Word counting, case conversions, text transformations
- **Data Extraction**: Email and URL extraction, word frequency analysis
- **Date/Time Operations**: Format conversions, date differences, age calculations
- **Data Utilities**: UUID generation, text hashing, Base64 encoding/decoding
- **Validation Tools**: URL validation, JSON formatting and validation
## 📁 Project Structure
```
4_2_function_tools/
├── README.md # This file - function tools guide
├── requirements.txt # Dependencies for function tools
├── .env.example # Environment variables template (shared)
├── calculator_agent/ # Mathematical tools implementation
│ ├── __init__.py
│ ├── agent.py # Calculator agent with custom tools
│ └── tools.py # Mathematical function tools
└── utility_agent/ # Utility tools implementation
├── __init__.py
├── agent.py # Utility agent with various tools
└── tools.py # Text processing, date/time, and data utilities
```
## 🎯 Learning Objectives
By the end of this sub-example, you'll understand:
- ✅ How to create custom Python functions as tools
- ✅ Best practices for tool design and documentation
- ✅ How to handle parameters and return values effectively
- ✅ Error handling and validation strategies
- ✅ When to use function tools vs other approaches
## 🚀 Getting Started
1. **Set up your environment**:
```bash
cd 4_2_function_tools
# Copy the environment template
cp env.example .env
# Edit .env and add your Google AI API key
# Get your API key from: https://aistudio.google.com/
```
2. **Install dependencies**:
```bash
# Install required packages
pip install -r requirements.txt
```
3. **Run the agents**:
```bash
# Start the ADK web interface
adk web
# In the web interface, select:
# - calculator_agent: For mathematical calculations and conversions
# - utility_agent: For text processing, date/time, and data utilities
```
4. **Try the agents**:
- **Calculator Agent**: "Calculate 15% of 200", "Convert 100°F to Celsius", "Find statistics for [1,2,3,4,5]"
- **Utility Agent**: "Count words in this text", "Format date 2023-12-25", "Generate a UUID"
5. **Create Your Own**: Build custom tools for your use case
## 💡 Pro Tips
- **One Purpose Per Tool**: Each function should do one thing well
- **Rich Docstrings**: The docstring is crucial for agent understanding
- **Validate Inputs**: Always validate function parameters
- **Return Dictionaries**: Structured returns are easier to work with
- **Test Independently**: Test tools outside the agent first
## 🔧 Common Function Tool Patterns
### 1. **Simple Calculator Pattern**
```python
def add_numbers(a: float, b: float) -> dict:
"""Add two numbers together."""
return {"result": a + b, "operation": "addition"}
```
### 2. **Data Processing Pattern**
```python
def analyze_text(text: str) -> dict:
"""Analyze text for word count, sentiment, etc."""
return {
"word_count": len(text.split()),
"character_count": len(text),
"sentiment": "neutral" # Placeholder
}
```
### 3. **API Integration Pattern**
```python
def get_weather(city: str) -> dict:
"""Get weather information for a city."""
try:
# API call logic here
return {"temperature": 72, "condition": "sunny"}
except Exception as e:
return {"error": str(e), "status": "failed"}
```
### 4. **Conversion Pattern**
```python
def convert_temperature(temp: float, from_unit: str, to_unit: str) -> dict:
"""Convert temperature between units."""
# Conversion logic
return {
"original": {"value": temp, "unit": from_unit},
"converted": {"value": converted_temp, "unit": to_unit}
}
```
## 🚨 Important Notes
- **No Default Parameters**: ADK doesn't support default parameters
- **Return Dictionaries**: Always return structured data
- **Error Handling**: Implement proper error handling
- **Documentation**: Write clear, helpful docstrings
- **Testing**: Test functions independently before adding to agent
## 🔧 Common Use Cases
### Mathematical Tools (Calculator Agent)
- Basic arithmetic operations and expressions
- Statistical calculations (mean, median, mode, standard deviation)
- Financial calculations (compound interest, percentages)
- Unit conversions (temperature, measurements)
- Number formatting and rounding
### Text Processing Tools (Utility Agent)
- Word and character counting
- Case conversions and text transformations
- Email and URL extraction from text
- Word frequency analysis
- String manipulation and formatting
### Date/Time Tools (Utility Agent)
- Date format conversions
- Age calculations and date differences
- Time zone handling
- Duration calculations
- Date parsing and validation
### Data Utilities (Utility Agent)
- UUID generation for unique identifiers
- Text hashing with various algorithms
- Base64 encoding and decoding
- URL validation and parsing
- JSON formatting and validation
### Integration Tools
- API calls and external service integration
- Database queries and data retrieval
- File operations and data processing
- Custom business logic implementation

View file

@ -0,0 +1,77 @@
from google.adk.agents import LlmAgent
from .tools import (
calculate_basic_math,
convert_temperature,
calculate_compound_interest,
calculate_percentage,
calculate_statistics,
round_number
)
# Create a calculator agent with custom function tools
root_agent = LlmAgent(
name="calculator_agent",
model="gemini-2.5-flash",
description="A comprehensive calculator agent with mathematical and statistical capabilities",
instruction="""
You are a smart calculator assistant with access to various mathematical tools.
You can help users with:
**Basic Mathematics:**
- Arithmetic calculations (addition, subtraction, multiplication, division)
- Mathematical expressions with parentheses
- Order of operations (PEMDAS/BODMAS)
**Conversions:**
- Temperature conversions (Celsius, Fahrenheit, Kelvin)
- Unit conversions and formatting
**Financial Calculations:**
- Compound interest calculations
- Investment growth projections
- Percentage calculations
**Statistics:**
- Mean, median, mode calculations
- Standard deviation and variance
- Min, max, range, and sum
**Utilities:**
- Number rounding to specified decimal places
- Data formatting and presentation
**Available Tools:**
- `calculate_basic_math`: For arithmetic expressions
- `convert_temperature`: For temperature unit conversions
- `calculate_compound_interest`: For investment calculations
- `calculate_percentage`: For percentage calculations
- `calculate_statistics`: For statistical analysis
- `round_number`: For number rounding
**Guidelines:**
1. Always use the appropriate tool for calculations
2. Explain your approach and the tool you're using
3. Present results clearly with context
4. Handle errors gracefully and suggest alternatives
5. Show the formula or method when helpful
6. Provide detailed breakdowns for complex calculations
**Example interactions:**
- "Calculate 15% of 200" Use calculate_percentage
- "What's 25 * 4 + 10?" Use calculate_basic_math
- "Convert 100°F to Celsius" Use convert_temperature
- "Find mean of [1,2,3,4,5]" Use calculate_statistics
- "Compound interest on $1000 at 5% for 10 years" Use calculate_compound_interest
Always be helpful, accurate, and educational in your responses.
""",
tools=[
calculate_basic_math,
convert_temperature,
calculate_compound_interest,
calculate_percentage,
calculate_statistics,
round_number
]
)

View file

@ -0,0 +1,289 @@
import math
from typing import Dict, Union, List
def calculate_basic_math(expression: str) -> Dict[str, Union[float, str]]:
"""
Calculate basic mathematical expressions safely.
Use this function when users ask for basic arithmetic calculations
like addition, subtraction, multiplication, division, or expressions
with parentheses.
Args:
expression: A mathematical expression as a string (e.g., "2 + 3 * 4")
Returns:
Dictionary containing the result and operation details
"""
try:
# Remove any potentially dangerous characters and keep only safe ones
allowed_chars = "0123456789+-*/.() "
safe_expression = ''.join(c for c in expression if c in allowed_chars)
if not safe_expression.strip():
return {
"error": "Empty or invalid expression",
"status": "error"
}
# Evaluate the expression
result = eval(safe_expression)
return {
"result": float(result),
"expression": expression,
"safe_expression": safe_expression,
"status": "success"
}
except ZeroDivisionError:
return {
"error": "Division by zero",
"expression": expression,
"status": "error"
}
except Exception as e:
return {
"error": f"Error calculating expression: {str(e)}",
"expression": expression,
"status": "error"
}
def convert_temperature(temperature: float, from_unit: str, to_unit: str) -> Dict[str, Union[float, str, Dict]]:
"""
Convert temperature between Celsius, Fahrenheit, and Kelvin.
Use this function when users ask to convert temperatures between
different units (C, F, K).
Args:
temperature: Temperature value to convert
from_unit: Source unit ('C', 'F', 'K')
to_unit: Target unit ('C', 'F', 'K')
Returns:
Dictionary with conversion results
"""
try:
# Normalize unit inputs
from_unit = from_unit.upper()
to_unit = to_unit.upper()
# Validate units
valid_units = ['C', 'F', 'K']
if from_unit not in valid_units or to_unit not in valid_units:
return {
"error": f"Invalid units. Use C, F, or K. Got: {from_unit} to {to_unit}",
"status": "error"
}
# Convert to Celsius first
if from_unit == 'F':
celsius = (temperature - 32) * 5/9
elif from_unit == 'K':
celsius = temperature - 273.15
else:
celsius = temperature
# Convert from Celsius to target unit
if to_unit == 'F':
result = celsius * 9/5 + 32
elif to_unit == 'K':
result = celsius + 273.15
else:
result = celsius
return {
"result": round(result, 2),
"conversion": {
"from": {"value": temperature, "unit": from_unit},
"to": {"value": round(result, 2), "unit": to_unit}
},
"status": "success"
}
except Exception as e:
return {
"error": f"Error converting temperature: {str(e)}",
"status": "error"
}
def calculate_compound_interest(principal: float, rate: float, years: int, compound_frequency: int = 1) -> Dict[str, Union[float, str, Dict]]:
"""
Calculate compound interest for an investment.
Use this function when users ask about investment growth,
compound interest calculations, or future value of investments.
Args:
principal: Initial investment amount
rate: Annual interest rate (as decimal, e.g., 0.05 for 5%)
years: Number of years to compound
compound_frequency: How many times per year to compound (default: 1)
Returns:
Dictionary with calculation results and breakdown
"""
try:
if principal <= 0:
return {"error": "Principal must be positive", "status": "error"}
if rate < 0:
return {"error": "Interest rate cannot be negative", "status": "error"}
if years <= 0:
return {"error": "Years must be positive", "status": "error"}
if compound_frequency <= 0:
return {"error": "Compound frequency must be positive", "status": "error"}
# Calculate compound interest: A = P(1 + r/n)^(nt)
final_amount = principal * (1 + rate/compound_frequency) ** (compound_frequency * years)
total_interest = final_amount - principal
return {
"final_amount": round(final_amount, 2),
"total_interest": round(total_interest, 2),
"calculation_details": {
"principal": principal,
"annual_rate": rate,
"rate_percentage": f"{rate * 100}%",
"years": years,
"compound_frequency": compound_frequency,
"formula": "A = P(1 + r/n)^(nt)"
},
"status": "success"
}
except Exception as e:
return {
"error": f"Error calculating compound interest: {str(e)}",
"status": "error"
}
def calculate_percentage(value: float, total: float) -> Dict[str, Union[float, str]]:
"""
Calculate what percentage one value is of another.
Use this function when users ask to calculate percentages,
such as "what percentage is 25 of 100?"
Args:
value: The value to calculate percentage for
total: The total value (100% reference)
Returns:
Dictionary with percentage calculation results
"""
try:
if total == 0:
return {
"error": "Cannot calculate percentage when total is zero",
"status": "error"
}
percentage = (value / total) * 100
return {
"percentage": round(percentage, 2),
"calculation": {
"value": value,
"total": total,
"formula": f"({value} / {total}) * 100"
},
"formatted": f"{round(percentage, 2)}%",
"status": "success"
}
except Exception as e:
return {
"error": f"Error calculating percentage: {str(e)}",
"status": "error"
}
def calculate_statistics(numbers: List[float]) -> Dict[str, Union[float, str, int]]:
"""
Calculate basic statistics for a list of numbers.
Use this function when users ask for statistical analysis
of a set of numbers (mean, median, mode, etc.).
Args:
numbers: List of numbers to analyze
Returns:
Dictionary with statistical results
"""
try:
if not numbers:
return {"error": "Cannot calculate statistics for empty list", "status": "error"}
# Convert to floats and validate
try:
nums = [float(x) for x in numbers]
except (ValueError, TypeError):
return {"error": "All values must be numbers", "status": "error"}
# Calculate statistics
mean = sum(nums) / len(nums)
sorted_nums = sorted(nums)
# Median
n = len(sorted_nums)
if n % 2 == 0:
median = (sorted_nums[n//2 - 1] + sorted_nums[n//2]) / 2
else:
median = sorted_nums[n//2]
# Mode (most frequent value)
from collections import Counter
counts = Counter(nums)
mode_count = max(counts.values())
modes = [k for k, v in counts.items() if v == mode_count]
# Standard deviation
variance = sum((x - mean) ** 2 for x in nums) / len(nums)
std_dev = math.sqrt(variance)
return {
"count": len(nums),
"mean": round(mean, 2),
"median": round(median, 2),
"mode": modes[0] if len(modes) == 1 else modes,
"min": min(nums),
"max": max(nums),
"range": max(nums) - min(nums),
"standard_deviation": round(std_dev, 2),
"sum": sum(nums),
"status": "success"
}
except Exception as e:
return {
"error": f"Error calculating statistics: {str(e)}",
"status": "error"
}
def round_number(number: float, decimal_places: int = 2) -> Dict[str, Union[float, str]]:
"""
Round a number to specified decimal places.
Use this function when users ask to round numbers to specific
decimal places or need cleaner number formatting.
Args:
number: Number to round
decimal_places: Number of decimal places (default: 2)
Returns:
Dictionary with rounded number and details
"""
try:
if decimal_places < 0:
return {"error": "Decimal places cannot be negative", "status": "error"}
rounded_number = round(number, decimal_places)
return {
"rounded_number": rounded_number,
"original_number": number,
"decimal_places": decimal_places,
"status": "success"
}
except Exception as e:
return {
"error": f"Error rounding number: {str(e)}",
"status": "error"
}

View file

@ -0,0 +1,106 @@
from google.adk.agents import LlmAgent
from .tools import (
process_text,
format_datetime,
calculate_date_difference,
generate_uuid,
hash_text,
encode_decode_base64,
validate_url,
format_json
)
# Create a utility agent with various utility tools
root_agent = LlmAgent(
name="utility_agent",
model="gemini-2.5-flash",
description="A comprehensive utility agent with text processing, date/time, and data formatting capabilities",
instruction="""
You are a utility assistant with access to various utility tools for text processing,
date/time operations, data formatting, and general utility functions.
You can help users with:
**Text Processing:**
- Word and character counting
- Case conversions (uppercase, lowercase, title case)
- Text transformations (reverse, remove spaces)
- Extract emails and URLs from text
- Word frequency analysis
**Date and Time Operations:**
- Convert between different date formats
- Calculate differences between dates
- Parse and format dates
- Age calculations and duration analysis
**Data Utilities:**
- Generate UUIDs for unique identifiers
- Hash text with various algorithms (MD5, SHA1, SHA256, SHA512)
- Base64 encoding and decoding
- URL validation and parsing
- JSON formatting and validation
**Available Tools:**
- `process_text`: Text processing and analysis operations
- `format_datetime`: Convert between date/time formats
- `calculate_date_difference`: Find differences between dates
- `generate_uuid`: Generate unique identifiers
- `hash_text`: Generate hash values for text
- `encode_decode_base64`: Base64 encoding/decoding
- `validate_url`: URL validation and parsing
- `format_json`: JSON formatting and validation
**Guidelines:**
1. Always use the appropriate tool for each task
2. Explain what tool you're using and why
3. Present results clearly with context
4. Handle errors gracefully and suggest alternatives
5. Provide helpful explanations for complex operations
6. Show examples when helpful
**Example interactions:**
- "Count words in this text: 'Hello world!'" Use process_text with count_words
- "Convert 2023-12-25 to December 25, 2023" Use format_datetime
- "How many days between 2023-01-01 and 2023-12-31?" Use calculate_date_difference
- "Generate a UUID" Use generate_uuid
- "Hash this password: 'mypassword'" Use hash_text
- "Encode this text in Base64: 'Hello World'" Use encode_decode_base64
- "Validate this URL: example.com" Use validate_url
- "Format this JSON: {'name':'John','age':30}" Use format_json
**Text Processing Operations:**
- count_words: Count words in text
- count_chars: Count characters (with/without spaces)
- uppercase/lowercase/title_case: Change text case
- reverse: Reverse text
- remove_spaces: Remove all spaces
- extract_emails: Find email addresses
- extract_urls: Find URLs
- word_frequency: Analyze word frequency
**Date Format Examples:**
- '%Y-%m-%d': 2023-12-25
- '%d/%m/%Y': 25/12/2023
- '%B %d, %Y': December 25, 2023
- '%Y-%m-%d %H:%M:%S': 2023-12-25 15:30:45
**Hash Algorithms:**
- md5: Fast, 128-bit (not secure for passwords)
- sha1: 160-bit (legacy, not recommended)
- sha256: 256-bit (recommended)
- sha512: 512-bit (most secure)
Always be helpful, accurate, and provide clear explanations for your operations.
""",
tools=[
process_text,
format_datetime,
calculate_date_difference,
generate_uuid,
hash_text,
encode_decode_base64,
validate_url,
format_json
]
)

View file

@ -0,0 +1,423 @@
import json
import re
import uuid
from datetime import datetime, timedelta
from typing import Dict, Union, List
from urllib.parse import urlparse
import hashlib
import base64
def process_text(text: str, operation: str) -> Dict[str, Union[str, int]]:
"""
Process text with various operations like counting, formatting, and transforming.
Use this function when users need text processing, formatting, or analysis.
Available operations: count_words, count_chars, uppercase, lowercase, title_case,
reverse, remove_spaces, extract_emails, extract_urls, word_frequency.
Args:
text: Input text to process
operation: Type of operation to perform
Returns:
Dictionary with processed text results
"""
try:
if not text:
return {"error": "Empty text provided", "status": "error"}
operations = {
"count_words": lambda t: {"word_count": len(t.split()), "text": t},
"count_chars": lambda t: {"char_count": len(t), "char_count_no_spaces": len(t.replace(" ", "")), "text": t},
"uppercase": lambda t: {"result": t.upper(), "original": t},
"lowercase": lambda t: {"result": t.lower(), "original": t},
"title_case": lambda t: {"result": t.title(), "original": t},
"reverse": lambda t: {"result": t[::-1], "original": t},
"remove_spaces": lambda t: {"result": re.sub(r'\s+', '', t), "original": t},
"extract_emails": lambda t: {"emails": re.findall(r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b', t), "original": t},
"extract_urls": lambda t: {"urls": re.findall(r'http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\\(\\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+', t), "original": t},
"word_frequency": lambda t: {"word_frequency": dict(sorted([(word.lower(), t.lower().split().count(word.lower())) for word in set(t.split())], key=lambda x: x[1], reverse=True)), "original": t}
}
if operation not in operations:
return {
"error": f"Invalid operation. Available: {', '.join(operations.keys())}",
"status": "error"
}
result = operations[operation](text)
result["operation"] = operation
result["status"] = "success"
return result
except Exception as e:
return {
"error": f"Error processing text: {str(e)}",
"status": "error"
}
def format_datetime(date_input: str, input_format: str, output_format: str) -> Dict[str, Union[str, Dict]]:
"""
Format and convert datetime strings between different formats.
Use this function when users need to convert date/time formats or parse dates.
Common formats: '%Y-%m-%d', '%d/%m/%Y', '%Y-%m-%d %H:%M:%S', '%B %d, %Y'
Args:
date_input: Input date string
input_format: Format of the input date (Python strftime format)
output_format: Desired output format (Python strftime format)
Returns:
Dictionary with formatted date results
"""
try:
# Parse the input date
parsed_date = datetime.strptime(date_input, input_format)
# Format to output format
formatted_date = parsed_date.strftime(output_format)
return {
"formatted_date": formatted_date,
"original": date_input,
"input_format": input_format,
"output_format": output_format,
"parsed_info": {
"year": parsed_date.year,
"month": parsed_date.month,
"day": parsed_date.day,
"weekday": parsed_date.strftime("%A"),
"month_name": parsed_date.strftime("%B")
},
"status": "success"
}
except ValueError as e:
return {
"error": f"Date parsing error: {str(e)}",
"date_input": date_input,
"input_format": input_format,
"status": "error"
}
except Exception as e:
return {
"error": f"Error formatting date: {str(e)}",
"status": "error"
}
def calculate_date_difference(date1: str, date2: str, date_format: str) -> Dict[str, Union[str, int, Dict]]:
"""
Calculate the difference between two dates.
Use this function when users need to find the time difference between dates,
calculate age, or determine duration between events.
Args:
date1: First date string
date2: Second date string
date_format: Format of both dates (Python strftime format)
Returns:
Dictionary with date difference calculations
"""
try:
# Parse both dates
parsed_date1 = datetime.strptime(date1, date_format)
parsed_date2 = datetime.strptime(date2, date_format)
# Calculate difference
diff = parsed_date2 - parsed_date1
# Calculate various difference formats
total_seconds = int(diff.total_seconds())
days = diff.days
hours = total_seconds // 3600
minutes = total_seconds // 60
# Calculate years, months, days breakdown
years = days // 365
remaining_days = days % 365
months = remaining_days // 30
remaining_days = remaining_days % 30
return {
"difference": {
"total_days": days,
"total_hours": hours,
"total_minutes": minutes,
"total_seconds": total_seconds,
"breakdown": {
"years": years,
"months": months,
"days": remaining_days
}
},
"date1": date1,
"date2": date2,
"date_format": date_format,
"status": "success"
}
except ValueError as e:
return {
"error": f"Date parsing error: {str(e)}",
"date1": date1,
"date2": date2,
"status": "error"
}
except Exception as e:
return {
"error": f"Error calculating date difference: {str(e)}",
"status": "error"
}
def generate_uuid(version: int = 4) -> Dict[str, Union[str, int]]:
"""
Generate a UUID (Universally Unique Identifier).
Use this function when users need unique identifiers for databases,
sessions, or any application requiring unique IDs.
Args:
version: UUID version (1, 4, or 5). Default is 4 (random)
Returns:
Dictionary with generated UUID information
"""
try:
if version == 1:
generated_uuid = str(uuid.uuid1())
elif version == 4:
generated_uuid = str(uuid.uuid4())
elif version == 5:
# UUID5 requires a namespace and name, using default
generated_uuid = str(uuid.uuid5(uuid.NAMESPACE_DNS, 'example.com'))
else:
return {
"error": "Invalid UUID version. Use 1, 4, or 5",
"status": "error"
}
return {
"uuid": generated_uuid,
"version": version,
"format": "8-4-4-4-12 hexadecimal digits",
"status": "success"
}
except Exception as e:
return {
"error": f"Error generating UUID: {str(e)}",
"status": "error"
}
def hash_text(text: str, algorithm: str = "sha256") -> Dict[str, Union[str, Dict]]:
"""
Generate hash values for text using various algorithms.
Use this function when users need to hash passwords, create checksums,
or generate unique fingerprints for text.
Args:
text: Text to hash
algorithm: Hash algorithm (md5, sha1, sha256, sha512)
Returns:
Dictionary with hash results
"""
try:
if not text:
return {"error": "Empty text provided", "status": "error"}
algorithms = {
"md5": hashlib.md5,
"sha1": hashlib.sha1,
"sha256": hashlib.sha256,
"sha512": hashlib.sha512
}
if algorithm not in algorithms:
return {
"error": f"Invalid algorithm. Available: {', '.join(algorithms.keys())}",
"status": "error"
}
hash_object = algorithms[algorithm]()
hash_object.update(text.encode('utf-8'))
hash_hex = hash_object.hexdigest()
return {
"hash": hash_hex,
"algorithm": algorithm,
"text_length": len(text),
"hash_length": len(hash_hex),
"status": "success"
}
except Exception as e:
return {
"error": f"Error hashing text: {str(e)}",
"status": "error"
}
def encode_decode_base64(text: str, operation: str) -> Dict[str, Union[str, int]]:
"""
Encode or decode text using Base64 encoding.
Use this function when users need to encode data for transmission
or decode Base64 encoded strings.
Args:
text: Text to encode/decode
operation: 'encode' to encode, 'decode' to decode
Returns:
Dictionary with encoding/decoding results
"""
try:
if not text:
return {"error": "Empty text provided", "status": "error"}
if operation == "encode":
encoded_bytes = base64.b64encode(text.encode('utf-8'))
result = encoded_bytes.decode('utf-8')
return {
"result": result,
"operation": "encode",
"original": text,
"original_length": len(text),
"result_length": len(result),
"status": "success"
}
elif operation == "decode":
try:
decoded_bytes = base64.b64decode(text)
result = decoded_bytes.decode('utf-8')
return {
"result": result,
"operation": "decode",
"original": text,
"original_length": len(text),
"result_length": len(result),
"status": "success"
}
except Exception as decode_error:
return {
"error": f"Invalid Base64 string: {str(decode_error)}",
"operation": "decode",
"status": "error"
}
else:
return {
"error": "Invalid operation. Use 'encode' or 'decode'",
"status": "error"
}
except Exception as e:
return {
"error": f"Error in Base64 operation: {str(e)}",
"status": "error"
}
def validate_url(url: str) -> Dict[str, Union[str, bool, Dict]]:
"""
Validate and parse URL components.
Use this function when users need to validate URLs or extract
URL components like domain, path, parameters.
Args:
url: URL to validate and parse
Returns:
Dictionary with URL validation and parsing results
"""
try:
if not url:
return {"error": "Empty URL provided", "status": "error"}
# Add protocol if missing
if not url.startswith(('http://', 'https://')):
url = 'https://' + url
parsed = urlparse(url)
# Basic validation
is_valid = bool(parsed.netloc and parsed.scheme)
return {
"is_valid": is_valid,
"original_url": url,
"components": {
"scheme": parsed.scheme,
"netloc": parsed.netloc,
"domain": parsed.netloc.split(':')[0],
"path": parsed.path,
"params": parsed.params,
"query": parsed.query,
"fragment": parsed.fragment,
"port": parsed.port
},
"status": "success"
}
except Exception as e:
return {
"error": f"Error validating URL: {str(e)}",
"url": url,
"status": "error"
}
def format_json(json_string: str, indent: int = 2) -> Dict[str, Union[str, Dict]]:
"""
Format and validate JSON strings.
Use this function when users need to format JSON data,
validate JSON syntax, or make JSON more readable.
Args:
json_string: JSON string to format
indent: Number of spaces for indentation
Returns:
Dictionary with formatted JSON results
"""
try:
if not json_string:
return {"error": "Empty JSON string provided", "status": "error"}
# Parse JSON to validate
parsed_json = json.loads(json_string)
# Format with indentation
formatted_json = json.dumps(parsed_json, indent=indent, ensure_ascii=False)
# Calculate statistics
minified_json = json.dumps(parsed_json, separators=(',', ':'))
return {
"formatted_json": formatted_json,
"minified_json": minified_json,
"is_valid": True,
"statistics": {
"original_length": len(json_string),
"formatted_length": len(formatted_json),
"minified_length": len(minified_json),
"indent_spaces": indent
},
"status": "success"
}
except json.JSONDecodeError as e:
return {
"error": f"Invalid JSON: {str(e)}",
"is_valid": False,
"original": json_string,
"status": "error"
}
except Exception as e:
return {
"error": f"Error formatting JSON: {str(e)}",
"status": "error"
}

View file

@ -0,0 +1,3 @@
# If using Gemini via Google AI Studio
GOOGLE_GENAI_USE_VERTEXAI=False
GOOGLE_API_KEY="your-api-key"

View file

@ -0,0 +1,304 @@
# 🔗 Third-party Tools
Third-party tools allow you to integrate **existing tool ecosystems** from frameworks like LangChain, CrewAI, and others. This dramatically expands your agent's capabilities by leveraging battle-tested tools from the broader AI community.
## 🎯 What You'll Learn
- **LangChain Integration**: Using LangChain's extensive tool library
- **CrewAI Tools**: Leveraging CrewAI's specialized agent tools
- **Tool Adapters**: How ADK wraps external tools
- **Ecosystem Benefits**: Advantages of using established tool libraries
- **Best Practices**: When and how to use third-party tools
## 🧠 Core Concept: Third-party Tools
Third-party tools are **external libraries wrapped for ADK**:
- **LangChain Tools**: Web scraping, document loaders, APIs
- **CrewAI Tools**: Web scraping, file operations, specialized functions
- **Custom Integrations**: Any external service or library
- **Wrapper Classes**: ADK provides adapters for seamless integration
### Key Advantages
- ✅ **Rich Ecosystem**: Access to hundreds of pre-built tools
- ✅ **Battle-tested**: Proven tools used by thousands of developers
- ✅ **Community Support**: Active communities and documentation
- ✅ **Rapid Development**: Don't reinvent the wheel
## 🔧 Available Third-party Integrations
### 1. **LangChain Tools**
- **Purpose**: Comprehensive tool ecosystem
- **Examples**: Web scraping, file operations, APIs
- **Benefits**: Mature, well-documented tools
### 2. **CrewAI Tools**
- **Purpose**: Specialized agent tools
- **Examples**: Web scraping, file operations, content processing
- **Benefits**: Optimized for agent workflows
### 3. **Custom Integrations**
- **Purpose**: Any external service or library
- **Examples**: Database connectors, API clients
- **Benefits**: Unlimited extensibility
## 🚀 Tutorial Examples
This sub-example includes two practical implementations:
### 📍 **LangChain Agent**
**Location**: `./langchain_agent/`
- **Web Search**: DuckDuckGo search integration for real-time information
- **Wikipedia Integration**: Access to encyclopedic knowledge and articles
- **Research Capabilities**: Comprehensive research combining multiple sources
- **Content Analysis**: Information synthesis and source citation
### 📍 **CrewAI Agent**
**Location**: `./crewai_agent/`
- **Website Operations**: Website content search and scraping capabilities
- **File System Tools**: Directory search and file reading operations
- **Content Extraction**: Advanced web scraping and data extraction
- **Document Processing**: Local file analysis and content processing
## 📁 Project Structure
```
4_3_thirdparty_tools/
├── README.md # This file - third-party tools guide
├── requirements.txt # Dependencies for third-party tools
├── ../env.example # Environment variables template (shared)
├── langchain_agent/ # LangChain integration
│ ├── __init__.py
│ └── agent.py # Agent with LangChain tools
└── crewai_agent/ # CrewAI integration
├── __init__.py
└── agent.py # Agent with CrewAI tools
```
## 🎯 Learning Objectives
By the end of this sub-example, you'll understand:
- ✅ How to integrate LangChain tools with ADK
- ✅ How to use CrewAI tools in ADK agents
- ✅ Best practices for third-party tool integration
- ✅ When to choose third-party vs custom tools
- ✅ How to handle tool compatibility issues
## 🔗 Getting Started
1. **Set up environment**:
```bash
cd 4_3_thirdparty_tools
# Copy the environment template
cp ../env.example .env
# Edit .env and add your Google AI API key
# Get your API key from: https://aistudio.google.com/
```
2. **Install Dependencies**: Install required packages
```bash
pip install -r requirements.txt
```
3. **Run the agents**:
```bash
# Start the ADK web interface
adk web
# In the web interface, select:
# - langchain_agent: For web search and Wikipedia research
# - crewai_agent: For website scraping and file operations
```
4. **Try the agents**:
- **LangChain Agent**: "Search for latest AI news", "Tell me about machine learning"
- **CrewAI Agent**: "Scrape content from example.com", "Search for Python files in current directory"
5. **Compare Approaches**: See the differences and benefits of each tool ecosystem
## 💡 Pro Tips
- **Choose Established Tools**: Use well-maintained libraries
- **Read Documentation**: Understand tool limitations and requirements
- **Handle Dependencies**: Manage external library versions carefully
- **Test Integration**: Verify tool compatibility with ADK
- **Monitor Performance**: Some tools may be slower than custom implementations
## 🔧 Integration Patterns
### 1. **LangChain Tool Wrapper**
```python
from google.adk.tools.langchain_tool import LangchainTool
from langchain_community.tools import DuckDuckGoSearchRun
# Wrap LangChain tool for ADK
search_tool = LangchainTool(DuckDuckGoSearchRun())
```
### 2. **CrewAI Tool Wrapper**
```python
from google.adk.tools.crewai_tool import CrewaiTool
from crewai_tools import ScrapeWebsiteTool, DirectorySearchTool, FileReadTool
# Basic tool - minimal configuration
scrape_tool = CrewaiTool(
name="scrape_website",
description="Scrape and extract content from websites",
tool=ScrapeWebsiteTool(
config=dict(
llm=dict(
provider="google", # Use Google instead of default OpenAI
config=dict(model="gemini-2.5-flash"),
),
)
)
)
# Search tool - needs embeddings for semantic search
search_tool = CrewaiTool(
name="website_search",
description="Search for content within websites",
tool=WebsiteSearchTool(
config=dict(
llm=dict(
provider="google",
config=dict(model="gemini-2.5-flash"),
),
embedder=dict(
provider="google",
config=dict(
model="gemini-embedding-001",
task_type="retrieval_document",
),
),
)
)
)
```
### 3. **Custom Integration Pattern**
```python
from google.adk.tools import FunctionTool
import external_library
def custom_integration(query: str) -> dict:
"""Integrate with external library."""
result = external_library.process(query)
return {"result": result, "status": "success"}
# Use as function tool
tool = FunctionTool(custom_integration)
```
## 🔧 Common Third-party Tools
### LangChain Tools
- **DuckDuckGoSearchRun**: Web search
- **WebBaseLoader**: Web scraping
- **WikipediaQueryRun**: Wikipedia search
- **PythonREPLTool**: Python code execution
- **ShellTool**: Shell command execution
### CrewAI Tools
- **ScrapeWebsiteTool**: Web scraping and content extraction
- **DirectorySearchTool**: File system search and exploration
- **FileReadTool**: File reading and content analysis
### Custom Integrations
- **Database connectors**: SQLAlchemy, MongoDB
- **API clients**: REST, GraphQL
- **File processors**: PDF, Excel, CSV
- **Cloud services**: AWS, GCP, Azure
## 🚨 Important Considerations
- **Dependencies**: Third-party tools add external dependencies
- **Compatibility**: Ensure tool versions work with ADK
- **Performance**: Some tools may be slower than custom implementations
- **Maintenance**: External tools may change or become deprecated
- **Security**: Validate external tool safety and permissions
### 🔧 **CrewAI Model Configuration**
⚠️ **Important**: CrewAI tools use OpenAI models by default. When using Google ADK, configure them to use Google models for consistency:
```python
# ❌ Default - Uses OpenAI models
tool = WebsiteSearchTool()
# ✅ Correct configuration - All tools need both LLM and embeddings
tool = ScrapeWebsiteTool(
config=dict(
llm=dict(
provider="google",
config=dict(model="gemini-2.5-flash"),
),
embedder=dict(
provider="google",
config=dict(
model="gemini-embedding-001",
task_type="retrieval_document",
),
),
)
)
# ✅ Same configuration pattern for all tools
tool = DirectorySearchTool(
config=dict(
llm=dict(
provider="google",
config=dict(model="gemini-2.5-flash"),
),
embedder=dict(
provider="google",
config=dict(
model="gemini-embedding-001",
task_type="retrieval_document",
),
),
)
)
```
**Key Points:**
- **LLM Config**: Always set `provider="google"` to avoid OpenAI defaults
- **Embeddings**: Required for all CrewAI tools to prevent OpenAI fallback
- **Available providers**: `google`, `openai`, `anthropic`, `ollama`, `llama2`, etc.
## 🔧 Common Use Cases
### Web and Research
- Web scraping and content extraction
- Website content analysis
- Document processing
- Content research and analysis
### File Operations
- File system search and exploration
- File reading and content analysis
- Directory navigation
- Local file processing
### Development Tools
- Code execution
- Documentation search
- Version control operations
- Testing utilities
### Cloud and Services
- Cloud storage operations
- Email and messaging
- Authentication services
- Monitoring and logging
## 📊 Comparison: Third-party vs Custom vs Built-in
| Aspect | Third-party | Custom | Built-in |
|--------|-------------|--------|----------|
| **Development Time** | Fast | Slow | Instant |
| **Flexibility** | Medium | High | Low |
| **Performance** | Variable | High | Highest |
| **Maintenance** | External | Internal | None |
| **Features** | Rich | Tailored | Basic |
| **Dependencies** | Many | Few | None |

View file

@ -0,0 +1,127 @@
from google.adk.agents import LlmAgent
from google.adk.tools.crewai_tool import CrewaiTool
from crewai_tools import (
ScrapeWebsiteTool,
DirectorySearchTool,
FileReadTool
)
scrape_website_tool = CrewaiTool(
name="scrape_website",
description="Scrape and extract content from websites",
tool=ScrapeWebsiteTool(
config=dict(
llm=dict(
provider="google",
config=dict(model="gemini-2.5-flash"),
),
embedder=dict(
provider="google",
config=dict(
model="gemini-embedding-001",
task_type="retrieval_document",
),
),
)
)
)
directory_search_tool = CrewaiTool(
name="directory_search",
description="Search for files and directories in the local filesystem",
tool=DirectorySearchTool(
config=dict(
llm=dict(
provider="google",
config=dict(model="gemini-2.5-flash"),
),
embedder=dict(
provider="google",
config=dict(
model="gemini-embedding-001",
task_type="retrieval_document",
),
),
)
)
)
file_read_tool = CrewaiTool(
name="file_read",
description="Read and analyze content from files",
tool=FileReadTool(
config=dict(
llm=dict(
provider="google",
config=dict(model="gemini-2.5-flash"),
),
embedder=dict(
provider="google",
config=dict(
model="gemini-embedding-001",
task_type="retrieval_document",
),
),
)
)
)
# Create an agent with CrewAI tools
root_agent = LlmAgent(
name="crewai_agent",
model="gemini-2.5-flash",
description="A versatile agent that uses CrewAI tools for web scraping, file operations, and content analysis",
instruction="""
You are a versatile assistant with access to powerful CrewAI tools for web scraping,
file operations, and content analysis.
Your capabilities include:
**Web Operations:**
- Website content search and analysis
- Web scraping and data extraction
- Content retrieval from specific URLs
- Website structure analysis
**File Operations:**
- Directory and file system search
- File reading and content analysis
- Local file processing
- Document analysis
**Available Tools:**
- `ScrapeWebsiteTool`: Extract and scrape content from web pages
- `DirectorySearchTool`: Search local directories and file systems
- `FileReadTool`: Read and analyze local files
**Guidelines:**
1. For web content analysis, use ScrapeWebsiteTool
2. For file operations, use DirectorySearchTool and FileReadTool
3. Always explain what tool you're using and why
4. Provide clear summaries of extracted content
5. Handle errors gracefully and suggest alternatives
6. Respect website terms of service and robots.txt
**Example workflows:**
- "Search for pricing information on company.com" Use ScrapeWebsiteTool
- "Extract all headings from this webpage" Use ScrapeWebsiteTool
- "Find all Python files in this directory" Use DirectorySearchTool
- "Read and summarize this document" Use FileReadTool
- "Analyze the structure of this website" Use ScrapeWebsiteTool
**Use Cases:**
- Content research and analysis
- Web scraping for data extraction
- File system exploration
- Document processing and analysis
- Website structure analysis
Always provide helpful, accurate information and explain your process clearly.
Be respectful of website policies and handle sensitive information appropriately.
""",
tools=[
scrape_website_tool,
directory_search_tool,
file_read_tool
]
)

View file

@ -0,0 +1,57 @@
from google.adk.agents import LlmAgent
from google.adk.tools.langchain_tool import LangchainTool
from langchain_community.tools import DuckDuckGoSearchRun, WikipediaQueryRun
from langchain_community.utilities import WikipediaAPIWrapper
# Create LangChain tools
search_tool = LangchainTool(DuckDuckGoSearchRun())
wiki_tool = LangchainTool(WikipediaQueryRun(api_wrapper=WikipediaAPIWrapper()))
# Create an agent with LangChain tools
root_agent = LlmAgent(
name="langchain_agent",
model="gemini-2.5-flash",
description="A research agent that uses LangChain tools for web search and Wikipedia queries",
instruction="""
You are a research assistant with access to powerful LangChain tools.
Your capabilities include:
**Web Search (DuckDuckGo):**
- Search the web for current information
- Find recent news and developments
- Discover websites and resources
- Get real-time information
**Wikipedia Search:**
- Search Wikipedia for encyclopedic information
- Get detailed articles on topics
- Access historical and factual information
- Find comprehensive background information
**Available Tools:**
- `DuckDuckGoSearchRun`: Web search using DuckDuckGo
- `WikipediaQueryRun`: Wikipedia article search and retrieval
**Guidelines:**
1. For recent news or current events, use DuckDuckGo search
2. For factual, encyclopedic information, use Wikipedia
3. Combine results from both sources when helpful
4. Always cite your sources
5. Be clear about which tool you're using
**Example workflows:**
- "What's the latest news about AI?" Use DuckDuckGo search
- "Tell me about the history of Rome" Use Wikipedia search
- "Current stock market trends" Use DuckDuckGo search
- "Information about photosynthesis" Use Wikipedia search
- "Recent developments in renewable energy" Use DuckDuckGo search
You can also use both tools for comprehensive research:
- Wikipedia for background information
- DuckDuckGo for current developments
Always provide helpful, accurate information and explain your research process.
""",
tools=[search_tool, wiki_tool]
)

View file

@ -0,0 +1,6 @@
google-adk>=1.5.0
langchain-community>=0.2.0
crewai-tools>=0.1.0
duckduckgo-search>=6.0.0
wikipedia>=0.6.0
requests>=2.25.0

View file

@ -0,0 +1,3 @@
GOOGLE_GENAI_USE_VERTEXAI=False
GOOGLE_API_KEY="your-api-key"
FIRECRAWL_API_KEY="your-api-key"

View file

@ -0,0 +1,243 @@
# 🌐 MCP Tools Integration
Welcome to the **Model Context Protocol (MCP)** integration guide! This example demonstrates how to connect your ADK agents with external data sources and tools through the standardized MCP protocol.
## 🎯 What You'll Learn
- **MCP Fundamentals**: Understanding the Model Context Protocol
- **ADK ↔ MCP Integration**: Using `MCPToolset` to connect to MCP servers
- **External Tool Access**: Leveraging tools from MCP servers
- **Server Communication**: Working with both local and remote MCP servers
- **Real-world Applications**: Practical examples with filesystem and Wikipedia
## 🧠 Core Concept: Model Context Protocol
The **Model Context Protocol (MCP)** is an open standard that enables AI agents to:
- Access external data sources consistently
- Use tools from remote servers
- Communicate with various applications
- Maintain context across interactions
### How MCP Works with ADK
```
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ ADK Agent │◄──►│ MCPToolset │◄──►│ MCP Server │
│ │ │ │ │ │
│ Gemini │ │ Bridge │ │ Tools │
└─────────────┘ └─────────────┘ └─────────────┘
```
**MCPToolset** acts as a bridge that:
- Connects to MCP servers (local or remote)
- Discovers available tools automatically
- Translates MCP tools into ADK-compatible format
- Manages connection lifecycle
## 🔧 Integration Patterns
### 1. **Using External MCP Servers**
Connect to existing MCP servers:
- **Filesystem Server**: File operations
- **Wikipedia Server**: Knowledge retrieval
- **Database Server**: Data access
- **API Server**: External service integration
### 2. **Communication Protocols**
- **Server-Sent Events (SSE)**: Real-time communication for remote servers
- **Standard I/O**: Local process communication for MCP servers
## 🚀 Examples in This Tutorial
### 📍 **Example 1: Filesystem Agent**
**Location**: `./filesystem_agent/`
- Connect to filesystem MCP server
- Perform file operations (read, write, list)
- Handle local file system interactions
- Use Standard I/O communication
### 🔥 **Example 2: Firecrawl Agent**
**Location**: `./firecrawl_agent/`
- Connect to Firecrawl MCP server for advanced web scraping
- Perform single page scraping, batch processing, and website crawling
- Extract structured data with AI-powered analysis
- Conduct deep web research with multi-source synthesis
- Use Standard I/O communication with cloud API integration
## 📁 Project Structure
```
4_4_mcp_tools/
├── README.md # This file - MCP integration guide
├── requirements.txt # MCP dependencies
├── filesystem_agent/ # Filesystem MCP integration
│ ├── __init__.py # Package initialization
│ ├── agent.py # Main agent implementation
│ └── README.md # Filesystem agent guide
├── firecrawl_agent/ # Firecrawl web scraping integration
│ ├── __init__.py # Package initialization
│ ├── agent.py # Main agent implementation
│ └── README.md # Firecrawl agent guide
```
## 🎯 Key Features
- **Seamless Integration**: `MCPToolset` handles all MCP protocol details
- **Automatic Discovery**: Tools are discovered and made available automatically
- **Multiple Protocols**: Supports both stdio and SSE communication
- **Error Handling**: Robust error management for network and server issues
- **Resource Management**: Proper cleanup of connections and resources
## 📋 Prerequisites
Before running these examples:
1. **Install Dependencies**:
```bash
pip install -r requirements.txt
```
2. **Set up Environment**:
```bash
# From the root tutorials directory
cp env.example .env
# Edit .env and add your Google AI API key
```
3. **Node.js for MCP Servers** (for community servers):
```bash
# Install Node.js if not already installed
# Required for npm/npx based MCP servers
```
## 🔄 How It Works
### Connection Flow
1. **Initialize MCPToolset** with connection parameters
2. **Establish Connection** to MCP server
3. **Discover Tools** via MCP protocol
4. **Adapt Tools** to ADK format
5. **Use Tools** in agent conversations
6. **Cleanup** connections on completion
### Code Example
```python
from google.adk.agents import LlmAgent
from google.adk.tools.mcp_tool.mcp_toolset import MCPToolset, StdioServerParameters
# Create MCP toolset for external server
toolset = MCPToolset(
connection_params=StdioServerParameters(
command='npx',
args=['-y', '@modelcontextprotocol/server-filesystem', '/path/to/folder']
)
)
# Create agent with MCP tools
agent = LlmAgent(
model='gemini-2.5-flash',
name='mcp_agent',
instruction='Use MCP tools to help users',
tools=[toolset]
)
```
## 🚀 Getting Started
### Quick Start
1. **Choose an example** to explore:
- **Filesystem Agent**: For file operations
- **Firecrawl Agent**: For advanced web scraping and research
2. **Follow the guide** in each example directory
3. **Run with ADK Web**:
```bash
# From the root tutorials directory
adk web
```
## 🔗 Example Walkthrough
### Filesystem Agent Example
```python
# Connect to filesystem MCP server
toolset = MCPToolset(
connection_params=StdioServerParameters(
command='npx',
args=['-y', '@modelcontextprotocol/server-filesystem', '/path/to/folder']
)
)
# Ask agent to use filesystem tools
# "List files in the current directory"
# "Read the contents of sample.txt"
```
### Firecrawl Agent Example
```python
# Connect to Firecrawl MCP server
toolset = MCPToolset(
connection_params=StdioServerParameters(
command='npx',
args=['-y', 'firecrawl-mcp'],
env={'FIRECRAWL_API_KEY': 'your_api_key'}
)
)
# Ask agent to use web scraping tools
# "Scrape the homepage of https://example.com"
# "Find all blog post URLs on https://blog.example.com"
# "Search for recent AI research papers and extract summaries"
# "Extract product details from this e-commerce page: [URL]"
```
## 💡 Best Practices
- **Connection Management**: Always handle connection lifecycle properly
- **Error Handling**: Implement robust error handling for network issues
- **Resource Cleanup**: Use proper cleanup patterns for connections
- **Security**: Validate inputs and handle authentication appropriately
- **Performance**: Consider connection pooling for high-throughput scenarios
## 🔍 Troubleshooting
### Common Issues
- **Connection Errors**: Check server URL and network connectivity
- **Tool Not Found**: Verify server is running and tools are exposed
- **Authentication**: Ensure proper API keys and credentials
- **Version Compatibility**: Check MCP protocol version compatibility
### Debug Commands
```bash
# Test MCP server connection
npx @modelcontextprotocol/inspector
# Check ADK agent logs
adk web --debug
```
## 🔗 Next Steps
After completing this tutorial:
- **[Tutorial 4: Memory Agent](../4_memory_agent/README.md)** - Add memory capabilities
- **[Tutorial 5: Workflow Agent](../5_workflow_agent/README.md)** - Multi-step processes
- **[Tutorial 6: Multi-agent System](../6_multi_agent_system/README.md)** - Agent collaboration
## 📚 Additional Resources
- **[MCP Specification](https://modelcontextprotocol.io/docs/spec)** - Protocol details
- **[ADK MCP Documentation](https://google.github.io/adk-docs/tools/mcp-tools/)** - Integration guide
- **[Community MCP Servers](https://github.com/modelcontextprotocol/servers)** - Ready-to-use servers
## 🎯 Real-World Applications
MCP tools enable:
- **Knowledge Retrieval**: Access Wikipedia, databases, documents
- **File Operations**: Read, write, manage files and directories
- **API Integration**: Connect to external services and APIs
- **Data Processing**: Transform and analyze data from various sources
- **Custom Tools**: Create and share specialized tools across agents

View file

@ -0,0 +1,188 @@
# 📁 Filesystem Agent - MCP Integration
This example demonstrates how to connect an ADK agent to a **filesystem MCP server** using the `MCPToolset`. The agent can perform file operations like reading, writing, and listing files through the Model Context Protocol.
## 🎯 What This Example Shows
- **MCP Server Connection**: Connect to `@modelcontextprotocol/server-filesystem`
- **File Operations**: Read, write, list files and directories
- **Stdio Communication**: Use standard input/output for local MCP server communication
- **Automatic Tool Discovery**: Let ADK discover and use available filesystem tools
## 🔧 How It Works
### MCP Server Setup
The agent connects to a filesystem MCP server that provides these tools:
- `list_directory`: List files and folders
- `read_file`: Read file contents
- `write_file`: Write content to files
- `create_directory`: Create new directories
### Connection Flow
```python
MCPToolset(
connection_params=StdioServerParameters(
command='npx',
args=['-y', '@modelcontextprotocol/server-filesystem', '/path/to/folder']
)
)
```
## 🚀 Getting Started
### Prerequisites
1. **Node.js and npm**: Required for the filesystem MCP server
2. **ADK Environment**: Set up with your Google AI API key
3. **Dependencies**: Install from `requirements.txt`
### Running the Agent
1. **Navigate to tutorials root**:
```bash
cd ai_agent_framework_crash_course/google_adk_tutorials/
```
2. **Start ADK Web**:
```bash
adk web
```
3. **Select Agent**: Choose `filesystem_mcp_agent` from the dropdown
4. **Test Commands**:
- "List files in the current directory"
- "Read the contents of sample.txt"
- "Create a new file called hello.txt with the content Hello World!"
- "Show me all text files in the directory"
## 📝 Example Conversations
### File Listing
```
User: List files in the current directory
Agent: I'll list the files in the current directory for you.
[Uses list_directory tool]
Found the following files:
- sample.txt
- hello.txt
```
### File Reading
```
User: Read the contents of sample.txt
Agent: I'll read the contents of sample.txt for you.
[Uses read_file tool]
The file contains:
This is a sample file for the MCP filesystem agent demonstration.
You can read, write, and list files using MCP tools.
```
### File Writing
```
User: Create a new file called notes.txt with the content "Meeting notes for today"
Agent: I'll create the file notes.txt with your specified content.
[Uses write_file tool]
Successfully created notes.txt with the content "Meeting notes for today".
```
## 🔧 Code Structure
### Agent Definition
```python
root_agent = LlmAgent(
model='gemini-2.5-flash',
name='filesystem_mcp_agent',
instruction="""
You are a helpful filesystem assistant that can help users manage their files.
You have access to filesystem tools through the Model Context Protocol (MCP).
""",
tools=[
MCPToolset(
connection_params=StdioServerParameters(
command='npx',
args=['-y', '@modelcontextprotocol/server-filesystem', DEMO_FOLDER]
)
)
]
)
```
### Demo Environment
The agent uses the parent directory of the agent file for demonstration:
- **Location**: Parent directory of the filesystem_agent folder
- **Sample File**: `sample.txt` with demo content
- **Working Directory**: Accessible to the MCP server for safe operations
## 🛠️ Available Tools
The filesystem MCP server provides these tools automatically:
| Tool | Description | Parameters |
|------|-------------|------------|
| `list_directory` | List files and folders | `path` (optional) |
| `read_file` | Read file contents | `path` (required) |
| `write_file` | Write content to file | `path`, `content` |
| `create_directory` | Create new directory | `path` |
## 🔍 Advanced Usage
### Tool Filtering
```python
MCPToolset(
connection_params=StdioServerParameters(
command='npx',
args=['-y', '@modelcontextprotocol/server-filesystem', DEMO_FOLDER]
),
tool_filter=['list_directory', 'read_file'] # Only expose specific tools
)
```
## 🚨 Important Notes
- **Security**: The MCP server only has access to the specified directory
- **Node.js Required**: The filesystem server runs via `npx`
- **Working Directory**: Uses parent directory for easy access to project files
- **Error Handling**: Agent handles file not found and permission errors gracefully
## 🔍 Troubleshooting
### Common Issues
1. **Node.js Not Found**:
```bash
# Install Node.js
# macOS: brew install node
# Ubuntu: sudo apt install nodejs npm
```
2. **Permission Errors**:
- Ensure the directory is writable
- Check file permissions
3. **MCP Server Not Starting**:
- Verify Node.js installation
- Check if port is available
- Review console logs
### Debug Commands
```bash
# Test MCP server directly
npx @modelcontextprotocol/server-filesystem /path/to/folder
# Run with debug logging
adk web --debug
```
## 🔗 Next Steps
After trying this example:
1. **Customize the Directory**: Change `DEMO_FOLDER` to your preferred location
2. **Add More Tools**: Explore other MCP servers
3. **Try Server Agent**: Learn to create custom MCP servers
4. **Integrate with Workflows**: Combine with other ADK features
## 📚 Related Documentation
- **[ADK MCP Tools](https://google.github.io/adk-docs/tools/mcp-tools/)** - Official documentation
- **[MCP Filesystem Server](https://github.com/modelcontextprotocol/servers/tree/main/src/filesystem)** - Server details
- **[Model Context Protocol](https://modelcontextprotocol.io/)** - Protocol specification

View file

@ -0,0 +1,76 @@
"""
Filesystem Agent - MCP Tools Integration Example
This example demonstrates how to connect an ADK agent to a filesystem MCP server
using the MCPToolset. The agent can perform file operations like reading, writing,
and listing files through the MCP protocol.
"""
import os
from google.adk.agents import LlmAgent
from google.adk.tools.mcp_tool.mcp_toolset import MCPToolset, StdioServerParameters
# Create a temporary directory for demonstration
# In a real application, you would use a specific folder path
DEMO_FOLDER = os.path.join(os.path.dirname(__file__), "..")
# Ensure the demo folder exists
os.makedirs(DEMO_FOLDER, exist_ok=True)
# Create a sample file for demonstration
sample_file_path = os.path.join(DEMO_FOLDER, "sample.txt")
with open(sample_file_path, "w") as f:
f.write("This is a sample file for the MCP filesystem agent demonstration.\n")
f.write("You can read, write, and list files using MCP tools.\n")
# Create the ADK agent with MCP filesystem tools
root_agent = LlmAgent(
model='gemini-2.5-flash',
name='filesystem_mcp_agent',
instruction=f"""
You are a helpful filesystem assistant that can help users manage their files.
You have access to filesystem tools through the Model Context Protocol (MCP).
You can:
- List files and directories
- Read file contents
- Write to files
- Create directories
The current working directory is: {DEMO_FOLDER}
Always be helpful and explain what you're doing when performing file operations.
If a user asks about files, use the available tools to check the filesystem.
""",
tools=[
MCPToolset(
connection_params=StdioServerParameters(
command='npx',
args=[
"-y", # Auto-confirm npm package installation
"@modelcontextprotocol/server-filesystem",
DEMO_FOLDER, # The directory path the MCP server can access
],
),
# Optional: Filter which tools from the MCP server to expose
# tool_filter=['list_directory', 'read_file', 'write_file']
)
],
)
# Export the agent for use with ADK web
__all__ = ['root_agent']
# Example usage in a script
if __name__ == "__main__":
print(f"Filesystem MCP Agent initialized!")
print(f"Demo folder: {DEMO_FOLDER}")
print(f"Sample file created at: {sample_file_path}")
print("\nTo use this agent:")
print("1. Run 'adk web' from the tutorials root directory")
print("2. Select 'filesystem_mcp_agent' from the dropdown")
print("3. Try commands like:")
print(" - 'List files in the current directory'")
print(" - 'Read the contents of sample.txt'")
print(" - 'Create a new file called hello.txt with the content Hello World!'")
print(" - 'Show me all text files in the directory'")

View file

@ -0,0 +1,291 @@
# 🔥 Firecrawl Agent - Advanced Web Scraping with MCP
Welcome to the **Firecrawl MCP Agent**! This powerful agent demonstrates how to integrate Firecrawl's advanced web scraping capabilities with Google ADK through the Model Context Protocol (MCP).
## 🌟 What You'll Learn
- **Firecrawl Integration**: Connect to Firecrawl's comprehensive web scraping platform
- **Advanced Web Scraping**: Single page, batch processing, and full website crawling
- **AI-Powered Extraction**: Use LLMs to extract structured data from web content
- **Research Capabilities**: Conduct deep web research with multi-source analysis
- **Real-world Applications**: Practical examples for data extraction and research
## 🚀 Key Features
### 🔧 Comprehensive Toolset
- **Single Page Scraping**: Extract content from individual URLs with advanced options
- **Batch Processing**: Efficiently scrape multiple URLs with parallel processing
- **Website Mapping**: Discover all URLs on a website for exploration
- **Web Search**: Search the web and extract content from results
- **Full Site Crawling**: Perform comprehensive website analysis with depth control
- **Structured Extraction**: Use AI to extract specific data points from pages
- **Deep Research**: Conduct in-depth research with multi-source analysis
- **LLMs.txt Generation**: Create standardized AI interaction guidelines for domains
### 🌍 Advanced Capabilities
- **Automatic Rate Limiting**: Built-in retry logic and backoff strategies
- **Multiple Output Formats**: Support for Markdown, HTML, and JSON
- **Content Filtering**: Advanced options for content selection and exclusion
- **Mobile/Desktop Rendering**: Choose between different rendering modes
- **Authentication Support**: Handle sites requiring login credentials
- **JavaScript Rendering**: Full support for dynamic content
## 📋 Prerequisites
### Required Dependencies
1. **Node.js**: Required for the Firecrawl MCP server
```bash
# Install Node.js if not already installed
# Visit https://nodejs.org/ for installation instructions
```
2. **Firecrawl API Key**: Get your API key from [Firecrawl.dev](https://firecrawl.dev)
```bash
# Set your API key as an environment variable
export FIRECRAWL_API_KEY=your_api_key_here
```
3. **Google ADK Dependencies**: Ensure you have the required packages
```bash
pip install -r ../requirements.txt
```
## 🛠️ Setup Instructions
### 1. Environment Configuration
```bash
# Set your Firecrawl API key
export FIRECRAWL_API_KEY=fc-your_api_key_here
# Optional: Configure retry settings
export FIRECRAWL_RETRY_MAX_ATTEMPTS=5
export FIRECRAWL_RETRY_INITIAL_DELAY=2000
```
### 2. Install Dependencies
```bash
# From the tutorials root directory
pip install -r requirements.txt
```
### 3. Run the Agent
```bash
# From the tutorials root directory
adk web
```
Then select `firecrawl_mcp_agent` from the dropdown menu.
## 🎯 Usage Examples
### Basic Web Scraping
```text
User: "Scrape the homepage of https://example.com"
Agent: Uses firecrawl_scrape to extract clean content in Markdown format
```
### Batch URL Processing
```text
User: "Extract content from these three articles: [url1, url2, url3]"
Agent: Uses firecrawl_batch_scrape for efficient parallel processing
```
### Website Discovery
```text
User: "Find all blog post URLs on https://blog.example.com"
Agent: Uses firecrawl_map to discover and list all available URLs
```
### Web Search & Extraction
```text
User: "Search for research papers on AI Agents in the last 4 weeks and extract key information"
Agent: Uses firecrawl_search to find relevant papers and extract summaries
```
### Structured Data Extraction
```text
User: "Extract product details (name, price, description) from this e-commerce page"
Agent: Uses firecrawl_extract with custom schema for structured data
```
### Deep Research
```text
User: "Perform comprehensive research on sustainable energy technologies"
Agent: Uses firecrawl_deep_research for multi-source analysis and synthesis
```
### Website Crawling
```text
User: "Crawl the documentation section of https://docs.example.com"
Agent: Uses firecrawl_crawl with appropriate depth and filtering
```
## 🔧 Available Tools
### Core Scraping Tools
| Tool | Purpose | Best For |
|------|---------|----------|
| `firecrawl_scrape` | Single page extraction | Known URLs, specific pages |
| `firecrawl_batch_scrape` | Multiple URL processing | Lists of URLs, parallel extraction |
| `firecrawl_map` | URL discovery | Exploring site structure |
### Advanced Tools
| Tool | Purpose | Best For |
|------|---------|----------|
| `firecrawl_search` | Web search + extraction | Finding relevant content |
| `firecrawl_crawl` | Full site crawling | Comprehensive site analysis |
| `firecrawl_extract` | Structured data extraction | Specific data points |
| `firecrawl_deep_research` | Multi-source research | Complex research tasks |
### Utility Tools
| Tool | Purpose | Best For |
|------|---------|----------|
| `firecrawl_generate_llmstxt` | LLMs.txt generation | AI interaction guidelines |
| `firecrawl_check_crawl_status` | Monitor crawl progress | Long-running operations |
| `firecrawl_check_batch_status` | Monitor batch progress | Batch operation tracking |
## 💡 Best Practices
### Tool Selection Guide
- **Single URL**: Use `firecrawl_scrape`
- **Multiple known URLs**: Use `firecrawl_batch_scrape`
- **Discover URLs**: Use `firecrawl_map` first
- **Search the web**: Use `firecrawl_search`
- **Structured data**: Use `firecrawl_extract`
- **Deep research**: Use `firecrawl_deep_research`
- **Full site analysis**: Use `firecrawl_crawl` (with limits)
### Performance Optimization
- Use batch operations for multiple URLs instead of individual scrapes
- Set appropriate limits for crawl operations to avoid timeouts
- Monitor long-running operations with status check tools
- Respect rate limits and be considerate of target websites
### Content Quality
- Use `onlyMainContent: true` to extract clean content
- Leverage content filtering options for better results
- Choose appropriate output formats (Markdown for text, JSON for data)
- Use structured extraction for specific data requirements
## ⚙️ Configuration Options
### Scraping Parameters
```python
# Example configuration for scrape operations
{
"formats": ["markdown"], # Output format
"onlyMainContent": True, # Extract main content only
"waitFor": 1000, # Wait time for page load
"timeout": 30000, # Request timeout
"mobile": False, # Use mobile rendering
"includeTags": ["article", "main"], # Include specific HTML tags
"excludeTags": ["nav", "footer"] # Exclude specific HTML tags
}
```
### Batch Processing
```python
# Example batch configuration
{
"maxUrls": 50, # Maximum URLs to process
"parallelLimit": 5, # Parallel processing limit
"options": {
"formats": ["markdown"],
"onlyMainContent": True
}
}
```
### Crawling Parameters
```python
# Example crawl configuration
{
"maxDepth": 2, # Crawl depth limit
"limit": 100, # Maximum pages to crawl
"allowExternalLinks": False, # Stay within domain
"deduplicateSimilarURLs": True # Remove duplicate content
}
```
## 🚨 Important Notes
### Rate Limiting
- Firecrawl includes automatic rate limiting and retry logic
- Batch operations are queued and may take time to complete
- Monitor operation status for long-running tasks
### Resource Management
- Crawl operations can be resource-intensive
- Set appropriate limits to avoid timeouts or excessive token usage
- Use batch status checks for large operations
### API Usage
- Requires a valid Firecrawl API key for cloud operations
- Consider self-hosted deployment for high-volume usage
- Monitor credit usage through the Firecrawl dashboard
## 🔍 Troubleshooting
### Common Issues
**Connection Errors**
```bash
# Check Node.js installation
node --version
# Test Firecrawl MCP server
npx -y firecrawl-mcp
```
**API Key Issues**
```bash
# Verify API key is set
echo $FIRECRAWL_API_KEY
# Test API key validity
curl -H "Authorization: Bearer $FIRECRAWL_API_KEY" https://api.firecrawl.dev/v1/scrape
```
**Tool Not Found**
- Ensure ADK MCP server is properly configured
- Check that Node.js is installed and accessible
- Verify the Firecrawl MCP package can be installed
### Debug Commands
```bash
# Test MCP server connection
npx @modelcontextprotocol/inspector
# Run agent with debug output
adk web --debug
```
## 📚 Additional Resources
- **[Firecrawl Documentation](https://docs.firecrawl.dev)** - Complete API reference
- **[Firecrawl MCP Server](https://github.com/mendableai/firecrawl-mcp-server)** - Source code and examples
- **[MCP Specification](https://modelcontextprotocol.io/docs/spec)** - Protocol details
- **[ADK MCP Documentation](https://google.github.io/adk-docs/tools/mcp-tools/)** - Integration guide
## 🎯 Real-World Applications
### Data Collection & Research
- Market research and competitor analysis
- Academic research and paper collection
- News monitoring and trend analysis
- Product catalog extraction
- Social media content analysis
### Content Management
- Website migration and content auditing
- SEO analysis and optimization
- Content quality assessment
- Documentation extraction
- Knowledge base creation
### Business Intelligence
- Lead generation and contact extraction
- Price monitoring and comparison
- Review and sentiment analysis
- Industry trend tracking
- Regulatory compliance monitoring

View file

@ -0,0 +1,119 @@
"""
Firecrawl Agent - Advanced Web Scraping with MCP Tools Integration
This example demonstrates how to connect an ADK agent to a Firecrawl MCP server
using the MCPToolset. The agent can perform advanced web scraping operations like
single page scraping, batch scraping, web crawling, content extraction, and deep research.
"""
import os
from google.adk.agents import LlmAgent
from google.adk.tools.mcp_tool.mcp_toolset import MCPToolset, StdioServerParameters
# Create the ADK agent with Firecrawl MCP tools
root_agent = LlmAgent(
model='gemini-2.5-flash',
name='firecrawl_mcp_agent',
instruction="""
You are an advanced web scraping and research assistant powered by Firecrawl.
You have access to comprehensive web scraping tools through the Model Context Protocol (MCP):
🔧 **Available Tools:**
- **firecrawl_scrape**: Extract content from a single URL with advanced options
- **firecrawl_batch_scrape**: Efficiently scrape multiple URLs with parallel processing
- **firecrawl_map**: Discover all URLs on a website for exploration
- **firecrawl_search**: Search the web and extract content from results
- **firecrawl_crawl**: Perform comprehensive website crawling with depth control
- **firecrawl_extract**: Extract structured data using AI-powered analysis
- **firecrawl_deep_research**: Conduct in-depth research with multi-source analysis
- **firecrawl_generate_llmstxt**: Generate LLMs.txt files for domains
- **firecrawl_check_crawl_status**: Monitor crawl job progress
- **firecrawl_check_batch_status**: Monitor batch operation progress
🎯 **Tool Selection Guide:**
- **Single URL**: Use `firecrawl_scrape`
- **Multiple known URLs**: Use `firecrawl_batch_scrape`
- **Discover URLs**: Use `firecrawl_map`
- **Web search**: Use `firecrawl_search`
- **Structured data**: Use `firecrawl_extract`
- **Deep research**: Use `firecrawl_deep_research`
- **Full site analysis**: Use `firecrawl_crawl` (with caution on limits)
🌟 **Key Features:**
- Automatic rate limiting and retry logic
- Parallel processing for batch operations
- LLM-powered content extraction
- Support for multiple output formats (Markdown, HTML, JSON)
- Advanced filtering and content selection
- Mobile and desktop rendering options
💡 **Best Practices:**
- Always explain which tool you're using and why
- For large operations, inform users about potential wait times
- Use batch operations for multiple URLs instead of individual scrapes
- Leverage structured extraction for specific data needs
- Respect rate limits and be considerate of target websites
🚨 **Important Notes:**
- Crawl operations can be resource-intensive; use appropriate limits
- Batch operations are queued and may take time to complete
- Always check the status of long-running operations
- Some tools require a valid Firecrawl API key
Be helpful, efficient, and always explain your approach to web scraping tasks.
""",
tools=[
MCPToolset(
connection_params=StdioServerParameters(
command='npx',
args=[
"-y", # Auto-confirm npm package installation
"firecrawl-mcp", # The Firecrawl MCP server package
],
env={
# Note: Users need to set FIRECRAWL_API_KEY in their environment
# or add it to their system environment variables
"FIRECRAWL_API_KEY": os.getenv("FIRECRAWL_API_KEY", "")
}
),
# Optional: Filter which tools from the MCP server to expose
# Uncomment the line below to limit to specific tools
# tool_filter=['firecrawl_scrape', 'firecrawl_batch_scrape', 'firecrawl_search', 'firecrawl_map']
)
],
)
# Export the agent for use with ADK web
__all__ = ['root_agent']
# Example usage in a script
if __name__ == "__main__":
print("🔥 Firecrawl MCP Agent initialized!")
print("\n🔧 Available Capabilities:")
print("- Single page scraping with advanced options")
print("- Batch processing of multiple URLs")
print("- Website mapping and URL discovery")
print("- Web search with content extraction")
print("- Comprehensive website crawling")
print("- AI-powered structured data extraction")
print("- Deep research with multi-source analysis")
print("- LLMs.txt generation for domains")
print("\n🚀 To use this agent:")
print("1. Set your Firecrawl API key: export FIRECRAWL_API_KEY=your_api_key")
print("2. Run 'adk web' from the tutorials root directory")
print("3. Select 'firecrawl_mcp_agent' from the dropdown")
print("\n💡 Example commands to try:")
print(" - 'Scrape the homepage of https://example.com'")
print(" - 'Find all blog post URLs on https://blog.example.com'")
print(" - 'Search for recent AI research papers and extract key information'")
print(" - 'Extract product details from this e-commerce page: [URL]'")
print(" - 'Perform deep research on sustainable energy technologies'")
print(" - 'Crawl the documentation section of https://docs.example.com'")
print("\n⚠️ Important Setup:")
print("- Requires Node.js for the Firecrawl MCP server")
print("- Requires a valid Firecrawl API key (get one at https://firecrawl.dev)")
print("- Some operations may take time for large datasets")

View file

@ -0,0 +1,10 @@
google-adk>=1.5.0
mcp>=1.5.0
requests>=2.25.0
beautifulsoup4>=4.12.0
html2text>=2024.2.26
python-dotenv>=1.0.0
# Firecrawl MCP agent dependencies
# Note: The main Firecrawl MCP server runs via npx (Node.js)
# These are additional Python packages that may be useful
firecrawl-py>=1.0.0

View file

@ -0,0 +1,128 @@
# 🎯 Tutorial 4: Tool Using Agent
Welcome to the world of tools! This tutorial teaches you how to create agents that can use **different types of tools** to perform specific tasks. This is where your agents become truly powerful and capable of real-world actions.
## 🎯 What You'll Learn
- **Built-in Tools**: Using Google ADK's pre-built capabilities
- **Function Tools**: Creating custom Python functions as tools
- **Third-party Tools**: Integrating with LangChain, CrewAI, and other frameworks
- **MCP Tools**: Integration with Model Context Protocol
## 🧠 Core Concept: Tools in ADK
Tools are **functions that your agent can call** to perform specific tasks. Think of them as the agent's "hands" - they allow the agent to:
- Search the web and access real-time information
- Execute code and perform calculations
- Call external APIs and services
- Access databases and file systems
- Interact with other AI frameworks
## 🔧 Types of Tools in ADK
### 1. **Built-in Tools**
Google ADK provides powerful pre-built tools:
- **Search Tool**: Web search capabilities
- **Code Execution Tool**: Run Python code safely
- **RAG Tools**: Retrieval-augmented generation
- **Cloud Tools**: Google Cloud integrations
*Note: Built-in tools work only with Gemini models*
### 2. **Function Tools**
Custom Python functions you create:
- Mathematical calculations
- Data processing
- API calls
- File operations
- Business logic
### 3. **Third-party Tools**
Integration with other frameworks:
- **LangChain Tools**: Web scraping, document loaders, etc.
- **CrewAI Tools**: Specialized agent tools
- **Custom Integrations**: Any external service
### 4. **MCP Tools**
Integration with Model Context Protocol:
- **External MCP Servers**: Connect to existing MCP servers
- **Custom MCP Servers**: Create your own MCP server
- **Protocol Communication**: SSE and Streamable HTTP support
## 🚀 Tutorial Structure
This tutorial contains **four comprehensive examples**:
### 📍 **Example 1: Built-in Tools**
**Location**: `./4_1_builtin_tools/`
- Learn to use Google ADK's pre-built tools
- Implement web search capabilities
- Explore code execution tools
### 📍 **Example 2: Function Tools**
**Location**: `./4_2_function_tools/`
- Create custom Python functions as tools
- Build mathematical and utility tools
- Implement API integration tools
### 📍 **Example 3: Third-party Tools**
**Location**: `./4_3_thirdparty_tools/`
- Integrate LangChain tools
- Use CrewAI specialized tools
- Create custom integrations
### 📍 **Example 4: MCP Tools**
**Location**: `./4_4_mcp_tools/`
- Connect to Model Context Protocol servers
- Use filesystem and Wikipedia MCP tools
- Create custom MCP servers
## 📁 Project Structure
```
4_tool_using_agent/
├── README.md # This tutorial overview
├── 4_1_builtin_tools/ # Built-in tools examples
├── 4_2_function_tools/ # Function tools examples
├── 4_3_thirdparty_tools/ # Third-party tools examples
└── 4_4_mcp_tools/ # MCP tools examples
```
Each example directory follows the standard structure:
- **Python file**: Contains the agent implementation and Streamlit app
- **README.md**: Setup and usage documentation
- **requirements.txt**: Dependencies list
## 🎯 Learning Objectives
By the end of this tutorial, you'll understand:
- ✅ How to use Google ADK's built-in tools effectively
- ✅ How to create and integrate custom function tools
- ✅ How to leverage third-party tool ecosystems
- ✅ How to connect to and create MCP servers
- ✅ When to use each type of tool
- ✅ Best practices for tool design and integration
## 💡 Pro Tips
- **Start with Built-ins**: Use Google's tools when possible - they're optimized
- **Clear Descriptions**: Write detailed docstrings for your tools
- **Error Handling**: Always handle potential errors in your tools
- **Tool Selection**: Help the AI understand when to use each tool
- **Testing**: Test each tool independently before combining
## 🎯 Real-World Applications
Tool-using agents are essential for:
- **Information Retrieval**: Search engines, knowledge bases
- **Data Analysis**: Processing and analyzing data
- **API Integration**: Connecting to external services
- **Automation**: Performing repetitive tasks
- **Decision Making**: Using external data for decisions
## 🚨 Important Notes
- **Model Compatibility**: Built-in tools only work with Gemini models
- **Tool Mixing**: Cannot mix built-in and custom tools in same agent
- **Performance**: Built-in tools are optimized for speed
- **Security**: Custom tools require proper validation

View file

@ -0,0 +1,92 @@
# 🚀 Google ADK Crash Course
A comprehensive tutorial series for learning Google's Agent Development Kit (ADK) from basics to advanced concepts. This crash course is designed to take you from zero to hero in building AI agents with Google ADK.
## 📚 What is Google ADK?
Google ADK (Agent Development Kit) is a flexible and modular framework for **developing and deploying AI agents**. It's optimized for Gemini and the Google ecosystem but is **model-agnostic** and **deployment-agnostic**, making it compatible with other frameworks.
### Key Features:
- **Flexible Orchestration**: Define workflows using workflow agents or LLM-driven dynamic routing
- **Multi-Agent Architecture**: Build modular applications with multiple specialized agents
- **Rich Tool Ecosystem**: Use pre-built tools, create custom functions, or integrate 3rd-party libraries
- **Deployment Ready**: Containerize and deploy agents anywhere
- **Built-in Evaluation**: Assess agent performance systematically
- **Safety and Security**: Built-in patterns for trustworthy agents
## 🎯 Learning Path
This crash course covers the essential concepts of Google ADK through hands-on tutorials:
### 📚 **Tutorials**
1. **[1_starter_agent](./1_starter_agent/README.md)** - Your first ADK agent
- Basic agent creation
- Understanding the ADK workflow
- Simple text processing
2. **[2_model_agnostic_agent](./2_model_agnostic_agent/README.md)** - Model-agnostic agent development
- Google Gemini models (AI Studio & Vertex AI)
- Anthropic Claude integration
- Local models with Ollama
- LiteLLM integration for multiple providers
3. **[3_structured_output_agent](./3_structured_output_agent/README.md)** - Type-safe responses
- Pydantic schemas
- Structured data validation
- Business logic implementation
4. **[4_tool_using_agent](./4_tool_using_agent/README.md)** - Agent with tools
- Built-in tools (Search, Code Execution)
- Function tools (Custom Python functions)
- Third-party tools (LangChain, CrewAI)
- MCP tools integration
5. **More tutorials coming soon!**
## 🛠️ Prerequisites
Before starting this crash course, ensure you have:
- **Python 3.8+** installed
- **Google AI API Key** from [Google AI Studio](https://aistudio.google.com/)
- Basic understanding of Python and APIs
## 📖 How to Use This Course
Each tutorial follows a consistent structure:
- **README.md**: Concept explanation and learning objectives
- **Python file**: Contains the agent implementation and Streamlit app
- **requirements.txt**: Dependencies for the tutorial
### Learning Approach:
1. **Read the README** to understand the concept
2. **Examine the code** to see the implementation
3. **Run the example** to see it in action
4. **Experiment** by modifying the code
5. **Move to the next tutorial** when ready
## 🎯 Tutorial Features
Each tutorial includes:
- ✅ **Clear concept explanation**
- ✅ **Minimal, working code examples**
- ✅ **Real-world use cases**
- ✅ **Step-by-step instructions**
- ✅ **Best practices and tips**
## 📚 Additional Resources
- [Google ADK Documentation](https://google.github.io/adk-docs/)
- [Google AI Studio](https://aistudio.google.com/)
- [Gemini API Reference](https://ai.google.dev/docs)
- [Pydantic Documentation](https://docs.pydantic.dev/)
## 🤝 Contributing
Feel free to contribute improvements, bug fixes, or additional tutorials. Each tutorial should:
- Be self-contained and runnable
- Include clear documentation
- Follow the established structure
- Use minimal, understandable code