Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Agents: Example of observability for CrewAI #1621

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
SERPER_API_KEY=
OPENAI_API_KEY=
OPENAI_MODEL_NAME=gpt-4o
39 changes: 39 additions & 0 deletions examples/expositional/frameworks/crewai/surprise_trip/README.md
Original file line number Diff line number Diff line change
@@ -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.
5,514 changes: 5,514 additions & 0 deletions examples/expositional/frameworks/crewai/surprise_trip/poetry.lock

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
[build-system]
build-backend = "poetry.core.masonry.api"
requires = [
"poetry-core",
]

[tool.poetry]
name = "surprise_travel"
version = "0.1.0"
description = "surprise-travel using crewAI"
authors = [
"Your Name <[email protected]>",
]

[tool.poetry.dependencies]
python = ">=3.10,<=3.13"
crewai = { extras = [
"tools",
], version = "^0.35.8" }
crewai-tools = "^0.4.6"
pip = "^24.1.1"

[tool.poetry.scripts]
surprise_travel = "surprise_travel.main:run"
train = "surprise_travel.main:train"

[trulens]
trulens-core = "1.2.0"
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from trulens.dashboard import run_dashboard
from trulens.core import TruSession

session = TruSession()

run_dashboard(session=session)

if __name__ == "__main__":
run_dashboard()
Original file line number Diff line number Diff line change
@@ -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.
Original file line number Diff line number Diff line change
@@ -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.
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
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

# trulens additions
from trulens.apps.custom import instrument

class Activity(BaseModel):
sfc-gh-pmardziel marked this conversation as resolved.
Show resolved Hide resolved
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'

@instrument
@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,
)

@instrument
@agent
def restaurant_scout(self) -> Agent:
return Agent(
config=self.agents_config['restaurant_scout'],
tools=[SerperDevTool(), ScrapeWebsiteTool()],
verbose=True,
allow_delegation=False,
)

@instrument
@agent
def itinerary_compiler(self) -> Agent:
return Agent(
config=self.agents_config['itinerary_compiler'],
tools=[SerperDevTool()],
verbose=True,
allow_delegation=False,
)

@instrument
@task
def personalized_activity_planning_task(self) -> Task:
return Task(
config=self.tasks_config['personalized_activity_planning_task'],
agent=self.personalized_activity_planner()
)

@instrument
@task
def restaurant_scenic_location_scout_task(self) -> Task:
return Task(
config=self.tasks_config['restaurant_scenic_location_scout_task'],
agent=self.restaurant_scout()
)

@instrument
@task
def itinerary_compilation_task(self) -> Task:
return Task(
config=self.tasks_config['itinerary_compilation_task'],
agent=self.itinerary_compiler(),
output_json=Itinerary
)

@instrument
@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/
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#!/usr/bin/env python
import sys
from surprise_travel.crew import SurpriseTravelCrew

surprise_travel_crew = SurpriseTravelCrew()

from trulens.apps.custom import TruCustomApp
from trulens.core import TruSession

session = TruSession()

session.reset_database()

tru_suprise_travel_crew = TruCustomApp(
surprise_travel_crew,
app_name="SurpriseTravelCrew",
app_version="1.0.0",
feedbacks=[],
)


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'
}
with tru_suprise_travel_crew as recorder:
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:
surprise_travel_crew.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}")
Original file line number Diff line number Diff line change
@@ -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."
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
�}�.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
�}�.