-
Notifications
You must be signed in to change notification settings - Fork 421
feat: add structured output tutorial (#14) #249
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
builder-ujaladi
wants to merge
1
commit into
strands-agents:main
Choose a base branch
from
builder-ujaladi:feat/14-structured-output
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,98 @@ | ||
| # Structured Output with Strands Agents | ||
|
|
||
| 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. | ||
|
|
||
| ## Architecture | ||
|
|
||
|  | ||
|
|
||
| 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. | ||
|
|
||
| ## Tutorial Details | ||
|
|
||
| | Information | Details | | ||
| |------------------------|----------------------------------------------------------------------| | ||
| | **Strands Features** | Structured Output, Pydantic Validation, Streaming, Tool Integration | | ||
| | **Agent Pattern** | Single agent with structured output | | ||
| | **Tools** | `calculator` (from strands-agents-tools) | | ||
| | **Model** | Claude Sonnet 4.5 on Amazon Bedrock | | ||
|
|
||
| ## How It Works | ||
|
|
||
| 1. Developer defines a Pydantic `BaseModel` describing the desired output schema | ||
| 2. The model is passed to the agent via `structured_output_model=MyModel` | ||
| 3. The SDK converts the Pydantic model into a tool specification and registers it as a dynamic tool | ||
| 4. The LLM processes the prompt, optionally using regular tools to gather information | ||
| 5. The LLM calls the structured output tool with data matching the schema | ||
| 6. Pydantic validates the output — on failure, the error is sent back and the LLM self-corrects | ||
| 7. On success, the validated object is available at `result.structured_output` | ||
|
|
||
| ## Prerequisites | ||
|
|
||
| - Python 3.10 or later | ||
| - AWS account with [Amazon Bedrock](https://aws.amazon.com/bedrock/) model access configured | ||
| - [Model access](https://docs.aws.amazon.com/bedrock/latest/userguide/model-access-modify.html) enabled for Claude Sonnet 4.5 | ||
| - Basic understanding of Python and [Pydantic](https://docs.pydantic.dev/) | ||
| - Familiarity with Strands Agents basics [(see Tutorial 01)](../01-first-agent/) | ||
|
|
||
| ## Tutorial Structure | ||
|
|
||
| ``` | ||
| 14-structured-output/ | ||
| ├── README.md | ||
| ├── requirements.txt | ||
| ├── structured-output.ipynb | ||
| └── images/ | ||
| └── architecture.png | ||
| ``` | ||
|
|
||
| | File | Description | | ||
| |------|-------------| | ||
| | [structured-output.ipynb](./structured-output.ipynb) | Interactive notebook covering all 5 structured output patterns | | ||
|
|
||
| ## What You'll Learn | ||
|
|
||
| - **Your First Structured Output**: Define a flat Pydantic model, pass it to an agent, and access typed results — both sync and async | ||
| - **Complex Schemas**: Build nested models with `List`, `Optional`, field validators, and enum constraints | ||
| - **Validation & Self-Correction**: Understand the automatic retry loop when validation fails, handle `StructuredOutputException`, and customize the forcing prompt | ||
| - **Tools + Structured Output**: Combine regular tools with structured output so agents can gather data and return structured results | ||
| - **Streaming Behavior**: Use `stream_async()` and understand that structured output appears only in the final event | ||
|
|
||
| ## Installation | ||
|
|
||
| Install the required dependencies: | ||
|
|
||
| ```bash | ||
| pip install -r requirements.txt | ||
| ``` | ||
|
|
||
| ## Running the Examples | ||
|
|
||
| 1. Open the notebook: [structured-output.ipynb](./structured-output.ipynb) | ||
| 2. Run cells sequentially — each section builds on the previous one | ||
| 3. Observe the agent's structured output in each example | ||
|
|
||
| > **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. | ||
|
|
||
| ## Key Concepts | ||
|
|
||
| - **Structured Output**: A feature that makes agents return validated Pydantic objects instead of free-form text | ||
| - **`structured_output_model`**: The parameter (on Agent constructor or per-call) that specifies the Pydantic model to use | ||
| - **Structured Output Tool**: A dynamic tool the SDK auto-registers from your Pydantic model — the LLM calls it to produce structured data | ||
| - **Validation & Self-Correction**: When the LLM's output fails Pydantic validation, the SDK sends the error back and the LLM retries automatically | ||
| - **Forcing**: If the LLM ignores the structured output tool, the SDK forces it by restricting available tools and setting `tool_choice` | ||
| - **`StructuredOutputException`**: Raised when the LLM fails to produce valid structured output even after forcing | ||
| - **`structured_output_prompt`**: A customizable message sent to the LLM when forcing is triggered | ||
|
|
||
| ## Additional Resources | ||
|
|
||
| - [Strands Agents Documentation](https://strandsagents.com/) | ||
| - [Structured Output User Guide](https://strandsagents.com/latest/user-guide/concepts/agents/structured-output/) | ||
| - [Pydantic Documentation](https://docs.pydantic.dev/) | ||
| - [Strands Tools Repository](https://github.com/strands-agents/tools) | ||
|
|
||
| ## Next Steps | ||
|
|
||
| - Learn about [Memory](../06-memory/) to persist agent memory across sessions | ||
| - Explore [Agents as Tools](../10-agents-as-tools/) to compose structured output agents into larger systems | ||
| - Try [Graph Workflows](../12-graph/) to build multi-step pipelines with structured data flowing between nodes | ||
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| strands-agents | ||
| strands-agents-tools | ||
| pydantic |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The architecture diagram tries to show everything at once, which feels a bit overwhelming. Could you simplify it to represent just the core concept? You pass a model, you get a typed object back — that's the "aha moment."