diff --git a/docs/concepts/crews.mdx b/docs/concepts/crews.mdx index ec0f190de..3225b48b6 100644 --- a/docs/concepts/crews.mdx +++ b/docs/concepts/crews.mdx @@ -41,6 +41,155 @@ A crew in crewAI represents a collaborative group of agents working together to **Crew Max RPM**: The `max_rpm` attribute sets the maximum number of requests per minute the crew can perform to avoid rate limits and will override individual agents' `max_rpm` settings if you set it. +## Creating Crews + +There are two ways to create crews in CrewAI: using **YAML configuration (recommended)** or defining them **directly in code**. + +### YAML Configuration (Recommended) + +Using YAML configuration provides a cleaner, more maintainable way to define crews and is consistent with how agents and tasks are defined in CrewAI projects. + +After creating your CrewAI project as outlined in the [Installation](/installation) section, you can define your crew in a class that inherits from `CrewBase` and uses decorators to define agents, tasks, and the crew itself. + +#### Example Crew Class with Decorators + +```python code +from crewai import Agent, Crew, Task, Process +from crewai.project import CrewBase, agent, task, crew, before_kickoff, after_kickoff + + +@CrewBase +class YourCrewName: + """Description of your crew""" + + # Paths to your YAML configuration files + # To see an example agent and task defined in YAML, checkout the following: + # - Task: https://docs.crewai.com/concepts/tasks#yaml-configuration-recommended + # - Agents: https://docs.crewai.com/concepts/agents#yaml-configuration-recommended + agents_config = 'config/agents.yaml' + tasks_config = 'config/tasks.yaml' + + @before_kickoff + def prepare_inputs(self, inputs): + # Modify inputs before the crew starts + inputs['additional_data'] = "Some extra information" + return inputs + + @after_kickoff + def process_output(self, output): + # Modify output after the crew finishes + output.raw += "\nProcessed after kickoff." + return output + + @agent + def agent_one(self) -> Agent: + return Agent( + config=self.agents_config['agent_one'], + verbose=True + ) + + @agent + def agent_two(self) -> Agent: + return Agent( + config=self.agents_config['agent_two'], + verbose=True + ) + + @task + def task_one(self) -> Task: + return Task( + config=self.tasks_config['task_one'] + ) + + @task + def task_two(self) -> Task: + return Task( + config=self.tasks_config['task_two'] + ) + + @crew + def crew(self) -> Crew: + return Crew( + agents=self.agents, # Automatically collected by the @agent decorator + tasks=self.tasks, # Automatically collected by the @task decorator. + process=Process.sequential, + verbose=True, + ) +``` + + +Tasks will be executed in the order they are defined. + + +The `CrewBase` class, along with these decorators, automates the collection of agents and tasks, reducing the need for manual management. + +#### Decorators overview from `annotations.py` + +CrewAI provides several decorators in the `annotations.py` file that are used to mark methods within your crew class for special handling: + +- `@CrewBase`: Marks the class as a crew base class. +- `@agent`: Denotes a method that returns an `Agent` object. +- `@task`: Denotes a method that returns a `Task` object. +- `@crew`: Denotes the method that returns the `Crew` object. +- `@before_kickoff`: (Optional) Marks a method to be executed before the crew starts. +- `@after_kickoff`: (Optional) Marks a method to be executed after the crew finishes. + +These decorators help in organizing your crew's structure and automatically collecting agents and tasks without manually listing them. + +### Direct Code Definition (Alternative) + +Alternatively, you can define the crew directly in code without using YAML configuration files. + +```python code +from crewai import Agent, Crew, Task, Process +from crewai_tools import YourCustomTool + +class YourCrewName: + def agent_one(self) -> Agent: + return Agent( + role="Data Analyst", + goal="Analyze data trends in the market", + backstory="An experienced data analyst with a background in economics", + verbose=True, + tools=[YourCustomTool()] + ) + + def agent_two(self) -> Agent: + return Agent( + role="Market Researcher", + goal="Gather information on market dynamics", + backstory="A diligent researcher with a keen eye for detail", + verbose=True + ) + + def task_one(self) -> Task: + return Task( + description="Collect recent market data and identify trends.", + expected_output="A report summarizing key trends in the market.", + agent=self.agent_one() + ) + + def task_two(self) -> Task: + return Task( + description="Research factors affecting market dynamics.", + expected_output="An analysis of factors influencing the market.", + agent=self.agent_two() + ) + + def crew(self) -> Crew: + return Crew( + agents=[self.agent_one(), self.agent_two()], + tasks=[self.task_one(), self.task_two()], + process=Process.sequential, + verbose=True + ) +``` + +In this example: + +- Agents and tasks are defined directly within the class without decorators. +- We manually create and manage the list of agents and tasks. +- This approach provides more control but can be less maintainable for larger projects. ## Crew Output @@ -188,4 +337,4 @@ Then, to replay from a specific task, use: crewai replay -t ``` -These commands let you replay from your latest kickoff tasks, still retaining context from previously executed tasks. \ No newline at end of file +These commands let you replay from your latest kickoff tasks, still retaining context from previously executed tasks. diff --git a/pyproject.toml b/pyproject.toml index 86891294c..cac8bab9b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "crewai" -version = "0.85.0" +version = "0.86.0" description = "Cutting-edge framework for orchestrating role-playing, autonomous AI agents. By fostering collaborative intelligence, CrewAI empowers agents to work together seamlessly, tackling complex tasks." readme = "README.md" requires-python = ">=3.10,<=3.13" @@ -15,7 +15,7 @@ dependencies = [ "opentelemetry-exporter-otlp-proto-http>=1.22.0", "instructor>=1.3.3", "regex>=2024.9.11", - "crewai-tools>=0.14.0", + "crewai-tools>=0.17.0", "click>=8.1.7", "python-dotenv>=1.0.0", "appdirs>=1.4.4", diff --git a/src/crewai/__init__.py b/src/crewai/__init__.py index a6ec565e9..0833afd58 100644 --- a/src/crewai/__init__.py +++ b/src/crewai/__init__.py @@ -14,7 +14,7 @@ warnings.filterwarnings( category=UserWarning, module="pydantic.main", ) -__version__ = "0.85.0" +__version__ = "0.86.0" __all__ = [ "Agent", "Crew", diff --git a/src/crewai/cli/templates/crew/crew.py b/src/crewai/cli/templates/crew/crew.py index 0a8c7481a..383bfac48 100644 --- a/src/crewai/cli/templates/crew/crew.py +++ b/src/crewai/cli/templates/crew/crew.py @@ -1,37 +1,26 @@ from crewai import Agent, Crew, Process, Task -from crewai.project import CrewBase, agent, crew, task, before_kickoff, after_kickoff -# Uncomment the following line to use an example of a custom tool -# from {{folder_name}}.tools.custom_tool import MyCustomTool -# Uncomment the following line to use an example of a knowledge source -# from crewai.knowledge.source.text_file_knowledge_source import TextFileKnowledgeSource +from crewai.project import CrewBase, agent, crew, task -# Check our tools documentations for more information on how to use them -# from crewai_tools import SerperDevTool +# If you want to run a snippet of code before or after the crew starts, +# you can use the @before_kickoff and @after_kickoff decorators +# https://docs.crewai.com/concepts/crews#example-crew-class-with-decorators @CrewBase class {{crew_name}}(): """{{crew_name}} crew""" + # Learn more about YAML configuration files here: + # Agents: https://docs.crewai.com/concepts/agents#yaml-configuration-recommended + # Tasks: https://docs.crewai.com/concepts/tasks#yaml-configuration-recommended agents_config = 'config/agents.yaml' tasks_config = 'config/tasks.yaml' - @before_kickoff # Optional hook to be executed before the crew starts - def pull_data_example(self, inputs): - # Example of pulling data from an external API, dynamically changing the inputs - inputs['extra_data'] = "This is extra data" - return inputs - - @after_kickoff # Optional hook to be executed after the crew has finished - def log_results(self, output): - # Example of logging results, dynamically changing the output - print(f"Results: {output}") - return output - + # If you would like to add tools to your agents, you can learn more about it here: + # https://docs.crewai.com/concepts/agents#agent-tools @agent def researcher(self) -> Agent: return Agent( config=self.agents_config['researcher'], - # tools=[MyCustomTool()], # Example of custom tool, loaded on the beginning of file verbose=True ) @@ -42,6 +31,9 @@ class {{crew_name}}(): verbose=True ) + # To learn more about structured task outputs, + # task dependencies, and task callbacks, check out the documentation: + # https://docs.crewai.com/concepts/tasks#overview-of-a-task @task def research_task(self) -> Task: return Task( @@ -58,14 +50,8 @@ class {{crew_name}}(): @crew def crew(self) -> Crew: """Creates the {{crew_name}} crew""" - # You can add knowledge sources here - # knowledge_path = "user_preference.txt" - # sources = [ - # TextFileKnowledgeSource( - # file_path="knowledge/user_preference.txt", - # metadata={"preference": "personal"} - # ), - # ] + # To learn how to add knowledge sources to your crew, check out the documentation: + # https://docs.crewai.com/concepts/knowledge#what-is-knowledge return Crew( agents=self.agents, # Automatically created by the @agent decorator @@ -73,5 +59,4 @@ class {{crew_name}}(): process=Process.sequential, verbose=True, # process=Process.hierarchical, # In case you wanna use that instead https://docs.crewai.com/how-to/Hierarchical/ - # knowledge_sources=sources, # In the case you want to add knowledge sources ) diff --git a/src/crewai/cli/templates/crew/pyproject.toml b/src/crewai/cli/templates/crew/pyproject.toml index e45732685..d9ac06cd0 100644 --- a/src/crewai/cli/templates/crew/pyproject.toml +++ b/src/crewai/cli/templates/crew/pyproject.toml @@ -5,7 +5,7 @@ description = "{{name}} using crewAI" authors = [{ name = "Your Name", email = "you@example.com" }] requires-python = ">=3.10,<=3.13" dependencies = [ - "crewai[tools]>=0.85.0,<1.0.0" + "crewai[tools]>=0.86.0,<1.0.0" ] [project.scripts] diff --git a/src/crewai/cli/templates/flow/crews/poem_crew/poem_crew.py b/src/crewai/cli/templates/flow/crews/poem_crew/poem_crew.py index cc3ce7150..5e978d985 100644 --- a/src/crewai/cli/templates/flow/crews/poem_crew/poem_crew.py +++ b/src/crewai/cli/templates/flow/crews/poem_crew/poem_crew.py @@ -1,31 +1,47 @@ from crewai import Agent, Crew, Process, Task from crewai.project import CrewBase, agent, crew, task +# If you want to run a snippet of code before or after the crew starts, +# you can use the @before_kickoff and @after_kickoff decorators +# https://docs.crewai.com/concepts/crews#example-crew-class-with-decorators + + @CrewBase -class PoemCrew(): - """Poem Crew""" +class PoemCrew: + """Poem Crew""" - agents_config = 'config/agents.yaml' - tasks_config = 'config/tasks.yaml' + # Learn more about YAML configuration files here: + # Agents: https://docs.crewai.com/concepts/agents#yaml-configuration-recommended + # Tasks: https://docs.crewai.com/concepts/tasks#yaml-configuration-recommended + agents_config = "config/agents.yaml" + tasks_config = "config/tasks.yaml" - @agent - def poem_writer(self) -> Agent: - return Agent( - config=self.agents_config['poem_writer'], - ) + # If you would lik to add tools to your crew, you can learn more about it here: + # https://docs.crewai.com/concepts/agents#agent-tools + @agent + def poem_writer(self) -> Agent: + return Agent( + config=self.agents_config["poem_writer"], + ) - @task - def write_poem(self) -> Task: - return Task( - config=self.tasks_config['write_poem'], - ) + # To learn more about structured task outputs, + # task dependencies, and task callbacks, check out the documentation: + # https://docs.crewai.com/concepts/tasks#overview-of-a-task + @task + def write_poem(self) -> Task: + return Task( + config=self.tasks_config["write_poem"], + ) - @crew - def crew(self) -> Crew: - """Creates the Research Crew""" - return Crew( - agents=self.agents, # Automatically created by the @agent decorator - tasks=self.tasks, # Automatically created by the @task decorator - process=Process.sequential, - verbose=True, - ) + @crew + def crew(self) -> Crew: + """Creates the Research Crew""" + # To learn how to add knowledge sources to your crew, check out the documentation: + # https://docs.crewai.com/concepts/knowledge#what-is-knowledge + + return Crew( + agents=self.agents, # Automatically created by the @agent decorator + tasks=self.tasks, # Automatically created by the @task decorator + process=Process.sequential, + verbose=True, + ) diff --git a/src/crewai/cli/templates/flow/pyproject.toml b/src/crewai/cli/templates/flow/pyproject.toml index d981987c8..ba4f4a823 100644 --- a/src/crewai/cli/templates/flow/pyproject.toml +++ b/src/crewai/cli/templates/flow/pyproject.toml @@ -5,7 +5,7 @@ description = "{{name}} using crewAI" authors = [{ name = "Your Name", email = "you@example.com" }] requires-python = ">=3.10,<=3.13" dependencies = [ - "crewai[tools]>=0.85.0,<1.0.0", + "crewai[tools]>=0.86.0,<1.0.0", ] [project.scripts] diff --git a/src/crewai/cli/templates/pipeline/pyproject.toml b/src/crewai/cli/templates/pipeline/pyproject.toml new file mode 100644 index 000000000..97abd41a5 --- /dev/null +++ b/src/crewai/cli/templates/pipeline/pyproject.toml @@ -0,0 +1,17 @@ +[tool.poetry] +name = "{{folder_name}}" +version = "0.1.0" +description = "{{name}} using crewAI" +authors = ["Your Name "] + +[tool.poetry.dependencies] +python = ">=3.10,<=3.13" +crewai = { extras = ["tools"], version = ">=0.86.0,<1.0.0" } +asyncio = "*" + +[tool.poetry.scripts] +{{folder_name}} = "{{folder_name}}.main:main" + +[build-system] +requires = ["poetry-core"] +build-backend = "poetry.core.masonry.api" \ No newline at end of file diff --git a/src/crewai/cli/templates/tool/pyproject.toml b/src/crewai/cli/templates/tool/pyproject.toml index 33dabd38e..585bbef38 100644 --- a/src/crewai/cli/templates/tool/pyproject.toml +++ b/src/crewai/cli/templates/tool/pyproject.toml @@ -5,6 +5,6 @@ description = "Power up your crews with {{folder_name}}" readme = "README.md" requires-python = ">=3.10,<=3.13" dependencies = [ - "crewai[tools]>=0.85.0" + "crewai[tools]>=0.86.0" ] diff --git a/uv.lock b/uv.lock index 900e730da..42fb38424 100644 --- a/uv.lock +++ b/uv.lock @@ -608,7 +608,7 @@ wheels = [ [[package]] name = "crewai" -version = "0.85.0" +version = "0.86.0" source = { editable = "." } dependencies = [ { name = "appdirs" }, @@ -685,7 +685,7 @@ requires-dist = [ { name = "auth0-python", specifier = ">=4.7.1" }, { name = "chromadb", specifier = ">=0.5.18" }, { name = "click", specifier = ">=8.1.7" }, - { name = "crewai-tools", specifier = ">=0.14.0" }, + { name = "crewai-tools", specifier = ">=0.17.0" }, { name = "crewai-tools", marker = "extra == 'tools'", specifier = ">=0.14.0" }, { name = "fastembed", marker = "extra == 'fastembed'", specifier = ">=0.4.1" }, { name = "instructor", specifier = ">=1.3.3" }, @@ -733,7 +733,7 @@ dev = [ [[package]] name = "crewai-tools" -version = "0.14.0" +version = "0.17.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "beautifulsoup4" }, @@ -742,7 +742,6 @@ dependencies = [ { name = "docx2txt" }, { name = "embedchain" }, { name = "lancedb" }, - { name = "langchain" }, { name = "openai" }, { name = "pydantic" }, { name = "pyright" }, @@ -751,9 +750,9 @@ dependencies = [ { name = "requests" }, { name = "selenium" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/9b/6d/4fa91b481b120f83bb58f365203d8aa8564e8ced1035d79f8aedb7d71e2f/crewai_tools-0.14.0.tar.gz", hash = "sha256:510f3a194bcda4fdae4314bd775521964b5f229ddbe451e5d9e0216cae57f4e3", size = 815892 } +sdist = { url = "https://files.pythonhosted.org/packages/cc/15/365f74e0e8313e7a3399bf01d908aa73575c823275f9196ec14c23159878/crewai_tools-0.17.0.tar.gz", hash = "sha256:2a2986000775c76bad45b9f3a2be857d293cf5daffe5f316abc052e630b1e5ce", size = 818983 } wheels = [ - { url = "https://files.pythonhosted.org/packages/c8/ed/9f4e64e1507062957b0118085332d38b621c1000874baef2d1c4069bfd97/crewai_tools-0.14.0-py3-none-any.whl", hash = "sha256:0a804a828c29869c3af3253f4fc4c3967a3f80f06dab22e9bbe9526608a31564", size = 462980 }, + { url = "https://files.pythonhosted.org/packages/f4/1d/976adc2a4e5237cb03625de412cd051dea7d524084ed442adedfda871526/crewai_tools-0.17.0-py3-none-any.whl", hash = "sha256:85cf15286684ecad579b5a497888c6bf8a079ca443f7dd63a52bf1709655e4a3", size = 467975 }, ] [[package]]