Tools
Tools are functions that LLMs can call during agent execution.
@tool Decorator
from sypho_sdk import tool
@tool
async def search_database(query: str, limit: int = 10):
"""
Search the database for matching records
Args:
query: Search query string
limit: Maximum number of results to return
"""
# Implementation
return results
Function Signature
- Must be async:
async def - Type hints: Used to generate JSON schema
- Docstring: Becomes tool description for LLM
- Args section: Documents parameters
Parameter Types
@tool
async def example(
required_str: str,
optional_int: int = 42,
boolean_flag: bool = False,
list_param: list[str] = None,
dict_param: dict = None
):
pass
Generates JSON schema:
{
"type": "object",
"required": ["required_str"],
"properties": {
"required_str": {"type": "string"},
"optional_int": {"type": "integer"},
"boolean_flag": {"type": "boolean"},
"list_param": {"type": "array", "items": {"type": "string"}},
"dict_param": {"type": "object"}
}
}
Return Values
Return JSON-serializable data:
@tool
async def fetch_user(user_id: str):
return {
"id": user_id,
"name": "Alice",
"email": "alice@example.com"
}
Calling Tools
From Entrypoint
@entrypoint
async def main(input: dict, context: AgentContext):
result = await context.call_tool("search_database", {
"query": "python",
"limit": 5
})
return {"results": result}
From LLM (Agent Mode)
LLM automatically calls tools:
User: "Search for python tutorials"
LLM decides to call: search_database(query="python tutorials", limit=10)
Tool returns: [...]
LLM synthesizes: "I found 10 python tutorials..."
Platform vs Local Tools
Local Tools
Defined in your agent code with @tool:
@tool
async def my_custom_tool():
pass
Platform Tools
Built-in, always available:
structured_data_savestructured_data_getstructured_data_querystructured_data_deletestructured_data_list_keys
No @tool decorator needed, just call via context.
Best Practices
1. Clear Descriptions
@tool
async def send_email(to: str, subject: str, body: str):
"""
Send an email to a recipient
Use this tool when you need to send email notifications or responses.
Args:
to: Recipient email address
subject: Email subject line
body: Email body content (plain text)
"""
pass
2. Error Handling
@tool
async def api_call(endpoint: str):
try:
response = await http_client.get(endpoint)
return {"status": "success", "data": response.json()}
except Exception as e:
return {"status": "error", "message": str(e)}
3. Validation
@tool
async def process_age(age: int):
if age < 0 or age > 150:
return {"error": "Invalid age"}
return {"valid": True, "age": age}