Open-Source Wikis

/

LangChain

/

Features

/

Structured output

langchain-ai/langchain

Structured output

Strategies for forcing a model's response to match a schema. Source: libs/langchain_v1/langchain/agents/structured_output.py (and BaseChatModel.with_structured_output in libs/core/langchain_core/language_models/chat_models.py).

Purpose

Plain text from a chat model is great for chat. For structured workflows — extraction, classification, agent final answers — you need typed output. LangChain offers two layers:

  1. Model-levelBaseChatModel.with_structured_output(schema) returns a runnable that emits a typed value. This works without an agent and is what most users reach for first.
  2. Agent-levelcreate_agent(..., response_format=schema) constrains the agent's final response and stores it in state["structured_response"]. This composes with multi-step tool use.

Strategies

libs/langchain_v1/langchain/agents/structured_output.py defines four:

Strategy What it does When to use
AutoStrategy (default) Picks the best available method based on the model's profile (supports_responses_api → provider strategy; otherwise tool strategy) When you don't care which method is used
ToolStrategy(schema) Binds a single tool whose parameters are the schema; parses the tool call args Universally supported
ProviderStrategy(schema) Uses the provider's native structured-output endpoint (OpenAI JSON Schema, Anthropic strict tools) Best validation, lowest token overhead
Custom ResponseFormat subclass Implement your own Rare

Schema types accepted:

  • Pydantic BaseModel subclass
  • Python @dataclass
  • TypedDict
  • Raw JSON Schema dict

The dispatch is driven by _parse_with_schema in structured_output.py, which routes based on SchemaKind ("pydantic" | "dataclass" | "typeddict" | "json_schema").

How AutoStrategy decides

graph TD
    Schema[Pydantic / dataclass / TypedDict / JSON schema]
    Profile[Model profile]
    Auto{AutoStrategy}
    Provider[ProviderStrategy]
    Tool[ToolStrategy]

    Schema --> Auto
    Profile --> Auto
    Auto -->|provider supports JSON Schema| Provider
    Auto -->|otherwise| Tool

AutoStrategy checks model.profile.supports_native_structured_output (or a provider-specific flag). When the profile data isn't loaded, the factory falls back to a hard-coded list of model name prefixes that are known to support it (gpt-5, gpt-4.1, gpt-4o, gpt-oss, o3-pro, o3-mini, grok, …) — see FALLBACK_MODELS_WITH_STRUCTURED_OUTPUT in libs/langchain_v1/langchain/agents/factory.py.

Errors

structured_output.py defines:

  • StructuredOutputError — base class.
  • MultipleStructuredOutputsError — model returned more than one structured tool call when only one was expected.
  • StructuredOutputValidationError — the tool-call arguments failed schema validation.

When using ToolStrategy, the agent loop can recover by:

  1. Catching the validation error.
  2. Adding a tool error message to the conversation.
  3. Letting the model try again.

The default error template is:

Error: {error}
 Please fix your mistakes.

defined as STRUCTURED_OUTPUT_ERROR_TEMPLATE in factory.py.

Model-level structured output

For non-agent code paths:

from pydantic import BaseModel
from langchain_openai import ChatOpenAI

class Person(BaseModel):
    name: str
    age: int

model = ChatOpenAI(model="gpt-5")
typed_model = model.with_structured_output(Person, method="function_calling")
result = typed_model.invoke("Alice is 30 years old.")
# result is Person(name="Alice", age=30)

Methods:

  • "function_calling" — bind a single tool whose schema matches the type, parse the call.
  • "json_mode" — request JSON output, parse it.
  • "json_schema" — use the provider's native JSON Schema endpoint (OpenAI's response_format={"type": "json_schema"}).

Partner-specific overrides may add others (e.g. Anthropic's tool-with-input_schema).

include_raw=True returns a dict {"raw": AIMessage, "parsed": Person | None, "parsing_error": Exception | None} instead of just the parsed value, useful when you want both the typed result and the underlying message for tracing.

Agent-level structured output

from langchain.agents import create_agent

agent = create_agent(
    model="openai:gpt-5",
    tools=[search],
    response_format=AnalysisReport,    # accepts a schema or a ResponseFormat
)

result = agent.invoke({"messages": [...]})
report: AnalysisReport = result["structured_response"]

Behind the scenes, the factory:

  1. Wraps the schema in an AutoStrategy (or uses the provided strategy).
  2. Adds the structured-output tool to the model's bound tools.
  3. Detects when the model emits the structured-output tool call and treats it as the agent's final answer.
  4. Stores the parsed value in state["structured_response"] and exits the loop.

Integration points

  • BaseChatModel.with_structured_output is the universal entry point at the model layer.
  • create_agent(response_format=...) is the agent-layer entry point.
  • Standard tests in libs/standard-tests/langchain_tests/integration_tests/ exercise structured output across providers using a common schema.
  • Partner packages override with_structured_output to dispatch to provider-native endpoints when available.

Entry points for modification

  • For a new strategy, subclass ResponseFormat in structured_output.py and handle it in factory.py's strategy selection.
  • For a new schema kind (beyond Pydantic / dataclass / TypedDict / JSON schema), extend SchemaKind and _parse_with_schema.
  • For provider-specific structured-output endpoints, implement them in the partner's with_structured_output override.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Structured output – LangChain wiki | Factory