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 .