mirror of
https://github.com/crewAIInc/crewAI-examples.git
synced 2026-04-23 03:00:08 -04:00
Merge branch 'main' into patch-1
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1 +1,2 @@
|
||||
.DS_Store
|
||||
.DS_Store
|
||||
.env
|
||||
@@ -32,7 +32,7 @@ This example uses GPT-4.
|
||||
- `./src/nodes.py`: Class with the function for each node.
|
||||
- `./src/state.py`: State declaration.
|
||||
- `./src/crew/agents.py`: Class defining the CrewAI Agents.
|
||||
- `./src/crew/taks.py`: Class definig the CrewAI Tasks.
|
||||
- `./src/crew/tasks.py`: Class definig the CrewAI Tasks.
|
||||
- `./src/crew/crew.py`: Class defining the CrewAI Crew.
|
||||
- `./src/crew/tools.py`: Class implementing the GmailDraft Tool.
|
||||
|
||||
|
||||
@@ -15,12 +15,12 @@ class CreateDraftTool():
|
||||
email, subject, message = data.split('|')
|
||||
gmail = GmailToolkit()
|
||||
draft = GmailCreateDraft(api_resource=gmail.api_resource)
|
||||
resutl = draft({
|
||||
result = draft({
|
||||
'to': [email],
|
||||
'subject': subject,
|
||||
'message': message
|
||||
})
|
||||
return f"\nDraft created: {resutl}\n"
|
||||
return f"\nDraft created: {result}\n"
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -5,6 +5,12 @@ This is a collection of examples of different ways to use the crewAI framework t
|
||||
By [@joaomdmoura](https://x.com/joaomdmoura).
|
||||
|
||||
## Examples
|
||||
- [Marketing Strategy](https://github.com/joaomdmoura/crewAI-examples/tree/main/marketing_strategy)
|
||||
- [Surprise Trip](https://github.com/joaomdmoura/crewAI-examples/tree/main/surprise_trip)
|
||||
- [Match to Proposal](https://github.com/joaomdmoura/crewAI-examples/tree/main/match_profile_to_positions)
|
||||
- [Find Job Candidades Demo](https://github.com/joaomdmoura/crewAI-examples/tree/main/recruitment)
|
||||
|
||||
## Old Examples, need to be updated
|
||||
|
||||
### Basic Examples
|
||||
- [Create Job Posting](https://github.com/joaomdmoura/crewAI-examples/tree/main/job-posting)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from textwrap import dedent
|
||||
from crewai import Agent
|
||||
|
||||
|
||||
class GameAgents():
|
||||
def senior_engineer_agent(self):
|
||||
return Agent(
|
||||
@@ -17,14 +18,14 @@ class GameAgents():
|
||||
def qa_engineer_agent(self):
|
||||
return Agent(
|
||||
role='Software Quality Control Engineer',
|
||||
goal='create prefect code, by analizing the code that is given for errors',
|
||||
backstory=dedent("""\
|
||||
goal='Create Perfect code, by analyzing the code that is given for errors',
|
||||
backstory=dedent("""\
|
||||
You are a software engineer that specializes in checking code
|
||||
for errors. You have an eye for detail and a knack for finding
|
||||
for errors. You have an eye for detail and a knack for finding
|
||||
hidden bugs.
|
||||
You check for missing imports, variable declarations, mismatched
|
||||
You check for missing imports, variable declarations, mismatched
|
||||
brackets and syntax errors.
|
||||
You also check for security vulnerabilities, and logic errors"""),
|
||||
You also check for security vulnerabilities, and logic errors"""),
|
||||
allow_delegation=False,
|
||||
verbose=True
|
||||
)
|
||||
@@ -32,10 +33,10 @@ class GameAgents():
|
||||
def chief_qa_engineer_agent(self):
|
||||
return Agent(
|
||||
role='Chief Software Quality Control Engineer',
|
||||
goal='Ensure that the code does the job that it is supposed to do',
|
||||
backstory=dedent("""\
|
||||
goal='Ensure that the code does the job that it is supposed to do',
|
||||
backstory=dedent("""\
|
||||
You feel that programmers always do only half the job, so you are
|
||||
super dedicate to make high quality code."""),
|
||||
allow_delegation=True,
|
||||
verbose=True
|
||||
)
|
||||
)
|
||||
|
||||
@@ -7,10 +7,9 @@ class GameTasks():
|
||||
|
||||
Instructions
|
||||
------------
|
||||
{game}
|
||||
|
||||
Your Final answer must be the full python code, only the python code and nothing else.
|
||||
{game}
|
||||
"""),
|
||||
expected_output="Your Final answer must be the full python code, only the python code and nothing else.",
|
||||
agent=agent
|
||||
)
|
||||
|
||||
@@ -25,9 +24,8 @@ class GameTasks():
|
||||
Using the code you got, check for errors. Check for logic errors,
|
||||
syntax errors, missing imports, variable declarations, mismatched brackets,
|
||||
and security vulnerabilities.
|
||||
|
||||
Your Final answer must be the full python code, only the python code and nothing else.
|
||||
"""),
|
||||
expected_output="Your Final answer must be the full python code, only the python code and nothing else.",
|
||||
agent=agent
|
||||
)
|
||||
|
||||
@@ -41,8 +39,7 @@ class GameTasks():
|
||||
|
||||
You will look over the code to insure that it is complete and
|
||||
does the job that it is supposed to do.
|
||||
|
||||
Your Final answer must be the full python code, only the python code and nothing else.
|
||||
"""),
|
||||
expected_output="Your Final answer must be the full python code, only the python code and nothing else.",
|
||||
agent=agent
|
||||
)
|
||||
@@ -14,7 +14,7 @@ By [@joaomdmoura](https://x.com/joaomdmoura)
|
||||
- [License](#license)
|
||||
|
||||
## CrewAI Framework
|
||||
CrewAI is designed to facilitate the collaboration of role-playing AI agents. In this example, these agents work together to give a complete stock analysis and investment recommendation
|
||||
CrewAI is designed to facilitate the collaboration of role-playing AI agents. In this example, these agents work together to generate a creative and trendy instagram post.
|
||||
|
||||
## Running the Script
|
||||
This example uses OpenHermes 2.5 through Ollama by default so you should to download [Ollama](ollama.ai) and [OpenHermes](https://ollama.ai/library/openhermes).
|
||||
@@ -26,7 +26,7 @@ You can change the model by changing the `MODEL` env var in the `.env` file.
|
||||
- **Execute the Script**: Run `python main.py` and input your idea.
|
||||
|
||||
## Details & Explanation
|
||||
- **Running the Script**: Execute `python main.py`` and input your idea when prompted. The script will leverage the CrewAI framework to process the idea and generate a landing page.
|
||||
- **Running the Script**: Execute `python main.py`` and input your idea when prompted. The script will leverage the CrewAI framework to process the idea and generate an instagram post.
|
||||
- **Key Components**:
|
||||
- `./main.py`: Main script file.
|
||||
- `./tasks.py`: Main file with the tasks prompts.
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
from crewai import Agent
|
||||
from crewai_tools.tools import WebsiteSearchTool, SeperDevTool, FileReadTool
|
||||
from crewai_tools.tools import WebsiteSearchTool, SerperDevTool, FileReadTool
|
||||
|
||||
web_search_tool = WebsiteSearchTool()
|
||||
seper_dev_tool = SeperDevTool()
|
||||
seper_dev_tool = SerperDevTool()
|
||||
file_read_tool = FileReadTool(
|
||||
file_path='job_description_example.md',
|
||||
description='A tool to read the job description example file.'
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
python-dotenv=1.0.1
|
||||
crewai=0.14.3
|
||||
python-dotenv==1.0.1
|
||||
crewai==0.14.3
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
## Introduction
|
||||
This project is an example using the CrewAI framework to automate the process of creating landing pages from a single idea. CrewAI orchestrates autonomous AI agents, enabling them to collaborate and execute complex tasks efficiently.
|
||||
|
||||
*Disclaimer: Templates are not inlcuded as they are Tailwind templates. Place Tailwind individual template folders in `./templates`, if you have a lincese you can download them at (https://tailwindui.com/templates), their references are at `config/templates.json`, this was not tested this with other templates, prompts in `tasks.py` might require some changes for that to work.*
|
||||
*Disclaimer: Templates are not included as they are Tailwind templates. Place Tailwind individual template folders in `./templates`, if you have a lincese you can download them at (https://tailwindui.com/templates), their references are at `config/templates.json`, this was not tested this with other templates, prompts in `tasks.py` might require some changes for that to work.*
|
||||
|
||||
By [@joaomdmoura](https://x.com/joaomdmoura)
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ class TaskPrompts():
|
||||
def choose_template():
|
||||
return dedent("""
|
||||
Learn the templates options choose and copy
|
||||
the one that suits the idea bellow the best,
|
||||
the one that suits the idea below the best,
|
||||
YOU MUST COPY, and then YOU MUST read the src/component
|
||||
in the directory you just copied, to decide what
|
||||
component files should be updated to make the
|
||||
|
||||
@@ -6,7 +6,8 @@ This project is an example using the CrewAI framework to automate the process re
|
||||
## Running the Script
|
||||
This example uses the OpenAI API to call a model. This can be through a locally hosted solution like LM Studio, or the Open AI API endpoint with your API key.
|
||||
|
||||
- **Configure Environment**: Copy `.env.example` and set up the environment variables the model, endpoint url, and api key.
|
||||
=======
|
||||
- **Configure Environment**: Rename `.env.example` to `.env` and set up the environment variables the model, endpoint url, and api key.
|
||||
- **Install Dependencies**: Run `poetry install --no-root`.
|
||||
- **Execute the Script**: Run `python main.py README.md` to see a list of recommended changes to this document.
|
||||
|
||||
|
||||
3
marketing_strategy/.env.example
Normal file
3
marketing_strategy/.env.example
Normal file
@@ -0,0 +1,3 @@
|
||||
SERPER_API_KEY=
|
||||
OPENAI_API_KEY=
|
||||
OPENAI_MODEL_NAME=gpt-4o
|
||||
39
marketing_strategy/README.md
Normal file
39
marketing_strategy/README.md
Normal file
@@ -0,0 +1,39 @@
|
||||
|
||||
# AI Crew for Marketing Strategy
|
||||
## Introduction
|
||||
This project demonstrates the use of the CrewAI framework to automate the creation of a marketing strategy. CrewAI orchestrates autonomous AI agents, enabling them to collaborate and execute complex tasks efficiently.
|
||||
|
||||
By [@joaomdmoura](https://x.com/joaomdmoura)
|
||||
|
||||
- [CrewAI Framework](#crewai-framework)
|
||||
- [Running the script](#running-the-script)
|
||||
- [Details & Explanation](#details--explanation)
|
||||
- [Contributing](#contributing)
|
||||
- [Support and Contact](#support-and-contact)
|
||||
- [License](#license)
|
||||
|
||||
## CrewAI Framework
|
||||
CrewAI is designed to facilitate the collaboration of role-playing AI agents. In this example, these agents work together to create a comprehensive marketing strategy and develop compelling marketing content.
|
||||
|
||||
## Running the Script
|
||||
It uses GPT-4o by default so you should have access to that to run it.
|
||||
|
||||
***Disclaimer:** This will use gpt-4o unless you change it to use a different model, and by doing so it may incur in different costs.*
|
||||
|
||||
- **Configure Environment**: Copy `.env.example` and set up the environment variables for [OpenAI](https://platform.openai.com/api-keys) and other tools as needed, like [Serper](serper.dev).
|
||||
- **Install Dependencies**: Run `poetry lock && poetry install`.
|
||||
- **Customize**: Modify `src/marketing_posts/main.py` to add custom inputs for your agents and tasks.
|
||||
- **Customize Further**: Check `src/marketing_posts/config/agents.yaml` to update your agents and `src/marketing_posts/config/tasks.yaml` to update your tasks.
|
||||
- **Execute the Script**: Run `poetry run marketing_posts` and input your project details.
|
||||
|
||||
## Details & Explanation
|
||||
- **Running the Script**: Execute `poetry run marketing_posts`. The script will leverage the CrewAI framework to generate a detailed marketing strategy.
|
||||
- **Key Components**:
|
||||
- `src/marketing_posts/main.py`: Main script file.
|
||||
- `src/marketing_posts/crew.py`: Main crew file where agents and tasks come together, and the main logic is executed.
|
||||
- `src/marketing_posts/config/agents.yaml`: Configuration file for defining agents.
|
||||
- `src/marketing_posts/config/tasks.yaml`: Configuration file for defining tasks.
|
||||
- `src/marketing_posts/tools`: Contains tool classes used by the agents.
|
||||
|
||||
## License
|
||||
This project is released under the MIT License.
|
||||
5438
marketing_strategy/poetry.lock
generated
Normal file
5438
marketing_strategy/poetry.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
18
marketing_strategy/pyproject.toml
Normal file
18
marketing_strategy/pyproject.toml
Normal file
@@ -0,0 +1,18 @@
|
||||
[tool.poetry]
|
||||
name = "marketing_posts"
|
||||
version = "0.1.0"
|
||||
description = "marketing-posts using crewAI"
|
||||
authors = ["Your Name <you@example.com>"]
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = ">=3.10,<=3.13"
|
||||
crewai = { extras = ["tools"], version = "^0.35.8" }
|
||||
crewai-tools = "^0.4.6"
|
||||
|
||||
[tool.poetry.scripts]
|
||||
marketing_posts = "marketing_posts.main:run"
|
||||
train = "marketing_posts.main:train"
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core"]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
0
marketing_strategy/src/marketing_posts/__init__.py
Normal file
0
marketing_strategy/src/marketing_posts/__init__.py
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
43
marketing_strategy/src/marketing_posts/config/agents.yaml
Normal file
43
marketing_strategy/src/marketing_posts/config/agents.yaml
Normal file
@@ -0,0 +1,43 @@
|
||||
lead_market_analyst:
|
||||
role: >
|
||||
Lead Market Analyst
|
||||
goal: >
|
||||
Conduct amazing analysis of the products and competitors, providing in-depth
|
||||
insights to guide marketing strategies.
|
||||
backstory: >
|
||||
As the Lead Market Analyst at a premier digital marketing firm, you specialize
|
||||
in dissecting online business landscapes.
|
||||
|
||||
chief_marketing_strategist:
|
||||
role: >
|
||||
Chief Marketing Strategist
|
||||
goal: >
|
||||
Synthesize amazing insights from product analysis to formulate incredible
|
||||
marketing strategies.
|
||||
backstory: >
|
||||
You are the Chief Marketing Strategist at a leading digital marketing agency,
|
||||
known for crafting bespoke strategies that drive success.
|
||||
|
||||
creative_content_creator:
|
||||
role: >
|
||||
Creative Content Creator
|
||||
goal: >
|
||||
Develop compelling and innovative content for social media campaigns, with a
|
||||
focus on creating high-impact ad copies.
|
||||
backstory: >
|
||||
As a Creative Content Creator at a top-tier digital marketing agency, you
|
||||
excel in crafting narratives that resonate with audiences. Your expertise
|
||||
lies in turning marketing strategies into engaging stories and visual
|
||||
content that capture attention and inspire action.
|
||||
|
||||
chief_creative_director:
|
||||
role: >
|
||||
Chief Creative Director
|
||||
goal: >
|
||||
Oversee the work done by your team to make sure it is the best possible and
|
||||
aligned with the product goals, review, approve, ask clarifying questions or
|
||||
delegate follow-up work if necessary.
|
||||
backstory: >
|
||||
You are the Chief Content Officer at a leading digital marketing agency
|
||||
specializing in product branding. You ensure your team crafts the best
|
||||
possible content for the customer.
|
||||
42
marketing_strategy/src/marketing_posts/config/tasks.yaml
Normal file
42
marketing_strategy/src/marketing_posts/config/tasks.yaml
Normal file
@@ -0,0 +1,42 @@
|
||||
research_task:
|
||||
description: >
|
||||
Conduct a thorough research about the customer and competitors in the context
|
||||
of {customer_domain}.
|
||||
Make sure you find any interesting and relevant information given the
|
||||
current year is 2024.
|
||||
We are working with them on the following project: {project_description}.
|
||||
expected_output: >
|
||||
A complete report on the customer and their customers and competitors,
|
||||
including their demographics, preferences, market positioning and audience engagement.
|
||||
|
||||
project_understanding_task:
|
||||
description: >
|
||||
Understand the project details and the target audience for
|
||||
{project_description}.
|
||||
Review any provided materials and gather additional information as needed.
|
||||
expected_output: >
|
||||
A detailed summary of the project and a profile of the target audience.
|
||||
|
||||
marketing_strategy_task:
|
||||
description: >
|
||||
Formulate a comprehensive marketing strategy for the project
|
||||
{project_description} of the customer {customer_domain}.
|
||||
Use the insights from the research task and the project understanding
|
||||
task to create a high-quality strategy.
|
||||
expected_output: >
|
||||
A detailed marketing strategy document that outlines the goals, target
|
||||
audience, key messages, and proposed tactics, make sure to have name, tatics, channels and KPIs
|
||||
|
||||
campaign_idea_task:
|
||||
description: >
|
||||
Develop creative marketing campaign ideas for {project_description}.
|
||||
Ensure the ideas are innovative, engaging, and aligned with the overall marketing strategy.
|
||||
expected_output: >
|
||||
A list of 5 campaign ideas, each with a brief description and expected impact.
|
||||
|
||||
copy_creation_task:
|
||||
description: >
|
||||
Create marketing copies based on the approved campaign ideas for {project_description}.
|
||||
Ensure the copies are compelling, clear, and tailored to the target audience.
|
||||
expected_output: >
|
||||
Marketing copies for each campaign idea.
|
||||
111
marketing_strategy/src/marketing_posts/crew.py
Normal file
111
marketing_strategy/src/marketing_posts/crew.py
Normal file
@@ -0,0 +1,111 @@
|
||||
from typing import List
|
||||
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 marketing_posts.tools.custom_tool import MyCustomTool
|
||||
|
||||
# Check our tools documentations for more information on how to use them
|
||||
from crewai_tools import SerperDevTool, ScrapeWebsiteTool
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
class MarketStrategy(BaseModel):
|
||||
"""Market strategy model"""
|
||||
name: str = Field(..., description="Name of the market strategy")
|
||||
tatics: List[str] = Field(..., description="List of tactics to be used in the market strategy")
|
||||
channels: List[str] = Field(..., description="List of channels to be used in the market strategy")
|
||||
KPIs: List[str] = Field(..., description="List of KPIs to be used in the market strategy")
|
||||
|
||||
class CampaignIdea(BaseModel):
|
||||
"""Campaign idea model"""
|
||||
name: str = Field(..., description="Name of the campaign idea")
|
||||
description: str = Field(..., description="Description of the campaign idea")
|
||||
audience: str = Field(..., description="Audience of the campaign idea")
|
||||
channel: str = Field(..., description="Channel of the campaign idea")
|
||||
|
||||
class Copy(BaseModel):
|
||||
"""Copy model"""
|
||||
title: str = Field(..., description="Title of the copy")
|
||||
body: str = Field(..., description="Body of the copy")
|
||||
|
||||
@CrewBase
|
||||
class MarketingPostsCrew():
|
||||
"""MarketingPosts crew"""
|
||||
agents_config = 'config/agents.yaml'
|
||||
tasks_config = 'config/tasks.yaml'
|
||||
|
||||
@agent
|
||||
def lead_market_analyst(self) -> Agent:
|
||||
return Agent(
|
||||
config=self.agents_config['lead_market_analyst'],
|
||||
tools=[SerperDevTool(), ScrapeWebsiteTool()],
|
||||
verbose=True,
|
||||
memory=False,
|
||||
)
|
||||
|
||||
@agent
|
||||
def chief_marketing_strategist(self) -> Agent:
|
||||
return Agent(
|
||||
config=self.agents_config['chief_marketing_strategist'],
|
||||
tools=[SerperDevTool(), ScrapeWebsiteTool()],
|
||||
verbose=True,
|
||||
memory=False,
|
||||
)
|
||||
|
||||
@agent
|
||||
def creative_content_creator(self) -> Agent:
|
||||
return Agent(
|
||||
config=self.agents_config['creative_content_creator'],
|
||||
verbose=True,
|
||||
memory=False,
|
||||
)
|
||||
|
||||
@task
|
||||
def research_task(self) -> Task:
|
||||
return Task(
|
||||
config=self.tasks_config['research_task'],
|
||||
agent=self.lead_market_analyst()
|
||||
)
|
||||
|
||||
@task
|
||||
def project_understanding_task(self) -> Task:
|
||||
return Task(
|
||||
config=self.tasks_config['project_understanding_task'],
|
||||
agent=self.chief_marketing_strategist()
|
||||
)
|
||||
|
||||
@task
|
||||
def marketing_strategy_task(self) -> Task:
|
||||
return Task(
|
||||
config=self.tasks_config['marketing_strategy_task'],
|
||||
agent=self.chief_marketing_strategist(),
|
||||
output_json=MarketStrategy
|
||||
)
|
||||
|
||||
@task
|
||||
def campaign_idea_task(self) -> Task:
|
||||
return Task(
|
||||
config=self.tasks_config['campaign_idea_task'],
|
||||
agent=self.creative_content_creator(),
|
||||
output_json=CampaignIdea
|
||||
)
|
||||
|
||||
@task
|
||||
def copy_creation_task(self) -> Task:
|
||||
return Task(
|
||||
config=self.tasks_config['copy_creation_task'],
|
||||
agent=self.creative_content_creator(),
|
||||
context=[self.marketing_strategy_task(), self.campaign_idea_task()],
|
||||
output_json=Copy
|
||||
)
|
||||
|
||||
@crew
|
||||
def crew(self) -> Crew:
|
||||
"""Creates the MarketingPosts 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,
|
||||
# process=Process.hierarchical, # In case you wanna use that instead https://docs.crewai.com/how-to/Hierarchical/
|
||||
)
|
||||
37
marketing_strategy/src/marketing_posts/main.py
Normal file
37
marketing_strategy/src/marketing_posts/main.py
Normal file
@@ -0,0 +1,37 @@
|
||||
#!/usr/bin/env python
|
||||
import sys
|
||||
from marketing_posts.crew import MarketingPostsCrew
|
||||
|
||||
|
||||
def run():
|
||||
# Replace with your inputs, it will automatically interpolate any tasks and agents information
|
||||
inputs = {
|
||||
'customer_domain': 'crewai.com',
|
||||
'project_description': """
|
||||
CrewAI, a leading provider of multi-agent systems, aims to revolutionize marketing automation for its enterprise clients. This project involves developing an innovative marketing strategy to showcase CrewAI's advanced AI-driven solutions, emphasizing ease of use, scalability, and integration capabilities. The campaign will target tech-savvy decision-makers in medium to large enterprises, highlighting success stories and the transformative potential of CrewAI's platform.
|
||||
|
||||
Customer Domain: AI and Automation Solutions
|
||||
Project Overview: Creating a comprehensive marketing campaign to boost awareness and adoption of CrewAI's services among enterprise clients.
|
||||
"""
|
||||
}
|
||||
MarketingPostsCrew().crew().kickoff(inputs=inputs)
|
||||
|
||||
|
||||
def train():
|
||||
"""
|
||||
Train the crew for a given number of iterations.
|
||||
"""
|
||||
inputs = {
|
||||
'customer_domain': 'crewai.com',
|
||||
'project_description': """
|
||||
CrewAI, a leading provider of multi-agent systems, aims to revolutionize marketing automation for its enterprise clients. This project involves developing an innovative marketing strategy to showcase CrewAI's advanced AI-driven solutions, emphasizing ease of use, scalability, and integration capabilities. The campaign will target tech-savvy decision-makers in medium to large enterprises, highlighting success stories and the transformative potential of CrewAI's platform.
|
||||
|
||||
Customer Domain: AI and Automation Solutions
|
||||
Project Overview: Creating a comprehensive marketing campaign to boost awareness and adoption of CrewAI's services among enterprise clients.
|
||||
"""
|
||||
}
|
||||
try:
|
||||
MarketingPostsCrew().crew().train(n_iterations=int(sys.argv[1]), inputs=inputs)
|
||||
|
||||
except Exception as e:
|
||||
raise Exception(f"An error occurred while training the crew: {e}")
|
||||
1
marketing_strategy/trained_agents_data.pkl
Normal file
1
marketing_strategy/trained_agents_data.pkl
Normal file
@@ -0,0 +1 @@
|
||||
<EFBFBD>}<7D>.
|
||||
2
match_profile_to_positions/.env.example
Normal file
2
match_profile_to_positions/.env.example
Normal file
@@ -0,0 +1,2 @@
|
||||
OPENAI_API_KEY=
|
||||
OPENAI_MODEL_NAME=gpt-4o
|
||||
39
match_profile_to_positions/README.md
Normal file
39
match_profile_to_positions/README.md
Normal file
@@ -0,0 +1,39 @@
|
||||
|
||||
# AI Crew for Matching CVs to Job Proposals
|
||||
## Introduction
|
||||
This project demonstrates the use of the CrewAI framework to automate the process of matching CVs to job proposals. CrewAI orchestrates autonomous AI agents, enabling them to collaborate and execute complex tasks efficiently.
|
||||
|
||||
By [@joaomdmoura](https://x.com/joaomdmoura)
|
||||
|
||||
- [CrewAI Framework](#crewai-framework)
|
||||
- [Running the script](#running-the-script)
|
||||
- [Details & Explanation](#details--explanation)
|
||||
- [Contributing](#contributing)
|
||||
- [Support and Contact](#support-and-contact)
|
||||
- [License](#license)
|
||||
|
||||
## CrewAI Framework
|
||||
CrewAI is designed to facilitate the collaboration of role-playing AI agents. In this example, these agents work together to extract relevant information from CVs and match them to job opportunities, ensuring the best fit between candidates and job roles.
|
||||
|
||||
## Running the Script
|
||||
It uses GPT-4o by default so you should have access to that to run it.
|
||||
|
||||
***Disclaimer:** This will use gpt-4o unless you change it to use a different model, and by doing so it may incur different costs.*
|
||||
|
||||
- **Configure Environment**: Copy `.env.example` and set up the environment variables for [OpenAI](https://platform.openai.com/api-keys) and other tools as needed.
|
||||
- **Install Dependencies**: Run `poetry lock && poetry install`.
|
||||
- **Customize**: Modify `src/match_to_proposal/main.py` to add custom inputs for your agents and tasks.
|
||||
- **Customize Further**: Check `src/match_to_proposal/config/agents.yaml` to update your agents and `src/match_to_proposal/config/tasks.yaml` to update your tasks.
|
||||
- **Execute the Script**: Run `poetry run match_to_proposal` and input your project details.
|
||||
|
||||
## Details & Explanation
|
||||
- **Running the Script**: Execute `poetry run match_to_proposal`. The script will leverage the CrewAI framework to match CVs to job proposals and generate a detailed report.
|
||||
- **Key Components**:
|
||||
- `src/match_to_proposal/main.py`: Main script file.
|
||||
- `src/match_to_proposal/crew.py`: Main crew file where agents and tasks come together, and the main logic is executed.
|
||||
- `src/match_to_proposal/config/agents.yaml`: Configuration file for defining agents.
|
||||
- `src/match_to_proposal/config/tasks.yaml`: Configuration file for defining tasks.
|
||||
- `src/match_to_proposal/tools`: Contains tool classes used by the agents.
|
||||
|
||||
## License
|
||||
This project is released under the MIT License.
|
||||
BIN
match_profile_to_positions/db/chroma.sqlite3
Normal file
BIN
match_profile_to_positions/db/chroma.sqlite3
Normal file
Binary file not shown.
5438
match_profile_to_positions/poetry.lock
generated
Normal file
5438
match_profile_to_positions/poetry.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
18
match_profile_to_positions/pyproject.toml
Normal file
18
match_profile_to_positions/pyproject.toml
Normal file
@@ -0,0 +1,18 @@
|
||||
[tool.poetry]
|
||||
name = "match_to_proposal"
|
||||
version = "0.1.0"
|
||||
description = "match_to_proposal using crewAI"
|
||||
authors = ["Your Name <you@example.com>"]
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = ">=3.10,<=3.13"
|
||||
crewai = { extras = ["tools"], version = "^0.35.8" }
|
||||
crewai-tools = "^0.4.6"
|
||||
|
||||
[tool.poetry.scripts]
|
||||
match_to_proposal = "match_to_proposal.main:run"
|
||||
train = "match_to_proposal.main:train"
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core"]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,23 @@
|
||||
cv_reader:
|
||||
role: >
|
||||
CV Reader
|
||||
goal: >
|
||||
Extract relevant information from the CV, such as skills, experience, and education.
|
||||
backstory: >
|
||||
With years of experience in HR, you excel at quickly identifying key qualifications in resumes.
|
||||
|
||||
job_opportunities_parser:
|
||||
role: >
|
||||
Job Opportunities Parser
|
||||
goal: >
|
||||
Extract job descriptions from the CSV file, including job title, required skills, and responsibilities.
|
||||
backstory: >
|
||||
A data analyst who has transitioned into HR, you have a knack for organizing and interpreting job data.
|
||||
|
||||
matcher:
|
||||
role: >
|
||||
Matcher
|
||||
goal: >
|
||||
Match the CV to the job opportunities based on skills and experience.
|
||||
backstory: >
|
||||
A seasoned recruiter, you specialize in finding the perfect fit between candidates and job roles.
|
||||
@@ -0,0 +1,34 @@
|
||||
read_cv_task:
|
||||
description: >
|
||||
Extract relevant information from the given CV. Focus on skills, experience,
|
||||
education, and key achievements.
|
||||
Ensure to capture the candidate's professional summary, technical skills,
|
||||
work history, and educational background.
|
||||
|
||||
|
||||
CV file: {path_to_cv}
|
||||
expected_output: >
|
||||
A structured summary of the CV, including:
|
||||
- Professional Summary
|
||||
- Technical Skills
|
||||
- Work History
|
||||
- Education
|
||||
- Key Achievements
|
||||
|
||||
match_cv_task:
|
||||
description: >
|
||||
Match the CV to the job opportunities based on skills, experience, and key
|
||||
achievements.
|
||||
Evaluate how well the candidate's profile fits each job description,
|
||||
focusing on the alignment of skills, work history, and key achievements
|
||||
with the job requirements.
|
||||
|
||||
|
||||
Jobs CSV file: {path_to_jobs_csv}
|
||||
|
||||
CV file: {path_to_cv}
|
||||
expected_output: >
|
||||
A ranked list of job opportunities that best match the CV, including:
|
||||
- Job Title
|
||||
- Match Score (based on skills and experience)
|
||||
- Key Matching Points
|
||||
53
match_profile_to_positions/src/match_to_proposal/crew.py
Normal file
53
match_profile_to_positions/src/match_to_proposal/crew.py
Normal file
@@ -0,0 +1,53 @@
|
||||
from crewai import Agent, Crew, Process, Task
|
||||
from crewai.project import CrewBase, agent, crew, task
|
||||
|
||||
from crewai_tools import CSVSearchTool, FileReadTool
|
||||
|
||||
@CrewBase
|
||||
class MatchToProposalCrew():
|
||||
"""MatchToProposal crew"""
|
||||
agents_config = 'config/agents.yaml'
|
||||
tasks_config = 'config/tasks.yaml'
|
||||
|
||||
@agent
|
||||
def cv_reader(self) -> Agent:
|
||||
return Agent(
|
||||
config=self.agents_config['cv_reader'],
|
||||
tools=[FileReadTool()],
|
||||
verbose=True,
|
||||
allow_delegation=False
|
||||
)
|
||||
|
||||
@agent
|
||||
def matcher(self) -> Agent:
|
||||
return Agent(
|
||||
config=self.agents_config['matcher'],
|
||||
tools=[FileReadTool(), CSVSearchTool()],
|
||||
verbose=True,
|
||||
allow_delegation=False
|
||||
)
|
||||
|
||||
@task
|
||||
def read_cv_task(self) -> Task:
|
||||
return Task(
|
||||
config=self.tasks_config['read_cv_task'],
|
||||
agent=self.cv_reader()
|
||||
)
|
||||
|
||||
@task
|
||||
def match_cv_task(self) -> Task:
|
||||
return Task(
|
||||
config=self.tasks_config['match_cv_task'],
|
||||
agent=self.matcher()
|
||||
)
|
||||
|
||||
@crew
|
||||
def crew(self) -> Crew:
|
||||
"""Creates the MatchToProposal 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,
|
||||
# process=Process.hierarchical, # In case you want to use that instead https://docs.crewai.com/how-to/Hierarchical/
|
||||
)
|
||||
44
match_profile_to_positions/src/match_to_proposal/data/cv.md
Normal file
44
match_profile_to_positions/src/match_to_proposal/data/cv.md
Normal file
@@ -0,0 +1,44 @@
|
||||
# John Doe
|
||||
|
||||
## Professional Summary
|
||||
Experienced Software Engineer with a strong background in Python, JavaScript, and RESTful APIs. Proven ability to develop and maintain software applications, collaborate with cross-functional teams, and ensure code quality.
|
||||
|
||||
## Technical Skills
|
||||
- **Programming Languages**: Python, JavaScript
|
||||
- **Web Development**: RESTful APIs, HTML, CSS
|
||||
- **Frameworks/Libraries**: Django, Flask, React
|
||||
- **Tools**: Git, Docker, Jenkins
|
||||
- **Databases**: MySQL, PostgreSQL
|
||||
|
||||
## Work History
|
||||
|
||||
### Senior Software Engineer
|
||||
**Tech Innovations Inc., San Francisco, CA**
|
||||
*January 2020 - Present*
|
||||
- Developed and maintained multiple web applications using Python and JavaScript.
|
||||
- Collaborated with cross-functional teams to design and implement RESTful APIs.
|
||||
- Ensured code quality through rigorous testing and code reviews.
|
||||
- Automated deployment processes using Docker and Jenkins.
|
||||
|
||||
### Software Engineer
|
||||
**Innovative Solutions LLC, San Francisco, CA**
|
||||
*June 2017 - December 2019*
|
||||
- Worked on full-stack web development projects using Python and JavaScript.
|
||||
- Built and maintained RESTful APIs for various applications.
|
||||
- Participated in Agile development processes, including sprint planning and daily stand-ups.
|
||||
- Mentored junior developers and conducted code reviews.
|
||||
|
||||
## Education
|
||||
**Bachelor of Science in Computer Science**
|
||||
*University of California, Berkeley*
|
||||
*Graduated: May 2017*
|
||||
|
||||
## Key Achievements
|
||||
- Successfully led a project to migrate a legacy system to a modern web-based platform, resulting in a 30% increase in performance.
|
||||
- Recognized as Employee of the Month for outstanding performance and dedication.
|
||||
- Implemented a CI/CD pipeline that reduced deployment times by 50%.
|
||||
|
||||
## Contact Information
|
||||
- **Email**: john.doe@example.com
|
||||
- **Phone**: (123) 456-7890
|
||||
- **LinkedIn**: linkedin.com/in/johndoe
|
||||
@@ -0,0 +1,6 @@
|
||||
Job Title,Required Skills,Key Responsibilities,Company Name,Company Location
|
||||
Software Engineer,"Python,JavaScript,RESTful APIs","Develop and maintain software applications, collaborate with cross-functional teams, ensure code quality",TechCorp,San Francisco
|
||||
Data Scientist,"Python,R,Machine Learning,Data Analysis","Analyze large datasets to extract insights, build predictive models, collaborate with stakeholders",DataTech,New York
|
||||
Project Manager,"Agile, Scrum,Leadership,Communication","Manage project timelines, coordinate with team members, ensure project goals are met",ProjectPlus,Chicago
|
||||
DevOps Engineer,"Docker,Kubernetes,CI/CD","Implement and manage CI/CD pipelines, automate deployment processes, monitor system performance",DevOpsCo,Seattle
|
||||
Marketing Specialist,"SEO,Content Creation,Social Media","Develop and execute marketing campaigns, create content for various platforms, analyze campaign performance",MarketGenius,Los Angeles
|
||||
|
13
match_profile_to_positions/src/match_to_proposal/main.py
Normal file
13
match_profile_to_positions/src/match_to_proposal/main.py
Normal file
@@ -0,0 +1,13 @@
|
||||
#!/usr/bin/env python
|
||||
import sys
|
||||
from match_to_proposal.crew import MatchToProposalCrew
|
||||
|
||||
|
||||
def run():
|
||||
# Replace with your inputs, it will automatically interpolate any tasks and agents information
|
||||
inputs = {
|
||||
'path_to_jobs_csv': './src/match_to_proposal/data/jobs.csv',
|
||||
'path_to_cv': './src/match_to_proposal/data/cv.md'
|
||||
}
|
||||
MatchToProposalCrew().crew().kickoff(inputs=inputs)
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
from crewai_tools import BaseTool
|
||||
|
||||
|
||||
class MyCustomTool(BaseTool):
|
||||
name: str = "Name of my tool"
|
||||
description: str = (
|
||||
"Clear description for what this tool is useful for, you agent will need this information to use it."
|
||||
)
|
||||
|
||||
def _run(self, argument: str) -> str:
|
||||
# Implementation goes here
|
||||
return "this is an example of a tool output, ignore it and move along."
|
||||
1
match_profile_to_positions/trained_agents_data.pkl
Normal file
1
match_profile_to_positions/trained_agents_data.pkl
Normal file
@@ -0,0 +1 @@
|
||||
<EFBFBD>}<7D>.
|
||||
3
recruitment/.env.example
Normal file
3
recruitment/.env.example
Normal file
@@ -0,0 +1,3 @@
|
||||
OPENAI_API_KEY=Your openai key
|
||||
SERPER_API_KEY=Your serper key
|
||||
LINKEDIN_COOKIE=Your linkedin cookie
|
||||
53
recruitment/README.md
Normal file
53
recruitment/README.md
Normal file
@@ -0,0 +1,53 @@
|
||||
# AI Crew for Recruitment
|
||||
|
||||
**DISCALIMER** This example uses cookies to authenticate to LinkedIn, and it's meant only as an example or the selenium tool, using this for real-world applications may violate LinkedIn's terms of service and could lead to your account being banned. We do not endorse or encourage the use of this tool for any real-world applications.
|
||||
|
||||
## Introduction
|
||||
This project demonstrates the use of the CrewAI framework to automate the recruitment process. CrewAI orchestrates autonomous AI agents, enabling them to collaborate and execute complex tasks efficiently.
|
||||
|
||||
By [@joaomdmoura](https://x.com/joaomdmoura)
|
||||
|
||||
- [CrewAI Framework](#crewai-framework)
|
||||
- [Running the script](#running-the-script)
|
||||
- [Details & Explanation](#details--explanation)
|
||||
- [Contributing](#contributing)
|
||||
- [Support and Contact](#support-and-contact)
|
||||
- [License](#license)
|
||||
|
||||
## CrewAI Framework
|
||||
CrewAI is designed to facilitate the collaboration of role-playing AI agents. In this example, these agents work together to streamline the recruitment process, ensuring the best fit between candidates and job roles.
|
||||
|
||||
## Running the Script
|
||||
It uses GPT-4o by default so you should have access to that to run it.
|
||||
|
||||
***DISCALIMER:** This example uses cookies to authenticate to LinkedIn, and it's meant only as an example or the selenium tool, using this for real-world applications may violate LinkedIn's terms of service and could lead to your account being banned. We do not endorse or encourage the use of this tool for any real-world applications.*
|
||||
|
||||
***Disclaimer:** This will use gpt-4o unless you change it to use a different model, and by doing so it may incur different costs.*
|
||||
|
||||
- **Configure Environment**: Copy `.env.example` and set up the environment variables for [OpenAI](https://platform.openai.com/api-keys) and other tools as needed.
|
||||
- **Install Dependencies**: Run `poetry lock && poetry install`.
|
||||
- **Customize**: Modify `src/recruitment/main.py` to add custom inputs for your agents and tasks.
|
||||
- **Customize Further**: Check `src/recruitment/config/agents.yaml` to update your agents and `src/recruitment/config/tasks.yaml` to update your tasks.
|
||||
- **Custom Tools**: You can find custom tools at `recruitment/src/recruitment/tools/`.
|
||||
- **Execute the Script**: Run `poetry run recruitment` and input your project details.
|
||||
|
||||
### Stepts to get Linkedin Cookie (LI_AT)
|
||||
- Navigate to www.linkedin.com and log in
|
||||
- Open browser developer tools (Ctrl-Shift-I or right click -> inspect element)
|
||||
- Select the appropriate tab for your browser (Application on Chrome, Storage on Firefox)
|
||||
- Click the Cookies dropdown on the left-hand menu, and select the www.linkedin.com option
|
||||
- Find and copy the li_at value and add it to your .env file
|
||||
- Be sure to fetch the cookies again if selenium doesnt login to linkedin after a while
|
||||
|
||||
## Details & Explanation
|
||||
- **Running the Script**: Execute `poetry run recruitment`. The script will leverage the CrewAI framework to automate recruitment tasks and generate a detailed report.
|
||||
- **Running Training**: Execute `poetry run train n` where n is the number of training iterations.
|
||||
- **Key Components**:
|
||||
- `src/recruitment/main.py`: Main script file.
|
||||
- `src/recruitment/crew.py`: Main crew file where agents and tasks come together, and the main logic is executed.
|
||||
- `src/recruitment/config/agents.yaml`: Configuration file for defining agents.
|
||||
- `src/recruitment/config/tasks.yaml`: Configuration file for defining tasks.
|
||||
- `src/recruitment/tools`: Contains tool classes used by the agents.
|
||||
|
||||
## License
|
||||
This project is released under the MIT License.
|
||||
5438
recruitment/poetry.lock
generated
Normal file
5438
recruitment/poetry.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
18
recruitment/pyproject.toml
Normal file
18
recruitment/pyproject.toml
Normal file
@@ -0,0 +1,18 @@
|
||||
[tool.poetry]
|
||||
name = "recruitment"
|
||||
version = "0.1.0"
|
||||
description = "recruitment using crewAI"
|
||||
authors = ["Your Name <you@example.com>"]
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = ">=3.10,<=3.13"
|
||||
crewai = { extras = ["tools"], version = "^0.35.8" }
|
||||
selenium = "^4.21.0"
|
||||
|
||||
[tool.poetry.scripts]
|
||||
recruitment = "recruitment.main:run"
|
||||
train = "recruitment.main:train"
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core"]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
0
recruitment/src/recruitment/__init__.py
Normal file
0
recruitment/src/recruitment/__init__.py
Normal file
38
recruitment/src/recruitment/config/agents.yaml
Normal file
38
recruitment/src/recruitment/config/agents.yaml
Normal file
@@ -0,0 +1,38 @@
|
||||
researcher:
|
||||
role: >
|
||||
Job Candidate Researcher
|
||||
goal: >
|
||||
Find potential candidates for the job
|
||||
backstory: >
|
||||
You are adept at finding the right candidates by exploring various online
|
||||
resources. Your skill in identifying suitable candidates ensures the best
|
||||
match for job positions.
|
||||
|
||||
matcher:
|
||||
role: >
|
||||
Candidate Matcher and Scorer
|
||||
goal: >
|
||||
Match the candidates to the best jobs and score them
|
||||
backstory: >
|
||||
You have a knack for matching the right candidates to the right job positions
|
||||
using advanced algorithms and scoring techniques. Your scores help
|
||||
prioritize the best candidates for outreach.
|
||||
|
||||
communicator:
|
||||
role: >
|
||||
Candidate Outreach Strategist
|
||||
goal: >
|
||||
Develop outreach strategies for the selected candidates
|
||||
backstory: >
|
||||
You are skilled at creating effective outreach strategies and templates to
|
||||
engage candidates. Your communication tactics ensure high response rates
|
||||
from potential candidates.
|
||||
|
||||
reporter:
|
||||
role: >
|
||||
Candidate Reporting Specialist
|
||||
goal: >
|
||||
Report the best candidates to the recruiters
|
||||
backstory: >
|
||||
You are proficient at compiling and presenting detailed reports for recruiters.
|
||||
Your reports provide clear insights into the best candidates to pursue.
|
||||
38
recruitment/src/recruitment/config/tasks.yaml
Normal file
38
recruitment/src/recruitment/config/tasks.yaml
Normal file
@@ -0,0 +1,38 @@
|
||||
research_candidates_task:
|
||||
description: >
|
||||
Conduct thorough research to find potential candidates for the specified job.
|
||||
Utilize various online resources and databases to gather a comprehensive list of potential candidates.
|
||||
Ensure that the candidates meet the job requirements provided.
|
||||
|
||||
Job Requirements:
|
||||
{job_requirements}
|
||||
expected_output: >
|
||||
A list of 10 potential candidates with their contact information and brief profiles highlighting their suitability.
|
||||
|
||||
match_and_score_candidates_task:
|
||||
description: >
|
||||
Evaluate and match the candidates to the best job positions based on their qualifications and suitability.
|
||||
Score each candidate to reflect their alignment with the job requirements, ensuring a fair and transparent assessment process.
|
||||
Don't try to scrape people's linkedin, since you don't have access to it.
|
||||
|
||||
Job Requirements:
|
||||
{job_requirements}
|
||||
expected_output: >
|
||||
A ranked list of candidates with detailed scores and justifications for each job position.
|
||||
|
||||
outreach_strategy_task:
|
||||
description: >
|
||||
Develop a comprehensive strategy to reach out to the selected candidates.
|
||||
Create effective outreach methods and templates that can engage the candidates and encourage them to consider the job opportunity.
|
||||
|
||||
Job Requirements:
|
||||
{job_requirements}
|
||||
expected_output: >
|
||||
A detailed list of outreach methods and templates ready for implementation, including communication strategies and engagement tactics.
|
||||
|
||||
report_candidates_task:
|
||||
description: >
|
||||
Compile a comprehensive report for recruiters on the best candidates to put forward.
|
||||
Summarize the findings from the previous tasks and provide clear recommendations based on the job requirements.
|
||||
expected_output: >
|
||||
A detailed report with the best candidates to pursue, no need to include the job requirements formatted as markdown without '```', including profiles, scores, and outreach strategies.
|
||||
84
recruitment/src/recruitment/crew.py
Normal file
84
recruitment/src/recruitment/crew.py
Normal file
@@ -0,0 +1,84 @@
|
||||
from crewai import Agent, Crew, Process, Task
|
||||
from crewai.project import CrewBase, agent, crew, task
|
||||
from crewai_tools import SerperDevTool, ScrapeWebsiteTool
|
||||
from recruitment.tools.linkedin import LinkedInTool
|
||||
|
||||
@CrewBase
|
||||
class RecruitmentCrew():
|
||||
"""Recruitment crew"""
|
||||
agents_config = 'config/agents.yaml'
|
||||
tasks_config = 'config/tasks.yaml'
|
||||
|
||||
@agent
|
||||
def researcher(self) -> Agent:
|
||||
return Agent(
|
||||
config=self.agents_config['researcher'],
|
||||
tools=[SerperDevTool(), ScrapeWebsiteTool(), LinkedInTool()],
|
||||
allow_delegation=False,
|
||||
verbose=True
|
||||
)
|
||||
|
||||
@agent
|
||||
def matcher(self) -> Agent:
|
||||
return Agent(
|
||||
config=self.agents_config['matcher'],
|
||||
tools=[SerperDevTool(), ScrapeWebsiteTool()],
|
||||
allow_delegation=False,
|
||||
verbose=True
|
||||
)
|
||||
|
||||
@agent
|
||||
def communicator(self) -> Agent:
|
||||
return Agent(
|
||||
config=self.agents_config['communicator'],
|
||||
tools=[SerperDevTool(), ScrapeWebsiteTool()],
|
||||
allow_delegation=False,
|
||||
verbose=True
|
||||
)
|
||||
|
||||
@agent
|
||||
def reporter(self) -> Agent:
|
||||
return Agent(
|
||||
config=self.agents_config['reporter'],
|
||||
allow_delegation=False,
|
||||
verbose=True
|
||||
)
|
||||
|
||||
@task
|
||||
def research_candidates_task(self) -> Task:
|
||||
return Task(
|
||||
config=self.tasks_config['research_candidates_task'],
|
||||
agent=self.researcher()
|
||||
)
|
||||
|
||||
@task
|
||||
def match_and_score_candidates_task(self) -> Task:
|
||||
return Task(
|
||||
config=self.tasks_config['match_and_score_candidates_task'],
|
||||
agent=self.matcher()
|
||||
)
|
||||
|
||||
@task
|
||||
def outreach_strategy_task(self) -> Task:
|
||||
return Task(
|
||||
config=self.tasks_config['outreach_strategy_task'],
|
||||
agent=self.communicator()
|
||||
)
|
||||
|
||||
@task
|
||||
def report_candidates_task(self) -> Task:
|
||||
return Task(
|
||||
config=self.tasks_config['report_candidates_task'],
|
||||
agent=self.reporter(),
|
||||
context=[self.research_candidates_task(), self.match_and_score_candidates_task(), self.outreach_strategy_task()],
|
||||
)
|
||||
|
||||
@crew
|
||||
def crew(self) -> Crew:
|
||||
"""Creates the Recruitment crew"""
|
||||
return Crew(
|
||||
agents=self.agents,
|
||||
tasks=self.tasks,
|
||||
process=Process.sequential,
|
||||
verbose=2,
|
||||
)
|
||||
92
recruitment/src/recruitment/main.py
Normal file
92
recruitment/src/recruitment/main.py
Normal file
@@ -0,0 +1,92 @@
|
||||
#!/usr/bin/env python
|
||||
import sys
|
||||
from recruitment.crew import RecruitmentCrew
|
||||
|
||||
|
||||
def run():
|
||||
# Replace with your inputs, it will automatically interpolate any tasks and agents information
|
||||
inputs = {
|
||||
'job_requirements': """
|
||||
job_requirement:
|
||||
title: >
|
||||
Ruby on Rails and React Engineer
|
||||
description: >
|
||||
We are seeking a skilled Ruby on Rails and React engineer to join our team.
|
||||
The ideal candidate will have experience in both backend and frontend development,
|
||||
with a passion for building high-quality web applications.
|
||||
|
||||
responsibilities: >
|
||||
- Develop and maintain web applications using Ruby on Rails and React.
|
||||
- Collaborate with teams to define and implement new features.
|
||||
- Write clean, maintainable, and efficient code.
|
||||
- Ensure application performance and responsiveness.
|
||||
- Identify and resolve bottlenecks and bugs.
|
||||
|
||||
requirements: >
|
||||
- Proven experience with Ruby on Rails and React.
|
||||
- Strong understanding of object-oriented programming.
|
||||
- Proficiency with JavaScript, HTML, CSS, and React.
|
||||
- Experience with SQL or NoSQL databases.
|
||||
- Familiarity with code versioning tools, such as Git.
|
||||
|
||||
preferred_qualifications: >
|
||||
- Experience with cloud services (AWS, Google Cloud, or Azure).
|
||||
- Familiarity with Docker and Kubernetes.
|
||||
- Knowledge of GraphQL.
|
||||
- Bachelor's degree in Computer Science or a related field.
|
||||
|
||||
perks_and_benefits: >
|
||||
- Competitive salary and bonuses.
|
||||
- Health, dental, and vision insurance.
|
||||
- Flexible working hours and remote work options.
|
||||
- Professional development opportunities.
|
||||
"""
|
||||
}
|
||||
RecruitmentCrew().crew().kickoff(inputs=inputs)
|
||||
|
||||
def train():
|
||||
"""
|
||||
Train the crew for a given number of iterations.
|
||||
"""
|
||||
inputs = {
|
||||
'job_requirements': """
|
||||
job_requirement:
|
||||
title: >
|
||||
Ruby on Rails and React Engineer
|
||||
description: >
|
||||
We are seeking a skilled Ruby on Rails and React engineer to join our team.
|
||||
The ideal candidate will have experience in both backend and frontend development,
|
||||
with a passion for building high-quality web applications.
|
||||
|
||||
responsibilities: >
|
||||
- Develop and maintain web applications using Ruby on Rails and React.
|
||||
- Collaborate with teams to define and implement new features.
|
||||
- Write clean, maintainable, and efficient code.
|
||||
- Ensure application performance and responsiveness.
|
||||
- Identify and resolve bottlenecks and bugs.
|
||||
|
||||
requirements: >
|
||||
- Proven experience with Ruby on Rails and React.
|
||||
- Strong understanding of object-oriented programming.
|
||||
- Proficiency with JavaScript, HTML, CSS, and React.
|
||||
- Experience with SQL or NoSQL databases.
|
||||
- Familiarity with code versioning tools, such as Git.
|
||||
|
||||
preferred_qualifications: >
|
||||
- Experience with cloud services (AWS, Google Cloud, or Azure).
|
||||
- Familiarity with Docker and Kubernetes.
|
||||
- Knowledge of GraphQL.
|
||||
- Bachelor's degree in Computer Science or a related field.
|
||||
|
||||
perks_and_benefits: >
|
||||
- Competitive salary and bonuses.
|
||||
- Health, dental, and vision insurance.
|
||||
- Flexible working hours and remote work options.
|
||||
- Professional development opportunities.
|
||||
"""
|
||||
}
|
||||
try:
|
||||
RecruitmentCrew().crew().train(n_iterations=int(sys.argv[1]), inputs=inputs)
|
||||
|
||||
except Exception as e:
|
||||
raise Exception(f"An error occurred while training the crew: {e}")
|
||||
0
recruitment/src/recruitment/tools/__init__.py
Normal file
0
recruitment/src/recruitment/tools/__init__.py
Normal file
41
recruitment/src/recruitment/tools/client.py
Normal file
41
recruitment/src/recruitment/tools/client.py
Normal file
@@ -0,0 +1,41 @@
|
||||
import os
|
||||
import urllib
|
||||
from selenium.webdriver.common.by import By
|
||||
|
||||
from .driver import Driver
|
||||
|
||||
class Client:
|
||||
def __init__(self):
|
||||
url = 'https://linkedin.com/'
|
||||
cookie = {
|
||||
"name": "li_at",
|
||||
"value": os.environ["LINKEDIN_COOKIE"],
|
||||
"domain": ".linkedin.com"
|
||||
}
|
||||
|
||||
self.driver = Driver(url, cookie)
|
||||
|
||||
def find_people(self, skills):
|
||||
skills = skills.split(",")
|
||||
search = " ".join(skills)
|
||||
encoded_string = urllib.parse.quote(search.lower())
|
||||
url = f"https://www.linkedin.com/search/results/people/?keywords={encoded_string}"
|
||||
self.driver.navigate(url)
|
||||
|
||||
people = self.driver.get_elements("ul li div div.linked-area")
|
||||
|
||||
results = []
|
||||
for person in people:
|
||||
try:
|
||||
result = {}
|
||||
result["name"] = person.find_element(By.CSS_SELECTOR, "span.entity-result__title-line").text
|
||||
result["position"] = person.find_element(By.CSS_SELECTOR, "div.entity-result__primary-subtitle").text
|
||||
result["location"] = person.find_element(By.CSS_SELECTOR, "div.entity-result__secondary-subtitle").text
|
||||
except Exception as e:
|
||||
print(e)
|
||||
continue
|
||||
results.append(result)
|
||||
return results
|
||||
|
||||
def close(self):
|
||||
self.driver.close()
|
||||
45
recruitment/src/recruitment/tools/driver.py
Normal file
45
recruitment/src/recruitment/tools/driver.py
Normal file
@@ -0,0 +1,45 @@
|
||||
import time
|
||||
from selenium import webdriver
|
||||
from selenium.webdriver.common.by import By
|
||||
from selenium.webdriver.firefox.options import Options
|
||||
|
||||
class Driver:
|
||||
def __init__(self, url, cookie=None):
|
||||
self.driver = self._create_driver(url, cookie)
|
||||
|
||||
def navigate(self, url, wait=3):
|
||||
self.driver.get(url)
|
||||
time.sleep(wait)
|
||||
|
||||
def scroll_to_bottom(self, wait=3):
|
||||
self.driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
|
||||
time.sleep(wait)
|
||||
self.driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
|
||||
time.sleep(wait)
|
||||
|
||||
def get_element(self, selector):
|
||||
return self.driver.find_element(By.CSS_SELECTOR, selector)
|
||||
|
||||
def get_elements(self, selector):
|
||||
return self.driver.find_elements(By.CSS_SELECTOR, selector)
|
||||
|
||||
def fill_text_field(self, selector, text):
|
||||
element = self.get_element(selector)
|
||||
element.clear()
|
||||
element.send_keys(text)
|
||||
|
||||
def click_button(self, selector):
|
||||
element = self.get_element(selector)
|
||||
element.click()
|
||||
|
||||
def _create_driver(self, url, cookie):
|
||||
options = Options()
|
||||
# options.add_argument("--headless")
|
||||
driver = webdriver.Firefox(options=options)
|
||||
driver.get(url)
|
||||
if cookie:
|
||||
driver.add_cookie(cookie)
|
||||
return driver
|
||||
|
||||
def close(self):
|
||||
self.driver.close()
|
||||
29
recruitment/src/recruitment/tools/linkedin.py
Normal file
29
recruitment/src/recruitment/tools/linkedin.py
Normal file
@@ -0,0 +1,29 @@
|
||||
from crewai_tools import BaseTool
|
||||
|
||||
from .client import Client as LinkedinClient
|
||||
|
||||
|
||||
class LinkedInTool(BaseTool):
|
||||
name: str = "Retrieve LinkedIn profiles"
|
||||
description: str = (
|
||||
"Retrieve LinkedIn profiles given a list of skills. Comma separated"
|
||||
)
|
||||
|
||||
def _run(self, skills: str) -> str:
|
||||
linkedin_client = LinkedinClient()
|
||||
people = linkedin_client.find_people(skills)
|
||||
people = self._format_publications_to_text(people)
|
||||
linkedin_client.close()
|
||||
return people
|
||||
|
||||
def _format_publications_to_text(self, people):
|
||||
result = ["\n".join([
|
||||
"Person Profile",
|
||||
"-------------",
|
||||
p['name'],
|
||||
p['position'],
|
||||
p['location']
|
||||
]) for p in people]
|
||||
result = "\n\n".join(result)
|
||||
|
||||
return result
|
||||
1
screenplay_writer/.env
Normal file
1
screenplay_writer/.env
Normal file
@@ -0,0 +1 @@
|
||||
OPENAI_API_KEY = <Enter Key Here>
|
||||
55
screenplay_writer/config /agents.yaml
Normal file
55
screenplay_writer/config /agents.yaml
Normal file
@@ -0,0 +1,55 @@
|
||||
spamfilter:
|
||||
role: >
|
||||
spamfilter
|
||||
goal: >
|
||||
Decide whether a text is spam or not.
|
||||
backstory: >
|
||||
You are an expert spam filter with years of experience. You DETEST advertisements, newsletters and vulgar language.
|
||||
|
||||
analyst:
|
||||
role: >
|
||||
analyse
|
||||
goal: >
|
||||
You will distill all arguments from all discussion members. Identify who said what. You can reword what they said as long as the main discussion points remain.
|
||||
backstory: >
|
||||
You are an expert discussion analyst.
|
||||
|
||||
scriptwriter:
|
||||
role: >
|
||||
scriptwriter
|
||||
goal: >
|
||||
Turn a conversation into a movie script. Only write the dialogue parts. Do not start the sentence with an action. Do not specify situational descriptions. Do not write parentheticals.
|
||||
backstory: >
|
||||
You are an expert on writing natural sounding movie script dialogues. You only focus on the text part and you HATE directional notes.
|
||||
|
||||
formatter:
|
||||
role: >
|
||||
formatter
|
||||
goal: >
|
||||
Format the text as asked. Leave out actions from discussion members that happen between brackets, eg (smiling).
|
||||
backstory: >
|
||||
You are an expert text formatter.
|
||||
|
||||
scorer:
|
||||
role: >
|
||||
scorer
|
||||
goal: >
|
||||
You score a dialogue assessing various aspects of the exchange between the participants using a 1-10 scale, where 1 is the lowest performance and 10 is the highest:
|
||||
Scale:
|
||||
1-3: Poor - The dialogue has significant issues that prevent effective communication.
|
||||
4-6: Average - The dialogue has some good points but also has notable weaknesses.
|
||||
7-9: Good - The dialogue is mostly effective with minor issues.
|
||||
10: Excellent - The dialogue is exemplary in achieving its purpose with no apparent issues.
|
||||
Factors to Consider:
|
||||
Clarity: How clear is the exchange? Are the statements and responses easy to understand?
|
||||
Relevance: Do the responses stay on topic and contribute to the conversation's purpose?
|
||||
Conciseness: Is the dialogue free of unnecessary information or redundancy?
|
||||
Politeness: Are the participants respectful and considerate in their interaction?
|
||||
Engagement: Do the participants seem interested and actively involved in the dialogue?
|
||||
Flow: Is there a natural progression of ideas and responses? Are there awkward pauses or interruptions?
|
||||
Coherence: Does the dialogue make logical sense as a whole?
|
||||
Responsiveness: Do the participants address each other's points adequately?
|
||||
Language Use: Is the grammar, vocabulary, and syntax appropriate for the context of the dialogue?
|
||||
Emotional Intelligence: Are the participants aware of and sensitive to the emotional tone of the dialogue?
|
||||
backstory: >
|
||||
You are an expert at scoring conversations on a scale of 1 to 10. You have a keen eye for detail and can identify the strengths and weaknesses of any dialogue.
|
||||
46
screenplay_writer/config /tasks.yaml
Normal file
46
screenplay_writer/config /tasks.yaml
Normal file
@@ -0,0 +1,46 @@
|
||||
task0:
|
||||
description: >
|
||||
Read the following newsgroup post. If this contains vulgar language reply with STOP . If this is spam reply with STOP.
|
||||
### NEWGROUP POST:
|
||||
{{discussion}}
|
||||
expected_output: >
|
||||
Either "STOP" if the post contains vulgar language or is spam, or no response if it does not.
|
||||
|
||||
task1:
|
||||
description: >
|
||||
Analyse in much detail the following discussion:
|
||||
### DISCUSSION:
|
||||
{{discussion}}
|
||||
expected_output: >
|
||||
A detailed analysis of the discussion, identifying who said what and rewording if necessary while maintaining the main discussion points.
|
||||
|
||||
task2:
|
||||
description: >
|
||||
Create a dialogue heavy screenplay from the discussion, between two persons. Do NOT write parentheticals. Leave out wrylies. You MUST SKIP directional notes.
|
||||
expected_output: >
|
||||
A screenplay dialogue consisting only of the dialogue parts between two persons, without parentheticals, wrylies, or directional notes.
|
||||
|
||||
task3:
|
||||
description: >
|
||||
Format the script exactly like this:
|
||||
## (person 1):
|
||||
(first text line from person 1)
|
||||
|
||||
## (person 2):
|
||||
(first text line from person 2)
|
||||
|
||||
## (person 1):
|
||||
(second text line from person 1)
|
||||
|
||||
## (person 2):
|
||||
(second text line from person 2)
|
||||
expected_output: >
|
||||
A formatted script with the specified structure, ensuring each line is formatted according to the provided template.
|
||||
|
||||
task4:
|
||||
description: >
|
||||
Score the following script:
|
||||
### SCRIPT:
|
||||
{{script}}
|
||||
expected_output: >
|
||||
A score from 1 to 10, indicating how well the script is.
|
||||
@@ -1,121 +1,45 @@
|
||||
'''
|
||||
Example script to automatically write a screenplay from a newsgroup post using agents with Crew.ai (https://github.com/joaomdmoura/crewAI)
|
||||
You can also try it out with a personal email with many replies back and forth and see it turn into a movie script.
|
||||
Demonstrates:
|
||||
- multiple API endpoints (offical Mistral, Together.ai, Anyscale)
|
||||
- running single tasks: spam detection and scoring
|
||||
- running a crew to create a screenplay from a newsgroup post by first analyzing the text, creating a dialogue and ultimately formatting it
|
||||
Additional endpoints requirements:
|
||||
pip install langchain_mistralai
|
||||
pip install langchain-together
|
||||
Author: Toon Beerten (toon@neontreebot.be)
|
||||
License: MIT
|
||||
'''
|
||||
import os
|
||||
import re
|
||||
import yaml
|
||||
from pathlib import Path
|
||||
from crewai import Agent, Task, Crew, Process
|
||||
from langchain.agents import AgentType, initialize_agent, load_tools
|
||||
from langchain.chat_models import openai
|
||||
#endpoint specific imports
|
||||
import langchain_mistralai
|
||||
from langchain_mistralai.chat_models import ChatMistralAI
|
||||
from langchain_community.llms import Together
|
||||
from langchain_community.chat_models import ChatAnyscale
|
||||
from dotenv import load_dotenv
|
||||
|
||||
load_dotenv()
|
||||
|
||||
## Choose here which API endpoint to use, uncomment only one:
|
||||
# Official Mistral: benefit of having access to mistral-medium
|
||||
# Together.ai: lots of models to choose from
|
||||
# Anyscale: cheapest at the time of writing
|
||||
#endpoint = 'mistral_official'
|
||||
#endpoint = 'togetherai'
|
||||
endpoint = 'mistral_official'
|
||||
# Use Path for file locations
|
||||
current_dir = Path.cwd()
|
||||
agents_config_path = current_dir / "config" / "agents.yaml"
|
||||
tasks_config_path = current_dir / "config" / "tasks.yaml"
|
||||
|
||||
#put you API keys here
|
||||
mistral_key = ''
|
||||
togetherai_key = ''
|
||||
anyscale_key = ''
|
||||
# Load YAML configuration files
|
||||
with open(agents_config_path, "r") as file:
|
||||
agents_config = yaml.safe_load(file)
|
||||
|
||||
#model choice: i already have good results with mistralai/Mistral-7B-Instruct-v0.2
|
||||
|
||||
if endpoint == 'mistral_official':
|
||||
mixtral=ChatMistralAI(mistral_api_key=mistral_key, model="mistral-tiny",temperature=0.6)
|
||||
elif endpoint == 'togetherai':
|
||||
#i get timeouts using Together() , so i use ChatOpenAI() instead
|
||||
#mixtral = Together(model="mistralai/Mistral-7B-Instruct-v0.2", together_api_key=togetherai_key ) #or mistralai/Mixtral-8x7B-Instruct-v0.1
|
||||
mixtral= openai.ChatOpenAI(base_url="https://api.together.xyz/v1", api_key=togetherai_key, temperature=0.5, model="mistralai/Mistral-7B-Instruct-v0.2")
|
||||
elif endpoint == 'anyscale':
|
||||
mixtral = ChatAnyscale(model='mistralai/Mistral-7B-Instruct-v0.1', api_key=anyscale_key, streaming=False)
|
||||
|
||||
with open(tasks_config_path, "r") as file:
|
||||
tasks_config = yaml.safe_load(file)
|
||||
|
||||
## Define Agents
|
||||
spamfilter = Agent(
|
||||
role='spamfilter',
|
||||
goal='''Decide whether a text is spam or not.''',
|
||||
backstory='You are an expert spam filter with years of experience. You DETEST advertisements, newsletters and vulgar language.',
|
||||
llm=mixtral,
|
||||
verbose=True,
|
||||
allow_delegation=False
|
||||
config=agents_config["spamfilter"], allow_delegation=False, verbose=True
|
||||
)
|
||||
|
||||
analyst = Agent(
|
||||
role='analyse',
|
||||
goal='''You will distill all arguments from all discussion members. Identify who said what. You can reword what they said as long as the main discussion points remain.''',
|
||||
backstory='You are an expert discussion analyst.',
|
||||
llm=mixtral,
|
||||
verbose=True,
|
||||
allow_delegation=False
|
||||
)
|
||||
analyst = Agent(config=agents_config["analyst"], allow_delegation=False, verbose=True)
|
||||
|
||||
scriptwriter = Agent(
|
||||
role='scriptwriter',
|
||||
goal='Turn a conversation into a movie script. Only write the dialogue parts. Do not start the sentence with an action. Do not specify situational descriptions. Do not write parentheticals.',
|
||||
backstory='''You are an expert on writing natural sounding movie script dialogues. You only focus on the text part and you HATE directional notes.''',
|
||||
llm=mixtral,
|
||||
verbose=True,
|
||||
allow_delegation=False
|
||||
|
||||
config=agents_config["scriptwriter"], allow_delegation=False, verbose=True
|
||||
)
|
||||
|
||||
formatter = Agent(
|
||||
role='formatter',
|
||||
goal='''Format the text as asked. Leave out actions from discussion members that happen between brackets, eg (smiling).''',
|
||||
backstory='You are an expert text formatter.',
|
||||
llm=mixtral,
|
||||
verbose=True,
|
||||
allow_delegation=False
|
||||
)
|
||||
|
||||
scorer = Agent(
|
||||
role='scorer',
|
||||
goal='''You score a dialogue assessing various aspects of the exchange between the participants using a 1-10 scale, where 1 is the lowest performance and 10 is the highest:
|
||||
Scale:
|
||||
1-3: Poor - The dialogue has significant issues that prevent effective communication.
|
||||
4-6: Average - The dialogue has some good points but also has notable weaknesses.
|
||||
7-9: Good - The dialogue is mostly effective with minor issues.
|
||||
10: Excellent - The dialogue is exemplary in achieving its purpose with no apparent issues.
|
||||
Factors to Consider:
|
||||
Clarity: How clear is the exchange? Are the statements and responses easy to understand?
|
||||
Relevance: Do the responses stay on topic and contribute to the conversation's purpose?
|
||||
Conciseness: Is the dialogue free of unnecessary information or redundancy?
|
||||
Politeness: Are the participants respectful and considerate in their interaction?
|
||||
Engagement: Do the participants seem interested and actively involved in the dialogue?
|
||||
Flow: Is there a natural progression of ideas and responses? Are there awkward pauses or interruptions?
|
||||
Coherence: Does the dialogue make logical sense as a whole?
|
||||
Responsiveness: Do the participants address each other's points adequately?
|
||||
Language Use: Is the grammar, vocabulary, and syntax appropriate for the context of the dialogue?
|
||||
Emotional Intelligence: Are the participants aware of and sensitive to the emotional tone of the dialogue?
|
||||
''',
|
||||
backstory='You are an expert at scoring conversations on a scale of 1 to 10.',
|
||||
llm=mixtral,
|
||||
verbose=True,
|
||||
allow_delegation=False
|
||||
config=agents_config["formatter"], allow_delegation=False, verbose=True
|
||||
)
|
||||
|
||||
|
||||
#this is one example of a public post in the newsgroup alt.atheism
|
||||
#try it out yourself by replacing this with your own email thread or text or ...
|
||||
discussion = '''From: keith@cco.caltech.edu (Keith Allan Schneider)
|
||||
scorer = Agent(config=agents_config["scorer"], allow_delegation=False, verbose=True)
|
||||
|
||||
|
||||
# this is one example of a public post in the newsgroup alt.atheism
|
||||
# try it out yourself by replacing this with your own email thread or text or ...
|
||||
discussion = """From: keith@cco.caltech.edu (Keith Allan Schneider)
|
||||
Subject: Re: <Political Atheists?
|
||||
Organization: California Institute of Technology, Pasadena
|
||||
Lines: 50
|
||||
@@ -171,47 +95,58 @@ by your logic, administer as minimum as punishment as possible, to avoid
|
||||
violating the liberty or happiness of an innocent person?
|
||||
|
||||
keith
|
||||
'''
|
||||
"""
|
||||
|
||||
# Filter out spam and vulgar posts
|
||||
task0 = Task(description='Read the following newsgroup post. If this contains vulgar language reply with STOP . If this is spam reply with STOP.\n### NEWGROUP POST:\n' + discussion, agent=spamfilter)
|
||||
task0 = Task(
|
||||
description=tasks_config["task0"]["description"],
|
||||
expected_output=tasks_config["task0"]["expected_output"],
|
||||
agent=spamfilter,
|
||||
)
|
||||
result = task0.execute()
|
||||
if "STOP" in result:
|
||||
#stop here and proceed to next post
|
||||
print('This spam message will be filtered out')
|
||||
# stop here and proceed to next post
|
||||
print("This spam message will be filtered out")
|
||||
|
||||
# process post with a crew of agents, ultimately delivering a well formatted dialogue
|
||||
task1 = Task(description='Analyse in much detail the following discussion:\n### DISCUSSION:\n' + discussion, agent=analyst)
|
||||
task2 = Task(description='Create a dialogue heavy screenplay from the discussion, between two persons. Do NOT write parentheticals. Leave out wrylies. You MUST SKIP directional notes.', agent=scriptwriter)
|
||||
task3 = Task(description='''Format the script exactly like this:
|
||||
## (person 1):
|
||||
(first text line from person 1)
|
||||
|
||||
## (person 2):
|
||||
(first text line from person 2)
|
||||
|
||||
## (person 1):
|
||||
(second text line from person 1)
|
||||
|
||||
## (person 2):
|
||||
(second text line from person 2)
|
||||
|
||||
''', agent=formatter)
|
||||
crew = Crew(
|
||||
agents=[analyst, scriptwriter,formatter],
|
||||
tasks=[task1, task2, task3],
|
||||
verbose=2, # Crew verbose more will let you know what tasks are being worked on, you can set it to 1 or 2 to different logging levels
|
||||
process=Process.sequential # Sequential process will have tasks executed one after the other and the outcome of the previous one is passed as extra content into this next.
|
||||
task1 = Task(
|
||||
description=tasks_config["task1"]["description"],
|
||||
expected_output=tasks_config["task1"]["expected_output"],
|
||||
agent=analyst,
|
||||
)
|
||||
|
||||
task2 = Task(
|
||||
description=tasks_config["task2"]["description"],
|
||||
expected_output=tasks_config["task2"]["expected_output"],
|
||||
agent=scriptwriter,
|
||||
)
|
||||
|
||||
task3 = Task(
|
||||
description=tasks_config["task3"]["description"],
|
||||
expected_output=tasks_config["task3"]["expected_output"],
|
||||
agent=formatter,
|
||||
)
|
||||
crew = Crew(
|
||||
agents=[analyst, scriptwriter, formatter],
|
||||
tasks=[task1, task2, task3],
|
||||
verbose=2, # Crew verbose more will let you know what tasks are being worked on, you can set it to 1 or 2 to different logging levels
|
||||
process=Process.sequential, # Sequential process will have tasks executed one after the other and the outcome of the previous one is passed as extra content into this next.
|
||||
)
|
||||
|
||||
result = crew.kickoff()
|
||||
|
||||
#get rid of directions and actions between brackets, eg: (smiling)
|
||||
result = re.sub(r'\(.*?\)', '', result)
|
||||
# get rid of directions and actions between brackets, eg: (smiling)
|
||||
result = re.sub(r"\(.*?\)", "", result)
|
||||
|
||||
print('===================== end result from crew ===================================')
|
||||
print("===================== end result from crew ===================================")
|
||||
print(result)
|
||||
print('===================== score ==================================================')
|
||||
task4 = Task(description='Read the following dialogue. Then score the script on a scale of 1 to 10. Only give the score as a number, nothing else. Do not give an explanation.\n'+result, agent=scorer)
|
||||
print("===================== score ==================================================")
|
||||
task4 = Task(
|
||||
description=tasks_config["task4"]["description"],
|
||||
expected_output=tasks_config["task4"]["expected_output"],
|
||||
agent=scorer,
|
||||
)
|
||||
|
||||
score = task4.execute()
|
||||
score = score.split('\n')[0] #sometimes an explanation comes after score, ignore
|
||||
print(f'Scoring the dialogue as: {score}/10')
|
||||
score = score.split("\n")[0] # sometimes an explanation comes after score, ignore
|
||||
print(f"Scoring the dialogue as: {score}/10")
|
||||
|
||||
@@ -24,10 +24,10 @@ not to, and by doing so it will cost you money.*
|
||||
|
||||
- **Configure Environment**: Copy ``.env.example` and set up the environment variables for [Browseless](https://www.browserless.io/), [Serper](https://serper.dev/), [SEC-API](https://sec-api.io) and [OpenAI](https://platform.openai.com/api-keys)
|
||||
- **Install Dependencies**: Run `poetry install --no-root`.
|
||||
- **Execute the Script**: Run `python main.py` and input your idea.
|
||||
- **Execute the Script**: Run `poetry run python main.py` and input your idea.
|
||||
|
||||
## Details & Explanation
|
||||
- **Running the Script**: Execute `python main.py`` and input the company to be analyzed when prompted. The script will leverage the CrewAI framework to analyze the company and generate a detailed report.
|
||||
- **Running the Script**: Execute `poetry run python main.py` and input the company to be analyzed when prompted. The script will leverage the CrewAI framework to analyze the company and generate a detailed report.
|
||||
- **Key Components**:
|
||||
- `./main.py`: Main script file.
|
||||
- `./stock_analysis_tasks.py`: Main file with the tasks prompts.
|
||||
|
||||
3
surprise_trip/.env.example
Normal file
3
surprise_trip/.env.example
Normal file
@@ -0,0 +1,3 @@
|
||||
SERPER_API_KEY=
|
||||
OPENAI_API_KEY=
|
||||
OPENAI_MODEL_NAME=gpt-4o
|
||||
39
surprise_trip/README.md
Normal file
39
surprise_trip/README.md
Normal file
@@ -0,0 +1,39 @@
|
||||
|
||||
# AI Crew for Surprise Travel Planning
|
||||
## Introduction
|
||||
This project demonstrates the use of the CrewAI framework to automate the creation of surprise travel plans. CrewAI orchestrates autonomous AI agents, enabling them to collaborate and execute complex tasks efficiently.
|
||||
|
||||
By [@joaomdmoura](https://x.com/joaomdmoura)
|
||||
|
||||
- [CrewAI Framework](#crewai-framework)
|
||||
- [Running the script](#running-the-script)
|
||||
- [Details & Explanation](#details--explanation)
|
||||
- [Contributing](#contributing)
|
||||
- [Support and Contact](#support-and-contact)
|
||||
- [License](#license)
|
||||
|
||||
## CrewAI Framework
|
||||
CrewAI is designed to facilitate the collaboration of role-playing AI agents. In this example, these agents work together to create a comprehensive surprise travel plan, ensuring a seamless and exciting travel experience.
|
||||
|
||||
## Running the Script
|
||||
It uses GPT-4 by default so you should have access to that to run it.
|
||||
|
||||
***Disclaimer:** This will use gpt-4 unless you change it to use a different model, and by doing so it may incur different costs.*
|
||||
|
||||
- **Configure Environment**: Copy `.env.example` and set up the environment variables for [OpenAI](https://platform.openai.com/api-keys) and other tools as needed.
|
||||
- **Install Dependencies**: Run `poetry lock && poetry install`.
|
||||
- **Customize**: Modify `src/surprise_travel/main.py` to add custom inputs for your agents and tasks.
|
||||
- **Customize Further**: Check `src/surprise_travel/config/agents.yaml` to update your agents and `src/surprise_travel/config/tasks.yaml` to update your tasks.
|
||||
- **Execute the Script**: Run `poetry run surprise_travel` and input your project details.
|
||||
|
||||
## Details & Explanation
|
||||
- **Running the Script**: Execute `poetry run surprise_travel`. The script will leverage the CrewAI framework to generate a detailed surprise travel plan.
|
||||
- **Key Components**:
|
||||
- `src/surprise_travel/main.py`: Main script file.
|
||||
- `src/surprise_travel/crew.py`: Main crew file where agents and tasks come together, and the main logic is executed.
|
||||
- `src/surprise_travel/config/agents.yaml`: Configuration file for defining agents.
|
||||
- `src/surprise_travel/config/tasks.yaml`: Configuration file for defining tasks.
|
||||
- `src/surprise_travel/tools`: Contains tool classes used by the agents.
|
||||
|
||||
## License
|
||||
This project is released under the MIT License.
|
||||
5460
surprise_trip/poetry.lock
generated
Normal file
5460
surprise_trip/poetry.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
20
surprise_trip/pyproject.toml
Normal file
20
surprise_trip/pyproject.toml
Normal file
@@ -0,0 +1,20 @@
|
||||
[tool.poetry]
|
||||
name = "surprise_travel"
|
||||
version = "0.1.0"
|
||||
description = "surprise-travel using crewAI"
|
||||
authors = ["Your Name <you@example.com>"]
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = ">=3.10,<=3.13"
|
||||
crewai = { extras = ["tools"], version = "^0.35.8" }
|
||||
crewai-tools = "^0.4.6"
|
||||
pip = "^24.1.1"
|
||||
install = "^1.3.5"
|
||||
|
||||
[tool.poetry.scripts]
|
||||
surprise_travel = "surprise_travel.main:run"
|
||||
train = "surprise_travel.main:train"
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core"]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
0
surprise_trip/src/surprise_travel/__init__.py
Normal file
0
surprise_trip/src/surprise_travel/__init__.py
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
23
surprise_trip/src/surprise_travel/config/agents.yaml
Normal file
23
surprise_trip/src/surprise_travel/config/agents.yaml
Normal file
@@ -0,0 +1,23 @@
|
||||
personalized_activity_planner:
|
||||
role: >
|
||||
Activity Planner
|
||||
goal: >
|
||||
Research and find cool things to do at the destination, including activities and events that match the traveler's interests and age group
|
||||
backstory: >
|
||||
You are skilled at creating personalized itineraries that cater to the specific preferences and demographics of travelers.
|
||||
|
||||
restaurant_scout:
|
||||
role: >
|
||||
Restaurant Scout
|
||||
goal: >
|
||||
Find highly-rated restaurants and dining experiences at the destination, and recommend scenic locations and fun activities
|
||||
backstory: >
|
||||
As a food lover, you know the best spots in town for a delightful culinary experience. You also have a knack for finding picturesque and entertaining locations.
|
||||
|
||||
itinerary_compiler:
|
||||
role: >
|
||||
Itinerary Compiler
|
||||
goal: >
|
||||
Compile all researched information into a comprehensive day-by-day itinerary, ensuring the integration of flights and hotel information
|
||||
backstory: >
|
||||
With an eye for detail, you organize all the information into a coherent and enjoyable travel plan.
|
||||
59
surprise_trip/src/surprise_travel/config/tasks.yaml
Normal file
59
surprise_trip/src/surprise_travel/config/tasks.yaml
Normal file
@@ -0,0 +1,59 @@
|
||||
personalized_activity_planning_task:
|
||||
description: >
|
||||
Research and find cool things to do at {destination}.
|
||||
Focus on activities and events that match the traveler's interests and age group.
|
||||
Utilize internet search tools and recommendation engines to gather the information.
|
||||
|
||||
|
||||
Traveler's information:
|
||||
|
||||
|
||||
- origin: {origin}
|
||||
|
||||
- destination: {destination}
|
||||
|
||||
- age of the traveler: {age}
|
||||
|
||||
- hotel localtion: {hotel_location}
|
||||
|
||||
- flight infromation: {flight_information}
|
||||
|
||||
- how long is the trip: {trip_duration}
|
||||
expected_output: >
|
||||
A list of recommended activities and events for each day of the trip.
|
||||
Each entry should include the activity name, location, a brief description, and why it's suitable for the traveler.
|
||||
And potential reviews and ratings of the activities.
|
||||
|
||||
restaurant_scenic_location_scout_task:
|
||||
description: >
|
||||
Find highly-rated restaurants and dining experiences at {destination}.
|
||||
Recommend scenic locations and fun activities that align with the traveler's preferences.
|
||||
Use internet search tools, restaurant review sites, and travel guides.
|
||||
Make sure to find a variety of options to suit different tastes and budgets, and ratings for them.
|
||||
|
||||
Traveler's information:
|
||||
|
||||
|
||||
- origin: {origin}
|
||||
|
||||
- destination: {destination}
|
||||
|
||||
- age of the traveler: {age}
|
||||
|
||||
- hotel localtion: {hotel_location}
|
||||
|
||||
- flight infromation: {flight_information}
|
||||
|
||||
- how long is the trip: {trip_duration}
|
||||
expected_output: >
|
||||
A list of recommended restaurants, scenic locations, and fun activities for each day of the trip.
|
||||
Each entry should include the name, location (address), type of cuisine or activity, and a brief description and ratings.
|
||||
|
||||
itinerary_compilation_task:
|
||||
description: >
|
||||
Compile all researched information into a comprehensive day-by-day itinerary for the trip to {destination}.
|
||||
Ensure the itinerary integrates flights, hotel information, and all planned activities and dining experiences.
|
||||
Use text formatting and document creation tools to organize the information.
|
||||
expected_output: >
|
||||
A detailed itinerary document, the itinerary should include a day-by-day
|
||||
plan with flights, hotel details, activities, restaurants, and scenic locations.
|
||||
97
surprise_trip/src/surprise_travel/crew.py
Normal file
97
surprise_trip/src/surprise_travel/crew.py
Normal file
@@ -0,0 +1,97 @@
|
||||
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 surprise_travel.tools.custom_tool import MyCustomTool
|
||||
|
||||
# Check our tools documentation for more information on how to use them
|
||||
from crewai_tools import SerperDevTool, ScrapeWebsiteTool
|
||||
from pydantic import BaseModel, Field
|
||||
from typing import List, Optional
|
||||
|
||||
class Activity(BaseModel):
|
||||
name: str = Field(..., description="Name of the activity")
|
||||
location: str = Field(..., description="Location of the activity")
|
||||
description: str = Field(..., description="Description of the activity")
|
||||
date: str = Field(..., description="Date of the activity")
|
||||
cousine: str = Field(..., description="Cousine of the restaurant")
|
||||
why_its_suitable: str = Field(..., description="Why it's suitable for the traveler")
|
||||
reviews: Optional[List[str]] = Field(..., description="List of reviews")
|
||||
rating: Optional[float] = Field(..., description="Rating of the activity")
|
||||
|
||||
class DayPlan(BaseModel):
|
||||
date: str = Field(..., description="Date of the day")
|
||||
activities: List[Activity] = Field(..., description="List of activities")
|
||||
restaurants: List[str] = Field(..., description="List of restaurants")
|
||||
flight: Optional[str] = Field(None, description="Flight information")
|
||||
|
||||
class Itinerary(BaseModel):
|
||||
name: str = Field(..., description="Name of the itinerary, something funny")
|
||||
day_plans: List[DayPlan] = Field(..., description="List of day plans")
|
||||
hotel: str = Field(..., description="Hotel information")
|
||||
|
||||
@CrewBase
|
||||
class SurpriseTravelCrew():
|
||||
"""SurpriseTravel crew"""
|
||||
agents_config = 'config/agents.yaml'
|
||||
tasks_config = 'config/tasks.yaml'
|
||||
|
||||
@agent
|
||||
def personalized_activity_planner(self) -> Agent:
|
||||
return Agent(
|
||||
config=self.agents_config['personalized_activity_planner'],
|
||||
tools=[SerperDevTool(), ScrapeWebsiteTool()], # Example of custom tool, loaded at the beginning of file
|
||||
verbose=True,
|
||||
allow_delegation=False,
|
||||
)
|
||||
|
||||
@agent
|
||||
def restaurant_scout(self) -> Agent:
|
||||
return Agent(
|
||||
config=self.agents_config['restaurant_scout'],
|
||||
tools=[SerperDevTool(), ScrapeWebsiteTool()],
|
||||
verbose=True,
|
||||
allow_delegation=False,
|
||||
)
|
||||
|
||||
@agent
|
||||
def itinerary_compiler(self) -> Agent:
|
||||
return Agent(
|
||||
config=self.agents_config['itinerary_compiler'],
|
||||
tools=[SerperDevTool()],
|
||||
verbose=True,
|
||||
allow_delegation=False,
|
||||
)
|
||||
|
||||
@task
|
||||
def personalized_activity_planning_task(self) -> Task:
|
||||
return Task(
|
||||
config=self.tasks_config['personalized_activity_planning_task'],
|
||||
agent=self.personalized_activity_planner()
|
||||
)
|
||||
|
||||
@task
|
||||
def restaurant_scenic_location_scout_task(self) -> Task:
|
||||
return Task(
|
||||
config=self.tasks_config['restaurant_scenic_location_scout_task'],
|
||||
agent=self.restaurant_scout()
|
||||
)
|
||||
|
||||
@task
|
||||
def itinerary_compilation_task(self) -> Task:
|
||||
return Task(
|
||||
config=self.tasks_config['itinerary_compilation_task'],
|
||||
agent=self.itinerary_compiler(),
|
||||
output_json=Itinerary
|
||||
)
|
||||
|
||||
@crew
|
||||
def crew(self) -> Crew:
|
||||
"""Creates the SurpriseTravel 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,
|
||||
# process=Process.hierarchical, # In case you want to use that instead https://docs.crewai.com/how-to/Hierarchical/
|
||||
)
|
||||
36
surprise_trip/src/surprise_travel/main.py
Normal file
36
surprise_trip/src/surprise_travel/main.py
Normal file
@@ -0,0 +1,36 @@
|
||||
#!/usr/bin/env python
|
||||
import sys
|
||||
from surprise_travel.crew import SurpriseTravelCrew
|
||||
|
||||
|
||||
def run():
|
||||
# Replace with your inputs, it will automatically interpolate any tasks and agents information
|
||||
inputs = {
|
||||
'origin': 'São Paulo, GRU',
|
||||
'destination': 'New York, JFK',
|
||||
'age': 31,
|
||||
'hotel_location': 'Brooklyn',
|
||||
'flight_information': 'GOL 1234, leaving at June 30th, 2024, 10:00',
|
||||
'trip_duration': '14 days'
|
||||
}
|
||||
result = SurpriseTravelCrew().crew().kickoff(inputs=inputs)
|
||||
print(result)
|
||||
|
||||
|
||||
def train():
|
||||
"""
|
||||
Train the crew for a given number of iterations.
|
||||
"""
|
||||
inputs = {
|
||||
'origin': 'São Paulo, GRU',
|
||||
'destination': 'New York, JFK',
|
||||
'age': 31,
|
||||
'hotel_location': 'Brooklyn',
|
||||
'flight_information': 'GOL 1234, leaving at June 30th, 2024, 10:00',
|
||||
'trip_duration': '14 days'
|
||||
}
|
||||
try:
|
||||
SurpriseTravelCrew().crew().train(n_iterations=int(sys.argv[1]), inputs=inputs)
|
||||
|
||||
except Exception as e:
|
||||
raise Exception(f"An error occurred while training the crew: {e}")
|
||||
0
surprise_trip/src/surprise_travel/tools/__init__.py
Normal file
0
surprise_trip/src/surprise_travel/tools/__init__.py
Normal file
12
surprise_trip/src/surprise_travel/tools/custom_tool.py
Normal file
12
surprise_trip/src/surprise_travel/tools/custom_tool.py
Normal file
@@ -0,0 +1,12 @@
|
||||
from crewai_tools import BaseTool
|
||||
|
||||
|
||||
class MyCustomTool(BaseTool):
|
||||
name: str = "Name of my tool"
|
||||
description: str = (
|
||||
"Clear description for what this tool is useful for, you agent will need this information to use it."
|
||||
)
|
||||
|
||||
def _run(self, argument: str) -> str:
|
||||
# Implementation goes here
|
||||
return "this is an example of a tool output, ignore it and move along."
|
||||
BIN
surprise_trip/trained_agents_data.pkl
Normal file
BIN
surprise_trip/trained_agents_data.pkl
Normal file
Binary file not shown.
BIN
surprise_trip/training_data.pkl
Normal file
BIN
surprise_trip/training_data.pkl
Normal file
Binary file not shown.
@@ -2,82 +2,90 @@ from crewai import Task
|
||||
from textwrap import dedent
|
||||
from datetime import date
|
||||
|
||||
class TripTasks:
|
||||
|
||||
class TripTasks():
|
||||
def identify_task(self, agent, origin, cities, interests, range):
|
||||
return Task(
|
||||
description=dedent(f"""
|
||||
Analyze and select the best city for the trip based
|
||||
on specific criteria such as weather patterns, seasonal
|
||||
events, and travel costs. This task involves comparing
|
||||
multiple cities, considering factors like current weather
|
||||
conditions, upcoming cultural or seasonal events, and
|
||||
overall travel expenses.
|
||||
|
||||
Your final answer must be a detailed
|
||||
report on the chosen city, and everything you found out
|
||||
about it, including the actual flight costs, weather
|
||||
forecast and attractions.
|
||||
{self.__tip_section()}
|
||||
|
||||
def identify_task(self, agent, origin, cities, interests, range):
|
||||
return Task(description=dedent(f"""
|
||||
Analyze and select the best city for the trip based
|
||||
on specific criteria such as weather patterns, seasonal
|
||||
events, and travel costs. This task involves comparing
|
||||
multiple cities, considering factors like current weather
|
||||
conditions, upcoming cultural or seasonal events, and
|
||||
overall travel expenses.
|
||||
|
||||
Your final answer must be a detailed
|
||||
report on the chosen city, and everything you found out
|
||||
about it, including the actual flight costs, weather
|
||||
forecast and attractions.
|
||||
{self.__tip_section()}
|
||||
Traveling from: {origin}
|
||||
City Options: {cities}
|
||||
Trip Date: {range}
|
||||
Traveler Interests: {interests}
|
||||
"""),
|
||||
agent=agent,
|
||||
expected_output="Detailed report on the chosen city including flight costs, weather forecast, and attractions"
|
||||
)
|
||||
|
||||
Traveling from: {origin}
|
||||
City Options: {cities}
|
||||
Trip Date: {range}
|
||||
Traveler Interests: {interests}
|
||||
"""),
|
||||
agent=agent)
|
||||
def gather_task(self, agent, origin, interests, range):
|
||||
return Task(
|
||||
description=dedent(f"""
|
||||
As a local expert on this city you must compile an
|
||||
in-depth guide for someone traveling there and wanting
|
||||
to have THE BEST trip ever!
|
||||
Gather information about key attractions, local customs,
|
||||
special events, and daily activity recommendations.
|
||||
Find the best spots to go to, the kind of place only a
|
||||
local would know.
|
||||
This guide should provide a thorough overview of what
|
||||
the city has to offer, including hidden gems, cultural
|
||||
hotspots, must-visit landmarks, weather forecasts, and
|
||||
high level costs.
|
||||
|
||||
The final answer must be a comprehensive city guide,
|
||||
rich in cultural insights and practical tips,
|
||||
tailored to enhance the travel experience.
|
||||
{self.__tip_section()}
|
||||
|
||||
def gather_task(self, agent, origin, interests, range):
|
||||
return Task(description=dedent(f"""
|
||||
As a local expert on this city you must compile an
|
||||
in-depth guide for someone traveling there and wanting
|
||||
to have THE BEST trip ever!
|
||||
Gather information about key attractions, local customs,
|
||||
special events, and daily activity recommendations.
|
||||
Find the best spots to go to, the kind of place only a
|
||||
local would know.
|
||||
This guide should provide a thorough overview of what
|
||||
the city has to offer, including hidden gems, cultural
|
||||
hotspots, must-visit landmarks, weather forecasts, and
|
||||
high level costs.
|
||||
|
||||
The final answer must be a comprehensive city guide,
|
||||
rich in cultural insights and practical tips,
|
||||
tailored to enhance the travel experience.
|
||||
{self.__tip_section()}
|
||||
Trip Date: {range}
|
||||
Traveling from: {origin}
|
||||
Traveler Interests: {interests}
|
||||
"""),
|
||||
agent=agent,
|
||||
expected_output="Comprehensive city guide including hidden gems, cultural hotspots, and practical travel tips"
|
||||
)
|
||||
|
||||
Trip Date: {range}
|
||||
Traveling from: {origin}
|
||||
Traveler Interests: {interests}
|
||||
"""),
|
||||
agent=agent)
|
||||
def plan_task(self, agent, origin, interests, range):
|
||||
return Task(
|
||||
description=dedent(f"""
|
||||
Expand this guide into a full 7-day travel
|
||||
itinerary with detailed per-day plans, including
|
||||
weather forecasts, places to eat, packing suggestions,
|
||||
and a budget breakdown.
|
||||
|
||||
You MUST suggest actual places to visit, actual hotels
|
||||
to stay and actual restaurants to go to.
|
||||
|
||||
This itinerary should cover all aspects of the trip,
|
||||
from arrival to departure, integrating the city guide
|
||||
information with practical travel logistics.
|
||||
|
||||
Your final answer MUST be a complete expanded travel plan,
|
||||
formatted as markdown, encompassing a daily schedule,
|
||||
anticipated weather conditions, recommended clothing and
|
||||
items to pack, and a detailed budget, ensuring THE BEST
|
||||
TRIP EVER. Be specific and give it a reason why you picked
|
||||
each place, what makes them special! {self.__tip_section()}
|
||||
|
||||
def plan_task(self, agent, origin, interests, range):
|
||||
return Task(description=dedent(f"""
|
||||
Expand this guide into a a full 7-day travel
|
||||
itinerary with detailed per-day plans, including
|
||||
weather forecasts, places to eat, packing suggestions,
|
||||
and a budget breakdown.
|
||||
|
||||
You MUST suggest actual places to visit, actual hotels
|
||||
to stay and actual restaurants to go to.
|
||||
|
||||
This itinerary should cover all aspects of the trip,
|
||||
from arrival to departure, integrating the city guide
|
||||
information with practical travel logistics.
|
||||
|
||||
Your final answer MUST be a complete expanded travel plan,
|
||||
formatted as markdown, encompassing a daily schedule,
|
||||
anticipated weather conditions, recommended clothing and
|
||||
items to pack, and a detailed budget, ensuring THE BEST
|
||||
TRIP EVER, Be specific and give it a reason why you picked
|
||||
# up each place, what make them special! {self.__tip_section()}
|
||||
Trip Date: {range}
|
||||
Traveling from: {origin}
|
||||
Traveler Interests: {interests}
|
||||
"""),
|
||||
agent=agent,
|
||||
expected_output="Complete expanded travel plan with daily schedule, weather conditions, packing suggestions, and budget breakdown"
|
||||
)
|
||||
|
||||
Trip Date: {range}
|
||||
Traveling from: {origin}
|
||||
Traveler Interests: {interests}
|
||||
"""),
|
||||
agent=agent)
|
||||
|
||||
def __tip_section(self):
|
||||
return "If you do your BEST WORK, I'll tip you $100!"
|
||||
def __tip_section(self):
|
||||
return "If you do your BEST WORK, I'll tip you $100!"
|
||||
|
||||
Reference in New Issue
Block a user