You want the agent to break a goal into an ordered list of steps. How do you stop yourself from writing result.output.split('\n') and stripping each line?
A Pydantic model with a steps: list[str] field? Or something simpler for a single-field shape?
Simpler. result_type=list[str] is itself a valid type — PydanticAI accepts it directly. No wrapper class needed, no .steps attribute, no parsing. The raw .output is already a Python list:
agent = Agent(model, result_type=list[str])
result = agent.run_sync("Plan launching a blog post")
print(result.output)So PydanticAI builds a JSON array schema from list[str], and result.output comes back as a real Python list I can iterate over?
Exactly. The library handles schema generation, validation, and coercion. Your code only sees the clean list — ready for enumeration, filtering, or further agent calls. A minimal planner:
def plan_steps(goal: str) -> list:
agent = Agent(model, result_type=list[str])
result = agent.run_sync(goal)
return result.outputAnd if the model returns ten steps for one goal and three for another? The type only says list of strings, not length?
Length is not part of the type — the agent decides based on the goal. For a tight plan you add a system_prompt like "Return at most five concise steps." The type guarantees shape; the prompt guides substance. Two different knobs, both useful.
So next time I need an ordered to-do out of the agent, I just annotate list[str] and skip every parser I would have written?
Parser eliminated. Same agent call, typed list out, one less layer of defensive code in your pipeline.
TL;DR: result_type=list[str] returns a Python list directly — no Pydantic class needed.
list[str] — built-in generic, PydanticAI treats it as a JSON array schemaresult.output — already a list, iterate immediatelysystem_prompt — shape content (length, tone) without changing the type| Shape | result_type |
|---|---|
| Plain list | list[str] |
| Multi-field | class Plan(BaseModel) |
| One fixed label | Literal["a","b"] |
Prefer list[str] when every item has the same shape and the list length is agent-driven.
You want the agent to break a goal into an ordered list of steps. How do you stop yourself from writing result.output.split('\n') and stripping each line?
A Pydantic model with a steps: list[str] field? Or something simpler for a single-field shape?
Simpler. result_type=list[str] is itself a valid type — PydanticAI accepts it directly. No wrapper class needed, no .steps attribute, no parsing. The raw .output is already a Python list:
agent = Agent(model, result_type=list[str])
result = agent.run_sync("Plan launching a blog post")
print(result.output)So PydanticAI builds a JSON array schema from list[str], and result.output comes back as a real Python list I can iterate over?
Exactly. The library handles schema generation, validation, and coercion. Your code only sees the clean list — ready for enumeration, filtering, or further agent calls. A minimal planner:
def plan_steps(goal: str) -> list:
agent = Agent(model, result_type=list[str])
result = agent.run_sync(goal)
return result.outputAnd if the model returns ten steps for one goal and three for another? The type only says list of strings, not length?
Length is not part of the type — the agent decides based on the goal. For a tight plan you add a system_prompt like "Return at most five concise steps." The type guarantees shape; the prompt guides substance. Two different knobs, both useful.
So next time I need an ordered to-do out of the agent, I just annotate list[str] and skip every parser I would have written?
Parser eliminated. Same agent call, typed list out, one less layer of defensive code in your pipeline.
TL;DR: result_type=list[str] returns a Python list directly — no Pydantic class needed.
list[str] — built-in generic, PydanticAI treats it as a JSON array schemaresult.output — already a list, iterate immediatelysystem_prompt — shape content (length, tone) without changing the type| Shape | result_type |
|---|---|
| Plain list | list[str] |
| Multi-field | class Plan(BaseModel) |
| One fixed label | Literal["a","b"] |
Prefer list[str] when every item has the same shape and the list length is agent-driven.
Create a free account to get started. Paid plans unlock all tracks.