From 5392d418d46f62e7317319dcb1295135624ef23e Mon Sep 17 00:00:00 2001 From: Aaron Farntrog Date: Thu, 23 Oct 2025 10:58:05 -0400 Subject: [PATCH 1/4] docs: add documentation for the new structured output approach --- .../concepts/agents/structured-output.md | 323 +++++++++++++----- 1 file changed, 231 insertions(+), 92 deletions(-) diff --git a/docs/user-guide/concepts/agents/structured-output.md b/docs/user-guide/concepts/agents/structured-output.md index 967a0c8b..692b0030 100644 --- a/docs/user-guide/concepts/agents/structured-output.md +++ b/docs/user-guide/concepts/agents/structured-output.md @@ -1,26 +1,14 @@ # Structured Output -Structured output enables you to get type-safe, validated responses from language models using Pydantic models. Instead of receiving raw text that you need to parse, you can define the exact structure you want and receive a validated Python object that matches your schema. This transforms unstructured LLM outputs into reliable, program-friendly data structures that integrate seamlessly with your application's type system and validation rules. +Structured output enables you to get type-safe, validated responses from language models using [Pydantic](https://docs.pydantic.dev/latest/concepts/models/) models. Instead of receiving raw text that you need to parse, you can define the exact structure you want and receive a validated Python object that matches your schema. This transforms unstructured LLM outputs into reliable, program-friendly data structures that integrate seamlessly with your application's type system and validation rules. -## What is Structured Output? - -Structured output allows you to constrain language model responses to follow a specific schema defined by a [Pydantic](https://docs.pydantic.dev/latest/concepts/models/) model. This ensures responses are properly formatted, validated, and type-safe, eliminating the need for manual parsing of text responses. ```mermaid flowchart LR - A[Pydantic Model] --> B[Agent.structured_output] - - subgraph Process[" "] - direction TB - C[convert_pydantic_to_tool_spec] --> D[LLM Response] - end - - B --> Process - Process --> E[Validated Pydantic Model] + A[Pydantic Model] --> B[Agent Invocation] + B --> C[LLM] --> D[Validated Pydantic Model] + D --> E[AgentResult.structured_output] ``` - -*The conversion to tool spec happens behind the scenes* - Key benefits: - **Type Safety**: Get typed Python objects instead of raw strings @@ -31,9 +19,9 @@ Key benefits: ## How It Works -The structured output system converts your Pydantic models into tool specifications that guide the language model to produce correctly formatted responses. Various model providers supported in Strands Agents sdk-python can work with these specifications, with some supporting Pydantic `BaseModel` directly. +The structured output system converts your Pydantic models into tool specifications that guide the language model to produce correctly formatted responses. All of the model providers supported in Strands can work with Structured Output. -Strands handles this through the [`Agent.structured_output()`](../../../api-reference/agent.md#strands.agent.agent.Agent.structured_output) method, which manages the conversion, validation, and response processing automatically. +Strands handles this by accepting the `structured_output_model` parameter to agent invocations, which manages the conversion, validation, and response processing automatically. The validated result is available in the `AgentResult.structured_output` field. ## Usage @@ -43,26 +31,18 @@ Define your desired output structure using Pydantic models: from pydantic import BaseModel, Field from typing import Optional, List -class WeatherForecast(BaseModel): - """Complete weather forecast information.""" - location: str = Field(description="The location for this forecast") - current_time: str = Field(description="Current time in HH:MM format") - current_weather: str = Field(description="Current weather conditions") - temperature: Optional[float] = Field(default=None, description="Temperature in Celsius") - forecast_days: List[str] = Field(default_factory=list, description="Multi-day forecast") +class PersonInfo(BaseModel): + """Model that contains information about a Person""" + name: str = Field(description="Name of the person") + age: int = Field(description="Age of the person") + occupation: str = Field(description="Occupation of the person") ``` -Then use the `Agent.structured_output()` method as shown in the following sections. - -> #### Note on Usage -> For model providers that do not provide a native "structured output" API, using `structured_ouput` creates a tool with the same name as the Pydantic model you have defined, say - "SomePydanticModel". -> `agent.structured_output` should be used to re-organize information from the existing conversation (or optional prompt) into the Pydantic model. To do this, `structured_output` expects to invoke only the SomePydanticModel tool. Attempting to use any other tool will result in errors. -> -> Note that the prompt attached to the `structured_output` call will not be integrated into the conversation history, therefore `structured_output` should solely be invoked to restructure data from a conversation or from the isolated optional prompt. +Then use the `structured_output_model` parameter in your agent invocations as shown in the following sections. ### Basic Usage -Extract structured information from text: +Extract structured information from text by passing the `structured_output_model` parameter: ```python from pydantic import BaseModel @@ -74,79 +54,159 @@ class PersonInfo(BaseModel): occupation: str agent = Agent() -result = agent.structured_output( - PersonInfo, - "John Smith is a 30-year-old software engineer" +result = agent( + "John Smith is a 30 year-old software engineer", + structured_output_model=PersonInfo ) -print(f"Name: {result.name}") # "John Smith" -print(f"Age: {result.age}") # 30 -print(f"Job: {result.occupation}") # "software engineer" +print(f"Name: {result.structured_output.name}") # "John Smith" +print(f"Age: {result.structured_output.age}") # 30 +print(f"Job: {result.structured_output.occupation}") # "software engineer" ``` -### Multi-Modal Input +### Structured Output agent with Auto Retries -Extract structured information from prompts containing images, documents, and other content types: +Automatically retry validation when initial extraction fails due to field validators: ```python -class PersonInfo(BaseModel): - name: str - age: int - occupation: str +from strands.agent import Agent +from pydantic import BaseModel, field_validator -with open("path/to/document.pdf", "rb") as fp: - document_bytes = fp.read() -agent = Agent() -result = agent.structured_output( - PersonInfo, - [ - {"text": "Please process this application."}, - { - "document": { - "format": "pdf", - "name": "application", - "source": { - "bytes": document_bytes, - }, - }, - }, - ] +class Name(BaseModel): + first_name: str + + @field_validator("first_name") + @classmethod + def validate_first_name(cls, value: str) -> str: + if not value.endswith('abc'): + raise ValueError("You must append 'abc' to the end of my name") + return value + + +agent = Agent() +result = agent("What is Aaron's name?", structured_output_model=Name) +``` + + +### Structured Output agent with Streaming + +Stream structured output progressively while maintaining type safety and validation: + +```python +from strands import Agent +from pydantic import BaseModel, Field + +class WeatherForecast(BaseModel): + """Weather forecast data.""" + location: str + temperature: int + condition: str + humidity: int + wind_speed: int + forecast_date: str + +streaming_agent = Agent() + +async for event in streaming_agent.stream_async( + "Generate a weather forecast for Seattle: 68°F, partly cloudy, 55% humidity, 8 mph winds, for tomorrow", + structured_output_model=WeatherForecast +): + if "data" in event: + print(event["data"], end="", flush=True) + elif "result" in event: + print(f'The forcast for today is: {event["result"].structured_output}') +``` + + +### Structured Output agent with other tools + +Combine structured output with tool usage to format tool execution results: + +```python +from strands import Agent +from strands_tools import calculator +from pydantic import BaseModel, Field + +class MathResult(BaseModel): + operation: str = Field(description="the performed operation") + result: int = Field(description="the result of the operation") + +tool_agent = Agent( + tools=[calculator] ) +res = tool_agent("What is 42 + 8", structured_output_model=MathResult) ``` -For a complete list of supported content types, please refer to the [API Reference](../../../api-reference/types.md#strands.types.content.ContentBlock). +### Many Invocations with a Single Agent and different Structured Output types + +Reuse a single agent instance with different structured output models for varied extraction tasks: + +```python +from strands import Agent +from pydantic import BaseModel, Field + +class Person(BaseModel): + """A person's basic information""" + name: str = Field(description="Full name") + age: int = Field(description="Age in years", ge=0, le=150) + email: str = Field(description="Email address") + phone: Optional[str] = Field(description="Phone number", default=None) + +class Task(BaseModel): + """A task or todo item""" + title: str = Field(description="Task title") + description: str = Field(description="Detailed description") + priority: str = Field(description="Priority level: low, medium, high") + completed: bool = Field(description="Whether task is completed", default=False) + + +agent = Agent() +person_res = agent("Extract person: John Doe, 35, john@test.com", structured_output_model=Person) +task_res = agent("Create task: Review code, high priority, completed", structured_output_model=Task) +``` ### Using Conversation History -Structured output can work with existing conversation context: +Extract structured information from prior conversation context without repeating questions: ```python +from strands import Agent +from pydantic import BaseModel +from typing import Optional + agent = Agent() # Build up conversation context agent("What do you know about Paris, France?") agent("Tell me about the weather there in spring.") -# Extract structured information with a prompt class CityInfo(BaseModel): city: str country: str population: Optional[int] = None climate: str -# Uses existing conversation context with a prompt -result = agent.structured_output(CityInfo, "Extract structured information about Paris") +# Extract structured information from the conversation +result = agent( + "Extract structured information about Paris from our conversation", + structured_output_model=CityInfo +) + +print(f"City: {result.structured_output.city}") # "Paris" +print(f"Country: {result.structured_output.country}") # "France" ``` -### Complex Nested Models +### Nested Models -Handle sophisticated data structures: +Handle sophisticated data structures with multiple levels of nesting and complex relationships: ```python -from typing import List +from typing import List, Optional from pydantic import BaseModel, Field +from strands import Agent + class Address(BaseModel): street: str @@ -167,41 +227,98 @@ class Person(BaseModel): skills: List[str] = Field(default_factory=list, description="Professional skills") agent = Agent() -result = agent.structured_output( - Person, - "Extract info: Jane Doe, a systems admin, 28, lives at 123 Main St, New York, NY. Email: jane@example.com" +result = agent( + "Extract info: Jane Doe, a systems admin, 28, lives at 123 Main St, New York, NY. Email: jane@example.com", + structured_output_model=Person +) + +print(result.structured_output.name) # "Jane Doe" +print(result.structured_output.address.city) # "New York" +print(result.structured_output.contacts[0].email) # "jane@example.com" +print(result.structured_output.skills) # ["systems admin"] +``` + + +### Agent-Level Default + +Set a default structured output model that applies to all agent invocations: + +```python +class PersonInfo(BaseModel): + name: str + age: int + occupation: str + +# Set default structured output model for all invocations +agent = Agent(structured_output_model=PersonInfo) +result = agent("John Smith is a 30 year-old software engineer") + +print(f"Name: {result.structured_output.name}") # "John Smith" +print(f"Age: {result.structured_output.age}") # 30 +print(f"Job: {result.structured_output.occupation}") # "software engineer" +``` + +!!! note "Note" + Since this is on the agent init level, not the invocation level, the expectation is that the agent will attempt structured output for each invocation. + + +### Overriding Agent Default + +Override the agent's default structured output model for specific invocations that require different schemas: + +```python +class PersonInfo(BaseModel): + name: str + age: int + occupation: str + +class CompanyInfo(BaseModel): + name: str + industry: str + employees: int + +# Agent with default PersonInfo model +agent = Agent(structured_output_model=PersonInfo) + +# Override with CompanyInfo for this specific call +result = agent( + "TechCorp is a software company with 500 employees", + structured_output_model=CompanyInfo ) -print(result.name) # "Jane Doe" -print(result.address.city) # "New York" -print(result.contacts[0].email) # "jane@example.com" -print(result.skills) # ["systems admin"] +print(f"Company: {result.structured_output.name}") # "TechCorp" +print(f"Industry: {result.structured_output.industry}") # "software" +print(f"Size: {result.structured_output.employees}") # 500 ``` + + + + Refer to Pydantic documentation for details on: - [Models and schema definition](https://docs.pydantic.dev/latest/concepts/models/) - [Field types and constraints](https://docs.pydantic.dev/latest/concepts/fields/) - [Custom validators](https://docs.pydantic.dev/latest/concepts/validators/) + ### Error Handling +In the event there is an issue with parsing the structured output, Strands will throw a custom `StructuredOutputException` that can be caught and handled appropriately: + ```python from pydantic import ValidationError +from strands.types.exceptions import StructuredOutputException try: - result = agent.structured_output(MyModel, prompt) -except ValidationError as e: - print(f"Validation failed: {e}") - # Handle appropriately - options include: - # 1. Retry with a more specific prompt - # 2. Fall back to a simpler model - # 3. Extract partial information from the error + result = agent(prompt, structured_output_model=MyModel) +except StructuredOutputException as e: + print(f"Structured output failed: {e}") ``` -### Async +### Async Support -Strands also supports obtaining structured output asynchronously through [`structured_output_async`](../../../api-reference/agent.md#strands.agent.agent.Agent.structured_output_async): +Everything mentioned above also works via the async `invoke_async` method: ```python import asyncio @@ -213,14 +330,37 @@ class PersonInfo(BaseModel): age: int occupation: str -async def structured_output(): +async def get_structured_output(): agent = Agent() - return await agent.structured_output_async( - PersonInfo, - "John Smith is a 30-year-old software engineer" + result = await agent.invoke_async( + "John Smith is a 30-year-old software engineer", + structured_output_model=PersonInfo ) + return result.structured_output + +person_info = asyncio.run(get_structured_output()) +``` + + +## Migration from Legacy API + +!!! warning "Deprecated API" + The `Agent.structured_output()` and `Agent.structured_output_async()` methods are deprecated. Use the new `structured_output_model` parameter approach instead. -result = asyncio.run(structured_output()) +### Before (Deprecated) + +```python +# Old approach - deprecated +result = agent.structured_output(PersonInfo, "John is 30 years old") +print(result.name) # Direct access to model fields +``` + +### After (Recommended) + +```python +# New approach - recommended +result = agent("John is 30 years old", structured_output_model=PersonInfo) +print(result.structured_output.name) # Access via structured_output field ``` @@ -229,4 +369,3 @@ result = asyncio.run(structured_output()) - **Keep models focused**: Define specific models for clear purposes - **Use descriptive field names**: Include helpful descriptions with `Field` - **Handle errors gracefully**: Implement proper error handling strategies with fallbacks -- **Extract key data at conversation completion**: Use structured output at the end of agent workflows to distill conversations into actionable data structures From 3bf3b86028232986638739935b4b036dd2325f9c Mon Sep 17 00:00:00 2001 From: Aaron Farntrog Date: Sun, 26 Oct 2025 15:58:59 -0400 Subject: [PATCH 2/4] docs: add documentation for the new structured output approach --- .../concepts/agents/structured-output.md | 250 +++++++----------- 1 file changed, 95 insertions(+), 155 deletions(-) diff --git a/docs/user-guide/concepts/agents/structured-output.md b/docs/user-guide/concepts/agents/structured-output.md index 692b0030..3c4bf92e 100644 --- a/docs/user-guide/concepts/agents/structured-output.md +++ b/docs/user-guide/concepts/agents/structured-output.md @@ -1,7 +1,11 @@ # Structured Output -Structured output enables you to get type-safe, validated responses from language models using [Pydantic](https://docs.pydantic.dev/latest/concepts/models/) models. Instead of receiving raw text that you need to parse, you can define the exact structure you want and receive a validated Python object that matches your schema. This transforms unstructured LLM outputs into reliable, program-friendly data structures that integrate seamlessly with your application's type system and validation rules. +!!! New + We have revamped the devx for structured output and deprecated the `structured_output_async` and `structured_output` methods. The following guide details how to use structured output. + +## Introduction +Structured output enables you to get type-safe, validated responses from language models using [Pydantic](https://docs.pydantic.dev/latest/concepts/models/) models. Instead of receiving raw text that you need to parse, you can define the exact structure you want and receive a validated Python object that matches your schema. This transforms unstructured LLM outputs into reliable, program-friendly data structures that integrate seamlessly with your application's type system and validation rules. ```mermaid flowchart LR @@ -9,6 +13,7 @@ flowchart LR B --> C[LLM] --> D[Validated Pydantic Model] D --> E[AgentResult.structured_output] ``` + Key benefits: - **Type Safety**: Get typed Python objects instead of raw strings @@ -17,54 +22,110 @@ Key benefits: - **IDE Support**: IDE type hinting from LLM-generated responses - **Error Prevention**: Catch malformed responses early -## How It Works - -The structured output system converts your Pydantic models into tool specifications that guide the language model to produce correctly formatted responses. All of the model providers supported in Strands can work with Structured Output. -Strands handles this by accepting the `structured_output_model` parameter to agent invocations, which manages the conversion, validation, and response processing automatically. The validated result is available in the `AgentResult.structured_output` field. +## Basic Usage -## Usage - -Define your desired output structure using Pydantic models: +Define an output structure using a Pydantic model. Then, assign the model to the `structured_output_model` parameter when invoking the agent. Then, access the Structured Output from the [`AgentResult`](../../../api-reference/agent.md#strands.agent.agent_result). ```python from pydantic import BaseModel, Field -from typing import Optional, List +from strands import Agent +# 1) Define the Pydantic model class PersonInfo(BaseModel): """Model that contains information about a Person""" name: str = Field(description="Name of the person") age: int = Field(description="Age of the person") occupation: str = Field(description="Occupation of the person") -``` - -Then use the `structured_output_model` parameter in your agent invocations as shown in the following sections. - -### Basic Usage - -Extract structured information from text by passing the `structured_output_model` parameter: - -```python -from pydantic import BaseModel -from strands import Agent - -class PersonInfo(BaseModel): - name: str - age: int - occupation: str +# 2) Pass the model to the agent agent = Agent() result = agent( "John Smith is a 30 year-old software engineer", structured_output_model=PersonInfo ) +# 3) Access the `structured_output` from the result print(f"Name: {result.structured_output.name}") # "John Smith" print(f"Age: {result.structured_output.age}") # 30 print(f"Job: {result.structured_output.occupation}") # "software engineer" ``` -### Structured Output agent with Auto Retries +???+ tip "Async Support" + Structured Output is supported with async via the `invoke_async` method: + + ```python + import asyncio + agent = Agent() + result = asyncio.run( + agent.invoke_async( + "John Smith is a 30 year-old software engineer", + structured_output_model=PersonInfo + ) + ) + ``` + +## More Information + +### How It Works + +The structured output system converts your Pydantic models into tool specifications that guide the language model to produce correctly formatted responses. All of the model providers supported in Strands can work with Structured Output. + +Strands handles this by accepting the `structured_output_model` parameter in agent invocations, which manages the conversion, validation, and response processing automatically. The validated result is available in the `AgentResult.structured_output` field. + + +### Error Handling + +In the event there is an issue with parsing the structured output, Strands will throw a custom `StructuredOutputException` that can be caught and handled appropriately: + +```python +from pydantic import ValidationError +from strands.types.exceptions import StructuredOutputException + +try: + result = agent(prompt, structured_output_model=MyModel) +except StructuredOutputException as e: + print(f"Structured output failed: {e}") +``` + +### Migration from Legacy API + +!!! warning "Deprecated API" + The `Agent.structured_output()` and `Agent.structured_output_async()` methods are deprecated. Use the new `structured_output_model` parameter approach instead. + +#### Before (Deprecated) + +```python +# Old approach - deprecated +result = agent.structured_output(PersonInfo, "John is 30 years old") +print(result.name) # Direct access to model fields +``` + +#### After (Recommended) + +```python +# New approach - recommended +result = agent("John is 30 years old", structured_output_model=PersonInfo) +print(result.structured_output.name) # Access via structured_output field +``` + +### Best Practices + +- **Keep models focused**: Define specific models for clear purposes +- **Use descriptive field names**: Include helpful descriptions with `Field` +- **Handle errors gracefully**: Implement proper error handling strategies with fallbacks + +### Related Documentation + +Refer to Pydantic documentation for details on: + +- [Models and schema definition](https://docs.pydantic.dev/latest/concepts/models/) +- [Field types and constraints](https://docs.pydantic.dev/latest/concepts/fields/) +- [Custom validators](https://docs.pydantic.dev/latest/concepts/validators/) + +## Cookbook + +### Auto Retries with Validation Automatically retry validation when initial extraction fails due to field validators: @@ -88,8 +149,7 @@ agent = Agent() result = agent("What is Aaron's name?", structured_output_model=Name) ``` - -### Structured Output agent with Streaming +### Streaming Structured Output Stream structured output progressively while maintaining type safety and validation: @@ -118,8 +178,7 @@ async for event in streaming_agent.stream_async( print(f'The forcast for today is: {event["result"].structured_output}') ``` - -### Structured Output agent with other tools +### Combining with Tools Combine structured output with tool usage to format tool execution results: @@ -138,13 +197,14 @@ tool_agent = Agent( res = tool_agent("What is 42 + 8", structured_output_model=MathResult) ``` -### Many Invocations with a Single Agent and different Structured Output types +### Multiple Output Types Reuse a single agent instance with different structured output models for varied extraction tasks: ```python from strands import Agent from pydantic import BaseModel, Field +from typing import Optional class Person(BaseModel): """A person's basic information""" @@ -166,7 +226,6 @@ person_res = agent("Extract person: John Doe, 35, john@test.com", structured_out task_res = agent("Create task: Review code, high priority, completed", structured_output_model=Task) ``` - ### Using Conversation History Extract structured information from prior conversation context without repeating questions: @@ -198,50 +257,10 @@ print(f"City: {result.structured_output.city}") # "Paris" print(f"Country: {result.structured_output.country}") # "France" ``` -### Nested Models -Handle sophisticated data structures with multiple levels of nesting and complex relationships: +### Agent-Level Defaults -```python -from typing import List, Optional -from pydantic import BaseModel, Field -from strands import Agent - - -class Address(BaseModel): - street: str - city: str - country: str - postal_code: Optional[str] = None - -class Contact(BaseModel): - email: Optional[str] = None - phone: Optional[str] = None - -class Person(BaseModel): - """Complete person information.""" - name: str = Field(description="Full name of the person") - age: int = Field(description="Age in years") - address: Address = Field(description="Home address") - contacts: List[Contact] = Field(default_factory=list, description="Contact methods") - skills: List[str] = Field(default_factory=list, description="Professional skills") - -agent = Agent() -result = agent( - "Extract info: Jane Doe, a systems admin, 28, lives at 123 Main St, New York, NY. Email: jane@example.com", - structured_output_model=Person -) - -print(result.structured_output.name) # "Jane Doe" -print(result.structured_output.address.city) # "New York" -print(result.structured_output.contacts[0].email) # "jane@example.com" -print(result.structured_output.skills) # ["systems admin"] -``` - - -### Agent-Level Default - -Set a default structured output model that applies to all agent invocations: +You can also aet a default structured output model that applies to all agent invocations: ```python class PersonInfo(BaseModel): @@ -262,9 +281,9 @@ print(f"Job: {result.structured_output.occupation}") # "software engineer" Since this is on the agent init level, not the invocation level, the expectation is that the agent will attempt structured output for each invocation. -### Overriding Agent Default +### Overriding Agent Defaults -Override the agent's default structured output model for specific invocations that require different schemas: +Even when you set a default `structured_output_model` at the agent initialization level, you can override it for specific invocations by passing a different `structured_output_model` during the agent invocation: ```python class PersonInfo(BaseModel): @@ -290,82 +309,3 @@ print(f"Company: {result.structured_output.name}") # "TechCorp" print(f"Industry: {result.structured_output.industry}") # "software" print(f"Size: {result.structured_output.employees}") # 500 ``` - - - - - -Refer to Pydantic documentation for details on: - -- [Models and schema definition](https://docs.pydantic.dev/latest/concepts/models/) -- [Field types and constraints](https://docs.pydantic.dev/latest/concepts/fields/) -- [Custom validators](https://docs.pydantic.dev/latest/concepts/validators/) - - -### Error Handling - -In the event there is an issue with parsing the structured output, Strands will throw a custom `StructuredOutputException` that can be caught and handled appropriately: - -```python -from pydantic import ValidationError -from strands.types.exceptions import StructuredOutputException - -try: - result = agent(prompt, structured_output_model=MyModel) -except StructuredOutputException as e: - print(f"Structured output failed: {e}") -``` - -### Async Support - -Everything mentioned above also works via the async `invoke_async` method: - -```python -import asyncio -from pydantic import BaseModel -from strands import Agent - -class PersonInfo(BaseModel): - name: str - age: int - occupation: str - -async def get_structured_output(): - agent = Agent() - result = await agent.invoke_async( - "John Smith is a 30-year-old software engineer", - structured_output_model=PersonInfo - ) - return result.structured_output - -person_info = asyncio.run(get_structured_output()) -``` - - -## Migration from Legacy API - -!!! warning "Deprecated API" - The `Agent.structured_output()` and `Agent.structured_output_async()` methods are deprecated. Use the new `structured_output_model` parameter approach instead. - -### Before (Deprecated) - -```python -# Old approach - deprecated -result = agent.structured_output(PersonInfo, "John is 30 years old") -print(result.name) # Direct access to model fields -``` - -### After (Recommended) - -```python -# New approach - recommended -result = agent("John is 30 years old", structured_output_model=PersonInfo) -print(result.structured_output.name) # Access via structured_output field -``` - - -## Best Practices - -- **Keep models focused**: Define specific models for clear purposes -- **Use descriptive field names**: Include helpful descriptions with `Field` -- **Handle errors gracefully**: Implement proper error handling strategies with fallbacks From 5794fa8fa4703dbfc4d80fbc1f5f2246e710bca8 Mon Sep 17 00:00:00 2001 From: Aaron Farntrog Date: Mon, 27 Oct 2025 10:04:38 -0400 Subject: [PATCH 3/4] docs: add documentation for the new structured output approach --- docs/user-guide/concepts/agents/structured-output.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/user-guide/concepts/agents/structured-output.md b/docs/user-guide/concepts/agents/structured-output.md index 3c4bf92e..ce2d7e70 100644 --- a/docs/user-guide/concepts/agents/structured-output.md +++ b/docs/user-guide/concepts/agents/structured-output.md @@ -25,7 +25,7 @@ Key benefits: ## Basic Usage -Define an output structure using a Pydantic model. Then, assign the model to the `structured_output_model` parameter when invoking the agent. Then, access the Structured Output from the [`AgentResult`](../../../api-reference/agent.md#strands.agent.agent_result). +Define an output structure using a Pydantic model. Then, assign the model to the `structured_output_model` parameter when invoking the [`agent`](../../../api-reference/agent.md#strands.agent.agent). Then, access the Structured Output from the [`AgentResult`](../../../api-reference/agent.md#strands.agent.agent_result). ```python from pydantic import BaseModel, Field @@ -71,7 +71,7 @@ print(f"Job: {result.structured_output.occupation}") # "software engineer" The structured output system converts your Pydantic models into tool specifications that guide the language model to produce correctly formatted responses. All of the model providers supported in Strands can work with Structured Output. -Strands handles this by accepting the `structured_output_model` parameter in agent invocations, which manages the conversion, validation, and response processing automatically. The validated result is available in the `AgentResult.structured_output` field. +Strands handles this by accepting the `structured_output_model` parameter in [`agent`](../../../api-reference/agent.md#strands.agent.agent) invocations, which manages the conversion, validation, and response processing automatically. The validated result is available in the `AgentResult.structured_output` field. ### Error Handling From 568e723b215ff08f7666c58a40db21b08c50bd47 Mon Sep 17 00:00:00 2001 From: Aaron Farntrog Date: Mon, 27 Oct 2025 11:35:28 -0400 Subject: [PATCH 4/4] docs: add documentation for the new structured output approach --- docs/user-guide/concepts/agents/structured-output.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/user-guide/concepts/agents/structured-output.md b/docs/user-guide/concepts/agents/structured-output.md index ce2d7e70..52524547 100644 --- a/docs/user-guide/concepts/agents/structured-output.md +++ b/docs/user-guide/concepts/agents/structured-output.md @@ -46,9 +46,10 @@ result = agent( ) # 3) Access the `structured_output` from the result -print(f"Name: {result.structured_output.name}") # "John Smith" -print(f"Age: {result.structured_output.age}") # 30 -print(f"Job: {result.structured_output.occupation}") # "software engineer" +person_info: PersonInfo = result.structured_output +print(f"Name: {person_info.name}") # "John Smith" +print(f"Age: {person_info.age}") # 30 +print(f"Job: {person_info.occupation}") # "software engineer" ``` ???+ tip "Async Support"