LangGraph Agents

Course Content

LangGraph Agents

7 sections · 49 lessons

What is StateGraph, and why does it require a state schema?


What you need to know

What the schema decides

  • Merging — messages: Annotated[list, add_messages] appends; route: str overwrites.
  • Parallel safety — two nodes writing an overwrite channel in the same super-step raise InvalidUpdateError; a reducer channel merges them.
  • Checkpoints — the schema is what gets saved, so it doubles as the persistence format.
  • Documentation — anyone can read the agent's working memory in one class.

Schema types

  • TypedDict — fast, the common default, type hints only.
  • Pydantic BaseModel — validates values at runtime; a node that writes amount="lots" into an int field fails when the next node reads it. Slower.
  • dataclass — lets you set default values.

Input and output schemas

Python
class ClaimIn(TypedDict):    claim_text: strclass ClaimOut(TypedDict):    decision: strclass ClaimState(TypedDict):    claim_text: str    extracted: dict        # internal    fraud_notes: str       # internal    decision: strbuilder = StateGraph(ClaimState, input_schema=ClaimIn, output_schema=ClaimOut)

The caller sends only claim_text and receives only decision. The fraud notes stay inside.

The second argument to StateGraph is context_schema, for run-time values that are not state, such as a user id or a database handle. It replaced the older config_schema.

A real-life example

An insurance claim graph is exposed as an API to the mobile app. In the first version, the output was the whole state, and a tester noticed the raw fraud_notes field — "high risk, similar claim from same hospital in May" — in the app's network log. Adding output_schema=ClaimOut fixed it in one line. The team then added a Pydantic model for the extracted artifact, which caught an OCR bug writing "12,500" as a string into an integer claim_amount.

Follow-up questions to expect

  • "Can two graphs share one schema?" — Yes, and subgraphs that share keys with the parent can be added directly as nodes.
  • "Why not pass everything in one untyped dict?" — You lose merge rules, parallel-write detection and any type checking; bugs appear as silent overwrites.
  • "What is MessagesState?" — A prebuilt schema with a single messages key using add_messages. You can subclass it to add keys.