Module 4 Lesson 2: Tool Definitions
Equipping your agent. How to define tools using decorators, pydantic, and base classes.
Tool Definitions: Extending the Agent's Reach
In Module 2, we learned that tools are "Described Functions." In LangChain, there are three primary ways to define these tools. Each method has its own strengths depending on the complexity of your application.
1. The @tool Decorator (Easiest)
This is the fastest way to turn a simple Python function into a tool. LangChain automatically uses the Function Name as the tool name and the Docstring as the description.
from langchain.tools import tool
@tool
def get_stock_price(symbol: str) -> float:
"""Returns the current stock price for a given ticker symbol (e.g., AAPL)."""
# ... logic to fetch price
return 150.25
2. Using Pydantic for Validation (Professional)
If your tool has multiple arguments and you want to ensure the LLM doesn't "hallucinate" incorrect data types, use the args_schema.
from pydantic import BaseModel, Field
class SearchInput(BaseModel):
query: str = Field(description="The search keyword")
max_results: int = Field(description="Number of results to return", default=5)
@tool("web_search", args_schema=SearchInput)
def search(query: str, max_results: int = 5):
"""Searches the web for the given query."""
return f"Searching for {query} (limit {max_results})..."
3. Pre-made Tools (LangChain Community)
You don't always need to write your own tools. LangChain has a massive library of ready-to-use tools for:
- Tavily / Google Search
- Wikipedia
- YouTube
- SQL / Database
- Arxiv
from langchain_community.tools.tavily_search import TavilySearchResults
search_tool = TavilySearchResults()
4. Visualizing the Tool Call Flow
graph LR
LLM[LLM Output] -->|JSON| Parser{Validation}
Parser -->|Valid| Exec[Function Execution]
Parser -->|Invalid| Error[Return Error to Agent]
Exec --> Result[Tool Output]
Result --> Memory[Conversation History]
5. Why Tool Names & Descriptions Matter
When the agent starts, it doesn't "see" your tool's code. It only sees a "System Prompt" like this:
You have access to these tools:
- get_stock_price: Returns the current stock price...
- web_search: Searches the web for the given query...
If your description is vague, the LLM will get confused. If you name your tool search_1 and search_2, the LLM won't know the difference. Clean naming is a prerequisite for reliable agents.
6. Tool Error Handling
You can tell LangChain how to handle tool failures directly in the definition:
@tool(handle_tool_errors=True)
def flaky_api():
"""Contact the flaky API."""
raise Exception("API is down")
# The agent will receive 'Error: API is down' instead of crashing the script.
Key Takeaways
- The @tool decorator is the standard for custom logic.
- Pydantic schemas prevent the LLM from sending the wrong data types to your tools.
- Descriptions are Instructions: They tell the brain when to use the hands.
- Check the LangChain Community library before building a standard tool (Search, SQL, etc.).