Structured output lets the agent return typed, machine-readable data instead of plain text. Instead of rendering a single string, you get a structured object you can map to any UI: cards, tables, charts, step-by-step breakdowns, or domain-specific renderers.Documentation Index
Fetch the complete documentation index at: https://langchain-5e9cc07a-preview-mdrxyo-1777658790-7be347c.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
What is structured output?
Instead of returning a free-form text response, the agent uses a tool call to return a structured object conforming to a predefined schema. This gives you:- Type-safe data: parse the response into a known TypeScript type
- Precise rendering control: render each field with its own UI treatment
- Consistent formatting: every response follows the same structure regardless of the underlying model
Use cases
- Product comparisons: feature tables, pros/cons lists, ratings
- Data analysis: summaries with metrics, breakdowns, and highlights
- Step-by-step guides: ordered instructions with descriptions and code snippets
- Recipes: ingredients, steps, timings, and nutritional info
- Math and science: formulas rendered with LaTeX, step-by-step derivations
- Travel planning: itineraries with dates, locations, and cost estimates
Define a schema
Define a TypeScript type for the structured data the agent returns. The shape of this schema determines how you render the UI. Here’s an example for a recipe assistant:| Field | Type | Description |
|---|---|---|
title | string | Name of the recipe |
description | string | Short summary of the dish |
servings | number | Number of servings |
ingredients | Ingredient[] | List of ingredients with amounts and units |
steps | RecipeStep[] | Ordered preparation steps |
totalTime | string | Estimated total preparation and cooking time |
Extract structured output from messages
The structured output lives in thetool_calls array of the last AIMessage. Extract it by finding the AI message and accessing the first tool call’s arguments:
The structured output tool call may not have
args populated until the agent finishes streaming. During streaming, args may be partially populated or undefined. Always check for completeness before rendering.Set up useStream
Define a TypeScript interface matching your agent’s state schema and pass it as a type parameter to useStream for type-safe access to state values. In the examples below, replace typeof myAgent with your interface name:
Render the structured data
Once you have a typed object, build a component that maps each field to the appropriate UI element. This is the core of the pattern: turning structured data into a purpose-built interface.| Data type | Rendering strategy |
|---|---|
| Plain text | Paragraphs, headings, list items |
| Numbers/metrics | Stat cards, progress bars, badges |
| Arrays | Lists, tables, grids |
| Nested objects | Nested cards, accordion sections |
| Markdown | Markdown renderer (e.g. react-markdown) |
| LaTeX/math | KaTeX or MathJax |
| Dates/times | Formatted timestamps, relative time |
| URLs | Links, embedded previews |
Handle partial streaming data
During streaming, the tool call arguments may be incomplete JSON. Guard against this in your extraction logic:requiredFields parameter to wait until critical fields are populated before rendering:
Render progressively during streaming
Rather than waiting for the complete structured output, render fields as they arrive. This gives users immediate feedback while the agent is still generating:Reset and re-submit
To let the user submit a new query after viewing a result, add a button that starts a new thread:Best practices
- Validate before rendering: always check that required fields exist before rendering, since streaming may deliver partial data
- Use a generic extraction function: parameterize your extraction logic with a type and required fields so it works across different schemas
- Render progressively: show fields as they arrive rather than waiting for the complete object, so users see immediate feedback
- Provide fallback representations: if a field supports rich rendering (LaTeX, Markdown, charts), also include a plain-text equivalent in your schema as a fallback
- Keep schemas flat when possible: deeply nested schemas are harder to render progressively and more likely to break during partial streaming
- Match UI to data: choose the rendering strategy that best represents each field type (tables for arrays, cards for nested objects, badges for status fields)
Connect these docs to Claude, VSCode, and more via MCP for real-time answers.

