AI agents are the most exciting development in applied AI right now. Unlike a standard LLM call that takes an input and returns an output, an agent can reason, plan, and take actions — calling tools, browsing the web, writing and running code, or interacting with external APIs to complete complex, multi-step tasks.

LangChain has become the go-to framework for building agents in Python. In this guide, I'll walk you through everything you need to know — from the core concepts to shipping a production-grade agent.

What Are AI Agents?

Think of a traditional LLM call as a calculator: you give it an expression and it returns an answer. An AI agent is more like a human employee: you give it a goal, and it figures out the steps, uses available tools, and iterates until the task is done.

A minimal agent has three components:

Key insight: An agent's power comes from the loop. The LLM doesn't know the answer upfront — it reasons through the problem one step at a time, using tools to gather information it needs.

The ReAct Framework

The most widely used agent pattern is ReAct (Reasoning + Acting). At each step, the agent produces a structured output:

Thought: I need to find the current price of Bitcoin.
Action: web_search
Action Input: "Bitcoin price today"
Observation: Bitcoin is currently trading at $67,420.

Thought: Now I have the price. I can answer the question.
Final Answer: Bitcoin is currently $67,420 USD.

LangChain implements this loop for you — all you need to do is define the tools and connect an LLM.

Building Your First Agent

Let's build a simple agent with web search and a calculator. First, install the dependencies:

pip install langchain langchain-openai duckduckgo-search

Then set up the agent:

from langchain.agents import create_react_agent, AgentExecutor
from langchain_openai import ChatOpenAI
from langchain_community.tools import DuckDuckGoSearchRun
from langchain.tools import tool
from langchain import hub

# Define tools
search = DuckDuckGoSearchRun()

@tool
def calculator(expression: str) -> str:
    """Evaluate a mathematical expression."""
    return str(eval(expression))

tools = [search, calculator]

# Create agent
llm = ChatOpenAI(model="gpt-4o", temperature=0)
prompt = hub.pull("hwchase17/react")
agent = create_react_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)

# Run it
result = agent_executor.invoke({
    "input": "What is the current market cap of Apple? How many times bigger is it than Google?"
})

Run this and watch the agent reason through the problem in real time — it will search for both values, then use the calculator to compute the ratio.

Adding Custom Tools

The real power comes from custom tools that connect your agent to your specific systems. Here's how to create a tool that queries a database:

@tool
def query_customer_database(customer_id: str) -> str:
    """Look up a customer's order history by their customer ID."""
    # Replace with your actual database query
    conn = get_db_connection()
    orders = conn.execute(
        "SELECT * FROM orders WHERE customer_id = ?", [customer_id]
    ).fetchall()
    return str(orders)

Good tool design matters a lot. Make sure your docstring is crystal clear — the LLM reads it to decide when and how to use the tool. Be specific about what parameters are expected and what gets returned.

Giving Your Agent Memory

By default, agents have no memory of previous conversations. For a customer support bot or personal assistant, you want the agent to remember what was discussed earlier. Add memory like this:

from langchain.memory import ConversationBufferMemory

memory = ConversationBufferMemory(
    memory_key="chat_history",
    return_messages=True
)

agent_executor = AgentExecutor(
    agent=agent,
    tools=tools,
    memory=memory,
    verbose=True
)

For production, swap ConversationBufferMemory for a persistent store like Redis or PostgreSQL so conversations survive restarts.

Multi-Agent Systems with LangGraph

Single agents work well for focused tasks. For complex workflows — like a research pipeline that searches, writes, reviews, and publishes — you need multiple agents working together. LangGraph is the best tool for this.

from langgraph.graph import StateGraph, END

# Define your agent graph
workflow = StateGraph(AgentState)
workflow.add_node("researcher", researcher_agent)
workflow.add_node("writer", writer_agent)
workflow.add_node("reviewer", reviewer_agent)

workflow.add_edge("researcher", "writer")
workflow.add_edge("writer", "reviewer")
workflow.add_conditional_edges("reviewer", should_revise)

LangGraph handles the state passing between agents, conditional routing (e.g. "send back for revision if quality score is below 8"), and even parallel execution.

Production Tips

The bottom line: AI agents are a step-change in what software can do. The combination of a powerful LLM, well-designed tools, and a good looping framework lets you automate tasks that previously required a human to orchestrate. Start simple, iterate, and always test with real-world inputs.

Want to Build AI Agents Yourself?

Our 12-week Generative AI coaching track takes you from zero to building and deploying production AI agents — with 1-on-1 sessions, code reviews, and a portfolio project.

View the Generative AI Course →
PC

Pal C

AI Engineer & Full-Stack Developer

Software engineer and AI specialist with 8+ years of industry experience. Has built production AI systems and taught 500+ students from 15+ countries. Passionate about making AI practical and accessible.