LangGraphLangGraph 1.2 · Python 3.10+
0%
1
Curious builder0 XP earned · 300 to level 2
0 daysFinish a lesson to begin
Badge collection0 of 6 unlocked
38 small wins to finish your pathNext lesson →

Structured output: answers in a fixed shape

model.with_structured_output(Schema) makes the model return data in a shape you define, not free text, so your code gets fields it can trust instead of a string to parse.

Last updated: 27 Sep, 2026 · LangChain 1.4

A model's reply is text, worded differently every time. When a node needs a decision your code will act on, such as a category and whether a ticket is urgent, you want a fixed shape, not a sentence.

The with_structured_output call

python
from pydantic import BaseModel

class Triage(BaseModel):
    category: str
    urgent: bool

structured = model.with_structured_output(Triage)
result = structured.invoke("I was charged twice and I am furious")
print(result.category, result.urgent)   # -> billing True

The output schema

First describe the shape you want back. A Pydantic model lists the field names and their types.

python
from pydantic import BaseModel

class Triage(BaseModel):   # the shape: two fields with types
    category: str
    urgent: bool

An object of that shape

with_structured_output hands back an object of this type. To show what a node receives without calling a real model, build one Triage directly.

python
# what with_structured_output gives back is an object of this type
result = Triage(category="billing", urgent=True)

Reading the fields

Read the fields straight off the object. There is no string to parse and no wording to guess at.

python
print(result.category, result.urgent)   # read fields directly

Reading a structured result end to end

The same pieces in one file, ready to run.

Example
from pydantic import BaseModel

class Triage(BaseModel):
    category: str
    urgent: bool

# what with_structured_output gives back is an object of this type
result = Triage(category="billing", urgent=True)
print(result.category, result.urgent)

With a real model, structured = model.with_structured_output(Triage) and then structured.invoke(...) hands back exactly this kind of Triage object, so your node reads result.category and result.urgent the same way.

Why the fields are safe to read

  • You describe the shape with a Pydantic model: field names and types.
  • with_structured_output returns a model that fills that shape and hands you an object, not text.
  • Your node then reads result.category directly, with no parsing and no guessing at the wording.

Free text vs structured output

Free textStructured output
What you getA stringAn object with fields
Your code mustParse and hopeRead a field
Fails whenThe wording changesThe model cannot fit the schema

Where structured output fits

  • Classifying a ticket into a category your code branches on.
  • Extracting fields (an order id, a date, a yes or no) the next node needs.
Watch out. Keep the schema small and the field names clear; the model reads them. A giant schema with vague names is the main reason structured output comes back wrong.
Try it yourself
  • Add a reason field to Triage.
  • Make a schema with an enum-like category using a Literal type.

This is what real progress feels like.