|
| 1 | +# Structured Output with Strands Agents |
| 2 | + |
| 3 | +This tutorial teaches you how to get reliable, typed, validated data from your Strands agents using structured output. Instead of parsing free-form text, you define a Pydantic model and the agent returns a validated Python object — ready for downstream code, APIs, and workflows. |
| 4 | + |
| 5 | +## Architecture |
| 6 | + |
| 7 | + |
| 8 | + |
| 9 | +The agent loop registers your Pydantic model as a dynamic tool. The LLM uses regular tools first, then calls the structured output tool last. Pydantic validates the output — if validation fails, the error is sent back to the LLM for self-correction. |
| 10 | + |
| 11 | +## Tutorial Details |
| 12 | + |
| 13 | +| Information | Details | |
| 14 | +|------------------------|----------------------------------------------------------------------| |
| 15 | +| **Strands Features** | Structured Output, Pydantic Validation, Streaming, Tool Integration | |
| 16 | +| **Agent Pattern** | Single agent with structured output | |
| 17 | +| **Tools** | `calculator` (from strands-agents-tools) | |
| 18 | +| **Model** | Claude Sonnet 4.5 on Amazon Bedrock | |
| 19 | + |
| 20 | +## How It Works |
| 21 | + |
| 22 | +1. Developer defines a Pydantic `BaseModel` describing the desired output schema |
| 23 | +2. The model is passed to the agent via `structured_output_model=MyModel` |
| 24 | +3. The SDK converts the Pydantic model into a tool specification and registers it as a dynamic tool |
| 25 | +4. The LLM processes the prompt, optionally using regular tools to gather information |
| 26 | +5. The LLM calls the structured output tool with data matching the schema |
| 27 | +6. Pydantic validates the output — on failure, the error is sent back and the LLM self-corrects |
| 28 | +7. On success, the validated object is available at `result.structured_output` |
| 29 | + |
| 30 | +## Prerequisites |
| 31 | + |
| 32 | +- Python 3.10 or later |
| 33 | +- AWS account with [Amazon Bedrock](https://aws.amazon.com/bedrock/) model access configured |
| 34 | +- [Model access](https://docs.aws.amazon.com/bedrock/latest/userguide/model-access-modify.html) enabled for Claude Sonnet 4.5 |
| 35 | +- Basic understanding of Python and [Pydantic](https://docs.pydantic.dev/) |
| 36 | +- Familiarity with Strands Agents basics [(see Tutorial 01)](../01-first-agent/) |
| 37 | + |
| 38 | +## Tutorial Structure |
| 39 | + |
| 40 | +``` |
| 41 | +14-structured-output/ |
| 42 | +├── README.md |
| 43 | +├── requirements.txt |
| 44 | +├── structured-output.ipynb |
| 45 | +└── images/ |
| 46 | + └── architecture.png |
| 47 | +``` |
| 48 | + |
| 49 | +| File | Description | |
| 50 | +|------|-------------| |
| 51 | +| [structured-output.ipynb](./structured-output.ipynb) | Interactive notebook covering all 5 structured output patterns | |
| 52 | + |
| 53 | +## What You'll Learn |
| 54 | + |
| 55 | +- **Your First Structured Output**: Define a flat Pydantic model, pass it to an agent, and access typed results — both sync and async |
| 56 | +- **Complex Schemas**: Build nested models with `List`, `Optional`, field validators, and enum constraints |
| 57 | +- **Validation & Self-Correction**: Understand the automatic retry loop when validation fails, handle `StructuredOutputException`, and customize the forcing prompt |
| 58 | +- **Tools + Structured Output**: Combine regular tools with structured output so agents can gather data and return structured results |
| 59 | +- **Streaming Behavior**: Use `stream_async()` and understand that structured output appears only in the final event |
| 60 | + |
| 61 | +## Installation |
| 62 | + |
| 63 | +Install the required dependencies: |
| 64 | + |
| 65 | +```bash |
| 66 | +pip install -r requirements.txt |
| 67 | +``` |
| 68 | + |
| 69 | +## Running the Examples |
| 70 | + |
| 71 | +1. Open the notebook: [structured-output.ipynb](./structured-output.ipynb) |
| 72 | +2. Run cells sequentially — each section builds on the previous one |
| 73 | +3. Observe the agent's structured output in each example |
| 74 | + |
| 75 | +> **Note:** The exact field values will vary between runs since the LLM generates content dynamically. The structure and types will always match your Pydantic model. |
| 76 | +
|
| 77 | +## Key Concepts |
| 78 | + |
| 79 | +- **Structured Output**: A feature that makes agents return validated Pydantic objects instead of free-form text |
| 80 | +- **`structured_output_model`**: The parameter (on Agent constructor or per-call) that specifies the Pydantic model to use |
| 81 | +- **Structured Output Tool**: A dynamic tool the SDK auto-registers from your Pydantic model — the LLM calls it to produce structured data |
| 82 | +- **Validation & Self-Correction**: When the LLM's output fails Pydantic validation, the SDK sends the error back and the LLM retries automatically |
| 83 | +- **Forcing**: If the LLM ignores the structured output tool, the SDK forces it by restricting available tools and setting `tool_choice` |
| 84 | +- **`StructuredOutputException`**: Raised when the LLM fails to produce valid structured output even after forcing |
| 85 | +- **`structured_output_prompt`**: A customizable message sent to the LLM when forcing is triggered |
| 86 | + |
| 87 | +## Additional Resources |
| 88 | + |
| 89 | +- [Strands Agents Documentation](https://strandsagents.com/) |
| 90 | +- [Structured Output User Guide](https://strandsagents.com/latest/user-guide/concepts/agents/structured-output/) |
| 91 | +- [Pydantic Documentation](https://docs.pydantic.dev/) |
| 92 | +- [Strands Tools Repository](https://github.com/strands-agents/tools) |
| 93 | + |
| 94 | +## Next Steps |
| 95 | + |
| 96 | +- Learn about [Memory](../06-memory/) to persist agent memory across sessions |
| 97 | +- Explore [Agents as Tools](../10-agents-as-tools/) to compose structured output agents into larger systems |
| 98 | +- Try [Graph Workflows](../12-graph/) to build multi-step pipelines with structured data flowing between nodes |
0 commit comments