-
Notifications
You must be signed in to change notification settings - Fork 3.8k
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
feat: Add planning feature to crew #919
Merged
Merged
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
bd0767b
feat: add planning feature to crew
pythonbyte 16cedcf
feat: add test to planning handler and change to execute_async method
pythonbyte 706dbeb
docs: add planning parameter to the Core documentation
pythonbyte fe2bac7
docs: add planning docs
pythonbyte 4484e50
Merge branch 'main' into feat/plan-execute
pythonbyte 59d5713
fix: fix type checking issue
pythonbyte 2188b10
fix: test and logic
pythonbyte 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 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
This file contains 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,119 @@ | ||
--- | ||
title: crewAI Planning | ||
description: Learn how to add planning to your crewAI Crew and improve their performance. | ||
--- | ||
|
||
## Introduction | ||
The planning feature in CrewAI allows you to add planning capability to your crew. When enabled, before each Crew iteration, all Crew information is sent to an AgentPlanner that will plan the tasks step by step, and this plan will be added to each task description. | ||
|
||
### Using the Planning Feature | ||
Getting started with the planning feature is very easy, the only step required is to add `planning=True` to your Crew: | ||
|
||
```python | ||
from crewai import Crew, Agent, Task, Process | ||
|
||
# Assemble your crew with planning capabilities | ||
my_crew = Crew( | ||
agents=self.agents, | ||
tasks=self.tasks, | ||
process=Process.sequential, | ||
planning=True, | ||
) | ||
``` | ||
|
||
From this point on, your crew will have planning enabled, and the tasks will be planned before each iteration. | ||
|
||
### Example | ||
|
||
When running the base case example, you will see something like the following output, which represents the output of the AgentPlanner responsible for creating the step-by-step logic to add to the Agents tasks. | ||
|
||
```bash | ||
|
||
[2024-07-15 16:49:11][INFO]: Planning the crew execution | ||
**Step-by-Step Plan for Task Execution** | ||
|
||
**Task Number 1: Conduct a thorough research about AI LLMs** | ||
|
||
**Agent:** AI LLMs Senior Data Researcher | ||
|
||
**Agent Goal:** Uncover cutting-edge developments in AI LLMs | ||
|
||
**Task Expected Output:** A list with 10 bullet points of the most relevant information about AI LLMs | ||
|
||
**Task Tools:** None specified | ||
|
||
**Agent Tools:** None specified | ||
|
||
**Step-by-Step Plan:** | ||
|
||
1. **Define Research Scope:** | ||
- Determine the specific areas of AI LLMs to focus on, such as advancements in architecture, use cases, ethical considerations, and performance metrics. | ||
|
||
2. **Identify Reliable Sources:** | ||
- List reputable sources for AI research, including academic journals, industry reports, conferences (e.g., NeurIPS, ACL), AI research labs (e.g., OpenAI, Google AI), and online databases (e.g., IEEE Xplore, arXiv). | ||
|
||
3. **Collect Data:** | ||
- Search for the latest papers, articles, and reports published in 2023 and early 2024. | ||
- Use keywords like "Large Language Models 2024", "AI LLM advancements", "AI ethics 2024", etc. | ||
|
||
4. **Analyze Findings:** | ||
- Read and summarize the key points from each source. | ||
- Highlight new techniques, models, and applications introduced in the past year. | ||
|
||
5. **Organize Information:** | ||
- Categorize the information into relevant topics (e.g., new architectures, ethical implications, real-world applications). | ||
- Ensure each bullet point is concise but informative. | ||
|
||
6. **Create the List:** | ||
- Compile the 10 most relevant pieces of information into a bullet point list. | ||
- Review the list to ensure clarity and relevance. | ||
|
||
**Expected Output:** | ||
A list with 10 bullet points of the most relevant information about AI LLMs. | ||
|
||
--- | ||
|
||
**Task Number 2: Review the context you got and expand each topic into a full section for a report** | ||
|
||
**Agent:** AI LLMs Reporting Analyst | ||
|
||
**Agent Goal:** Create detailed reports based on AI LLMs data analysis and research findings | ||
|
||
**Task Expected Output:** A fully fledge report with the main topics, each with a full section of information. Formatted as markdown without '```' | ||
|
||
**Task Tools:** None specified | ||
|
||
**Agent Tools:** None specified | ||
|
||
**Step-by-Step Plan:** | ||
|
||
1. **Review the Bullet Points:** | ||
- Carefully read through the list of 10 bullet points provided by the AI LLMs Senior Data Researcher. | ||
|
||
2. **Outline the Report:** | ||
- Create an outline with each bullet point as a main section heading. | ||
- Plan sub-sections under each main heading to cover different aspects of the topic. | ||
|
||
3. **Research Further Details:** | ||
- For each bullet point, conduct additional research if necessary to gather more detailed information. | ||
- Look for case studies, examples, and statistical data to support each section. | ||
|
||
4. **Write Detailed Sections:** | ||
- Expand each bullet point into a comprehensive section. | ||
- Ensure each section includes an introduction, detailed explanation, examples, and a conclusion. | ||
- Use markdown formatting for headings, subheadings, lists, and emphasis. | ||
|
||
5. **Review and Edit:** | ||
- Proofread the report for clarity, coherence, and correctness. | ||
- Make sure the report flows logically from one section to the next. | ||
- Format the report according to markdown standards. | ||
|
||
6. **Finalize the Report:** | ||
- Ensure the report is complete with all sections expanded and detailed. | ||
- Double-check formatting and make any necessary adjustments. | ||
|
||
**Expected Output:** | ||
A fully-fledged report with the main topics, each with a full section of information. Formatted as markdown without '```'. | ||
|
||
--- | ||
``` |
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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,64 @@ | ||
from typing import List | ||
|
||
from pydantic import BaseModel | ||
|
||
from crewai.agent import Agent | ||
from crewai.task import Task | ||
|
||
|
||
class PlannerTaskPydanticOutput(BaseModel): | ||
list_of_plans_per_task: List[str] | ||
|
||
|
||
class CrewPlanner: | ||
def __init__(self, tasks: List[Task]): | ||
self.tasks = tasks | ||
|
||
def _handle_crew_planning(self): | ||
"""Handles the Crew planning by creating detailed step-by-step plans for each task.""" | ||
planning_agent = self._create_planning_agent() | ||
tasks_summary = self._create_tasks_summary() | ||
|
||
planner_task = self._create_planner_task(planning_agent, tasks_summary) | ||
|
||
return planner_task.execute_sync() | ||
|
||
def _create_planning_agent(self) -> Agent: | ||
"""Creates the planning agent for the crew planning.""" | ||
return Agent( | ||
role="Task Execution Planner", | ||
goal=( | ||
"Your goal is to create an extremely detailed, step-by-step plan based on the tasks and tools " | ||
"available to each agent so that they can perform the tasks in an exemplary manner" | ||
), | ||
backstory="Planner agent for crew planning", | ||
) | ||
|
||
def _create_planner_task(self, planning_agent: Agent, tasks_summary: str) -> Task: | ||
"""Creates the planner task using the given agent and tasks summary.""" | ||
return Task( | ||
description=( | ||
f"Based on these tasks summary: {tasks_summary} \n Create the most descriptive plan based on the tasks " | ||
"descriptions, tools available, and agents' goals for them to execute their goals with perfection." | ||
), | ||
expected_output="Step by step plan on how the agents can execute their tasks using the available tools with mastery", | ||
agent=planning_agent, | ||
output_pydantic=PlannerTaskPydanticOutput, | ||
) | ||
|
||
def _create_tasks_summary(self) -> str: | ||
"""Creates a summary of all tasks.""" | ||
tasks_summary = [] | ||
for idx, task in enumerate(self.tasks): | ||
tasks_summary.append( | ||
f""" | ||
Task Number {idx + 1} - {task.description} | ||
"task_description": {task.description} | ||
"task_expected_output": {task.expected_output} | ||
"agent": {task.agent.role if task.agent else "None"} | ||
"agent_goal": {task.agent.goal if task.agent else "None"} | ||
"task_tools": {task.tools} | ||
"agent_tools": {task.agent.tools if task.agent else "None"} | ||
""" | ||
) | ||
return " ".join(tasks_summary) |
This file contains 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
This file contains 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,68 @@ | ||
from unittest.mock import patch | ||
|
||
import pytest | ||
|
||
from crewai.agent import Agent | ||
from crewai.task import Task | ||
from crewai.utilities.planning_handler import CrewPlanner, PlannerTaskPydanticOutput | ||
|
||
|
||
class TestCrewPlanner: | ||
@pytest.fixture | ||
def crew_planner(self): | ||
tasks = [ | ||
Task( | ||
description="Task 1", | ||
expected_output="Output 1", | ||
agent=Agent(role="Agent 1", goal="Goal 1", backstory="Backstory 1"), | ||
), | ||
Task( | ||
description="Task 2", | ||
expected_output="Output 2", | ||
agent=Agent(role="Agent 2", goal="Goal 2", backstory="Backstory 2"), | ||
), | ||
Task( | ||
description="Task 3", | ||
expected_output="Output 3", | ||
agent=Agent(role="Agent 3", goal="Goal 3", backstory="Backstory 3"), | ||
), | ||
] | ||
return CrewPlanner(tasks) | ||
|
||
def test_handle_crew_planning(self, crew_planner): | ||
with patch.object(Task, "execute_sync") as execute: | ||
execute.return_value = PlannerTaskPydanticOutput( | ||
list_of_plans_per_task=["Plan 1", "Plan 2", "Plan 3"] | ||
) | ||
result = crew_planner._handle_crew_planning() | ||
assert isinstance(result, PlannerTaskPydanticOutput) | ||
assert len(result.list_of_plans_per_task) == len(crew_planner.tasks) | ||
execute.assert_called_once() | ||
|
||
def test_create_planning_agent(self, crew_planner): | ||
agent = crew_planner._create_planning_agent() | ||
assert isinstance(agent, Agent) | ||
assert agent.role == "Task Execution Planner" | ||
|
||
def test_create_planner_task(self, crew_planner): | ||
planning_agent = Agent( | ||
role="Planning Agent", | ||
goal="Plan Step by Step Plan", | ||
backstory="Master in Planning", | ||
) | ||
tasks_summary = "Summary of tasks" | ||
task = crew_planner._create_planner_task(planning_agent, tasks_summary) | ||
|
||
assert isinstance(task, Task) | ||
assert task.description.startswith("Based on these tasks summary") | ||
assert task.agent == planning_agent | ||
assert ( | ||
task.expected_output | ||
== "Step by step plan on how the agents can execute their tasks using the available tools with mastery" | ||
) | ||
|
||
def test_create_tasks_summary(self, crew_planner): | ||
tasks_summary = crew_planner._create_tasks_summary() | ||
assert isinstance(tasks_summary, str) | ||
assert tasks_summary.startswith("\n Task Number 1 - Task 1") | ||
assert tasks_summary.endswith('"agent_tools": []\n ') |
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.
This was added to fix the Type Checking issue that was before this task.
@joaomdmoura On a second note, I was talking with @bhancockio, and we realized that the "if sef.converter_cls" was added by this PR #800
The issue with this overall function is that based on the typed return it should return a Converter, but both self.agent.get_output_converter and self.converter_cls could be None. So for now I'm raising the exception, but do you think is there something better that we can do it here or if its relevant to have this "converter_cls"?