LangChain: Glue Code for the AI Era
ai python
LangChain emerged as the standard framework for building LLM applications. It provides the building blocks to chain together prompts, models, and tools. Here’s how to use it.
Why LangChain
Building LLM apps requires:
- Prompt management
- Model switching
- Memory across conversations
- Tool integration
- Document processing
- Chain orchestration
LangChain provides all of this.
Installation
pip install langchain langchain-openai
Basic Chains
Simple Chain
from langchain_openai import ChatOpenAI
from langchain.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
# Components
model = ChatOpenAI(model="gpt-3.5-turbo")
prompt = ChatPromptTemplate.from_template("Explain {topic} in simple terms.")
parser = StrOutputParser()
# Chain
chain = prompt | model | parser
# Run
result = chain.invoke({"topic": "neural networks"})
Sequential Chains
# Chain outputs become inputs to next chain
summary_prompt = ChatPromptTemplate.from_template(
"Summarize this text: {text}"
)
translation_prompt = ChatPromptTemplate.from_template(
"Translate to Spanish: {summary}"
)
summarize = summary_prompt | model | StrOutputParser()
translate = translation_prompt | model | StrOutputParser()
# Compose
full_chain = (
{"summary": summarize}
| RunnablePassthrough.assign(translated=translate)
)
Prompt Templates
Basic
from langchain.prompts import PromptTemplate
template = PromptTemplate.from_template("""
You are a {role}. Answer the following question:
Question: {question}
Answer in a {style} style.
""")
prompt = template.format(
role="Python expert",
question="What are decorators?",
style="concise"
)
With Examples (Few-Shot)
from langchain.prompts import FewShotPromptTemplate
examples = [
{"input": "cat", "output": "animal"},
{"input": "desk", "output": "furniture"},
{"input": "python", "output": "programming language"},
]
example_prompt = PromptTemplate.from_template(
"Input: {input}\nOutput: {output}"
)
few_shot = FewShotPromptTemplate(
examples=examples,
example_prompt=example_prompt,
prefix="Categorize the following:",
suffix="Input: {input}\nOutput:",
input_variables=["input"]
)
Memory
Conversation Buffer
from langchain.memory import ConversationBufferMemory
from langchain.chains import ConversationChain
memory = ConversationBufferMemory()
conversation = ConversationChain(llm=model, memory=memory)
conversation.run("Hi, I'm building a web app")
# AI remembers this context
conversation.run("What framework should I use?")
# Responds knowing you're building a web app
Summary Memory
from langchain.memory import ConversationSummaryMemory
# Summarizes older messages to save tokens
memory = ConversationSummaryMemory(llm=model)
Vector Store Memory
from langchain.memory import VectorStoreRetrieverMemory
from langchain.vectorstores import Chroma
vectorstore = Chroma(embedding_function=OpenAIEmbeddings())
memory = VectorStoreRetrieverMemory(
retriever=vectorstore.as_retriever()
)
Document Loading
from langchain.document_loaders import (
TextLoader,
PDFLoader,
WebBaseLoader,
UnstructuredMarkdownLoader
)
# Load various sources
text_docs = TextLoader("file.txt").load()
pdf_docs = PDFLoader("document.pdf").load()
web_docs = WebBaseLoader("https://example.com").load()
md_docs = UnstructuredMarkdownLoader("README.md").load()
Splitting
from langchain.text_splitter import RecursiveCharacterTextSplitter
splitter = RecursiveCharacterTextSplitter(
chunk_size=1000,
chunk_overlap=200
)
chunks = splitter.split_documents(documents)
RAG Pattern
from langchain.vectorstores import Chroma
from langchain_openai import OpenAIEmbeddings
from langchain.chains import RetrievalQA
# Create vector store
embeddings = OpenAIEmbeddings()
vectorstore = Chroma.from_documents(chunks, embeddings)
# Create retrieval chain
qa_chain = RetrievalQA.from_chain_type(
llm=model,
chain_type="stuff",
retriever=vectorstore.as_retriever()
)
# Query
answer = qa_chain.run("What is the refund policy?")
Tools and Agents
Define Tools
from langchain.tools import tool
@tool
def search_database(query: str) -> str:
"""Search the internal database for information."""
# Actual database search
return "Results: ..."
@tool
def calculate(expression: str) -> str:
"""Evaluate a mathematical expression."""
return str(eval(expression))
Create Agent
from langchain.agents import create_react_agent, AgentExecutor
from langchain import hub
# Get a prompt from the hub
prompt = hub.pull("hwchase17/react")
# Create agent
agent = create_react_agent(model, [search_database, calculate], prompt)
agent_executor = AgentExecutor(agent=agent, tools=[search_database, calculate])
# Run
result = agent_executor.invoke({
"input": "What's the total revenue from the database divided by 12?"
})
Structured Output
from langchain_core.pydantic_v1 import BaseModel, Field
class MovieReview(BaseModel):
title: str = Field(description="Movie title")
rating: int = Field(description="Rating 1-10")
summary: str = Field(description="Brief review")
structured_llm = model.with_structured_output(MovieReview)
result = structured_llm.invoke("Review the movie Inception")
# Returns MovieReview object
Callbacks and Tracing
from langchain.callbacks import StdOutCallbackHandler
# See what's happening
handler = StdOutCallbackHandler()
result = chain.invoke(
{"topic": "databases"},
config={"callbacks": [handler]}
)
# Or use LangSmith for production tracing
import os
os.environ["LANGCHAIN_TRACING_V2"] = "true"
os.environ["LANGCHAIN_API_KEY"] = "..."
LCEL (LangChain Expression Language)
The modern way to compose chains:
from langchain_core.runnables import RunnableParallel, RunnableLambda
# Parallel execution
parallel = RunnableParallel({
"summary": summary_chain,
"keywords": keyword_chain
})
# Custom functions
def format_output(data):
return f"Summary: {data['summary']}\nKeywords: {data['keywords']}"
full_chain = parallel | RunnableLambda(format_output)
Common Patterns
Chat with Documents
from langchain.chains import ConversationalRetrievalChain
chain = ConversationalRetrievalChain.from_llm(
llm=model,
retriever=vectorstore.as_retriever(),
memory=ConversationBufferMemory(
memory_key="chat_history",
return_messages=True
)
)
chain.invoke({"question": "What does the document say about pricing?"})
Summarization
from langchain.chains.summarize import load_summarize_chain
chain = load_summarize_chain(model, chain_type="map_reduce")
summary = chain.run(long_documents)
When to Use LangChain
Good Fit
- RAG applications
- Complex multi-step chains
- Agent-based systems
- Rapid prototyping
Consider Alternatives
- Simple API calls (just use the SDK)
- High-performance production (may need optimization)
- When you need fine-grained control
Final Thoughts
LangChain is the React of LLM applications—opinionated, comprehensive, and widely adopted. It’s not always necessary, but knowing it makes you effective quickly.
Start with the basics, add complexity as needed.
Build LLM apps with standard building blocks.