LangGraph Agents

Course Content

LangGraph Agents

7 sections · 49 lessons

How do you handle node output formats and enforce structured state updates?


A blurred policy number, caught before payoutextract with aPydantic schemapattern checkfails: POL-12345error written tostate, not raisedrepair withthe exacterror, max 2still bad:human_reviewAbout 6% of bills fail; half are fixed on the second try.
Turning a validation failure into a routed state change keeps bad fields out of the database without crashing the run.

What you need to know

Python
from typing import Literalfrom pydantic import BaseModel, Field, ValidationErrorfrom langchain_core.exceptions import OutputParserExceptionclass ClaimFields(BaseModel):    policy_number: str = Field(pattern=r"^POL-\d{6}$")    amount_inr: int = Field(gt=0, le=5_000_000)    category: Literal["hospital", "pharmacy", "diagnostics"]def extract(state: dict) -> dict:    try:        f = llm.with_structured_output(ClaimFields).invoke(state["claim_text"])        return {"fields": f.model_dump(), "error": None}    except (ValidationError, OutputParserException) as e:        return {"error": str(e), "attempts": state["attempts"] + 1}def after_extract(state: dict) -> str:    if state["error"] is None:        return "score"    return "repair" if state["attempts"] < 2 else "human_review"

What happens at each layer

  • The model — with_structured_output sends the Pydantic schema to the provider (tool calling or native JSON schema mode) and parses the reply into a ClaimFields object.
  • The node — validation errors become data in state, not a crashed run.
  • The edge — reads error and attempts and picks score, repair or a human.

Three facts about node returns

  1. Only returned keys change. Everything else keeps its value.
  2. Keys that are not in the schema are silently ignored — a typo loses data without an error. Unit-test node outputs.
  3. With a Pydantic state schema, a wrong type written by one node fails validation when the next node reads it.

Keep types apart

  • messages — for the model to read.
  • fields, documents — artifacts for other nodes.
  • route, error, attempts — decisions for edges.

A real-life example

A claim-intake graph extracts fields from photos of hospital bills. About 6% of bills have a blurred policy number, so the model returns "POL-12345" (five digits). The Pydantic pattern rejects it; the node writes the error; the edge sends it to repair, which re-prompts with the exact error and a crop of the header area. Half of those are fixed on the second try; the rest go to human_review after two attempts. Before this design, bad policy numbers reached the database and failed a day later at payout.

Follow-up questions to expect

  • "Structured output or JSON mode?" — Structured output with a schema. JSON mode only guarantees valid JSON, not your fields and types.
  • "Why not just raise and let retry handle it?" — A retry policy repeats the same call. A validation failure needs a different prompt with the error in it, so it is a route, not a retry.
  • "How does create_agent do this?" — Pass response_format=YourModel; the final structured result appears under structured_response in the output.