Documentation Index
Fetch the complete documentation index at: https://docs.lyzr.ai/llms.txt
Use this file to discover all available pages before exploring further.
Add Python functions as tools that agents can execute. There are two ways: pass functions directly (simple) or use the Tool class (advanced).
Quick Start - Simple Function
The easiest way is to pass a function directly to add_tool():
from lyzr import Studio
studio = Studio(api_key="your-api-key")
# Define functions with type hints and docstrings
def get_weather(city: str) -> str:
"""Get current weather for a city"""
return f"Weather in {city}: Sunny, 72°F"
def search_products(query: str, max_results: int = 10) -> list:
"""Search products in the catalog"""
# Your implementation
return [{"name": "Product A", "price": 29.99}]
def send_email(to: str, subject: str, body: str) -> str:
"""Send an email to a recipient"""
# Your implementation
return "Email sent successfully"
# Create agent
agent = studio.create_agent(
name="Assistant",
provider="gpt-4o",
role="Helpful assistant",
goal="Help users with tasks"
)
# Add functions directly - ADK infers everything from type hints
agent.add_tool(get_weather)
agent.add_tool(search_products)
agent.add_tool(send_email)
# Run
response = agent.run("What's the weather in Paris?")
The ADK automatically:
- Uses the function name as the tool name
- Uses the docstring as the description
- Infers parameters from type hints
- Determines required vs optional from default values
For more control, use the Tool class:
from lyzr import Studio
from lyzr.tools import Tool
studio = Studio(api_key="your-api-key")
def search_products(query: str, category: str = "all") -> list:
"""Search products in catalog"""
return [{"name": "Product A", "price": 29.99}]
# Create tool with explicit schema
search_tool = Tool(
name="search_products",
description="Search for products in the catalog by query and optional category",
parameters={
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "Search query"
},
"category": {
"type": "string",
"description": "Product category filter",
"enum": ["all", "electronics", "clothing", "home"]
}
},
"required": ["query"]
},
function=search_products
)
agent = studio.create_agent(
name="Shopping Assistant",
provider="gpt-4o",
role="E-commerce assistant",
goal="Help users find products"
)
agent.add_tool(search_tool)
response = agent.run("Find me wireless headphones")
When to Use Each Approach
| Approach | Best For |
|---|
| Simple Function | Most use cases, rapid development |
| Tool Class | Custom descriptions, enum values, complex schemas |
Simple Function Requirements
For the ADK to auto-infer tool parameters:
def my_function(
required_param: str, # Required (no default)
optional_param: int = 10 # Optional (has default)
) -> str: # Return type
"""Short description of what the function does""" # Becomes tool description
return "result"
Supported Types
| Python Type | Inferred JSON Type |
|---|
str | "string" |
int | "integer" |
float | "number" |
bool | "boolean" |
list | "array" |
dict | "object" |
from lyzr.tools import Tool
tool = Tool(
name: str, # Required: Unique identifier
description: str, # Required: What the tool does (for LLM)
parameters: Dict[str, Any], # Required: JSON Schema for inputs
function: Callable = None # Optional: Python function to execute
)
Parameters
| Parameter | Type | Required | Description |
|---|
name | str | Yes | Unique tool name (no spaces) |
description | str | Yes | Clear description for LLM |
parameters | dict | Yes | JSON Schema defining inputs |
function | Callable | No | Python function to execute |
Defining Parameters
Parameters use JSON Schema format:
Basic Schema
parameters = {
"type": "object",
"properties": {
"param_name": {
"type": "string", # Type of parameter
"description": "What this parameter does"
}
},
"required": ["param_name"] # List of required parameters
}
Supported Types
# String
{"type": "string", "description": "User's name"}
# Integer
{"type": "integer", "description": "Number of items"}
# Number (float)
{"type": "number", "description": "Price in dollars"}
# Boolean
{"type": "boolean", "description": "Include shipping"}
# Array
{"type": "array", "items": {"type": "string"}, "description": "List of tags"}
# Enum (restricted values)
{"type": "string", "enum": ["low", "medium", "high"], "description": "Priority level"}
Complete Example
parameters = {
"type": "object",
"properties": {
"destination": {
"type": "string",
"description": "Destination city"
},
"departure_date": {
"type": "string",
"description": "Departure date (YYYY-MM-DD)"
},
"passengers": {
"type": "integer",
"description": "Number of passengers"
},
"class": {
"type": "string",
"enum": ["economy", "business", "first"],
"description": "Cabin class"
},
"direct_only": {
"type": "boolean",
"description": "Only show direct flights"
}
},
"required": ["destination", "departure_date"]
}
Auto-Infer Parameters
Generate parameters automatically from function signatures:
from lyzr.tools.local import infer_parameters_from_function
def book_appointment(
patient_name: str,
doctor_id: str,
date: str,
time: str,
notes: str = ""
) -> dict:
"""Book a medical appointment"""
pass
# Auto-generate parameters
params = infer_parameters_from_function(book_appointment)
# Create tool with inferred parameters
tool = Tool(
name="book_appointment",
description="Book a medical appointment for a patient",
parameters=params,
function=book_appointment
)
Type Mapping
| Python Type | JSON Schema Type |
|---|
str | "string" |
int | "integer" |
float | "number" |
bool | "boolean" |
list | "array" |
dict | "object" |
Optional[T] | Type of T |
Sync and Async Functions
Tools support both synchronous and asynchronous functions:
Synchronous
def get_stock_price(symbol: str) -> float:
"""Get current stock price"""
import requests
response = requests.get(f"https://api.stocks.com/{symbol}")
return response.json()["price"]
stock_tool = Tool(
name="get_stock_price",
description="Get current price for a stock symbol",
parameters={
"type": "object",
"properties": {
"symbol": {"type": "string", "description": "Stock symbol (e.g., AAPL)"}
},
"required": ["symbol"]
},
function=get_stock_price
)
Asynchronous
async def fetch_user_data(user_id: str) -> dict:
"""Fetch user data from API"""
import aiohttp
async with aiohttp.ClientSession() as session:
async with session.get(f"https://api.example.com/users/{user_id}") as resp:
return await resp.json()
user_tool = Tool(
name="fetch_user_data",
description="Fetch user profile data",
parameters={
"type": "object",
"properties": {
"user_id": {"type": "string", "description": "User ID"}
},
"required": ["user_id"]
},
function=fetch_user_data
)
agent = studio.create_agent(name="Bot", provider="gpt-4o")
agent.add_tool(my_tool)
from lyzr.tools import ToolRegistry
# Create registry
registry = ToolRegistry()
registry.add(search_tool)
registry.add(order_tool)
registry.add(track_tool)
# Add all to agent
for tool in registry.list():
agent.add_tool(tool)
At Creation Time
agent = studio.create_agent(
name="Assistant",
provider="gpt-4o",
role="Helper",
tools=[search_tool, order_tool] # Pass tools directly
)
Manage collections of tools:
from lyzr.tools import ToolRegistry
registry = ToolRegistry()
# Add tools
registry.add(tool1)
registry.register(tool2) # Alias for add()
# Get tool by name
tool = registry.get("tool_name")
# List all tools
all_tools = registry.list()
# Check if tool exists
if "my_tool" in registry:
print("Tool found")
# Remove tool
registry.remove("old_tool")
# Clear all tools
registry.clear()
# Get count
print(len(registry)) # Number of tools
Convert tools for API registration:
# Single tool
api_format = tool.to_api_format()
# {
# "name": "get_weather",
# "description": "Get current weather",
# "parameters": {...}
# }
# All tools in registry
all_tools_api = registry.to_api_format()
# List of tool API formats
Examples
import sqlite3
def query_customers(name: str = None, email: str = None) -> list:
"""Query customer database"""
conn = sqlite3.connect("customers.db")
cursor = conn.cursor()
query = "SELECT * FROM customers WHERE 1=1"
params = []
if name:
query += " AND name LIKE ?"
params.append(f"%{name}%")
if email:
query += " AND email LIKE ?"
params.append(f"%{email}%")
cursor.execute(query, params)
results = cursor.fetchall()
conn.close()
return [{"id": r[0], "name": r[1], "email": r[2]} for r in results]
customer_tool = Tool(
name="query_customers",
description="Search for customers by name or email",
parameters={
"type": "object",
"properties": {
"name": {"type": "string", "description": "Customer name (partial match)"},
"email": {"type": "string", "description": "Customer email (partial match)"}
},
"required": []
},
function=query_customers
)
import requests
def create_ticket(title: str, description: str, priority: str = "medium") -> dict:
"""Create a support ticket"""
response = requests.post(
"https://api.support.com/tickets",
json={
"title": title,
"description": description,
"priority": priority
},
headers={"Authorization": "Bearer token"}
)
return response.json()
ticket_tool = Tool(
name="create_ticket",
description="Create a new support ticket",
parameters={
"type": "object",
"properties": {
"title": {"type": "string", "description": "Ticket title"},
"description": {"type": "string", "description": "Detailed description"},
"priority": {
"type": "string",
"enum": ["low", "medium", "high", "urgent"],
"description": "Priority level"
}
},
"required": ["title", "description"]
},
function=create_ticket
)
import os
def list_files(directory: str, extension: str = None) -> list:
"""List files in a directory"""
files = os.listdir(directory)
if extension:
files = [f for f in files if f.endswith(extension)]
return [{"name": f, "path": os.path.join(directory, f)} for f in files]
file_tool = Tool(
name="list_files",
description="List files in a directory with optional extension filter",
parameters={
"type": "object",
"properties": {
"directory": {"type": "string", "description": "Directory path"},
"extension": {"type": "string", "description": "File extension filter (e.g., '.pdf')"}
},
"required": ["directory"]
},
function=list_files
)
Best Practices
Clear Descriptions
# Good: Specific and actionable
description="Search the product catalog by name, category, or price range"
# Bad: Vague
description="Search products"
Detailed Parameter Descriptions
# Good
{
"date": {
"type": "string",
"description": "Date in YYYY-MM-DD format (e.g., 2024-03-15)"
}
}
# Bad
{
"date": {
"type": "string",
"description": "Date"
}
}
Return Structured Data
# Good: Return dict/list for structured results
def get_user(user_id: str) -> dict:
return {"id": user_id, "name": "John", "email": "john@example.com"}
# Avoid: Plain strings for structured data
def get_user(user_id: str) -> str:
return "User John with email john@example.com"