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:

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

Consider Alternatives

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.

All posts