CrewAI Tutorial (Python): parsing structured output for beginners

By Cyprian AaronsUpdated 2026-04-21
crewaiparsing-structured-output-for-beginnerspython

This tutorial shows you how to make a CrewAI agent return structured data in Python and then parse it into a predictable format you can use in your app. You need this when plain text responses are too messy for downstream code, like when you want JSON-like fields for tickets, claims, customer notes, or compliance summaries.

What You'll Need

  • Python 3.10 or newer
  • crewai
  • crewai-tools if you want extra tools later
  • An OpenAI API key set as OPENAI_API_KEY
  • A virtual environment
  • Basic familiarity with CrewAI agents, tasks, and crews

Install the package first:

pip install crewai

Step-by-Step

  1. Start by defining the structure you want back from the agent.
    For beginners, a Pydantic model is the cleanest way to describe the output shape and validate it after the run.
from pydantic import BaseModel

class SupportSummary(BaseModel):
    customer_name: str
    issue_type: str
    urgency: str
    resolution_steps: list[str]
  1. Create an agent and a task that explicitly asks for structured output.
    The key is to tell CrewAI what schema you expect so the model has a target format instead of free-form prose.
from crewai import Agent, Task

support_agent = Agent(
    role="Support Analyst",
    goal="Summarize customer issues into structured data",
    backstory="You turn raw support notes into clean structured records.",
    verbose=True,
)

task = Task(
    description=(
        "Read the support note and extract customer_name, issue_type, "
        "urgency, and resolution_steps."
    ),
    expected_output="A structured summary of the support case.",
    agent=support_agent,
)
  1. Wire the task to a crew and tell it to use your schema as the output model.
    In CrewAI, output_pydantic gives you parsed, typed output instead of forcing you to manually scrape text.
from crewai import Crew, Process

crew = Crew(
    agents=[support_agent],
    tasks=[task],
    process=Process.sequential,
)

result = crew.kickoff(inputs={
    "support_note": (
        "Customer: Maria Chen. The app crashes after login on iPhone 15. "
        "This is urgent because she cannot access her account. "
        "Suggested steps: restart app, reinstall app, reset password."
    )
})
  1. If you want strict parsing into your Pydantic model, attach it to the task before running.
    This is what makes the response easy to consume in code because CrewAI will try to map the model output into your schema.
task = Task(
    description=(
        "Read the support note and extract customer_name, issue_type, "
        "urgency, and resolution_steps."
    ),
    expected_output="A SupportSummary object.",
    agent=support_agent,
    output_pydantic=SupportSummary,
)

crew = Crew(
    agents=[support_agent],
    tasks=[task],
    process=Process.sequential,
)

result = crew.kickoff(inputs={
    "support_note": (
        "Customer: Maria Chen. The app crashes after login on iPhone 15. "
        "This is urgent because she cannot access her account. "
        "Suggested steps: restart app, reinstall app, reset password."
    )
})
  1. Read the parsed object directly instead of handling raw strings.
    If parsing succeeds, you get a typed object that behaves like normal Python data.
parsed = result.pydantic

print(parsed.customer_name)
print(parsed.issue_type)
print(parsed.urgency)
print(parsed.resolution_steps)

data = parsed.model_dump()
print(data)
  1. Add a fallback for cases where parsing fails or returns plain text.
    In production systems, don’t assume every model response will be perfect; check both parsed and raw output.
if getattr(result, "pydantic", None):
    parsed = result.pydantic
    print("Parsed output:", parsed.model_dump())
else:
    print("Raw output:")
    print(result.raw)

Testing It

Run the script with your API key set in the environment and confirm that result.pydantic exists. The printed values should match your schema fields exactly, not just loosely resemble them.

If parsing fails, check that your task description clearly names each field and that your Pydantic model types are realistic. Lists should be lists, strings should be strings, and required fields should be easy for the model to infer from the input.

A good test is to change the input note and verify that only the relevant fields update while the structure stays stable. That tells you your schema is doing its job.

Next Steps

  • Add nested Pydantic models for more complex outputs like claim assessments or underwriting summaries
  • Learn how to combine structured output with tools so agents can fetch data before formatting it
  • Explore validation patterns for handling missing fields and retrying bad parses

Keep learning

By Cyprian Aarons, AI Consultant at Topiax.

Want the complete 8-step roadmap?

Grab the free AI Agent Starter Kit — architecture templates, compliance checklists, and a 7-email deep-dive course.

Get the Starter Kit

Related Guides