01. What is LangGraph?
LangGraph is a library built on top of LangChain that adds graph-based execution semantics to chains. The difference matters: a LangChain chain is an linear sequence of steps; a LangGraph application is a directed graph where any node can point to any other node, execution state is preserved between steps, and the graph can fork, loop, wait for human input, or terminate based on conditions. This model maps cleanly onto agentic pipelines where an agent decides what to do next, calls a tool, observes the result, then decides again.
The core primitives are: StateGraph (the container), add_node (attach a callable to the graph), add_edge (define a hard transition between nodes), add_conditional_edges (route based on state), and compile() which produces a runnable CompiledGraph. The compiled graph exposes a .invoke() method for synchronous execution and a .stream() method for token-level output streaming. Every invoke call takes an initial state dict and returns a final state dict after traversal.
LangGraph ships a built-in checkpointing layer so state survives crashes. It also ships a Command object that lets code inside any node redirect graph execution to arbitrary nodes—effectively a programmatic goto. Finally, it has first-class support for multi-agent patterns via subgraphs and shared state channels.
# Minimal working LangGraph app
from langgraph.graph import StateGraph, START, END
from typing import TypedDict
class AgentState(TypedDict):
messages: list[str]
def node_a(state: AgentState) -> AgentState:
return {"messages": state["messages"] + ["node_a executed"]}
builder = StateGraph(AgentState)
builder.add_node("a", node_a)
builder.add_edge(START, "a")
builder.add_edge("a", END)
graph = builder.compile()
result = graph.invoke({"messages": []})
print(result["messages"]) # ['node_a executed']
The failure mode to watch: if you forget to call compile() and try to invoke the builder directly, Python raises AttributeError: 'StateGraph' object has no attribute 'invoke'. Another common mistake is returning a partial state dict from a node—in strict mode, the returned dict must contain every key in your TypedDict schema, or LangGraph raises a ValueError about missing keys. Always return the full state or use the state_update shorthand pattern.
Create a three-node graph where START → node_b → node_c → END, compile it, and confirm that invoke() traverses all three nodes by reading the final state message list in a notebook cell.