LangChain cheatsheet.
Install
pip install langchain langchain-openai langchain-community langchain-anthropic
LCEL (LangChain Expression Language)
Composable pipelines via |:
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
prompt = ChatPromptTemplate.from_messages([
("system", "You are helpful."),
("human", "{question}"),
])
llm = ChatOpenAI(model="gpt-5")
parser = StrOutputParser()
chain = prompt | llm | parser
result = chain.invoke({"question": "Hello"})
# async
result = await chain.ainvoke({"question": "Hello"})
# batch
results = chain.batch([{"question": "Hi"}, {"question": "Hey"}])
# stream
for chunk in chain.stream({"question": "Hi"}): print(chunk, end="")
Runnables
Anything with .invoke() / .batch() / .stream():
from langchain_core.runnables import RunnableLambda, RunnablePassthrough
upper = RunnableLambda(lambda x: x.upper())
chain = upper | (lambda x: x + "!")
# Parallel
from langchain_core.runnables import RunnableParallel
chain = RunnableParallel(
upper=upper,
lower=RunnableLambda(str.lower),
)
RAG with LCEL
from langchain_community.vectorstores import Chroma
from langchain_openai import OpenAIEmbeddings
vectorstore = Chroma.from_texts(texts, OpenAIEmbeddings())
retriever = vectorstore.as_retriever(k=5)
prompt = ChatPromptTemplate.from_template("""
Answer using context:
{context}
Question: {question}
""")
chain = (
{"context": retriever, "question": RunnablePassthrough()}
| prompt
| llm
| StrOutputParser()
)
answer = chain.invoke("What is X?")
Output parsers
from langchain_core.output_parsers import JsonOutputParser, PydanticOutputParser
from pydantic import BaseModel
class Result(BaseModel):
name: str
score: int
parser = PydanticOutputParser(pydantic_object=Result)
prompt = ChatPromptTemplate.from_messages([
("system", "Output as JSON."),
("human", "{q}\n\n{format_instructions}"),
]).partial(format_instructions=parser.get_format_instructions())
chain = prompt | llm | parser
result: Result = chain.invoke({"q": "..."})
Memory
from langchain_core.runnables.history import RunnableWithMessageHistory
from langchain_community.chat_message_histories import ChatMessageHistory
store = {}
def get_session_history(session_id: str):
if session_id not in store:
store[session_id] = ChatMessageHistory()
return store[session_id]
with_history = RunnableWithMessageHistory(
chain,
get_session_history,
input_messages_key="question",
history_messages_key="history",
)
with_history.invoke(
{"question": "Hi, my name is Alice"},
config={"configurable": {"session_id": "user-1"}},
)
Document loaders
from langchain_community.document_loaders import (
TextLoader, PyPDFLoader, WebBaseLoader, DirectoryLoader,
UnstructuredMarkdownLoader, GitLoader,
)
docs = TextLoader("file.txt").load()
docs = PyPDFLoader("file.pdf").load_and_split()
docs = WebBaseLoader("https://example.com").load()
Text splitters
from langchain.text_splitter import RecursiveCharacterTextSplitter
splitter = RecursiveCharacterTextSplitter(
chunk_size=500,
chunk_overlap=50,
separators=["\n\n", "\n", " ", ""],
)
chunks = splitter.split_documents(docs)
Vector stores
from langchain_community.vectorstores import Chroma, Qdrant, FAISS, Pinecone
from langchain_openai import OpenAIEmbeddings
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
# Persistent
db = Chroma.from_documents(chunks, embeddings, persist_directory="./db")
db = Chroma(persist_directory="./db", embedding_function=embeddings)
Tool / agent
from langchain_core.tools import tool
from langgraph.prebuilt import create_react_agent
@tool
def search(query: str) -> str:
"""Search the web."""
return "results..."
agent = create_react_agent(model=llm, tools=[search])
result = agent.invoke({"messages": [{"role": "user", "content": "Find info on X"}]})
Streaming events
async for event in chain.astream_events(input, version="v2"):
if event["event"] == "on_chat_model_stream":
print(event["data"]["chunk"].content, end="")
Configurable
from langchain_core.runnables import ConfigurableField
llm = ChatOpenAI().configurable_fields(
model_name=ConfigurableField(id="model"),
temperature=ConfigurableField(id="temperature"),
)
# Override at runtime
result = chain.invoke(input, config={"configurable": {"model": "gpt-5", "temperature": 0}})
LangSmith (tracing)
export LANGCHAIN_TRACING_V2=true
export LANGCHAIN_API_KEY=...
Traces all chain runs. Helps debug.
When NOT to use LangChain
- Simple LLM call.
- One tool, one model.
- You want fine control over messages.
Just use the LLM SDK directly. LangChain shines when chaining many components.
Alternative: LlamaIndex
For RAG-heavy apps:
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader
docs = SimpleDirectoryReader("./data").load_data()
index = VectorStoreIndex.from_documents(docs)
engine = index.as_query_engine()
print(engine.query("What is X?"))
Common mistakes
- Over-using abstractions when SDK call would do.
- Different versions of langchain packages → import hell.
- LCEL pipes that obscure flow.
- Memory not scoped per user → mixed conversations.
- Forgetting to set tracing in prod (debugging hell later).
Read this next
If you want my LangChain RAG template, it’s at rajpoot.dev .
Building something AI-, backend-, or data-heavy and want a second pair of eyes? I do consulting and freelance work — see my projects and ways to reach me at rajpoot.dev .