🌐 EN | 🇯🇵 JP

Chapter 3: Agents and Tools

Building AI Agents with LangChain

📖 Reading Time: 20-25 minutes 📊 Difficulty: Beginner-Intermediate 💻 Code Examples: 6 📝 Exercises: 2

Learning Objectives

3.1 What are AI Agents?

An AI agent is an LLM that can autonomously decide which actions to take to accomplish a goal. Unlike simple chains that follow a fixed path, agents can:

graph TB A[User Query] --> B[Agent] B --> C{Decide Action} C -->|Use Tool| D[Execute Tool] D --> E[Observe Result] E --> C C -->|Done| F[Final Response] style B fill:#667eea,color:#fff style D fill:#11998e,color:#fff style F fill:#28a745,color:#fff

Agent Loop

The cycle of: (1) LLM decides which tool to call, (2) Tool executes and returns result, (3) LLM observes result and decides next action. This continues until the LLM determines the task is complete.

3.2 The create_agent API

LangChain v1.0 introduced create_agent as the standard way to build agents:

Code Example 1: Basic Agent with create_agent
from langchain.agents import create_agent
from langchain_openai import ChatOpenAI

# Define a simple tool
def get_weather(city: str) -> str:
    """Get the current weather for a city."""
    # In production, this would call a real weather API
    return f"The weather in {city} is sunny, 22°C"

def calculate(expression: str) -> str:
    """Evaluate a mathematical expression.

    Warning: This example uses eval() for simplicity. In production,
    use a safe math parser like `numexpr` or `asteval` instead.
    """
    try:
        # WARNING: eval() is dangerous with untrusted input!
        # For production, use: import numexpr; numexpr.evaluate(expression)
        return str(eval(expression))
    except Exception as e:
        return f"Error: {e}"

# Create the agent
agent = create_agent(
    model=ChatOpenAI(model="gpt-4"),
    tools=[get_weather, calculate],
    system_prompt="You are a helpful assistant that can check weather and do math."
)

# Run the agent
result = agent.invoke({
    "messages": [
        {"role": "user", "content": "What's the weather in Tokyo, and what's 25 * 4?"}
    ]
})

print(result["messages"][-1].content)

3.3 Defining Custom Tools

Tools can be defined in several ways. The simplest is using the @tool decorator:

Code Example 2: Custom Tools with @tool Decorator
from langchain_core.tools import tool

@tool
def search_database(query: str) -> str:
    """Search the product database for items matching the query.

    Args:
        query: The search term to look for in the database.
    """
    # Simulated database search
    products = {
        "laptop": "MacBook Pro - $1999",
        "phone": "iPhone 15 - $999",
        "tablet": "iPad Pro - $799"
    }
    query_lower = query.lower()
    for key, value in products.items():
        if key in query_lower:
            return value
    return "No products found"

@tool
def send_email(to: str, subject: str, body: str) -> str:
    """Send an email to the specified recipient.

    Args:
        to: Email address of the recipient.
        subject: Subject line of the email.
        body: Body content of the email.
    """
    # In production, this would actually send an email
    return f"Email sent to {to} with subject '{subject}'"

# Use the tools
print(search_database.name)  # "search_database"
print(search_database.description)  # From docstring
print(search_database.invoke("laptop"))  # "MacBook Pro - $1999"

Tool Schema

LangChain automatically extracts the schema from type hints and docstrings:

Best Practices for Tool Definitions

  • Use clear, descriptive function names
  • Write detailed docstrings—the LLM uses these to decide when to use the tool
  • Add type hints for all parameters
  • Keep tools focused on a single task

3.4 Built-in Tools

LangChain provides many pre-built tools through langchain-community:

Code Example 3: Using Built-in Tools
from langchain_community.tools import DuckDuckGoSearchRun
from langchain_community.tools import WikipediaQueryRun
from langchain_community.utilities import WikipediaAPIWrapper

# Web search tool
search = DuckDuckGoSearchRun()
result = search.invoke("Latest news about AI")
print(result)

# Wikipedia tool
wikipedia = WikipediaQueryRun(api_wrapper=WikipediaAPIWrapper())
result = wikipedia.invoke("Machine Learning")
print(result)

Common Built-in Tools

Tool Package Purpose
DuckDuckGoSearchRun langchain-community Web search
WikipediaQueryRun langchain-community Wikipedia lookup
ArxivQueryRun langchain-community Academic paper search
PythonREPLTool langchain-community Execute Python code
ShellTool langchain-community Run shell commands

Security Warning: High-Risk Tools

PythonREPLTool and ShellTool execute arbitrary code with full system access. Only use these tools in sandboxed environments or with strict input validation. Consider using allowlists, containerization (Docker), or restricted execution environments for production deployments.

3.5 Structured Tool Output

For complex tools, you can define structured input/output with Pydantic:

Code Example 4: Structured Tool with Pydantic
from langchain.agents import create_agent
from langchain_openai import ChatOpenAI
from langchain_core.tools import StructuredTool
from pydantic import BaseModel, Field

# Define input schema
class FlightSearchInput(BaseModel):
    origin: str = Field(description="Departure airport code (e.g., 'NRT')")
    destination: str = Field(description="Arrival airport code (e.g., 'LAX')")
    date: str = Field(description="Travel date in YYYY-MM-DD format")

def search_flights(origin: str, destination: str, date: str) -> str:
    """Search for available flights."""
    # Simulated flight search
    return f"Found 3 flights from {origin} to {destination} on {date}. Cheapest: $450"

# Create structured tool
flight_tool = StructuredTool.from_function(
    func=search_flights,
    name="flight_search",
    description="Search for flights between airports",
    args_schema=FlightSearchInput
)

# Use in agent
agent = create_agent(
    model=ChatOpenAI(model="gpt-4"),
    tools=[flight_tool],
    system_prompt="You are a travel assistant."
)

3.6 Agent Execution Patterns

Code Example 5: Streaming Agent Execution
from langchain.agents import create_agent
from langchain_openai import ChatOpenAI

# Assumes get_weather and calculate are defined as in Code Example 1

agent = create_agent(
    model=ChatOpenAI(model="gpt-4"),
    tools=[get_weather, calculate],
    system_prompt="You are a helpful assistant."
)

# Stream the agent's thinking process
for event in agent.stream({
    "messages": [{"role": "user", "content": "What's 15% of 250?"}]
}):
    if "messages" in event:
        for msg in event["messages"]:
            if hasattr(msg, "tool_calls") and msg.tool_calls:
                print(f"🔧 Calling tool: {msg.tool_calls[0]['name']}")
            elif hasattr(msg, "content") and msg.content:
                print(f"💬 {msg.content}")

3.7 Error Handling

Code Example 6: Handling Tool Errors
from langchain_core.tools import tool

@tool
def divide(a: float, b: float) -> str:
    """Divide a by b.

    Args:
        a: The numerator.
        b: The denominator.
    """
    if b == 0:
        return "Error: Cannot divide by zero"
    return str(a / b)

# The agent will receive the error message and can respond appropriately
agent = create_agent(
    model=ChatOpenAI(model="gpt-4"),
    tools=[divide],
    system_prompt="You are a math assistant. If a calculation fails, explain why."
)

result = agent.invoke({
    "messages": [{"role": "user", "content": "What is 10 divided by 0?"}]
})
print(result["messages"][-1].content)
# Agent will explain that division by zero is not possible

Exercises

Exercise 1: Build a Research Agent

Create an agent with tools for:

  • Searching the web (use DuckDuckGoSearchRun)
  • Looking up Wikipedia articles
  • Summarizing text (a custom tool that uses the LLM)

Test it by asking: "Research the history of neural networks and summarize the key milestones."

Exercise 2: Task Automation Agent

Build an agent for a fictional task management system with tools:

  • create_task(title, description, due_date)
  • list_tasks()
  • complete_task(task_id)

Store tasks in a simple dictionary and test the agent's ability to manage tasks.

Summary

Disclaimer

This content is provided for educational purposes. LangChain is developed and maintained by LangChain Inc.