Rapidly Build AI Agents with LangChain: A Hands‑On Tutorial
This article walks through why LangChain is the leading framework for AI agents, compares it with low‑level implementations, and provides step‑by‑step code examples for installation, prompt templates, LCEL pipelines, memory modules, RAG, custom tools, and a complete customer‑service agent, concluding with a concise feature comparison.
1. Why Choose LangChain?
LangChain offers a unified interface for over ten large‑language models, built‑in prompt‑template handling, decorator‑based tool definition, an AgentExecutor that manages the reasoning‑action loop, ready‑to‑use memory modules, and out‑of‑the‑box retrieval‑augmented generation (RAG).
Standardized model calls replace manual HTTP requests.
Prompt templates avoid raw string concatenation.
Tools are declared with @tool decorators instead of custom parsers.
The agent loop is provided by AgentExecutor rather than hand‑written while loops.
Memory strategies (buffer, window, summary, token‑based) are encapsulated in the Memory module.
RAG components (vector store, retriever) are ready to use.
Core advantages:
Standardization: one codebase works with many models.
Componentization: functionality can be assembled like building blocks.
Production‑ready: includes caching, retry, and fallback mechanisms.
2. LangChain Core Components
┌─────────────────────────────────────────────────────────────────┐
│ LangChain Architecture │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ LCEL (Expression Language) │ │
│ │ Chain │ Runnable │ Pipeline Operations │ │
│ └─────────────────────────────────────────────────────┘ │
│ │ │
│ ┌──────────┬──────────┬──────────┬──────────┬────────────┐ │
│ │ Model │ Prompt │ Memory │ Tools │ Retrieval │ │
│ └──────────┴──────────┴──────────┴──────────┴────────────┘ │
│ │ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Agent Executor (Decision + Loop) │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘3. Quick Start
3.1 Installation & Environment
pip install langchain langchain-openai python-dotenv # .env
OPENAI_API_KEY=your-api-key
OPENAI_BASE_URL=https://api.openai.com/v1
MODEL_NAME=gpt-43.2 Basic Call
# basic_chain.py
from langchain_openai import ChatOpenAI
from langchain.schema import HumanMessage, SystemMessage
llm = ChatOpenAI(model="gpt-4", temperature=0)
# Single‑message query
response = llm.invoke("What is an AI Agent?")
print(response.content)
# Multi‑turn conversation
messages = [
SystemMessage(content="You are a Python expert"),
HumanMessage(content="How to read and write files in Python?")
]
response = llm.invoke(messages)
print(response.content)4. Prompt Templates
4.1 Basic Template
# prompt_template.py
from langchain.prompts import PromptTemplate, ChatPromptTemplate
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-4", temperature=0)
# Simple template
template = PromptTemplate.from_template("Explain in {style} style: {concept}")
prompt = template.format(style="plain", concept="AI Agent")
print(prompt)
# Chat template
chat_template = ChatPromptTemplate.from_messages([
("system", "You are a {role} expert"),
("human", "{question}")
])
prompt = chat_template.format_messages(role="Python", question="What is a decorator?")
response = llm.invoke(prompt)
print(response.content)4.2 Few‑Shot Template
# few_shot_template.py
from langchain.prompts import FewShotPromptTemplate, PromptTemplate
examples = [
{"question": "1+1?", "answer": "2"},
{"question": "5*6?", "answer": "30"},
{"question": "10/2?", "answer": "5"}
]
example_template = PromptTemplate(
input_variables=["question", "answer"],
template="Question: {question}
Answer: {answer}"
)
few_shot_prompt = FewShotPromptTemplate(
examples=examples,
example_prompt=example_template,
suffix="Question: {input}",
input_variables=["input"]
)
print(few_shot_prompt.format(input="8/4?"))5. LCEL (LangChain Expression Language)
5.1 Pipeline Operations
# lcel_demo.py
from langchain_openai import ChatOpenAI
from langchain.prompts import ChatPromptTemplate
from langchain.schema.output_parser import StrOutputParser
llm = ChatOpenAI(model="gpt-4", temperature=0)
prompt = ChatPromptTemplate.from_template("Explain {concept} in {count} words")
chain = prompt | llm | StrOutputParser()
result = chain.invoke({"concept": "AI Agent", "count": 50})
print(result)5.2 Composing Multiple Chains
# chain_compose.py
from langchain_openai import ChatOpenAI
from langchain.prompts import ChatPromptTemplate
from langchain.schema.output_parser import StrOutputParser
from langchain.runnables import RunnableParallel, RunnablePassthrough
llm = ChatOpenAI(model="gpt-4", temperature=0)
setup = RunnableParallel(
summary=ChatPromptTemplate.from_template("Summarize: {text}") | llm | StrOutputParser(),
keywords=ChatPromptTemplate.from_template("Extract keywords: {text}") | llm | StrOutputParser()
)
chain = setup | (lambda x: f"Summary:
{x['summary']}
Keywords:
{x['keywords']}")
result = chain.invoke({"text": "AI Agent is an autonomous reasoning system"})
print(result)6. Memory Systems
6.1 Different Memory Types
# memory_demo.py
from langchain.memory import (
ConversationBufferMemory,
ConversationBufferWindowMemory,
ConversationSummaryMemory,
ConversationTokenBufferMemory,
)
from langchain.chains import ConversationChain
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-4", temperature=0)
# Buffer memory (stores all turns)
buffer_memory = ConversationBufferMemory()
chain = ConversationChain(llm=llm, memory=buffer_memory)
chain.predict(input="My name is Zhang San")
chain.predict(input="I am a Java engineer")
print(buffer_memory.load_memory_variables({}))
# Window memory (keeps last 2 turns)
window_memory = ConversationBufferWindowMemory(k=2)
chain2 = ConversationChain(llm=llm, memory=window_memory)
# Summary memory (auto‑summarizes long dialogs)
summary_memory = ConversationSummaryMemory(llm=llm)7. Retrieval‑Augmented Generation (RAG)
7.1 Document Loading & Splitting
# rag_basic.py
from langchain_community.document_loaders import TextLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_openai import OpenAIEmbeddings
from langchain_community.vectorstores import Chroma
loader = TextLoader("knowledge.txt", encoding="utf-8")
documents = loader.load()
text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)
docs = text_splitter.split_documents(documents)
embeddings = OpenAIEmbeddings()
vectorstore = Chroma.from_documents(docs, embeddings)
retriever = vectorstore.as_retriever(search_kwargs={"k": 3})
results = retriever.invoke("Company annual leave policy")
for doc in results:
print(doc.page_content)7.2 RAG QA Chain
# rag_qa_chain.py
from langchain.chains import RetrievalQA
from langchain_openai import ChatOpenAI
qa_chain = RetrievalQA.from_chain_type(
llm=ChatOpenAI(model="gpt-4"),
retriever=retriever,
return_source_documents=True
)
result = qa_chain.invoke("How many days of annual leave after one year?")
print(result["result"])
print(f"Sources: {[doc.metadata for doc in result['source_documents']]}" )8. Tools and Agents
8.1 Custom Tools
# custom_tool.py
from langchain.tools import tool
import requests, random
@tool
def get_weather(city: str) -> str:
"""Get weather for a city"""
weathers = {"Beijing": "Sunny 25°C", "Shanghai": "Cloudy 22°C"}
return weathers.get(city, "Unknown city")
@tool
def get_random_number(max_num: int = 100) -> str:
"""Generate a random number"""
return str(random.randint(1, max_num))
@tool
def http_get(url: str) -> str:
"""Send HTTP GET request"""
try:
resp = requests.get(url, timeout=5)
return f"Status code: {resp.status_code}"
except Exception:
return "Request failed"8.2 Creating an Agent
# create_agent.py
from langchain.agents import AgentExecutor, create_react_agent
from langchain_openai import ChatOpenAI
from langchain.tools import tool
from langchain.prompts import PromptTemplate
@tool
def get_weather(city: str) -> str:
"""Get weather"""
return f"{city}: Sunny 25°C"
@tool
def calculate(expr: str) -> str:
"""Math calculation"""
return str(eval(expr))
tools = [get_weather, calculate]
llm = ChatOpenAI(model="gpt-4", temperature=0)
REACT_PROMPT = PromptTemplate.from_template(
"""
You are an intelligent assistant that can use tools.
Available tools: {tools}
Tool names: {tool_names}
Format:
Thought: ...
Action: tool name
Action Input: ...
Observation: ...
Final Answer: ...
Question: {input}
{agent_scratchpad}
"""
)
agent = create_react_agent(llm, tools, REACT_PROMPT)
executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
result = executor.invoke({"input": "What is the weather in Beijing? Also compute 100+200"})
print(result["output"])9. Full Practical Example – Customer Service Agent
# customer_service_agent.py
import os
from dotenv import load_dotenv
from langchain.agents import AgentExecutor, create_react_agent
from langchain.tools import tool
from langchain.memory import ConversationBufferMemory
from langchain_openai import ChatOpenAI
from langchain.prompts import PromptTemplate
load_dotenv()
@tool
def query_order(order_id: str) -> str:
"""Query order status"""
orders = {"1001": "Shipped, arrives tomorrow", "1002": "Processing", "1003": "Delivered"}
return orders.get(order_id, "Order not found")
@tool
def cancel_order(order_id: str) -> str:
"""Cancel order (only if not shipped)"""
if order_id == "1002":
return f"Order {order_id} cancelled"
return f"Order {order_id} cannot be cancelled"
@tool
def get_refund_policy() -> str:
"""Get refund policy"""
return "7‑day no‑reason return, 15‑day exchange for quality issues"
@tool
def contact_human_service() -> str:
"""Transfer to human support"""
return "Connecting you to a human representative..."
def create_customer_agent():
llm = ChatOpenAI(model="gpt-4", temperature=0)
tools = [query_order, cancel_order, get_refund_policy, contact_human_service]
memory = ConversationBufferMemory(return_messages=True)
PROMPT = PromptTemplate.from_template(
"""
You are a smart customer‑service assistant that can use tools.
Chat history: {chat_history}
Available tools: {tools}
Tool names: {tool_names}
Format:
Thought: ...
Action: tool name
Action Input: ...
Observation: ...
Final Answer: ...
Question: {input}
{agent_scratchpad}
"""
)
agent = create_react_agent(llm, tools, PROMPT)
return AgentExecutor(agent=agent, tools=tools, memory=memory, verbose=True)
if __name__ == "__main__":
agent = create_customer_agent()
queries = ["Query order 1001", "Can order 1002 be cancelled?", "What is the refund policy?"]
for q in queries:
print(f"
👤 User: {q}")
result = agent.invoke({"input": q})
print(f"🤖 Agent: {result['output']}")10. LangChain vs. Native Implementation Comparison
Model Invocation : native ≈ 50 lines, LangChain ≈ 5 lines – unified interface.
Tool Integration : native ≈ 100 lines, LangChain ≈ 20 lines – automatic parsing.
Agent Loop : native ≈ 150 lines, LangChain ≈ 30 lines – ready‑to‑use.
Memory System : native ≈ 80 lines, LangChain ≈ 10 lines – multiple strategies.
RAG : native ≈ 200 lines, LangChain ≈ 30 lines – high integration.
11. Next Episode Preview
The upcoming article will cover Java‑based agents with Spring AI, compare Spring AI to LangChain, and demonstrate how to build production‑grade agent services.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Coder Trainee
Experienced in Java and Python, we share and learn together. For submissions or collaborations, DM us.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
