LangGraph exposes four streaming modes off a single graph.stream() call, each surfacing a different slice of execution state. Whether you need a full snapshot per node, lightweight deltas, token-by-token LLM output, or raw structured execution logs, there's a mode that fits — and picking the wrong one either floods your UI with redundant data or costs you incremental rendering latency. This post walks through all four using a real intent-classifier routing graph (classify → finance / HR / technical / others) as the running example, so you can see the exact output shape each mode produces.
Code Snippet
from langgraph.graph import MessagesState, StateGraph, START, END from langgraph.checkpoint.memory import InMemorySaver from langchain_core.messages import HumanMessage # Shared setup: graph + checkpointer + thread config checkpointer = InMemorySaver() graph = wf_builder.compile(checkpointer=checkpointer) _config = {"configurable": {"thread_id": "usr-classify-001"}} # ── Mode 1: values ─────────────────────────────────────────────────────────── # Emits the FULL state dict after every node fires. # Shape: complete MsgState snapshot — safe to re-render the whole UI from it. for chunk in graph.stream({"messages": HumanMessage(query)}, config=_config, stream_mode="values"): print(chunk) # {'messages': [...], 'intent': 'technical'} # ── Mode 2: updates ────────────────────────────────────────────────────────── # Emits ONLY the fields each node returned — the delta, not the full state. # Shape: {node_name: partial_state_dict} for chunk in graph.stream({"messages": HumanMessage(query)}, config=_config, stream_mode="updates"): print(chunk) # {'classify_process': {'intent': 'hr'}} # ── Mode 3: messages ───────────────────────────────────────────────────────── # Token-level LLM streaming with per-message metadata. # Shape: (AIMessageChunk, metadata_dict) — unpack .content for incremental text. for chunk, metadata in graph.stream({"messages": HumanMessage(query)}, config=_config, stream_mode="messages"): print(chunk.content, end="") # stream tokens as they arrive # ── Mode 4: debug ──────────────────────────────────────────────────────────── # Structured execution-trace logs — task start/finish events + node metadata. # Shape: raw dict — for observability pipelines, never end-user UI. for log in graph.stream({"messages": HumanMessage(query)}, config=_config, stream_mode="debug"): print(log)

No comments:
Post a Comment