AI
LangChain
Build LLM-powered applications with chains, agents, RAG pipelines, and memory using LangChain.
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
| Abstraction | Role |
|---|---|
Runnable | Base interface: .invoke(), .stream(), .batch() |
ChatPromptTemplate | Structured prompt builder |
BaseChatModel | LLM provider wrapper |
BaseOutputParser | Transform raw LLM output |
BaseRetriever | Fetch relevant documents |
BaseTool | Function callable by agents |
RunnableParallel | Run multiple runnables simultaneously |
RunnableWithMessageHistory | Wrap a chain with session memory |