Writing Tools for Your Agents: A Complete Guide
Last Updated on January 20, 2026 by Editorial Team
Author(s): Yashod Perera
Originally published on Towards AI.
This is the era of Agentic AI, where everyone is writing their agents with tools. But are we writing tools correctly? What is a tool? What are the best practices? If you are having those doubts, this is the article to read. Let’s dive into how to write tools.
Introduction to AI Agents
Almost everyone is rely on Large Language Models(LLMs) nowadays. Simply it is capable of providing answers for…
yashodgayashan.medium.com
What is a Tool for the Agent?
An agent mimics human behaviour in the AI world, where the LLM acts as the brain and tools serve as the hands that execute the tasks the brain decides.

In Simple Terms, A tool is a Python function that:
- Performs a specific task (API call, calculation, database query, etc.)
- Has a clear description the AI can understand
- Defines its input parameters with types
- Returns a result (usually a string)
How to write a tool
A tool is a well-defined function, documented with clear descriptions and examples, enabling an agent to understand when and how to invoke it.
from langchain_core.tools import tool
# Tool declaration makes tool available for Agents
@tool
def tool_name(parameter: type) -> str:
"""
Description of what this tool does.
The AI reads this to decide when to use the tool.
"""
# Your implementation here
result = do_something(parameter)
return str(result)
# Calculator Example
@tool
def calculator(expression: str) -> str:
"""
Evaluates a mathematical expression.
Examples: "2 + 2", "10 * 5", "(100 - 50) / 2"
"""
try:
result = eval(expression, {"__builtins__": {}}, {})
return str(result)
except Exception as e:
return f"Error: {str(e)}"
More examples can be found here.
What can you do with tools?
In theory, you can perform any programmatic action that can be expressed as a function. However, in practice, many tools are poorly defined and end up doing nothing useful.
Can we loosen a Phillips screw using a flat-head screwdriver? Yes, it’s possible. But is it the correct tool to use? No.
Best Practices for Writing Tools
- Write Clear Descriptions — Every tool must have a precise, unambiguous description that clearly explains what it does, when it should be used, and what kind of output it returns. Avoid generic wording and include practical examples so the agent can confidently decide when to invoke the tool and how to interpret its results.
# ❌ Bad
@tool
def process_data(data: str) -> str:
"""Processes data.""" # Too vague!
pass
# ✅ Good
@tool
def analyze_sentiment(text: str) -> str:
"""
Analyzes the sentiment of text and returns positive, negative, or neutral.
Use this when users ask about emotions or opinions in text.
Example: "This movie was amazing!" → "Positive"
"""
pass
- Always Return Strings — Tools should always return string outputs, even when the result is numeric or boolean. This ensures consistent formatting and prevents parsing issues when the agent consumes the response. Convert all return values to strings before sending them back to the agent.
# ❌ Bad
@tool
def get_count() -> int:
return 42 # Tools should return strings!
# ✅ Good
@tool
def get_count() -> str:
count = 42
return str(count)
- Handle Errors Gracefully — Tools should never fail silently or crash the agent workflow. Always anticipate edge cases and handle exceptions properly by returning clear, human-readable error messages. This allows the agent to understand what went wrong and respond appropriately instead of breaking the execution flow.
# ❌ Bad
@tool
def divide(a: float, b: float) -> str:
return str(a / b) # Will crash if b is 0!
# ✅ Good
@tool
def divide(a: float, b: float) -> str:
"""Divides two numbers and returns the result."""
try:
if b == 0:
return "Error: Cannot divide by zero"
return str(a / b)
except Exception as e:
return f"Calculation error: {str(e)}"
- Use Type Hints — Always define explicit type hints for tool parameters and return values. This helps the agent understand what kind of data to pass, reduces ambiguity, and improves the accuracy of tool invocation by making input expectations clear and predictable.
# ✅ Good - Clear types help the AI understand what to pass
@tool
def search_products(
query: str,
category: str,
max_price: float
) -> str:
"""Searches for products matching criteria."""
pass
- Add Usage Examples in Docstrings — Include concrete usage examples in the docstring to demonstrate how the tool should be called and what output to expect. Examples help the agent learn correct input patterns, understand formatting rules, and confidently choose the tool when similar user requests appear.
@tool
def format_date(date_string: str, format: str) -> str:
"""
Formats a date string according to the specified format.
Examples:
- format_date("2024-01-15", "MMM DD, YYYY") → "Jan 15, 2024"
- format_date("2024-01-15", "DD/MM/YY") → "15/01/24"
Supported formats: YYYY, MM, DD, MMM (month name)
"""
pass
- Validate Inputs — Always validate incoming parameters before processing. Enforcing value ranges, formats, and constraints prevents invalid operations, improves reliability, and ensures the agent receives clear feedback when inputs are incorrect.
@tool
def set_temperature(temp: float) -> str:
"""Sets the room temperature in Fahrenheit."""
# Validate range
if temp < 60 or temp > 85:
return "Error: Temperature must be between 60°F and 85°F"
# Your implementation
return f"Temperature set to {temp}°F"
- Keep Tools Focused — Each tool should perform a single, well-defined task. Avoid building multi-purpose tools with conditional logic, as they increase complexity and ambiguity. Small, focused tools are easier for agents to understand, invoke correctly, and maintain over time.
# ❌ Bad - Tool does too many things
@tool
def do_everything(action: str, data: str) -> str:
"""Does various actions based on input."""
if action == "email":
# send email
elif action == "save":
# save file
elif action == "search":
# search database
# ... too complex!
# ✅ Good - Separate tools for each task
@tool
def send_email(recipient: str, message: str) -> str:
"""Sends an email to a recipient."""
pass
@tool
def save_file(filename: str, content: str) -> str:
"""Saves content to a file."""
pass
Tool Security Checklist
When creating tools, always consider,
- Input validation: Check and sanitize all inputs
- Rate limiting: Prevent abuse of expensive operations
- Authentication: Verify user has permission
- Data sanitisation: Don’t expose sensitive information
- Timeout handling: Don’t let operations hang forever
- Error messages: Don’t leak internal system details
- Logging: Track tool usage for debugging/auditing
This article has guided you through all you need to know about how to write tools. If you have found this helpful, please hit that 👏 and share it on social media :).
References
Tools – Docs by LangChain
Tools extend what Under the hood, tools are callable functions with well-defined inputs and outputs that get passed to…
docs.langchain.com
Building An Enterprise Graded AI System
This article covers different components of LLM system with their responsibilities to provide a clear idea on how you…
generativeai.pub
Join thousands of data leaders on the AI newsletter. Join over 80,000 subscribers and keep up to date with the latest developments in AI. From research to projects and ideas. If you are building an AI startup, an AI-related product, or a service, we invite you to consider becoming a sponsor.
Published via Towards AI
Towards AI Academy
We Build Enterprise-Grade AI. We'll Teach You to Master It Too.
15 engineers. 100,000+ students. Towards AI Academy teaches what actually survives production.
Start free — no commitment:
→ 6-Day Agentic AI Engineering Email Guide — one practical lesson per day
→ Agents Architecture Cheatsheet — 3 years of architecture decisions in 6 pages
Our courses:
→ AI Engineering Certification — 90+ lessons from project selection to deployed product. The most comprehensive practical LLM course out there.
→ Agent Engineering Course — Hands on with production agent architectures, memory, routing, and eval frameworks — built from real enterprise engagements.
→ AI for Work — Understand, evaluate, and apply AI for complex work tasks.
Note: Article content contains the views of the contributing authors and not Towards AI.