Skip to content

Commit 066ad73

Browse files
Merge pull request #1698 from crewAIInc/brandon/cre-510-update-docs-to-talk-about-pydantic-and-json-outputs
Talk about getting structured consistent outputs with tasks.
2 parents b6c6eea + 0695c26 commit 066ad73

File tree

1 file changed

+162
-1
lines changed

1 file changed

+162
-1
lines changed

docs/concepts/tasks.mdx

+162-1
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,167 @@ analysis_task = Task(
263263
)
264264
```
265265

266+
## Getting Structured Consistent Outputs from Tasks
267+
When you need to ensure that a task outputs a structured and consistent format, you can use the `output_pydantic` or `output_json` properties on a task. These properties allow you to define the expected output structure, making it easier to parse and utilize the results in your application.
268+
269+
<Note>
270+
It's also important to note that the output of the final task of a crew becomes the final output of the actual crew itself.
271+
</Note>
272+
273+
### Using `output_pydantic`
274+
The `output_pydantic` property allows you to define a Pydantic model that the task output should conform to. This ensures that the output is not only structured but also validated according to the Pydantic model.
275+
276+
Here’s an example demonstrating how to use output_pydantic:
277+
278+
```python Code
279+
import json
280+
281+
from crewai import Agent, Crew, Process, Task
282+
from pydantic import BaseModel
283+
284+
285+
class Blog(BaseModel):
286+
title: str
287+
content: str
288+
289+
290+
blog_agent = Agent(
291+
role="Blog Content Generator Agent",
292+
goal="Generate a blog title and content",
293+
backstory="""You are an expert content creator, skilled in crafting engaging and informative blog posts.""",
294+
verbose=False,
295+
allow_delegation=False,
296+
llm="gpt-4o",
297+
)
298+
299+
task1 = Task(
300+
description="""Create a blog title and content on a given topic. Make sure the content is under 200 words.""",
301+
expected_output="A compelling blog title and well-written content.",
302+
agent=blog_agent,
303+
output_pydantic=Blog,
304+
)
305+
306+
# Instantiate your crew with a sequential process
307+
crew = Crew(
308+
agents=[blog_agent],
309+
tasks=[task1],
310+
verbose=True,
311+
process=Process.sequential,
312+
)
313+
314+
result = crew.kickoff()
315+
316+
# Option 1: Accessing Properties Using Dictionary-Style Indexing
317+
print("Accessing Properties - Option 1")
318+
title = result["title"]
319+
content = result["content"]
320+
print("Title:", title)
321+
print("Content:", content)
322+
323+
# Option 2: Accessing Properties Directly from the Pydantic Model
324+
print("Accessing Properties - Option 2")
325+
title = result.pydantic.title
326+
content = result.pydantic.content
327+
print("Title:", title)
328+
print("Content:", content)
329+
330+
# Option 3: Accessing Properties Using the to_dict() Method
331+
print("Accessing Properties - Option 3")
332+
output_dict = result.to_dict()
333+
title = output_dict["title"]
334+
content = output_dict["content"]
335+
print("Title:", title)
336+
print("Content:", content)
337+
338+
# Option 4: Printing the Entire Blog Object
339+
print("Accessing Properties - Option 5")
340+
print("Blog:", result)
341+
342+
```
343+
In this example:
344+
* A Pydantic model Blog is defined with title and content fields.
345+
* The task task1 uses the output_pydantic property to specify that its output should conform to the Blog model.
346+
* After executing the crew, you can access the structured output in multiple ways as shown.
347+
348+
#### Explanation of Accessing the Output
349+
1. Dictionary-Style Indexing: You can directly access the fields using result["field_name"]. This works because the CrewOutput class implements the __getitem__ method.
350+
2. Directly from Pydantic Model: Access the attributes directly from the result.pydantic object.
351+
3. Using to_dict() Method: Convert the output to a dictionary and access the fields.
352+
4. Printing the Entire Object: Simply print the result object to see the structured output.
353+
354+
### Using `output_json`
355+
The `output_json` property allows you to define the expected output in JSON format. This ensures that the task's output is a valid JSON structure that can be easily parsed and used in your application.
356+
357+
Here’s an example demonstrating how to use `output_json`:
358+
359+
```python Code
360+
import json
361+
362+
from crewai import Agent, Crew, Process, Task
363+
from pydantic import BaseModel
364+
365+
366+
# Define the Pydantic model for the blog
367+
class Blog(BaseModel):
368+
title: str
369+
content: str
370+
371+
372+
# Define the agent
373+
blog_agent = Agent(
374+
role="Blog Content Generator Agent",
375+
goal="Generate a blog title and content",
376+
backstory="""You are an expert content creator, skilled in crafting engaging and informative blog posts.""",
377+
verbose=False,
378+
allow_delegation=False,
379+
llm="gpt-4o",
380+
)
381+
382+
# Define the task with output_json set to the Blog model
383+
task1 = Task(
384+
description="""Create a blog title and content on a given topic. Make sure the content is under 200 words.""",
385+
expected_output="A JSON object with 'title' and 'content' fields.",
386+
agent=blog_agent,
387+
output_json=Blog,
388+
)
389+
390+
# Instantiate the crew with a sequential process
391+
crew = Crew(
392+
agents=[blog_agent],
393+
tasks=[task1],
394+
verbose=True,
395+
process=Process.sequential,
396+
)
397+
398+
# Kickoff the crew to execute the task
399+
result = crew.kickoff()
400+
401+
# Option 1: Accessing Properties Using Dictionary-Style Indexing
402+
print("Accessing Properties - Option 1")
403+
title = result["title"]
404+
content = result["content"]
405+
print("Title:", title)
406+
print("Content:", content)
407+
408+
# Option 2: Printing the Entire Blog Object
409+
print("Accessing Properties - Option 2")
410+
print("Blog:", result)
411+
```
412+
413+
In this example:
414+
* A Pydantic model Blog is defined with title and content fields, which is used to specify the structure of the JSON output.
415+
* The task task1 uses the output_json property to indicate that it expects a JSON output conforming to the Blog model.
416+
* After executing the crew, you can access the structured JSON output in two ways as shown.
417+
418+
#### Explanation of Accessing the Output
419+
420+
1. Accessing Properties Using Dictionary-Style Indexing: You can access the fields directly using result["field_name"]. This is possible because the CrewOutput class implements the __getitem__ method, allowing you to treat the output like a dictionary. In this option, we're retrieving the title and content from the result.
421+
2. Printing the Entire Blog Object: By printing result, you get the string representation of the CrewOutput object. Since the __str__ method is implemented to return the JSON output, this will display the entire output as a formatted string representing the Blog object.
422+
423+
---
424+
425+
By using output_pydantic or output_json, you ensure that your tasks produce outputs in a consistent and structured format, making it easier to process and utilize the data within your application or across multiple tasks.
426+
266427
## Integrating Tools with Tasks
267428

268429
Leverage tools from the [CrewAI Toolkit](https://github.com/joaomdmoura/crewai-tools) and [LangChain Tools](https://python.langchain.com/docs/integrations/tools) for enhanced task performance and agent interaction.
@@ -471,4 +632,4 @@ save_output_task = Task(
471632
Tasks are the driving force behind the actions of agents in CrewAI.
472633
By properly defining tasks and their outcomes, you set the stage for your AI agents to work effectively, either independently or as a collaborative unit.
473634
Equipping tasks with appropriate tools, understanding the execution process, and following robust validation practices are crucial for maximizing CrewAI's potential,
474-
ensuring agents are effectively prepared for their assignments and that tasks are executed as intended.
635+
ensuring agents are effectively prepared for their assignments and that tasks are executed as intended.

0 commit comments

Comments
 (0)