Agents &
Tools Integration
Build intelligent AI agents that can reason, plan, and use tools to solve complex problems. Learn how to create autonomous systems that combine LLMs with external capabilities.
Learning Objectives
- Understand the concept and architecture of LangChain agents
- Integrate built-in tools like calculators and web search
- Create custom tools for specific business needs
- Build a multi-functional AI assistant with autonomous decision-making
📋 Prerequisites: Ready for Advanced LangChain?
This intermediate-level tutorial assumes you have:
- • Completed lessons 5-8 (LangChain basics, chains, memory)
- • Strong Python programming skills
- • Understanding of LangChain prompts and chains
- • Familiarity with async programming concepts (helpful)
Understanding AI Agents: Core Concepts and Architecture
An agent is an AI system that can reason about problems, plan actions, and use tools to accomplish goals. Unlike simple chains that follow predefined steps, agents can dynamically decide what to do next.
❌ Traditional Chains:
→ Fixed sequence
→ No decision making
→ Can't use external tools
→ Limited problem solving
✅ Intelligent Agents:
→ Dynamic planning
→ Tool selection
→ External API integration
→ Multi-step reasoning
🧠 Agent Reasoning Process:
How to Build Your First LangChain Agent: Step-by-Step Tutorial
Zero-Shot Agent with Calculator
Let's start with a simple agent that can perform calculations and reasoning:
🔍 Understanding the Components:
- • Agent Type: ZERO_SHOT_REACT_DESCRIPTION uses reasoning and acting
- • Tools: Calculator tool for mathematical operations
- • Verbose Mode: Shows the agent's reasoning process
- • Max Iterations: Prevents infinite loops in agent reasoning
from langchain.agents import create_react_agent, AgentExecutor
from langchain_core.tools import Tool
from langchain.prompts import PromptTemplate
from langchain_google_genai import ChatGoogleGenerativeAI
import os
import math
from dotenv import load_dotenv
# Load environment variables
load_dotenv()
# Initialize the LLM
llm = ChatGoogleGenerativeAI(
model="gemini-2.0-flash",
temperature=0 # Lower temperature for more consistent tool usage
)
# Create a simple calculator tool
def calculate(expression: str) -> str:
"""Evaluate a mathematical expression"""
try:
# Use Python's eval for calculations
# Only allow safe math operations
allowed_names = {
k: v for k, v in math.__dict__.items() if not k.startswith("__")
}
# Add power operator
allowed_names['__builtins__'] = {'pow': pow}
# Basic safety check
if any(word in expression for word in ['import', 'exec', 'eval', 'open', 'file']):
return "Invalid expression - contains restricted keywords"
result = eval(expression, {"__builtins__": {}}, allowed_names)
return str(result)
except Exception as e:
return f"Error calculating: {str(e)}"
# Create tool
calculator_tool = Tool(
name="Calculator",
func=calculate,
description="Useful for mathematical calculations. Input should be a valid Python mathematical expression."
)
# Create the ReAct prompt
react_prompt = PromptTemplate.from_template("""Answer the following questions as best you can. You have access to the following tools:
{tools}
Use the following format:
Question: the input question you must answer
Thought: you should always think about what to do
Action: the action to take, should be one of [{tool_names}]
Action Input: the input to the action
Observation: the result of the action
... (this Thought/Action/Action Input/Observation can repeat N times)
Thought: I now know the final answer
Final Answer: the final answer to the original input question
Begin!
Question: {input}
Thought: {agent_scratchpad}""")
# Create the agent
agent = create_react_agent(
llm=llm,
tools=[calculator_tool],
prompt=react_prompt
)
# Create agent executor
agent_executor = AgentExecutor(
agent=agent,
tools=[calculator_tool],
verbose=True,
max_iterations=3,
handle_parsing_errors=True
)
# Test the agent with math problems
test_queries = [
"What is 15% of 2847?",
"If I invest $10,000 at 7% annual interest, how much will I have after 5 years with compound interest?",
"A pizza has 8 slices. If 3 people each eat 2.5 slices, how many slices are left?"
]
for query in test_queries:
print(f"\n{'='*50}")
print(f"Query: {query}")
print(f"{'='*50}")
try:
result = agent_executor.invoke({"input": query})
print(f"\nFinal Answer: {result['output']}")
except Exception as e:
print(f"Error: {e}")
# Example of agent reasoning output:
print(f"\n{'='*50}")
print("What you'll see in verbose mode:")
print(f"{'='*50}")
print("""
> Entering new AgentExecutor chain...
I need to calculate 15% of 2847.
Action: Calculator
Action Input: 2847 * 0.15
Observation: 427.05
Thought: I now know the final answer.
Final Answer: 15% of 2847 is 427.05
""")
💡 Agent Reasoning Process:
The agent follows the ReAct (Reasoning + Acting) pattern:
- • Thought: Analyzes the problem
- • Action: Chooses and uses appropriate tool
- • Observation: Processes tool result
- • Final Answer: Provides formatted response
🎯 Expected Results:
When you run this code, you'll see the agent solving each problem step by step:
Query 1: "What is 15% of 2847?"
→ Agent calculates: 2847 × 0.15 = 427.05
Query 2: Compound Interest
→ Agent applies formula: 10,000 × (1.07)^5 = $14,025.52
Query 3: Pizza Problem
→ Step 1: 3 people × 2.5 slices = 7.5 slices eaten
→ Step 2: 8 slices - 7.5 slices = 0.5 slices left
📖 Code Explanation:
- • Calculator Tool: A custom function that safely evaluates mathematical expressions using Python's eval with restricted scope
- • ReAct Prompt: Defines the exact format the agent should follow for reasoning and tool usage
- • Agent Executor: Manages the agent's execution, handles iterations, and provides verbose output
- • Safety Features: Keywords like 'import' and 'exec' are blocked to prevent code injection
⚠️ Modern Implementation Note:
This example uses the latest LangChain patterns. The deprecated initialize_agent
and load_tools
have been replaced with create_react_agent
and custom tool creation.
Creating Multi-Tool Agents: Combining Multiple Capabilities
Agent with Web Search and Calculator
Let's create an agent that can search the web and perform calculations:
🔍 Available Tools:
- • InfoSearch: Mock search for demonstration (simulates web/wiki search)
- • Calculator: Mathematical calculations using Python eval
- • Tool Selection: Agent automatically chooses appropriate tool based on the task
- • No External APIs: This example works without API keys for easier learning
from langchain.agents import create_react_agent, AgentExecutor
from langchain_core.tools import Tool
from langchain.prompts import PromptTemplate
from langchain_google_genai import ChatGoogleGenerativeAI
import os
import math
from dotenv import load_dotenv
# Load environment variables
load_dotenv()
# Initialize the LLM
llm = ChatGoogleGenerativeAI(
model="gemini-2.0-flash",
temperature=0
)
# Create a simple calculator tool
def calculate(expression: str) -> str:
"""Evaluate a mathematical expression"""
try:
allowed_names = {
k: v for k, v in math.__dict__.items() if not k.startswith("__")
}
allowed_names['__builtins__'] = {'pow': pow}
if any(word in expression for word in ['import', 'exec', 'eval', 'open', 'file']):
return "Invalid expression"
result = eval(expression, {"__builtins__": {}}, allowed_names)
return str(result)
except Exception as e:
return f"Error calculating: {str(e)}"
# Create a mock information search tool (simulates web/wiki search)
def search_info(query: str) -> str:
"""Search for information (mock implementation for demo)"""
# In production, this would use real APIs
mock_data = {
"tokyo population": "Tokyo metropolitan area has approximately 37.4 million people (2024)",
"japan population": "Japan's total population is approximately 124.8 million (2024)",
}
query_lower = query.lower()
# Check if any key words match the query
for key, value in mock_data.items():
# Check if all words in key are present in query
key_words = key.split()
if all(word in query_lower for word in key_words):
return value
return f"No specific information found for '{query}'. Try rephrasing your search."
# Create tools
calculator_tool = Tool(
name="Calculator",
func=calculate,
description="Useful for mathematical calculations. Input should be a valid mathematical expression."
)
search_tool = Tool(
name="InfoSearch",
func=search_info,
description="Search for general information like population data, distances, stock prices. Input should be a search query."
)
# Create the ReAct prompt for multi-tool usage
react_prompt = PromptTemplate.from_template("""Answer the following questions as best you can. You have access to the following tools:
{tools}
Use the following format:
Question: the input question you must answer
Thought: you should always think about what to do
Action: the action to take, should be one of [{tool_names}]
Action Input: the input to the action
Observation: the result of the action
... (this Thought/Action/Action Input/Observation can repeat N times)
Thought: I now know the final answer
Final Answer: the final answer to the original input question
IMPORTANT: Always use this exact format:
Action: ToolName
Action Input: your input here
Never write Action: ToolName(input) or any other format.
Example:
Question: What is 2 + 2?
Thought: I need to calculate 2 + 2
Action: Calculator
Action Input: 2 + 2
Observation: 4
Thought: I now know the final answer
Final Answer: 2 + 2 equals 4
Begin!
Question: {input}
Thought: {agent_scratchpad}""")
# Create the agent
agent = create_react_agent(
llm=llm,
tools=[search_tool, calculator_tool],
prompt=react_prompt
)
# Create agent executor
agent_executor = AgentExecutor(
agent=agent,
tools=[search_tool, calculator_tool],
verbose=True,
max_iterations=5, # Allow more iterations for complex tasks
handle_parsing_errors=True
)
# Test query that requires multiple tools
test_query = "What is the population of Tokyo and what percentage is that of Japan's total population?"
print(f"\n{'='*60}")
print(f"Query: {test_query}")
print(f"{'='*60}")
try:
result = agent_executor.invoke({"input": test_query})
print(f"\nFinal Answer: {result['output']}")
except Exception as e:
print(f"Error: {e}")
# Note: The verbose=True parameter above will show the actual reasoning process
# Similar to this example output:
"""
Example output (when verbose=True):
> Entering new AgentExecutor chain...
I need to find Tokyo's population and Japan's total population, then calculate the percentage.
Action: InfoSearch
Action Input: Tokyo population
Observation: Tokyo metropolitan area has approximately 37.4 million people (2024)
...
"""
# The actual output will vary based on the agent's reasoning
💡 Tool Selection Logic:
The agent intelligently selects tools based on the task:
- • Information needed: Uses InfoSearch tool
- • Calculations required: Uses Calculator tool
- • Multi-step problems: Combines multiple tools in sequence
- • Error handling: Retries with different approaches
🎯 Expected Result:
When you run this code, the agent will demonstrate multi-tool usage:
Tokyo Population Query - Complete Multi-Tool Flow:
- InfoSearch: Find Tokyo population → 37.4 million
- InfoSearch: Find Japan population → 124.8 million
- Calculator: Calculate percentage → 37.4 ÷ 124.8 × 100 = ~30%
Final Answer: Tokyo has 37.4M people, which is ~30% of Japan's 124.8M total
📖 Code Explanation:
- • Mock InfoSearch: Simulates web search without external APIs - perfect for learning
- • Smart Matching: Uses word-based matching to handle various phrasings
- • Multi-Tool Coordination: Agent automatically decides which tool to use
- • Production Ready: Replace mock data with real APIs when needed
⚠️ Troubleshooting:
If searches fail, the agent may:
- • Retry with different phrasings
- • Hit iteration limit (max_iterations=5)
- • Need more specific mock data entries
Solution: Add more key-value pairs to mock_data or use real search APIs.
How to Create Custom Tools for LangChain Agents in Python
Building Domain-Specific Tools
Create custom tools tailored to your specific business needs:
🔍 Custom Tool Components:
- • @tool decorator: Marks function as an agent tool
- • Type hints: Help agent understand input/output types
- • Docstrings: Describe tool purpose and usage for the agent
- • Error handling: Graceful failure modes
from langchain.tools import tool
from langchain.agents import create_react_agent, AgentExecutor
from langchain_core.prompts import PromptTemplate
from langchain_google_genai import ChatGoogleGenerativeAI
import os
from dotenv import load_dotenv
# Load environment variables
load_dotenv()
# Custom tool example - Weather information
@tool
def get_weather(city: str) -> str:
"""
Get current weather information for a specified city.
Useful when you need to find weather conditions, temperature, or forecast.
Args:
city: The name of the city to get weather for
Returns:
Weather information as a string
"""
# Mock implementation - Replace with real weather API (OpenWeatherMap, etc.)
mock_weather_data = {
"tokyo": "Sunny, 22°C, humidity 65%, light breeze",
"london": "Cloudy, 15°C, humidity 80%, chance of rain",
"new york": "Partly cloudy, 18°C, humidity 60%, windy",
}
city_lower = city.lower()
if city_lower in mock_weather_data:
return f"Weather in {city}: {mock_weather_data[city_lower]}"
return f"Weather data not available for {city}"
# Initialize LLM
llm = ChatGoogleGenerativeAI(
model="gemini-2.0-flash",
temperature=0
)
# Create ReAct prompt (same as before)
react_prompt = PromptTemplate.from_template("""Answer the following questions as best you can. You have access to the following tools:
{tools}
Use the following format:
Question: the input question you must answer
Thought: you should always think about what to do
Action: the action to take, should be one of [{tool_names}]
Action Input: the input to the action
Observation: the result of the action
... (this Thought/Action/Action Input/Observation can repeat N times)
Thought: I now know the final answer
Final Answer: the final answer to the original input question
Begin!
Question: {input}
Thought: {agent_scratchpad}""")
# Create agent with custom tool
agent = create_react_agent(
llm=llm,
tools=[get_weather],
prompt=react_prompt
)
# Create agent executor
agent_executor = AgentExecutor(
agent=agent,
tools=[get_weather],
verbose=True,
handle_parsing_errors=True
)
# Test the custom tool
query = "What's the weather like in Tokyo?"
print(f"Query: {query}")
print("-" * 50)
try:
result = agent_executor.invoke({"input": query})
print(f"\nAnswer: {result['output']}")
except Exception as e:
print(f"Error: {e}")
💡 Key Concepts Explained:
- • @tool decorator: Converts a Python function into a LangChain tool
- • Docstring is crucial: The agent reads this to understand when/how to use the tool
- • Type hints: Help with validation (city: str) → (str)
- • Simple is better: Start with mock data, add real APIs later
🎯 Expected Output:
Query: "What's the weather like in Tokyo?"
Action: get_weather
Action Input: Tokyo
Result: Weather in Tokyo: Sunny, 22°C, humidity 65%, light breeze
🚀 Extending to Real APIs:
# Real weather API example
@tool
def get_real_weather(city: str) -> str:
"""Get real weather data from OpenWeatherMap API"""
api_key = os.getenv("OPENWEATHER_API_KEY")
url = f"https://api.openweathermap.org/data/2.5/weather?q={city}&appid={api_key}"
try:
response = requests.get(url)
data = response.json()
temp_celsius = data['main']['temp'] - 273.15
return f"Weather in {city}: {data['weather'][0]['description']}, {temp_celsius:.1f}°C"
except:
return f"Unable to fetch weather for {city}"
LangChain Agent Types: Choosing the Right Agent for Your Use Case
Choosing the Right Agent Type
Different agent types are optimized for different use cases:
🤖 ZERO_SHOT_REACT_DESCRIPTION
Best for: Most general cases
Reasoning: Explicit thought process
Performance: Good balance
Tools: Works with any tools
🧠 CONVERSATIONAL_REACT_DESCRIPTION
Best for: Chat applications
Reasoning: More conversational
Performance: Great for dialogue
Memory: Built-in conversation history
⚡ STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION
Best for: Complex tool inputs
Reasoning: Structured format
Performance: Better with complex tools
Tools: Multi-parameter tools
🎯 SELF_ASK_WITH_SEARCH
Best for: Research tasks
Reasoning: Question decomposition
Performance: Great for complex queries
Tools: Requires search tool
💡 Selection Guidelines:
- • Starting out: Use ZERO_SHOT_REACT_DESCRIPTION
- • Chat applications: Use CONVERSATIONAL_REACT_DESCRIPTION
- • Complex tool inputs: Use STRUCTURED_CHAT variants
- • Research/QA: Use SELF_ASK_WITH_SEARCH
✨ Agent Development Best Practices
Tool Design
- • Write clear, descriptive tool docstrings
- • Use specific parameter names and types
- • Handle errors gracefully with helpful messages
- • Keep tools focused on single responsibilities
Agent Configuration
- • Set appropriate max_iterations to prevent loops
- • Use lower temperature for consistent tool usage
- • Enable verbose mode during development
- • Implement proper error handling and logging
🎨Common Agent Patterns
Research Agent
Web search + Calculator + Summarization tools for comprehensive research tasks
Business Assistant
Database queries + Email notifications + Calendar integration + Reporting tools
DevOps Agent
Server monitoring + Deployment tools + Log analysis + Alert management
🎉 Next Step
You've mastered agents and tools! Next, you'll learn about Document Processing & Text Splitting - the foundation for building powerful RAG (Retrieval-Augmented Generation) applications that can work with documents and knowledge bases.