mirror of
https://github.com/crewAIInc/crewAI-examples.git
synced 2026-01-10 06:17:58 -05:00
Reorganize repo structure and upgrade to CrewAI 0.152.0 (#277)
* Reorganize repo structure and upgrade to CrewAI 0.152.0 * chore(gitignore): ignore Python bytecode and __pycache__ across templates * chore(gitignore): ignore Python bytecode and __pycache__ across templates; clean tracked artifacts * Update crews/instagram_post/pyproject.toml Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
3
flows/self_evaluation_loop_flow/.gitignore
vendored
Normal file
3
flows/self_evaluation_loop_flow/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
.env
|
||||
__pycache__/
|
||||
lib/
|
||||
80
flows/self_evaluation_loop_flow/README.md
Normal file
80
flows/self_evaluation_loop_flow/README.md
Normal file
@@ -0,0 +1,80 @@
|
||||
# Self Evaluation Loop Flow
|
||||
|
||||
Welcome to the Self Evaluation Loop Flow project, powered by [crewAI](https://crewai.com). This project showcases a powerful pattern in AI workflows: automatic self-evaluation. By leveraging crewAI's multi-agent system, this flow demonstrates how to set up a Crew that evaluates the responses of other Crews, iterating with feedback to improve results.
|
||||
|
||||
## Overview
|
||||
|
||||
This flow guides you through setting up an automated self-evaluation system using two main Crews: the `ShakespeareanXPostCrew` and the `XPostReviewCrew`. The process involves the following steps:
|
||||
|
||||
1. **Generate Initial Output**: The `ShakespeareanXPostCrew` generates an initial Shakespearean-style post (X post) on a given topic, such as "Flying cars". This post is crafted to be humorous and playful, adhering to specific character limits and style guidelines.
|
||||
|
||||
2. **Evaluate Output**: The `XPostReviewCrew` evaluates the generated post to ensure it meets the required criteria, such as character count and absence of emojis. The crew provides feedback on the post's validity and quality.
|
||||
|
||||
3. **Iterate with Feedback**: If the post does not meet the criteria, the flow iterates by regenerating the post with the feedback provided. This iterative process continues until the post is valid or a maximum retry limit is reached.
|
||||
|
||||
4. **Finalize and Save**: Once the post is validated, it is finalized and saved for further use. If the maximum retry count is exceeded without achieving a valid post, the flow exits with the last generated post and feedback.
|
||||
|
||||
This pattern of automatic self-evaluation is crucial for developing robust AI systems that can adapt and improve over time, ensuring high-quality outputs through iterative refinement.
|
||||
|
||||
## Installation
|
||||
|
||||
Ensure you have Python >=3.10 <=3.13 installed on your system.
|
||||
|
||||
To install CrewAI, run the following command:
|
||||
|
||||
```bash
|
||||
pip install crewai==0.130.0
|
||||
```
|
||||
|
||||
This command will install CrewAI and its necessary dependencies, allowing you to start building and managing AI agents efficiently.
|
||||
|
||||
### Customizing
|
||||
|
||||
**Add your `OPENAI_API_KEY` into the `.env` file**
|
||||
|
||||
- Modify `src/flow_self_evalulation_loop/config/agents.yaml` to define your agents.
|
||||
- Modify `src/flow_self_evalulation_loop/config/tasks.yaml` to define your tasks.
|
||||
- Modify `src/flow_self_evalulation_loop/crew.py` to add your own logic, tools, and specific arguments.
|
||||
- Modify `src/flow_self_evalulation_loop/main.py` to add custom inputs for your agents and tasks.
|
||||
|
||||
## Running the Project
|
||||
|
||||
To kickstart your crew of AI agents and begin task execution, run this from the root folder of your project:
|
||||
|
||||
```bash
|
||||
crewai flow kickoff
|
||||
```
|
||||
|
||||
|
||||
This command initializes the self-evaluation loop flow, assembling the agents and assigning them tasks as defined in your configuration.
|
||||
|
||||
The unmodified example will generate a `report.md` file with the output of a research on LLMs in the root folder.
|
||||
|
||||
## Understanding Your Flow
|
||||
|
||||
The self-evaluation loop flow is composed of 2 Crews. These agents collaborate on a series of tasks, defined in `config/tasks.yaml`, leveraging their collective skills to achieve complex objectives. The `config/agents.yaml` file outlines the capabilities and configurations of each agent in your flow.
|
||||
|
||||
This flow is centered around two major Crews: the `ShakespeareanXPostCrew` and the `XPostReviewCrew`. The `ShakespeareanXPostCrew` is responsible for generating a Shakespearean-style post (X post) on a given topic, while the `XPostReviewCrew` evaluates the generated post to ensure it meets specific criteria. The process is iterative, using feedback from the review to refine the post until it is valid or a maximum retry limit is reached.
|
||||
|
||||
### Flow Structure
|
||||
|
||||
1. **Generate Initial Output**: A Crew generates the initial output based on predefined criteria.
|
||||
|
||||
2. **Evaluate Output**: Another Crew evaluates the output, providing feedback on its validity and quality.
|
||||
|
||||
3. **Iterate with Feedback**: If necessary, the initial Crew is re-run with feedback to improve the output.
|
||||
|
||||
4. **Finalize and Save**: Once validated, the output is saved for further use.
|
||||
|
||||
By understanding the flow structure, you can see how multiple Crews are orchestrated to work together, each handling a specific part of the self-evaluation process. This modular approach allows for efficient and scalable automation.
|
||||
|
||||
## Support
|
||||
|
||||
For support, questions, or feedback regarding the Self Evaluation Loop Flow or crewAI:
|
||||
|
||||
- Visit our [documentation](https://docs.crewai.com)
|
||||
- Reach out to us through our [GitHub repository](https://github.com/joaomdmoura/crewai)
|
||||
- [Join our Discord](https://discord.com/invite/X4JWnZnxPb)
|
||||
- [Chat with our docs](https://chatg.pt/DWjSBZn)
|
||||
|
||||
Let's create wonders together with the power and simplicity of crewAI.
|
||||
202
flows/self_evaluation_loop_flow/crewai_flow.html
Normal file
202
flows/self_evaluation_loop_flow/crewai_flow.html
Normal file
File diff suppressed because one or more lines are too long
17
flows/self_evaluation_loop_flow/pyproject.toml
Normal file
17
flows/self_evaluation_loop_flow/pyproject.toml
Normal file
@@ -0,0 +1,17 @@
|
||||
[project]
|
||||
name = "self_evaluation_loop_flow"
|
||||
version = "0.1.0"
|
||||
description = "self-evalulation-loop-flow using crewAI"
|
||||
authors = [{ name = "Your Name", email = "you@example.com" }]
|
||||
requires-python = ">=3.10,<=3.13"
|
||||
dependencies = [
|
||||
"crewai[tools]>=0.152.0",
|
||||
]
|
||||
|
||||
[project.scripts]
|
||||
kickoff = "self_evaluation_loop_flow.main:kickoff"
|
||||
plot = "self_evaluation_loop_flow.main:plot"
|
||||
|
||||
[build-system]
|
||||
requires = ["hatchling"]
|
||||
build-backend = "hatchling.build"
|
||||
BIN
flows/self_evaluation_loop_flow/self_evaluation_loop_flow.png
Normal file
BIN
flows/self_evaluation_loop_flow/self_evaluation_loop_flow.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 160 KiB |
@@ -0,0 +1,10 @@
|
||||
shakespearean_bard:
|
||||
role: >
|
||||
Shakespearean Bard
|
||||
goal: >
|
||||
Craft sarcastic and playful hot takes in the style of Shakespeare.
|
||||
Ensure that all responses fit within 280 characters and contain no emojis.
|
||||
backstory: >
|
||||
Thou art a witty bard, renowned for turning the mundane into the
|
||||
magnificent with thy playful jests and biting sarcasm. Armed with wit and
|
||||
wisdom, thou dost revel in the creation of humorous quips most pleasing to the ear.
|
||||
@@ -0,0 +1,12 @@
|
||||
write_x_post:
|
||||
description: >
|
||||
Given the topic '{topic}', compose a humorous hot take in the style of Shakespeare.
|
||||
The tone should be sarcastic and playful. The final short form social media post
|
||||
must be over 200 characters and not exceed 280 characters, and emojis are strictly forbidden.
|
||||
|
||||
Please incorporate the following feedback if present:
|
||||
{feedback}
|
||||
expected_output: >
|
||||
A witty, Shakespearean hot take between 200 and 280 characters [Inclusive].
|
||||
agent: shakespearean_bard
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
from crewai import Agent, Crew, Process, Task
|
||||
from crewai.project import CrewBase, agent, crew, task
|
||||
from self_evaluation_loop_flow.tools.CharacterCounterTool import CharacterCounterTool
|
||||
|
||||
|
||||
@CrewBase
|
||||
class ShakespeareanXPostCrew:
|
||||
"""Shakespearean X Post Crew"""
|
||||
|
||||
agents_config = "config/agents.yaml"
|
||||
tasks_config = "config/tasks.yaml"
|
||||
|
||||
@agent
|
||||
def shakespearean_bard(self) -> Agent:
|
||||
return Agent(
|
||||
config=self.agents_config["shakespearean_bard"],
|
||||
tools=[CharacterCounterTool()],
|
||||
)
|
||||
|
||||
@task
|
||||
def write_x_post(self) -> Task:
|
||||
return Task(
|
||||
config=self.tasks_config["write_x_post"],
|
||||
)
|
||||
|
||||
@crew
|
||||
def crew(self) -> Crew:
|
||||
"""Creates the Shakespearean X Post 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,
|
||||
)
|
||||
@@ -0,0 +1,10 @@
|
||||
x_post_verifier:
|
||||
role: >
|
||||
X Post Verifier
|
||||
goal: >
|
||||
Ensure that any X post meets the strict guidelines:
|
||||
it must be under 280 characters, contain no emojis, and be free of additional commentary.
|
||||
backstory: >
|
||||
You are a careful reviewer, skilled at understanding the core message of a post.
|
||||
Your job is to maintain the clarity and brevity of the post by ensuring it contains no emojis,
|
||||
unnecessary commentary, or excessive verbosity.
|
||||
@@ -0,0 +1,30 @@
|
||||
verify_x_post:
|
||||
description: >
|
||||
Verify that the given X post meets the following criteria:
|
||||
- It is between 200 and 280 characters inclusive.
|
||||
- It contains no emojis.
|
||||
- It contains only the post itself, without additional commentary.
|
||||
|
||||
The post should follow the 1-3-1 rule:
|
||||
- 1 bold statement to hook the reader
|
||||
- 3 lines of supporting information
|
||||
- 1 sentence to summarize the post
|
||||
|
||||
Additionally, if you believe there are any issues with the post
|
||||
or ways it could be improved, such as the structure of the post,
|
||||
rhythm, word choice, please provide feedback.
|
||||
|
||||
If any of the criteria are not met, the post is considered invalid.
|
||||
Provide actionable changes about what is wrong and what actions
|
||||
need to be taken to fix the post.
|
||||
|
||||
Your final response must include:
|
||||
- Valid: True/False
|
||||
- Feedback: Provide commentary if the post fails any of the criteria.
|
||||
|
||||
X Post to Verify:
|
||||
{x_post}
|
||||
expected_output: >
|
||||
Pass: True/False
|
||||
Feedback: Commentary here if failed.
|
||||
agent: x_post_verifier
|
||||
@@ -0,0 +1,43 @@
|
||||
from typing import Optional
|
||||
|
||||
from crewai import Agent, Crew, Process, Task
|
||||
from crewai.project import CrewBase, agent, crew, task
|
||||
from pydantic import BaseModel
|
||||
from self_evaluation_loop_flow.tools.CharacterCounterTool import CharacterCounterTool
|
||||
|
||||
|
||||
class XPostVerification(BaseModel):
|
||||
valid: bool
|
||||
feedback: Optional[str]
|
||||
|
||||
|
||||
@CrewBase
|
||||
class XPostReviewCrew:
|
||||
"""X Post Review Crew"""
|
||||
|
||||
agents_config = "config/agents.yaml"
|
||||
tasks_config = "config/tasks.yaml"
|
||||
|
||||
@agent
|
||||
def x_post_verifier(self) -> Agent:
|
||||
return Agent(
|
||||
config=self.agents_config["x_post_verifier"],
|
||||
tools=[CharacterCounterTool()],
|
||||
)
|
||||
|
||||
@task
|
||||
def verify_x_post(self) -> Task:
|
||||
return Task(
|
||||
config=self.tasks_config["verify_x_post"],
|
||||
output_pydantic=XPostVerification,
|
||||
)
|
||||
|
||||
@crew
|
||||
def crew(self) -> Crew:
|
||||
"""Creates the X Post Review Crew"""
|
||||
return Crew(
|
||||
agents=self.agents,
|
||||
tasks=self.tasks,
|
||||
process=Process.sequential,
|
||||
verbose=True,
|
||||
)
|
||||
@@ -0,0 +1,81 @@
|
||||
from typing import Optional
|
||||
|
||||
from crewai.flow.flow import Flow, listen, router, start
|
||||
from pydantic import BaseModel
|
||||
|
||||
from self_evaluation_loop_flow.crews.shakespeare_crew.shakespeare_crew import (
|
||||
ShakespeareanXPostCrew,
|
||||
)
|
||||
from self_evaluation_loop_flow.crews.x_post_review_crew.x_post_review_crew import (
|
||||
XPostReviewCrew,
|
||||
)
|
||||
|
||||
|
||||
class ShakespeareXPostFlowState(BaseModel):
|
||||
x_post: str = ""
|
||||
feedback: Optional[str] = None
|
||||
valid: bool = False
|
||||
retry_count: int = 0
|
||||
|
||||
|
||||
class ShakespeareXPostFlow(Flow[ShakespeareXPostFlowState]):
|
||||
|
||||
@start("retry")
|
||||
def generate_shakespeare_x_post(self):
|
||||
print("Generating Shakespearean X post")
|
||||
topic = "Flying cars"
|
||||
result = (
|
||||
ShakespeareanXPostCrew()
|
||||
.crew()
|
||||
.kickoff(inputs={"topic": topic, "feedback": self.state.feedback})
|
||||
)
|
||||
|
||||
print("X post generated", result.raw)
|
||||
self.state.x_post = result.raw
|
||||
|
||||
@router(generate_shakespeare_x_post)
|
||||
def evaluate_x_post(self):
|
||||
if self.state.retry_count > 3:
|
||||
return "max_retry_exceeded"
|
||||
|
||||
result = XPostReviewCrew().crew().kickoff(inputs={"x_post": self.state.x_post})
|
||||
self.state.valid = result["valid"]
|
||||
self.state.feedback = result["feedback"]
|
||||
|
||||
print("valid", self.state.valid)
|
||||
print("feedback", self.state.feedback)
|
||||
self.state.retry_count += 1
|
||||
|
||||
if self.state.valid:
|
||||
return "complete"
|
||||
|
||||
return "retry"
|
||||
|
||||
@listen("complete")
|
||||
def save_result(self):
|
||||
print("X post is valid")
|
||||
print("X post:", self.state.x_post)
|
||||
|
||||
# Save the valid X post to a file
|
||||
with open("x_post.txt", "w") as file:
|
||||
file.write(self.state.x_post)
|
||||
|
||||
@listen("max_retry_exceeded")
|
||||
def max_retry_exceeded_exit(self):
|
||||
print("Max retry count exceeded")
|
||||
print("X post:", self.state.x_post)
|
||||
print("Feedback:", self.state.feedback)
|
||||
|
||||
|
||||
def kickoff():
|
||||
shakespeare_flow = ShakespeareXPostFlow()
|
||||
shakespeare_flow.kickoff()
|
||||
|
||||
|
||||
def plot():
|
||||
shakespeare_flow = ShakespeareXPostFlow()
|
||||
shakespeare_flow.plot()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
kickoff()
|
||||
@@ -0,0 +1,20 @@
|
||||
from typing import Type
|
||||
|
||||
from crewai_tools import BaseTool
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
|
||||
class CharacterCounterInput(BaseModel):
|
||||
"""Input schema for CharacterCounterTool."""
|
||||
|
||||
text: str = Field(..., description="The string to count characters in.")
|
||||
|
||||
|
||||
class CharacterCounterTool(BaseTool):
|
||||
name: str = "Character Counter Tool"
|
||||
description: str = "Counts the number of characters in a given string."
|
||||
args_schema: Type[BaseModel] = CharacterCounterInput
|
||||
|
||||
def _run(self, text: str) -> str:
|
||||
character_count = len(text)
|
||||
return f"The input string has {character_count} characters."
|
||||
4583
flows/self_evaluation_loop_flow/uv.lock
generated
Normal file
4583
flows/self_evaluation_loop_flow/uv.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user