CrewAI Structured Output: Stop Data Drift with Pydantic
2 min read
If you have seen one task return markdown this time and a free-form essay next time, you are not alone.
The fix is straightforward: define output schema with Pydantic.
Why structured output?
- Downstream tasks can read fixed fields
- No brittle string parsing every run
- Failures are caught earlier (field mismatch throws errors)
It is basically an API contract. Stable collaboration needs a contract.
Create output models
from pydantic import BaseModel, Field
class Finding(BaseModel):
title: str = Field(description="Finding title")
summary: str = Field(description="Brief explanation")
source: str = Field(description="Reference URL")
class ResearchReport(BaseModel):
topic: str = Field(description="Topic name")
findings: list[Finding] = Field(description="Key findings list")
conclusion: str = Field(description="Final conclusion")Use output_pydantic in task
from crewai import Task
research_task = Task(
description="Research AI observability tools in 2026.",
expected_output="Structured research result.",
output_pydantic=ResearchReport,
)After execution, you can access stable fields directly instead of guessing from text.
Recommended pairing style
- Keep
expected_outputquality requirements explicit - Define field semantics (
summarylength,sourceformat) - Make downstream tasks rely on fields, not writing style
Common beginner mistakes
- Thinking Pydantic means
expected_outputis unnecessary - Too few fields, resulting in missing information
- Too many granular fields, causing frequent omissions
⚠️ Start with 3-5 key fields first. Expand only when needed.
Next step
Now your single crew can output reliably. Next, we move to multi-crew orchestration.
👉 Flow Basics