AI

LangChain

Build LLM-powered applications with chains, agents, RAG pipelines, and memory using LangChain.

#langchain #ai #llm #rag #agents #python #embeddings #vectorstore

Installation

# Core library
pip install langchain langchain-openai langchain-community

# Vector stores
pip install faiss-cpu             # FAISS (in-memory, fast)
pip install chromadb              # ChromaDB (persistent)
pip install langchain-chroma

# Document loaders and splitters
pip install pypdf unstructured

# Optional: LangSmith tracing
pip install langsmith

LLM Providers

OpenAI

from langchain_openai import ChatOpenAI

llm = ChatOpenAI(
    model="[model]",
    api_key="[api_key]",
    temperature=0.0,
    max_tokens=1024,
)

response = llm.invoke("What is a Kubernetes pod?")
print(response.content)

Anthropic Claude

from langchain_anthropic import ChatAnthropic

llm = ChatAnthropic(
    model="claude-opus-4-5",
    api_key="[api_key]",
    temperature=0.0,
)

response = llm.invoke("Explain Rust ownership in one paragraph.")
print(response.content)

Ollama (Local)

from langchain_ollama import ChatOllama

llm = ChatOllama(
    model="llama3.2",
    base_url="http://localhost:11434",
    temperature=0.1,
)

response = llm.invoke("Summarize this in 3 bullet points: ...")
print(response.content)

Prompt Templates

ChatPromptTemplate

from langchain_core.prompts import ChatPromptTemplate

prompt = ChatPromptTemplate.from_messages([
    ("system", "You are an expert in {domain}. Be concise and practical."),
    ("human",  "{question}"),
])

chain = prompt | llm
response = chain.invoke({"domain": "Rust", "question": "What is the borrow checker?"})
print(response.content)

Few-Shot Prompt

from langchain_core.prompts import FewShotChatMessagePromptTemplate, ChatPromptTemplate

examples = [
    {"input": "Paris, France",  "output": "Capital of France. Population ~2.1M. On the Seine."},
    {"input": "Berlin, Germany","output": "Capital of Germany. Population ~3.7M. On the Spree."},
]

example_prompt = ChatPromptTemplate.from_messages([
    ("human", "{input}"), ("ai", "{output}")
])

few_shot = FewShotChatMessagePromptTemplate(
    examples=examples,
    example_prompt=example_prompt,
)

final_prompt = ChatPromptTemplate.from_messages([
    ("system", "Summarise cities in one sentence."),
    few_shot,
    ("human", "{input}"),
])

chain = final_prompt | llm
print(chain.invoke({"input": "Tokyo, Japan"}).content)

Chains (LCEL)

LangChain Expression Language (LCEL) uses the | pipe operator to compose components.

Basic Chain

from langchain_core.output_parsers import StrOutputParser

chain = prompt | llm | StrOutputParser()

result = chain.invoke({"domain": "networking", "question": "What is BGP?"})
print(result)  # plain string

Sequential Chain

summary_prompt = ChatPromptTemplate.from_template("Summarise: {text}")
translate_prompt = ChatPromptTemplate.from_template("Translate to Spanish: {summary}")

parser = StrOutputParser()

chain = (
    summary_prompt
    | llm
    | parser
    | (lambda x: {"summary": x})
    | translate_prompt
    | llm
    | parser
)

print(chain.invoke({"text": "Rust uses a borrow checker to enforce memory safety at compile time..."}))

Streaming Output

for chunk in chain.stream({"domain": "Linux", "question": "Explain systemd units."}):
    print(chunk, end="", flush=True)

Parallel Execution (RunnableParallel)

from langchain_core.runnables import RunnableParallel

parallel = RunnableParallel(
    summary=summary_chain,
    keywords=keyword_chain,
)

result = parallel.invoke({"text": "..."})
print(result["summary"])
print(result["keywords"])

Output Parsers

JSON Output Parser

from langchain_core.output_parsers import JsonOutputParser
from pydantic import BaseModel, Field

class ReviewResult(BaseModel):
    risk_level:  str = Field(description="low, medium, or high")
    issues:      list[str] = Field(description="List of identified issues")
    approved:    bool = Field(description="Whether the code is approved")

parser = JsonOutputParser(pydantic_object=ReviewResult)

prompt = ChatPromptTemplate.from_messages([
    ("system", "You are a code reviewer. {format_instructions}"),
    ("human",  "Review this code:\n{code}"),
]).partial(format_instructions=parser.get_format_instructions())

chain = prompt | llm | parser
result = chain.invoke({"code": "fn main() { let x = vec![1,2,3]; println!(\"{:?}\", x); }"})
print(result.risk_level)

Retrieval-Augmented Generation (RAG)

Load and Split Documents

from langchain_community.document_loaders import PyPDFLoader, TextLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter

# Load
loader = PyPDFLoader("docs/manual.pdf")
docs = loader.load()

# Split into chunks
splitter = RecursiveCharacterTextSplitter(
    chunk_size=1000,
    chunk_overlap=150,
)
chunks = splitter.split_documents(docs)
print(f"Split into {len(chunks)} chunks")

Build a Vector Store

from langchain_openai import OpenAIEmbeddings
from langchain_chroma import Chroma

embeddings = OpenAIEmbeddings(model="text-embedding-3-large")

# Create and persist
vectorstore = Chroma.from_documents(
    documents=chunks,
    embedding=embeddings,
    persist_directory="./chroma_db",
)

# Load existing
vectorstore = Chroma(
    persist_directory="./chroma_db",
    embedding_function=embeddings,
)

Similarity Search

results = vectorstore.similarity_search("How does memory safety work?", k=4)
for doc in results:
    print(doc.page_content[:200])
    print("---")

RAG Chain

from langchain_core.runnables import RunnablePassthrough
from langchain_core.output_parsers import StrOutputParser

retriever = vectorstore.as_retriever(search_kwargs={"k": 5})

rag_prompt = ChatPromptTemplate.from_messages([
    ("system", "Answer using only the provided context. If unsure, say you don't know.\n\nContext:\n{context}"),
    ("human",  "{question}"),
])

def format_docs(docs):
    return "\n\n".join(d.page_content for d in docs)

rag_chain = (
    {"context": retriever | format_docs, "question": RunnablePassthrough()}
    | rag_prompt
    | llm
    | StrOutputParser()
)

answer = rag_chain.invoke("What are the main security features?")
print(answer)

Memory / Conversation History

In-Memory History

from langchain_core.chat_history import InMemoryChatMessageHistory
from langchain_core.runnables.history import RunnableWithMessageHistory

store = {}

def get_session_history(session_id: str):
    if session_id not in store:
        store[session_id] = InMemoryChatMessageHistory()
    return store[session_id]

prompt = ChatPromptTemplate.from_messages([
    ("system",       "You are a helpful assistant."),
    ("placeholder",  "{history}"),
    ("human",        "{question}"),
])

chain = prompt | llm | StrOutputParser()

with_history = RunnableWithMessageHistory(
    chain,
    get_session_history,
    input_messages_key="question",
    history_messages_key="history",
)

config = {"configurable": {"session_id": "user-123"}}

print(with_history.invoke({"question": "What is Rust?"}, config=config))
print(with_history.invoke({"question": "Give me an example."}, config=config))

Agents & Tools

Built-in Tools

from langchain_community.tools import DuckDuckGoSearchRun, WikipediaQueryRun
from langchain_community.utilities import WikipediaAPIWrapper

search = DuckDuckGoSearchRun()
wiki   = WikipediaQueryRun(api_wrapper=WikipediaAPIWrapper())

print(search.invoke("latest Linux kernel version"))

Custom Tool

from langchain_core.tools import tool

@tool
def get_file_lines(filepath: str) -> str:
    """Count the number of lines in a file. Input is an absolute file path."""
    try:
        with open(filepath) as f:
            return str(sum(1 for _ in f))
    except FileNotFoundError:
        return f"File not found: {filepath}"

ReAct Agent

from langchain.agents import create_react_agent, AgentExecutor
from langchain import hub

tools = [search, wiki, get_file_lines]
react_prompt = hub.pull("hwchase17/react")

agent = create_react_agent(llm=llm, tools=tools, prompt=react_prompt)
executor = AgentExecutor(agent=agent, tools=tools, verbose=True, max_iterations=5)

result = executor.invoke({"input": "Find the latest Rust stable release and summarise its key changes."})
print(result["output"])

LangSmith Tracing

Monitor, debug, and evaluate chains and agents:

export LANGSMITH_API_KEY="your_key"
export LANGSMITH_PROJECT="my-project"
export LANGSMITH_TRACING=true
# No code changes needed — all runs are automatically traced
result = rag_chain.invoke("What is memory safety?")

Key Abstractions

AbstractionRole
RunnableBase interface: .invoke(), .stream(), .batch()
ChatPromptTemplateStructured prompt builder
BaseChatModelLLM provider wrapper
BaseOutputParserTransform raw LLM output
BaseRetrieverFetch relevant documents
BaseToolFunction callable by agents
RunnableParallelRun multiple runnables simultaneously
RunnableWithMessageHistoryWrap a chain with session memory

Resources