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.

Steps to build a state graph in LangGraph:

  1. Create /workflow.py with the LangGraph imports plus typed state schema.
    workflow.py
    from typing_extensions import NotRequired, TypedDict
     
    from langgraph.graph import END, START, StateGraph
     
     
    class WorkflowState(TypedDict):
        text: str
        word_count: NotRequired[int]
  2. Append the text-normalization node below the state schema.
    def normalize_text(state: WorkflowState):
        print("normalize_text")
        return {"text": state["text"].strip().lower()}
  3. Append the word-count node below normalize_text().
    def count_words(state: WorkflowState):
        print("count_words")
        return {"word_count": len(state["text"].split())}
  4. Append the graph builder plus node registrations below count_words().
    builder = StateGraph(WorkflowState)
    builder.add_node("normalize_text", normalize_text)
    builder.add_node("count_words", count_words)
  5. Append the fixed edges plus graph compilation below the node registrations.
    builder.add_edge(START, "normalize_text")
    builder.add_edge("normalize_text", "count_words")
    builder.add_edge("count_words", END)
    graph = builder.compile()
  6. Append the graph invocation plus final-state print below graph = builder.compile().
    result = graph.invoke(
        {"text": "  LangGraph state  "}
    )
    print(f"Final state: {result}")
  7. Run /workflow.py to confirm the nodes execute in fixed edge order and the returned state contains both updates.
    $ python3 workflow.py
    normalize_text
    count_words
    Final state: {'text': 'langgraph state', 'word_count': 2}