A multi-step Python workflow is easier to reason about when every operation has an explicit state transition instead of disappearing inside one long function. LangGraph models that structure as nodes connected by edges, so a small graph makes execution order and shared state visible before models, persistence, or branching enter the design.
The StateGraph class accepts a state schema that defines the keys available to every node. Each node receives the current state, returns only the keys it changes, and leaves LangGraph to merge those updates before the next edge runs.
A model-free graph keeps the first build credential-free. One node normalizes text, the next reads that update to count words, and the final invocation returns both state fields. Seeing both node names before the final dictionary confirms the fixed edge order as well as the shared-state handoff.
Related: How to install LangGraph with pip
from typing_extensions import NotRequired, TypedDict from langgraph.graph import END, START, StateGraph class WorkflowState(TypedDict): text: str word_count: NotRequired[int]
def normalize_text(state: WorkflowState): print("normalize_text") return {"text": state["text"].strip().lower()}
def count_words(state: WorkflowState): print("count_words") return {"word_count": len(state["text"].split())}
builder = StateGraph(WorkflowState) builder.add_node("normalize_text", normalize_text) builder.add_node("count_words", count_words)
builder.add_edge(START, "normalize_text") builder.add_edge("normalize_text", "count_words") builder.add_edge("count_words", END) graph = builder.compile()
result = graph.invoke( {"text": " LangGraph state "} ) print(f"Final state: {result}")
$ python3 workflow.py
normalize_text
count_words
Final state: {'text': 'langgraph state', 'word_count': 2}