๐ฏ What You'll Learn Today
LangGraph Tutorial: Creating Custom LangChain Tools - Unit 2.2 Exercise 2
This tutorial is also available in Google Colab here or for download here
Joint Initiative: This tutorial is part of a collaboration between AI Product Engineer and the Nebius Academy.
This tutorial demonstrates how to create and implement custom tools in LangChain, focusing on proper tool definition, validation, and error handling using modern practices.
Key Concepts Covered
- Tool Definition and Decoration
- Modern Tool Invocation
- Error Handling
- Mathematical Operations
- Current LangChain Best Practices
import math
from datetime import datetime
#!pip install langchain-core
import numexpr
from langchain_core.tools import tool
Step 1: Calculator Tool Implementation
We implement a mathematical expression calculator tool.
Why This Matters
Proper tool implementation is crucial because
- Ensures safe expression evaluation
- Provides input validation
- Handles errors gracefully
- Maintains type safety
Debug Tips
-
Tool Invocation:
- Use
.invoke()
instead of direct calling - Monitor input validation
- Track error cases
- Verify output types
- Use
@tool
def calculator(expression: str) -> str:
"""Evaluate mathematical expressions safely.
Args:
expression: Mathematical expression (e.g., "2 * pi + 5")
Returns:
String result or error message
"""
local_dict = {
"pi": math.pi,
"e": math.e,
"sin": math.sin,
"cos": math.cos,
"tan": math.tan,
"sqrt": math.sqrt,
"abs": abs,
}
try:
cleaned_expression = expression.strip()
if not cleaned_expression:
return "Error: Empty expression"
result = numexpr.evaluate(
cleaned_expression,
global_dict={},
local_dict=local_dict,
)
if isinstance(result, (int, float)):
return f"{float(result):.6f}".rstrip("0").rstrip(".")
return str(result)
except Exception as e:
return f"Error evaluating expression: {e!s}"
Step 2: Weather Tool Implementation
We implement a simulated weather information tool.
Why This Matters
Modern tool implementation is crucial because
- Follows current best practices
- Ensures forward compatibility
- Provides consistent behavior
- Enables proper testing
Debug Tips
-
Modern Usage:
- Use
.invoke()
method - Check return types
- Monitor error handling
- Validate output format
- Use
@tool
def check_weather(location: str) -> str:
"""Simulate weather information retrieval.
Args:
location: Location to check weather for
Returns:
Simulated weather information
"""
try:
cleaned_location = location.strip()
if not cleaned_location:
return "Error: Empty location"
current_time = datetime.now().strftime("%H:%M")
return (
f"Weather for {cleaned_location} at {current_time} (Mock Data):\n"
f"Temperature: 22ยฐC\n"
f"Condition: Sunny\n"
f"Humidity: 60%"
)
except Exception as e:
return f"Error checking weather: {e!s}"
Step 3: Tool Demonstration
We implement demonstration functions using modern tool invocation.
Why This Matters
Proper demonstration is crucial because
- Shows correct usage patterns
- Avoids deprecation warnings
- Follows best practices
- Ensures future compatibility
Debug Tips
-
Invocation:
- Use
.invoke()
not direct calls - Check return values
- Monitor error cases
- Verify output formats
- Use
def demonstrate_tools():
"""Demonstrate tool usage with current practices."""
print("\nCalculator Examples:")
expressions = ["2 + 2", "pi * 2", "sin(pi/2)", "sqrt(16)", "invalid expression", ""]
calc_tool = calculator
weather_tool = check_weather
for expr in expressions:
# Use invoke() instead of direct calling
result = calc_tool.invoke(expr)
print(f"Expression: {expr!r}")
print(f"Result: {result}\n")
print("\nWeather Examples:")
locations = ["Paris", "New York", "", "Tokyo"]
for loc in locations:
# Use invoke() instead of direct calling
result = weather_tool.invoke(loc)
print(f"Location: {loc!r}")
print(f"Result: {result}\n")
def main():
"""Run the tool demonstration."""
print("LangChain Tools Demonstration")
print("============================")
demonstrate_tools()
if __name__ == "__main__":
main()
Common Pitfalls
- Using direct tool calls instead of
.invoke()
- Missing input validation
- Poor error messages
- Insufficient documentation
- Unsafe expression evaluation
Key Takeaways
- Modern Invocation: Use
.invoke()
method - Tool Definition: Proper decoration
- Error Handling: Clear messages
- Documentation: Complete docstrings
Next Steps
- Add async tool support
- Implement tool chaining
- Add input validation
- Enhance error handling
- Add tool metadata
Expected Output
Calculator Examples
Expression: '2 + 2'
Result: 4
Expression: 'pi * 2'
Result: 6.283185
Weather Examples
Location: 'Paris'
Result: Weather for Paris at 14:30 (Mock Data):
Temperature: 22ยฐC
Condition: Sunny
Humidity: 60%
๐ฌ๐ง Chapter