LangChain Cheat Sheet
Build LLM applications with chains, agents, tools, retrievers, and LangGraph orchestration using the modern LangChain Expression Language.
Build a Chain with LCEL
Compose a prompt, model, and output parser using the pipe operator.
from langchain_core.prompts import ChatPromptTemplatefrom langchain_core.output_parsers import StrOutputParserfrom langchain_anthropic import ChatAnthropicprompt = ChatPromptTemplate.from_messages([ ("system", "You are a concise technical assistant."), ("human", "{question}"),])model = ChatAnthropic(model="claude-sonnet-4-5", temperature=0)chain = prompt | model | StrOutputParser()result = chain.invoke({"question": "What is a monad?"})print(result)
RAG Chain with a Retriever
Wire a vector store retriever into a chain that grounds answers in retrieved context.
from langchain_community.vectorstores import Chromafrom langchain_core.runnables import RunnablePassthroughretriever = Chroma(persist_directory="./db", embedding_function=embeddings).as_retriever(k=4)def format_docs(docs): return "\n\n".join(d.page_content for d in docs)rag_chain = ( {"context": retriever | format_docs, "question": RunnablePassthrough()} | prompt | model | StrOutputParser())answer = rag_chain.invoke("How does the refund policy work?")
Tool-Calling Agent
Bind Python functions as tools and let the model decide when to call them.
from langchain_core.tools import toolfrom langgraph.prebuilt import create_react_agent@tooldef get_weather(city: str) -> str: """Look up the current weather for a city.""" return f"It is sunny in {city}"agent = create_react_agent(model, tools=[get_weather])response = agent.invoke({"messages": [("human", "What's the weather in Austin?")]})print(response["messages"][-1].content)
Streaming Responses
Stream tokens from a chain instead of waiting for the full completion.
for chunk in chain.stream({"question": "Summarize the CAP theorem."}): print(chunk, end="", flush=True)# async streamingasync for chunk in chain.astream({"question": "Summarize the CAP theorem."}): print(chunk, end="", flush=True)
Core Building Blocks
The primary abstractions you compose to build a LangChain application.
- Runnable- unified interface (invoke/stream/batch) implemented by prompts, models, parsers
- PromptTemplate / ChatPromptTemplate- parameterized prompt with variable substitution
- Retriever- fetches relevant documents given a query string
- Memory / checkpointer- persists conversation state across turns (LangGraph)
- Tool- a callable the model can invoke with structured arguments
- LangGraph- graph-based orchestration for stateful, multi-step agents
StateGraph with a SQLite Checkpointer
Wire nodes into an explicit graph and persist thread state so runs can resume across turns.
from typing import TypedDictfrom langgraph.graph import StateGraph, ENDfrom langgraph.checkpoint.sqlite import SqliteSaverclass State(TypedDict): question: str context: str answer: strdef retrieve(state: State) -> State: state["context"] = retriever.invoke(state["question"]) return statedef generate(state: State) -> State: state["answer"] = model.invoke(state["question"]).content return stategraph = StateGraph(State)graph.add_node("retrieve", retrieve)graph.add_node("generate", generate)graph.set_entry_point("retrieve")graph.add_edge("retrieve", "generate")graph.add_edge("generate", END)checkpointer = SqliteSaver.from_conn_string(":memory:")app = graph.compile(checkpointer=checkpointer)result = app.invoke( {"question": "What is the refund window?"}, config={"configurable": {"thread_id": "user-1"}},)
Force Structured Output with Pydantic
Bind a Pydantic schema to the model so it returns a validated object instead of raw text.
from pydantic import BaseModel, Fieldclass Extraction(BaseModel): name: str = Field(description="Person's full name") age: int | None = Field(default=None, description="Age if mentioned")structured_model = model.with_structured_output(Extraction)result = structured_model.invoke("John Doe is 34 years old.")print(result.name, result.age)
RunnableParallel and RunnableBranch
Fan a single input out to multiple chains at once, or route it to one chain based on a condition.
from langchain_core.runnables import RunnableParallel, RunnableBranchsummarize = prompt_summarize | model | StrOutputParser()translate = prompt_translate | model | StrOutputParser()parallel = RunnableParallel(summary=summarize, translation=translate)outputs = parallel.invoke({"question": text})router = RunnableBranch( (lambda x: x["lang"] == "es", spanish_chain), (lambda x: x["lang"] == "fr", french_chain), default_chain,)
Retries and Model Fallbacks
Add automatic retry with backoff, then fall back to a second model if the primary keeps failing.
from langchain_anthropic import ChatAnthropicfrom langchain_openai import ChatOpenAIprimary = ChatAnthropic(model="claude-sonnet-4-5").with_retry( stop_after_attempt=3, wait_exponential_jitter=True,)backup = ChatOpenAI(model="gpt-4o-mini")resilient_model = primary.with_fallbacks([backup])response = resilient_model.invoke("Explain quicksort in one sentence.")
LangGraph Advanced Concepts
Primitives for human-in-the-loop control, fan-out, and stateful multi-agent graphs.
- interrupt()- pauses graph execution for human review; resume with Command(resume=...)
- Command- explicit control-flow object that updates state and routes to the next node in one step
- Send- fans a node out to run once per item, enabling map-reduce style parallelism
- checkpointer (sqlite/postgres)- persists thread state so a run can resume, be replayed, or time-travel to an earlier step
- graph.get_state(config) / update_state(...)- inspects or hot-patches a paused run's state before resuming
- ToolNode- prebuilt node that executes every tool call the model emits in a single step
Prefer LangGraph's create_react_agent over the older AgentExecutor for anything new — it gives you explicit state, checkpointing, and human-in-the-loop interrupts that the legacy agent classes never supported well.