Structured output
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: 29 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.
A movie in four typed fields
The LangChain section of the video starts structured output with Pydantic. A Movie class inherits BaseModel and declares four fields: the title (a string), the year the movie was released (an int), the director (a string) and the rating out of 10 (a float). Each Field carries a description that tells the model which value goes where, and Pydantic checks each value against its type.
with_structured_output(Movie) wraps the model so its reply is a Movie object. Asked without the wrapper, "Provide details about the movie Inception" gets paragraphs; through the wrapper it gets four typed fields. The video's model, groq:qwen/qwen3-32b, has been retired, so the example runs on the course model. The video's prompt reads "moview", corrected here, and the video shows the result bare where this prints it:
from langchain.chat_models import init_chat_model
model = init_chat_model("groq:openai/gpt-oss-120b")
from pydantic import BaseModel, Field
class Movie(BaseModel):
title: str = Field(description="The title of the movie")
year: int = Field(description="This year the movie was released")
director: str = Field(description="The director of the movie")
rating: float = Field(description="The movies rating out of 10")
model_with_structure = model.with_structured_output(Movie)
response = model_with_structure.invoke("Provide details about the movie Inception")
print(repr(response))Movie(title='Inception', year=2010, director='Christopher Nolan', rating=8.8)
The shop's version below triages a complaint into a category and an urgency flag its code can branch on.
The with_structured_output call
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 TrueThe output schema
First describe the shape you want back. A Pydantic model lists the field names and their types.
from pydantic import BaseModel
class Triage(BaseModel): # the shape: two fields with types
category: str
urgent: boolAsking the model for that shape
Wrap the model with with_structured_output. The wrapped model reads the message and hands back a Triage object instead of text.
structured = model.with_structured_output(Triage)
result = structured.invoke("I was charged twice and I am furious")Reading the fields
Read the fields straight off the object. There is no string to parse and no wording to guess at.
print(result.category, result.urgent) # read fields directlyReading a structured result end to end
The same pieces in one file, ready to run.
from pydantic import BaseModel
from langchain.chat_models import init_chat_model
class Triage(BaseModel):
category: str
urgent: bool
model = init_chat_model("groq:openai/gpt-oss-120b", temperature=0) # uses your GROQ_API_KEY
structured = model.with_structured_output(Triage)
result = structured.invoke("I was charged twice and I am furious")
print(type(result).__name__)
print(result.category, result.urgent)Triage billing True
The model read the complaint and filled both fields itself.
Why the fields are safe to read
- You describe the shape with a Pydantic model: field names and types.
with_structured_outputreturns a model that fills that shape and hands you an object, not text.- Your node then reads
result.categorydirectly, with no parsing and no guessing at the wording.
Free text vs structured output
| Free text | Structured output | |
|---|---|---|
| What you get | A string | An object with fields |
| Your code must | Parse and hope | Read a field |
| Fails when | The wording changes | The 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.
Related
- Previous: ToolNode and tools_condition
- Next: Agent loop
- Reference: Structured output
- Add a
reasonfield toTriage. - Make a schema with an enum-like category using a Literal type.
This is what real progress feels like.