This commit is contained in:
Brandon Hancock
2024-08-01 16:55:38 -04:00
parent 9996cf206e
commit 41a0a10914
8 changed files with 232 additions and 29 deletions

View File

@@ -16,4 +16,19 @@ reporting_analyst:
backstory: >
You're a meticulous analyst with a keen eye for detail. You're known for
your ability to turn complex data into clear and concise reports, making
it easy for others to understand and act on the information you provide.
it easy for others to understand and act on the information you provide.
x_writer_agent:
role: >
Expert Social Media Content Creator specializing in short form written content
goal: >
Create viral-worthy, engaging short form posts that distill complex {topic} information
into compelling 280-character messages
backstory: >
You're a social media virtuoso with a particular talent for short form content. Your posts
consistently go viral due to your ability to craft hooks that stop users mid-scroll.
You've studied the techniques of social media masters like Justin Welsh, Dickie Bush,
Nicolas Cole, and Shaan Puri, incorporating their best practices into your own unique style.
Your superpower is taking intricate {topic} concepts and transforming them into
bite-sized, shareable content that resonates with a wide audience. You know exactly
how to structure a post for maximum impact and engagement.

View File

@@ -12,6 +12,28 @@ reporting_task:
Review the context you got and expand each topic into a full section for a report.
Make sure the report is detailed and contains any and all relevant information.
expected_output: >
A fully fledge reports with the mains topics, each with a full section of information.
Formatted as markdown without '```'
A fully fledge reports with a title, mains topics, each with a full section of information.
agent: reporting_analyst
write_x_task:
description: >
Using the research report provided, create an engaging short form post about {topic}.
Your post should have a great hook, summarize key points, and be structured for easy
consumption on a digital platform. The post must be under 280 characters.
Follow these guidelines:
1. Start with an attention-grabbing hook
2. Condense the main insights from the research
3. Use clear, concise language
4. Include a call-to-action or thought-provoking question if space allows
5. Ensure the post flows well and is easy to read quickly
Here is the title of the research report you will be using
Title: {title}
Research:
{research}
expected_output: >
A compelling X post under 280 characters that effectively summarizes the key findings
about {topic}, starts with a strong hook, and is optimized for engagement on the platform.
agent: x_writer_agent

View File

@@ -0,0 +1,58 @@
from pydantic import BaseModel
from crewai import Agent, Crew, Process, Task
from crewai.project import CrewBase, agent, crew, task
# Uncomment the following line to use an example of a custom tool
# from {{folder_name}}.tools.custom_tool import MyCustomTool
# Check our tools documentations for more information on how to use them
# from crewai_tools import SerperDevTool
class ResearchReport(BaseModel):
"""Research Report"""
title: str
body: str
@CrewBase
class ResearchCrew():
"""Research Crew"""
agents_config = '../config/agents.yaml'
tasks_config = '../config/tasks.yaml'
@agent
def researcher(self) -> Agent:
return Agent(
config=self.agents_config['researcher'],
verbose=True
)
@agent
def reporting_analyst(self) -> Agent:
return Agent(
config=self.agents_config['reporting_analyst'],
verbose=True
)
@task
def research_task(self) -> Task:
return Task(
config=self.tasks_config['research_task'],
)
@task
def reporting_task(self) -> Task:
return Task(
config=self.tasks_config['reporting_task'],
output_pydantic=ResearchReport
)
@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=2,
)

View File

@@ -8,8 +8,8 @@ from crewai.project import CrewBase, agent, crew, task
# from crewai_tools import SerperDevTool
@CrewBase
class {{crew_name}}Crew():
"""{{crew_name}} crew"""
class WriteLinkedInCrew():
"""Research Crew"""
agents_config = '../config/agents.yaml'
tasks_config = '../config/tasks.yaml'
@@ -17,7 +17,6 @@ class {{crew_name}}Crew():
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
)
@@ -49,5 +48,4 @@ class {{crew_name}}Crew():
tasks=self.tasks, # Automatically created by the @task decorator
process=Process.sequential,
verbose=2,
# process=Process.hierarchical, # In case you wanna use that instead https://docs.crewai.com/how-to/Hierarchical/
)

View File

@@ -0,0 +1,37 @@
from crewai import Agent, Crew, Process, Task
from crewai.project import CrewBase, agent, crew, task
# Uncomment the following line to use an example of a custom tool
# from {{folder_name}}.tools.custom_tool import MyCustomTool
# Check our tools documentations for more information on how to use them
# from crewai_tools import SerperDevTool
@CrewBase
class WriteXCrew():
"""Research Crew"""
agents_config = '../config/agents.yaml'
tasks_config = '../config/tasks.yaml'
@agent
def x_writer_agent(self) -> Agent:
return Agent(
config=self.agents_config['x_writer_agent'],
verbose=True
)
@task
def write_x_task(self) -> Task:
return Task(
config=self.tasks_config['write_x_task'],
)
@crew
def crew(self) -> Crew:
"""Creates the Write X 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=2,
)

View File

@@ -1,17 +1,26 @@
#!/usr/bin/env python
import asyncio
from {{folder_name}}.src.{{folder_name}}.pipeline import {{pipeline_name}}Pipeline
from pipeline import {{pipeline_name}}Pipeline
async def run():
"""
Run the pipeline.
"""
inputs = [
{"topic": "AI LLMs"},
{"topic": "AI wearables"},
]
await {{pipeline_name}}Pipeline().pipeline().kickoff(inputs=inputs)
pipeline = {{pipeline_name}}Pipeline().pipeline()
results = await pipeline.kickoff(inputs)
# Process and print results
for result in results:
print(f"Raw output: {result.raw}")
if result.json_dict:
print(f"JSON output: {result.json_dict}")
print("\n")
def main():
asyncio.run(run())
if __name__ == "__main__":
asyncio.run(run())
main()

View File

@@ -1,26 +1,91 @@
"""
This pipeline file includes two different examples to demonstrate the flexibility of crewAI pipelines.
Example 1: Two-Stage Pipeline
-----------------------------
This pipeline consists of two crews:
1. ResearchCrew: Performs research on a given topic.
2. WriteXCrew: Generates an X (Twitter) post based on the research findings.
Key features:
- The ResearchCrew's final task uses output_json to store all research findings in a JSON object.
- This JSON object is then passed to the WriteXCrew, where tasks can access the research findings.
Example 2: Three-Stage Pipeline with Parallel Execution
-------------------------------------------------------
This pipeline consists of three crews:
1. ResearchCrew: Performs research on a given topic.
2. WriteXCrew and WriteLinkedInCrew: Run in parallel, using the research findings to generate posts for X and LinkedIn, respectively.
Key features:
- Demonstrates the ability to run multiple crews in parallel.
- Shows how to structure a pipeline with both sequential and parallel stages.
Usage:
- To switch between examples, comment/uncomment the respective code blocks below.
- Ensure that you have implemented all necessary crew classes (ResearchCrew, WriteXCrew, WriteLinkedInCrew) before running.
"""
# Common imports for both examples
from crewai import Pipeline
from crewai.project import PipelineBase
from crews.crew import *
from crewai.project.pipeline_base import PipelineBase
from crewai.project.annotations import pipeline
# Uncomment the crews you need for your chosen example
from .crews.research_crew import ResearchCrew
from .crews.write_x_crew import WriteXCrew
# from .crews.write_linkedin_crew import WriteLinkedInCrew # Uncomment for Example 2
# EXAMPLE 1: Two-Stage Pipeline
# -----------------------------
# Uncomment the following code block to use Example 1
@PipelineBase
class {{pipeline_name}}Pipeline:
class ContentPipeline:
def __init__(self):
# Initialize crews
{% for crew_name in crew_names %}
self.{{crew_name.lower()}}_crew = {{crew_name}}Crew().crew()
{% endfor %}
self.research_crew = ResearchCrew().crew()
self.write_x_crew = WriteXCrew().crew()
@pipeline
def create_pipeline(self):
return Pipeline(
stages=[
{% for crew_name in crew_names %}
self.{{crew_name.lower()}}_crew,
{% endfor %}
self.research_crew,
self.write_x_crew
]
)
async def run(self, inputs):
pipeline = self.create_pipeline()
results = await pipeline.kickoff(inputs)
return results
return results
# EXAMPLE 2: Three-Stage Pipeline with Parallel Execution
# -------------------------------------------------------
# Uncomment the following code block to use Example 2
# @PipelineBase
# class ContentPipeline:
# def __init__(self):
# # Initialize crews
# self.research_crew = ResearchCrew().crew()
# self.write_x_crew = WriteXCrew().crew()
# self.write_linkedin_crew = WriteLinkedInCrew().crew()
# @pipeline
# def create_pipeline(self):
# return Pipeline(
# stages=[
# self.research_crew,
# [self.write_x_crew, self.write_linkedin_crew] # Parallel execution
# ]
# )
# async def run(self, inputs):
# pipeline = self.create_pipeline()
# results = await pipeline.kickoff(inputs)
# return results

View File

@@ -6,14 +6,13 @@ authors = ["Your Name <you@example.com>"]
[tool.poetry.dependencies]
python = ">=3.10,<=3.13"
crewai = { extras = ["tools"], version = "^0.46.0" }
#crewai = { extras = ["tools"], version = "^0.41.1" }
crewai = { extras = ["tools"], path = "/Users/brandonhancock/Code/crewai/crewAI" }
asyncio = "*"
[tool.poetry.scripts]
{{folder_name}} = "{{folder_name}}.main:run"
train = "{{folder_name}}.main:train"
replay = "{{folder_name}}.main:replay"
test = "{{folder_name}}.main:test"
{{folder_name}} = "{{folder_name}}.src.{{folder_name}}.main:main"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
build-backend = "poetry.core.masonry.api"