Skip to main content

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_save
  • structured_data_get
  • structured_data_query
  • structured_data_delete
  • structured_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}

Next Steps