├── 2_trip_planner ├── tools │ ├── __init__.py │ ├── calculator_tools.py │ └── search_tools.py ├── .gitignore ├── pyproject.toml ├── trip_agents.py ├── main.py ├── trip_tasks.py └── README.md ├── 3_stock_analysis ├── tools │ ├── __init__.py │ ├── calculator_tools.py │ ├── search_tools.py │ └── sec_tools.py ├── .gitignore ├── pyproject.toml ├── main.py ├── stock_analysis_agents.py ├── stock_analysis_tasks.py └── README.md ├── 1_game-builder-crew ├── .gitignore ├── pyproject.toml ├── README.md ├── main.py ├── agents.py └── tasks.py ├── README.md └── outputs ├── stock_analysis_chatgpt4_turbo.md ├── trip_planner_chatgpt4_turbo.md ├── stock_analysis_chatgpt4o.md ├── game_planner_chatgpt4_turbo.py ├── game_planner_chatgpt4o.py └── trip_planner_chatgpt4o.md /2_trip_planner/tools/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /3_stock_analysis/tools/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /2_trip_planner/.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | .DS_Store 3 | __pycache__ -------------------------------------------------------------------------------- /3_stock_analysis/.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | .DS_Store 3 | __pycache__ -------------------------------------------------------------------------------- /1_game-builder-crew/.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__ 2 | .env 3 | .DS_Store -------------------------------------------------------------------------------- /3_stock_analysis/tools/calculator_tools.py: -------------------------------------------------------------------------------- 1 | from langchain.tools import tool 2 | 3 | 4 | class CalculatorTools(): 5 | 6 | @tool("Make a calculation") 7 | def calculate(operation): 8 | """Useful to perform any mathematical calculations, 9 | like sum, minus, multiplication, division, etc. 10 | The input to this tool should be a mathematical 11 | expression, a couple examples are `200*7` or `5000/2*10` 12 | """ 13 | return eval(operation) 14 | -------------------------------------------------------------------------------- /2_trip_planner/tools/calculator_tools.py: -------------------------------------------------------------------------------- 1 | from langchain.tools import tool 2 | 3 | class CalculatorTools(): 4 | 5 | @tool("Make a calculation") 6 | def calculate(operation): 7 | """Useful to perform any mathematical calculations, 8 | like sum, minus, multiplication, division, etc. 9 | The input to this tool should be a mathematical 10 | expression, a couple examples are `200*7` or `5000/2*10` 11 | """ 12 | try: 13 | return eval(operation) 14 | except SyntaxError: 15 | return "Error: Invalid syntax in mathematical expression" 16 | -------------------------------------------------------------------------------- /1_game-builder-crew/pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "game-crew" 3 | version = "0.1.0" 4 | description = "" 5 | authors = ["Your Name "] 6 | 7 | [tool.poetry.dependencies] 8 | python = ">=3.10.0,<3.12" 9 | crewai = {extras = ["tools"], version = "^0.30.11"} 10 | python-dotenv = "1.0.0" 11 | agentops = "^0.1.10" 12 | 13 | [tool.pyright] 14 | # https://github.com/microsoft/pyright/blob/main/docs/configuration.md 15 | useLibraryCodeForTypes = true 16 | exclude = [".cache"] 17 | 18 | [tool.ruff] 19 | # https://beta.ruff.rs/docs/configuration/ 20 | select = ['E', 'W', 'F', 'I', 'B', 'C4', 'ARG', 'SIM'] 21 | ignore = ['W291', 'W292', 'W293'] 22 | 23 | [build-system] 24 | requires = ["poetry-core>=1.0.0"] 25 | build-backend = "poetry.core.masonry.api" 26 | -------------------------------------------------------------------------------- /2_trip_planner/pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "chatgpt4o" 3 | version = "0.1.0" 4 | description = "" 5 | authors = ["João Moura ", "Brandon Hancock "] 6 | 7 | [tool.poetry.dependencies] 8 | python = ">=3.10.0,<3.12" 9 | crewai = {extras = ["tools"], version = "^0.30.11"} 10 | unstructured = '==0.10.25' 11 | pyowm = '3.3.0' 12 | tools = "^0.1.9" 13 | python-dotenv = "1.0.0" 14 | agentops = "^0.1.10" 15 | 16 | [tool.pyright] 17 | # https://github.com/microsoft/pyright/blob/main/docs/configuration.md 18 | useLibraryCodeForTypes = true 19 | exclude = [".cache"] 20 | 21 | [tool.ruff] 22 | # https://beta.ruff.rs/docs/configuration/ 23 | select = ['E', 'W', 'F', 'I', 'B', 'C4', 'ARG', 'SIM'] 24 | ignore = ['W291', 'W292', 'W293'] 25 | 26 | [build-system] 27 | requires = ["poetry-core>=1.0.0"] 28 | build-backend = "poetry.core.masonry.api" -------------------------------------------------------------------------------- /3_stock_analysis/pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "stock-analysis-crew" 3 | version = "0.1.0" 4 | description = "" 5 | authors = ["João Moura ", "Brandon Hancock "] 6 | 7 | [tool.poetry.dependencies] 8 | python = ">=3.10.0,<3.12" 9 | crewai = {extras = ["tools"], version = "^0.30.11"} 10 | unstructured = '==0.10.25' 11 | pyowm = '3.3.0' 12 | tools = "^0.1.9" 13 | wikipedia = "1.4.0" 14 | yfinance = "0.2.35" 15 | sec-api = "1.0.17" 16 | tiktoken = "0.5.2" 17 | faiss-cpu = "1.7.4" 18 | python-dotenv = "1.0.0" 19 | agentops = "^0.1.10" 20 | 21 | [tool.pyright] 22 | # https://github.com/microsoft/pyright/blob/main/docs/configuration.md 23 | useLibraryCodeForTypes = true 24 | exclude = [".cache"] 25 | 26 | [tool.ruff] 27 | # https://beta.ruff.rs/docs/configuration/ 28 | select = ['E', 'W', 'F', 'I', 'B', 'C4', 'ARG', 'SIM'] 29 | ignore = ['W291', 'W292', 'W293'] 30 | 31 | [build-system] 32 | requires = ["poetry-core>=1.0.0"] 33 | build-backend = "poetry.core.masonry.api" -------------------------------------------------------------------------------- /2_trip_planner/tools/search_tools.py: -------------------------------------------------------------------------------- 1 | import json 2 | import os 3 | 4 | import requests 5 | from langchain.tools import tool 6 | 7 | 8 | class SearchTools(): 9 | 10 | @tool("Search the internet") 11 | def search_internet(query): 12 | """Useful to search the internet 13 | about a a given topic and return relevant results""" 14 | top_result_to_return = 4 15 | url = "https://google.serper.dev/search" 16 | payload = json.dumps({"q": query}) 17 | headers = { 18 | 'X-API-KEY': os.environ['SERPER_API_KEY'], 19 | 'content-type': 'application/json' 20 | } 21 | response = requests.request("POST", url, headers=headers, data=payload) 22 | # check if there is an organic key 23 | if 'organic' not in response.json(): 24 | return "Sorry, I couldn't find anything about that, there could be an error with you serper api key." 25 | else: 26 | results = response.json()['organic'] 27 | string = [] 28 | for result in results[:top_result_to_return]: 29 | try: 30 | string.append('\n'.join([ 31 | f"Title: {result['title']}", f"Link: {result['link']}", 32 | f"Snippet: {result['snippet']}", "\n-----------------" 33 | ])) 34 | except KeyError: 35 | next 36 | 37 | return '\n'.join(string) 38 | -------------------------------------------------------------------------------- /1_game-builder-crew/README.md: -------------------------------------------------------------------------------- 1 | # AI Crew for Game Building 2 | ## Introduction 3 | This project is an example using the CrewAI framework to automate the process of create simple games. CrewAI orchestrates autonomous AI agents, enabling them to collaborate and execute complex tasks efficiently. 4 | 5 | #### Game Builder 6 | [![Game Builder](https://img.youtube.com/vi/g1AQxvR7Vsg/0.jpg)](https://www.youtube.com/watch?v=g1AQxvR7Vsg "Game Builder") 7 | 8 | By [@joaomdmoura](https://x.com/joaomdmoura) 9 | 10 | - [CrewAI Framework](#crewai-framework) 11 | - [Running the script](#running-the-script) 12 | - [Details & Explanation](#details--explanation) 13 | - [Using Local Models with Ollama](#using-local-models-with-ollama) 14 | - [License](#license) 15 | 16 | ## CrewAI Framework 17 | 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 18 | 19 | ## Running the Script 20 | This example uses GPT-4. 21 | 22 | - **Configure Environment**: Copy ``.env.example` and set up the environment variable 23 | - **Install Dependencies**: Run `poetry install --no-root`. 24 | - **Execute the Script**: Run `python main.py` and input your idea. 25 | 26 | ## Details & Explanation 27 | - **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. 28 | - **Key Components**: 29 | - `./main.py`: Main script file. 30 | - `./tasks.py`: Main file with the tasks prompts. 31 | - `./agents.py`: Main file with the agents creation. 32 | 33 | ## License 34 | This project is released under the MIT License. 35 | -------------------------------------------------------------------------------- /1_game-builder-crew/main.py: -------------------------------------------------------------------------------- 1 | import agentops 2 | from agents import GameAgents 3 | from tasks import GameTasks 4 | from crewai import Crew 5 | from dotenv import load_dotenv 6 | load_dotenv() 7 | 8 | agentops.init(tags=["game_builder"]) 9 | 10 | tasks = GameTasks() 11 | agents = GameAgents() 12 | 13 | print("## Welcome to the Game Crew") 14 | print('-------------------------------') 15 | game = """Snake is a classic arcade game where the player controls a snake that continuously moves around the screen. 16 | The objective is to navigate the snake to eat randomly placed food items, causing the snake to grow in length with each item consumed. 17 | The game ends if the snake runs into the screen boundaries or collides with its own body, requiring careful maneuvering to achieve a high score.""" 18 | 19 | # Create Agents 20 | senior_engineer_agent = agents.senior_engineer_agent() 21 | qa_engineer_agent = agents.qa_engineer_agent() 22 | chief_qa_engineer_agent = agents.chief_qa_engineer_agent() 23 | 24 | # Create Tasks 25 | code_game = tasks.code_task(senior_engineer_agent, game) 26 | review_game = tasks.review_task(qa_engineer_agent, game) 27 | approve_game = tasks.evaluate_task(chief_qa_engineer_agent, game) 28 | 29 | # Create Crew responsible for Copy 30 | crew = Crew( 31 | agents=[ 32 | senior_engineer_agent, 33 | qa_engineer_agent, 34 | chief_qa_engineer_agent 35 | ], 36 | tasks=[ 37 | code_game, 38 | review_game, 39 | approve_game 40 | ], 41 | verbose=True 42 | ) 43 | 44 | game = crew.kickoff() 45 | 46 | # Print results 47 | print("\n\n########################") 48 | print("## Here is the result") 49 | print("########################\n") 50 | print("final code for the game:") 51 | print(game) 52 | -------------------------------------------------------------------------------- /2_trip_planner/trip_agents.py: -------------------------------------------------------------------------------- 1 | from crewai import Agent 2 | from langchain_openai import ChatOpenAI 3 | 4 | from tools.calculator_tools import CalculatorTools 5 | from tools.search_tools import SearchTools 6 | 7 | 8 | class TripAgents(): 9 | def __init__(self): 10 | self.llm = ChatOpenAI( 11 | model="gpt-4o" 12 | # model="gpt-4-turbo" 13 | ) 14 | 15 | def city_selection_agent(self): 16 | return Agent( 17 | role='City Selection Expert', 18 | goal='Select the best city based on weather, season, and prices', 19 | backstory='An expert in analyzing travel data to pick ideal destinations', 20 | tools=[ 21 | SearchTools.search_internet, 22 | ], 23 | llm=self.llm, 24 | verbose=True) 25 | 26 | def local_expert(self): 27 | return Agent( 28 | role='Local Expert at this city', 29 | goal='Provide the BEST insights about the selected city', 30 | backstory="""A knowledgeable local guide with extensive information 31 | about the city, it's attractions and customs""", 32 | tools=[ 33 | SearchTools.search_internet, 34 | ], 35 | llm=self.llm, 36 | verbose=True) 37 | 38 | def travel_concierge(self): 39 | return Agent( 40 | role='Amazing Travel Concierge', 41 | goal="""Create the most amazing travel itineraries with budget and 42 | packing suggestions for the city""", 43 | backstory="""Specialist in travel planning and logistics with 44 | decades of experience""", 45 | tools=[ 46 | SearchTools.search_internet, 47 | CalculatorTools.calculate, 48 | ], 49 | llm=self.llm, 50 | verbose=True) 51 | -------------------------------------------------------------------------------- /3_stock_analysis/main.py: -------------------------------------------------------------------------------- 1 | import agentops 2 | from crewai import Crew 3 | 4 | from stock_analysis_agents import StockAnalysisAgents 5 | from stock_analysis_tasks import StockAnalysisTasks 6 | 7 | from dotenv import load_dotenv 8 | load_dotenv() 9 | 10 | agentops.init(tags=["stock_analysis"]) 11 | 12 | 13 | class FinancialCrew: 14 | def __init__(self, company): 15 | self.company = company 16 | 17 | def run(self): 18 | agents = StockAnalysisAgents() 19 | tasks = StockAnalysisTasks() 20 | 21 | research_analyst_agent = agents.research_analyst() 22 | financial_analyst_agent = agents.financial_analyst() 23 | investment_advisor_agent = agents.investment_advisor() 24 | 25 | research_task = tasks.research(research_analyst_agent, self.company) 26 | financial_task = tasks.financial_analysis(financial_analyst_agent) 27 | filings_task = tasks.filings_analysis(financial_analyst_agent) 28 | recommend_task = tasks.recommend(investment_advisor_agent) 29 | 30 | crew = Crew( 31 | agents=[ 32 | research_analyst_agent, 33 | financial_analyst_agent, 34 | investment_advisor_agent 35 | ], 36 | tasks=[ 37 | research_task, 38 | financial_task, 39 | filings_task, 40 | recommend_task 41 | ], 42 | verbose=True, 43 | ) 44 | 45 | result = crew.kickoff() 46 | return result 47 | 48 | 49 | if __name__ == "__main__": 50 | print("## Welcome to Financial Analysis Crew") 51 | print('-------------------------------') 52 | company = "Tesla" 53 | 54 | financial_crew = FinancialCrew(company) 55 | result = financial_crew.run() 56 | print("\n\n########################") 57 | print("## Here is the Report") 58 | print("########################\n") 59 | print(result) 60 | -------------------------------------------------------------------------------- /1_game-builder-crew/agents.py: -------------------------------------------------------------------------------- 1 | from textwrap import dedent 2 | from crewai import Agent 3 | from langchain_openai import ChatOpenAI 4 | 5 | 6 | class GameAgents(): 7 | def __init__(self): 8 | self.llm = ChatOpenAI( 9 | model="gpt-4o" 10 | # model="gpt-4-turbo" 11 | ) 12 | 13 | def senior_engineer_agent(self): 14 | return Agent( 15 | role='Senior Software Engineer', 16 | goal='Create software as needed', 17 | backstory=dedent("""\ 18 | You are a Senior Software Engineer at a leading tech think tank. 19 | Your expertise in programming in python. and do your best to 20 | produce perfect code"""), 21 | allow_delegation=False, 22 | verbose=True, 23 | llm=self.llm 24 | ) 25 | 26 | def qa_engineer_agent(self): 27 | return Agent( 28 | role='Software Quality Control Engineer', 29 | goal='create prefect code, by analizing the code that is given for errors', 30 | backstory=dedent("""\ 31 | You are a software engineer that specializes in checking code 32 | for errors. You have an eye for detail and a knack for finding 33 | hidden bugs. 34 | You check for missing imports, variable declarations, mismatched 35 | brackets and syntax errors. 36 | You also check for security vulnerabilities, and logic errors"""), 37 | allow_delegation=False, 38 | verbose=True, 39 | llm=self.llm 40 | ) 41 | 42 | def chief_qa_engineer_agent(self): 43 | return Agent( 44 | role='Chief Software Quality Control Engineer', 45 | goal='Ensure that the code does the job that it is supposed to do', 46 | backstory=dedent("""\ 47 | You feel that programmers always do only half the job, so you are 48 | super dedicate to make high quality code."""), 49 | allow_delegation=True, 50 | verbose=True, 51 | llm=self.llm 52 | ) 53 | -------------------------------------------------------------------------------- /3_stock_analysis/tools/search_tools.py: -------------------------------------------------------------------------------- 1 | import json 2 | import os 3 | 4 | import requests 5 | from langchain.tools import tool 6 | 7 | 8 | class SearchTools(): 9 | @tool("Search the internet") 10 | def search_internet(query): 11 | """Useful to search the internet 12 | about a a given topic and return relevant results""" 13 | top_result_to_return = 4 14 | url = "https://google.serper.dev/search" 15 | payload = json.dumps({"q": query}) 16 | headers = { 17 | 'X-API-KEY': os.environ['SERPER_API_KEY'], 18 | 'content-type': 'application/json' 19 | } 20 | response = requests.request("POST", url, headers=headers, data=payload) 21 | results = response.json()['organic'] 22 | string = [] 23 | for result in results[:top_result_to_return]: 24 | try: 25 | string.append('\n'.join([ 26 | f"Title: {result['title']}", f"Link: {result['link']}", 27 | f"Snippet: {result['snippet']}", "\n-----------------" 28 | ])) 29 | except KeyError: 30 | next 31 | 32 | return '\n'.join(string) 33 | 34 | @tool("Search news on the internet") 35 | def search_news(query): 36 | """Useful to search news about a company, stock or any other 37 | topic and return relevant results""""" 38 | top_result_to_return = 4 39 | url = "https://google.serper.dev/news" 40 | payload = json.dumps({"q": query}) 41 | headers = { 42 | 'X-API-KEY': os.environ['SERPER_API_KEY'], 43 | 'content-type': 'application/json' 44 | } 45 | response = requests.request("POST", url, headers=headers, data=payload) 46 | results = response.json()['news'] 47 | string = [] 48 | for result in results[:top_result_to_return]: 49 | try: 50 | string.append('\n'.join([ 51 | f"Title: {result['title']}", f"Link: {result['link']}", 52 | f"Snippet: {result['snippet']}", "\n-----------------" 53 | ])) 54 | except KeyError: 55 | next 56 | 57 | return '\n'.join(string) 58 | -------------------------------------------------------------------------------- /1_game-builder-crew/tasks.py: -------------------------------------------------------------------------------- 1 | from textwrap import dedent 2 | from crewai import Task 3 | 4 | 5 | class GameTasks(): 6 | def code_task(self, agent, game): 7 | return Task( 8 | description=dedent(f""" 9 | You will create a game using Python. These are the instructions: 10 | 11 | Instructions 12 | ------------ 13 | {game} 14 | 15 | Your final answer must be the full Python code, only the Python code and nothing else. 16 | """), 17 | expected_output="The full Python code for the game, following the provided instructions.", 18 | agent=agent 19 | ) 20 | 21 | def review_task(self, agent, game): 22 | return Task( 23 | description=dedent(f""" 24 | You are helping create a game using Python. These are the instructions: 25 | 26 | Instructions 27 | ------------ 28 | {game} 29 | 30 | Using the code you received, check for errors. Check for logic errors, 31 | syntax errors, missing imports, variable declarations, mismatched brackets, 32 | and security vulnerabilities. 33 | 34 | Your final answer must be the full Python code, only the Python code and nothing else. 35 | """), 36 | expected_output="The full Python code for the game with any identified errors corrected.", 37 | agent=agent 38 | ) 39 | 40 | def evaluate_task(self, agent, game): 41 | return Task( 42 | description=dedent(f""" 43 | You are helping create a game using Python. These are the instructions: 44 | 45 | Instructions 46 | ------------ 47 | {game} 48 | 49 | You will look over the code to ensure that it is complete and 50 | does the job that it is supposed to do. 51 | 52 | Your final answer must be the full Python code, only the Python code and nothing else. 53 | """), 54 | expected_output="The full Python code for the game, verified to be complete and functional.", 55 | agent=agent 56 | ) 57 | -------------------------------------------------------------------------------- /2_trip_planner/main.py: -------------------------------------------------------------------------------- 1 | import agentops 2 | from crewai import Crew 3 | from textwrap import dedent 4 | from trip_agents import TripAgents 5 | from trip_tasks import TripTasks 6 | 7 | from dotenv import load_dotenv 8 | load_dotenv() 9 | 10 | agentops.init(tags=["trip_planner"]) 11 | 12 | 13 | class TripCrew: 14 | 15 | def __init__(self, origin, cities, date_range, interests): 16 | self.cities = cities 17 | self.origin = origin 18 | self.interests = interests 19 | self.date_range = date_range 20 | 21 | def run(self): 22 | agents = TripAgents() 23 | tasks = TripTasks() 24 | 25 | city_selector_agent = agents.city_selection_agent() 26 | local_expert_agent = agents.local_expert() 27 | travel_concierge_agent = agents.travel_concierge() 28 | 29 | identify_task = tasks.identify_task( 30 | city_selector_agent, 31 | self.origin, 32 | self.cities, 33 | self.interests, 34 | self.date_range 35 | ) 36 | gather_task = tasks.gather_task( 37 | local_expert_agent, 38 | self.origin, 39 | self.interests, 40 | self.date_range 41 | ) 42 | plan_task = tasks.plan_task( 43 | travel_concierge_agent, 44 | self.origin, 45 | self.interests, 46 | self.date_range 47 | ) 48 | 49 | crew = Crew( 50 | agents=[ 51 | city_selector_agent, local_expert_agent, travel_concierge_agent 52 | ], 53 | tasks=[identify_task, gather_task, plan_task], 54 | verbose=True 55 | ) 56 | 57 | result = crew.kickoff() 58 | return result 59 | 60 | 61 | if __name__ == "__main__": 62 | print("## Welcome to Trip Planner Crew") 63 | print('-------------------------------') 64 | location = "Atlanta, GA" 65 | cities = "Zagreb and Split, Croatia" 66 | date_range = "August 5th through August 12th 2024" 67 | interests = "Beach, Site Seeing, Nightlife, Food, Culture, History" 68 | 69 | trip_crew = TripCrew(location, cities, date_range, interests) 70 | result = trip_crew.run() 71 | print("\n\n########################") 72 | print("## Here is you Trip Plan") 73 | print("########################\n") 74 | print(result) 75 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Overview 2 | 3 | In this project, I updated 3 examples from https://github.com/joaomdmoura/crewAI-examples/ to use the latest version of CrewAI (0.30.11). 4 | 5 | To track the performance of each example, I added AgentOps to each project. 6 | 7 | Once everything was setup, I ran each example project with ChatGPT4 and ChatGPT4o. 8 | 9 | Check the results below! 10 | 11 | # Results 12 | 13 | ## 1. Game Builder 14 | 15 | ### ChatGPT4o Result 16 | 17 | - AgentOps Id: 6763a693-542b-47eb-bd51-40a5c09f86c0 18 | - LLM Cost: $0.18 19 | - Time: 1m 33s 20 | - Prompt Tokens: 14,487 21 | - Completion Tokens: 6,948 22 | 23 | ### ChatGPT4-Turbo Result 24 | 25 | - AgentOps Id: a60b39c0-ae51-48be-b430-08383f95d6fc 26 | - LLM Cost: $0.23 27 | - Time: 1m 33s 28 | - Prompt Tokens: 9,416 29 | - Completion Tokens: 4,557 30 | 31 | ### Comparison 32 | 33 | - Cost: ChatGPT4o is about 21.7% cheaper than ChatGPT4-Turbo. 34 | - Response Time: Both ChatGPT4o and ChatGPT4-Turbo have the same response time. 35 | - Token Usage: ChatGPT4o uses about 41.9% more tokens overall compared to ChatGPT4-Turbo, indicating potentially more detailed responses. 36 | 37 | ## 2. Trip Planner 38 | 39 | ### ChatGPT4o Result 40 | 41 | - AgentOps Id: c826fdea-8710-4a60-b1a4-5825acb41246 42 | - LLM Cost: $0.36 43 | - Time: 2m 45s 44 | - Prompt Tokens: 44,736 45 | - Completion Tokens: 9,370 46 | 47 | ### ChatGPT4-Turbo Result 48 | 49 | - AgentOps Id: 55da4c75-8c76-4e19-946b-0abc94929c84 50 | - LLM Cost: $0.48 51 | - Time: 4m 40s 52 | - Prompt Tokens: 33,699 53 | - Completion Tokens: 6,277 54 | 55 | ### Comparison 56 | 57 | - Cost: ChatGPT4o is about 25% cheaper than ChatGPT4-Turbo. 58 | - Response Time: ChatGPT4o is about 41% faster than ChatGPT4-Turbo. 59 | - Token Usage: ChatGPT4o uses about 32% more tokens overall compared to ChatGPT4-Turbo. 60 | 61 | ## 3. Stock analysis 62 | 63 | ### ChatGPT4o Result 64 | 65 | - AgentOps Id: f5d5f942-3b0f-47a2-8cd3-b843eef72116 66 | - LLM Cost: $0.33 67 | - Time: 3m 14s 68 | - Prompt Tokens: 38,838 69 | - Completion Tokens: 9,051 70 | 71 | ### ChatGPT4-Turbo Result 72 | 73 | - AgentOps Id: fbe4b206-12ce-49eb-b86b-53ed56b6ec85 74 | - LLM Cost: $0.52 75 | - Time: 3m 36s 76 | - Prompt Tokens: 40,777 77 | - Completion Tokens: 3,793 78 | 79 | ### Comparison 80 | 81 | - Cost: ChatGPT4o is about 36.5% cheaper than ChatGPT4-Turbo. 82 | - Response Time: ChatGPT4o is about 10.2% faster than ChatGPT4-Turbo. 83 | - Token Usage: ChatGPT4o uses about 11.3% fewer tokens overall compared to ChatGPT4-Turbo. 84 | -------------------------------------------------------------------------------- /3_stock_analysis/stock_analysis_agents.py: -------------------------------------------------------------------------------- 1 | from crewai import Agent 2 | from langchain_openai import ChatOpenAI 3 | 4 | from tools.calculator_tools import CalculatorTools 5 | from tools.search_tools import SearchTools 6 | from tools.sec_tools import SECTools 7 | 8 | from langchain.tools.yahoo_finance_news import YahooFinanceNewsTool 9 | 10 | 11 | class StockAnalysisAgents(): 12 | def __init__(self): 13 | self.llm = ChatOpenAI( 14 | model="gpt-4o" 15 | # model="gpt-4-turbo" 16 | ) 17 | 18 | def financial_analyst(self): 19 | return Agent( 20 | role='The Best Financial Analyst', 21 | goal="""Impress all customers with your financial data 22 | and market trends analysis""", 23 | backstory="""The most seasoned financial analyst with 24 | lots of expertise in stock market analysis and investment 25 | strategies that is working for a super important customer.""", 26 | verbose=True, 27 | tools=[ 28 | SearchTools.search_internet, 29 | CalculatorTools.calculate, 30 | SECTools.search_10q, 31 | SECTools.search_10k 32 | ], 33 | llm=self.llm 34 | ) 35 | 36 | def research_analyst(self): 37 | return Agent( 38 | role='Staff Research Analyst', 39 | goal="""Being the best at gather, interpret data and amaze 40 | your customer with it""", 41 | backstory="""Known as the BEST research analyst, you're 42 | skilled in sifting through news, company announcements, 43 | and market sentiments. Now you're working on a super 44 | important customer""", 45 | verbose=True, 46 | tools=[ 47 | SearchTools.search_internet, 48 | SearchTools.search_news, 49 | YahooFinanceNewsTool(), 50 | SECTools.search_10q, 51 | SECTools.search_10k 52 | ], 53 | llm=self.llm 54 | ) 55 | 56 | def investment_advisor(self): 57 | return Agent( 58 | role='Private Investment Advisor', 59 | goal="""Impress your customers with full analyses over stocks 60 | and completer investment recommendations""", 61 | backstory="""You're the most experienced investment advisor 62 | and you combine various analytical insights to formulate 63 | strategic investment advice. You are now working for 64 | a super important customer you need to impress.""", 65 | verbose=True, 66 | tools=[ 67 | SearchTools.search_internet, 68 | SearchTools.search_news, 69 | CalculatorTools.calculate, 70 | YahooFinanceNewsTool() 71 | ], 72 | llm=self.llm 73 | ) 74 | -------------------------------------------------------------------------------- /outputs/stock_analysis_chatgpt4_turbo.md: -------------------------------------------------------------------------------- 1 | **Tesla, Inc. (TSLA) Investment Recommendation Report** 2 | 3 | **Executive Summary:** 4 | Tesla, Inc. remains a pivotal player in the sustainable energy and electric vehicle markets, with continuous investments in technology and geographic expansion. Despite facing operational challenges and market adaptation issues, the company's strategic positioning and robust internal controls provide a solid foundation for future growth. 5 | 6 | **Financial Health and EDGAR Filings Insights:** 7 | 8 | - **Financial Overview:** Tesla has shown significant growth in long-lived assets, rising from $34.954 billion at the end of 2023 to $36.598 billion as of March 31, 2024. This increase reflects ongoing investments, particularly in key markets such as the US, Germany, and China. 9 | - **Operational Efficiency:** Although inventory levels have increased, signaling potential slower sales turnover, Tesla has taken proactive restructuring actions, including employee terminations, to reduce costs and improve efficiency, incurring over $350 million in associated costs. 10 | - **Risk Management:** The company maintains effective internal controls and compliance with market regulations, ensuring financial integrity and readiness for regulatory reviews. 11 | 12 | **Market Sentiment:** 13 | The proactive restructuring efforts and continued technological advancements are viewed positively by the market. However, the significant restructuring costs and increased inventory levels have raised concerns about operational efficiency and market demand responsiveness. 14 | 15 | **Insider Trading Activity:** 16 | Recent insider trading reports indicate a mixture of buy and sell activities among Tesla's top executives. Key transactions include a notable sale by Officer Zhu Xiaotong and CFO Taneja Vaibhav, which might signal insider perspectives on the company’s valuation and future prospects. 17 | 18 | **Upcoming Events:** 19 | Tesla's next earnings report is scheduled for July 17, 2024. This event will be crucial in providing investors with updated financial performance data and management's commentary on future strategies and market conditions. 20 | 21 | **Investment Recommendation:** 22 | Given Tesla's robust investment in technology and expansion, effective risk management frameworks, and strategic restructuring efforts, Tesla presents a solid investment opportunity for long-term growth-oriented investors. However, potential investors should be mindful of the operational challenges and market adaptation issues that could affect short-term performance. 23 | 24 | **Investment Strategy:** 25 | 26 | - **Long-Term Hold:** For investors focused on sustainable growth sectors with a higher risk tolerance. 27 | - **Monitor Insider and Earnings Reports:** Closely monitor upcoming earnings reports and insider trading activity for any significant changes that might impact market sentiment and stock performance. 28 | 29 | **Conclusion:** 30 | Tesla, Inc. continues to innovate and expand its market presence in the sustainable energy sector. While current challenges related to inventory management and restructuring costs warrant caution, Tesla’s strategic initiatives and strong governance framework position it well for future success. Investors are advised to maintain a long-term perspective while staying vigilant of short-term market dynamics and internal corporate activities. 31 | -------------------------------------------------------------------------------- /outputs/trip_planner_chatgpt4_turbo.md: -------------------------------------------------------------------------------- 1 | # 7-Day Itinerary for Split, Croatia (August 5th - August 12th, 2024) 2 | 3 | ## Day 1: Arrival and Diocletian's Palace 4 | 5 | - **Morning**: Arrive in Split, check into your accommodation. Consider staying at Cornaro Hotel, a centrally located hotel with easy access to major sites. 6 | - **Afternoon**: Visit Diocletian's Palace, a UNESCO World Heritage site. Explore ancient cellars, the Peristyle, Jupiter's Temple, and the Cathedral of Saint Domnius. 7 | - **Evening**: Dinner at Konoba Fetivi, known for traditional Dalmatian dishes. Expect to spend around $25 per person. 8 | 9 | ## Day 2: Marjan Forest Park and Beach Day 10 | 11 | - **Morning**: Hike or bike through Marjan Forest Park for panoramic views of the city and sea. 12 | - **Afternoon**: Relax at Kaštelet Beach, a picturesque pebble beach. 13 | - **Evening**: Enjoy seafood at Zrno Soli, located on the waterfront. Dinner budget around $30 per person. 14 | 15 | ## Day 3: Klis Fortress and Local Cuisine 16 | 17 | - **Morning**: Visit Klis Fortress for spectacular views and historical insights. 18 | - **Afternoon**: Lunch at Bokeria Kitchen and Wine Bar, featuring a modern take on local cuisine. Budget about $20 per person. 19 | - **Evening**: Explore Riva Harbor, dine at Bòme Boutique Restaurant for innovative culinary experiences. Budget around $30 per person. 20 | 21 | ## Day 4: Day Trip to Nearby Islands 22 | 23 | - **Full Day**: Take a boat tour to Brač or Hvar, including activities like swimming and snorkeling. Tour costs approximately $50 per person. 24 | - **Evening**: Return to Split, dinner at Dvor. Romantic setting, budget about $40 per person. 25 | 26 | ## Day 5: Explore Old Split and Split Summer Festival 27 | 28 | - **Morning**: Stroll through historic Old Split. Visit landmarks like the Cathedral of St Domnius. 29 | - **Afternoon**: Attend Split Summer Festival events. Entry fees around $20. 30 | - **Evening**: Dinner at Trattoria Tinel. Budget $25 per person. 31 | 32 | ## Day 6: Croatian National Theater and Nightlife 33 | 34 | - **Morning**: Visit the Croatian National Theater, tour or a morning performance. Ticket price approximately $15. 35 | - **Afternoon**: Paradox Wine and Cheese Bar for local flavors. Spend about $20. 36 | - **Evening**: Experience nightlife at Fabrique Pub. Drinks and entertainment budget around $30. 37 | 38 | ## Day 7: Leisure and Departure 39 | 40 | - **Morning**: Breakfast at Brasserie on 7, enjoy views of the Adriatic. Budget $15 for breakfast. 41 | - **Afternoon**: Last-minute shopping or relax at Bačvice Beach. 42 | - **Evening**: Prepare for departure. 43 | 44 | ### Weather and Packing Suggestions 45 | 46 | - **Weather**: Expect comfortable summer weather, around 28°C (82°F). Pack light clothing, swimwear, comfortable shoes for walking, and a light jacket for cooler evenings. 47 | 48 | ### Budget Breakdown (Per Person) 49 | 50 | - **Accommodation**: $100 per night x 7 nights = $700 51 | - **Meals**: Average $30 per meal x 3 meals per day x 7 days = $630 52 | - **Transportation and Entry Fees**: Approximately $200 for local transit and entry to attractions. 53 | - **Miscellaneous**: Including shopping and additional expenses, budget around $150. 54 | 55 | **Total Estimate**: $1,680 56 | 57 | This itinerary offers a comprehensive experience of Split, blending historical exploration, cultural immersion, relaxation, and local gastronomy, ensuring a memorable and enjoyable trip. 58 | -------------------------------------------------------------------------------- /2_trip_planner/trip_tasks.py: -------------------------------------------------------------------------------- 1 | from crewai import Task 2 | from textwrap import dedent 3 | from datetime import date 4 | 5 | 6 | class TripTasks(): 7 | 8 | def identify_task(self, agent, origin, cities, interests, range): 9 | return Task( 10 | description=dedent(f""" 11 | Analyze and select the best city for the trip based 12 | on specific criteria such as weather patterns, seasonal 13 | events, and travel costs. This task involves comparing 14 | multiple cities, considering factors like current weather 15 | conditions, upcoming cultural or seasonal events, and 16 | overall travel expenses. 17 | 18 | Your final answer must be a detailed report on the chosen 19 | city, and everything you found out about it, including the 20 | actual flight costs, weather forecast, and attractions. 21 | 22 | Traveling from: {origin} 23 | City Options: {cities} 24 | Trip Date: {range} 25 | Traveler Interests: {interests} 26 | """), 27 | expected_output="A detailed report on the chosen city including flight costs, weather forecast, and attractions.", 28 | agent=agent 29 | ) 30 | 31 | def gather_task(self, agent, origin, interests, range): 32 | return Task( 33 | description=dedent(f""" 34 | As a local expert on this city, you must compile an 35 | in-depth guide for someone traveling there and wanting 36 | to have THE BEST trip ever! Gather information about key 37 | attractions, local customs, special events, and daily 38 | activity recommendations. Find the best spots to go to, 39 | the kind of place only a local would know. 40 | 41 | This guide should provide a thorough overview of what the 42 | city has to offer, including hidden gems, cultural hotspots, 43 | must-visit landmarks, weather forecasts, and high-level costs. 44 | 45 | The final answer must be a comprehensive city guide, 46 | rich in cultural insights and practical tips, tailored 47 | to enhance the travel experience. 48 | 49 | Trip Date: {range} 50 | Traveling from: {origin} 51 | Traveler Interests: {interests} 52 | """), 53 | expected_output="A comprehensive city guide including hidden gems, cultural hotspots, must-visit landmarks, weather forecasts, and high-level costs.", 54 | agent=agent 55 | ) 56 | 57 | def plan_task(self, agent, origin, interests, range): 58 | return Task( 59 | description=dedent(f""" 60 | Expand this guide into a full 7-day travel itinerary 61 | with detailed per-day plans, including weather forecasts, 62 | places to eat, packing suggestions, and a budget breakdown. 63 | 64 | You MUST suggest actual places to visit, actual hotels 65 | to stay, and actual restaurants to go to. 66 | 67 | This itinerary should cover all aspects of the trip, from 68 | arrival to departure, integrating the city guide information 69 | with practical travel logistics. 70 | 71 | Your final answer MUST be a complete expanded travel plan, 72 | formatted as markdown, encompassing a daily schedule, 73 | anticipated weather conditions, recommended clothing and 74 | items to pack, and a detailed budget, ensuring THE BEST 75 | TRIP EVER. Be specific and give reasons why you picked 76 | each place, and what makes them special! 77 | 78 | Trip Date: {range} 79 | Traveling from: {origin} 80 | Traveler Interests: {interests} 81 | """), 82 | expected_output="A full 7-day travel itinerary in markdown format including daily schedule, weather conditions, recommended clothing, items to pack, and a detailed budget.", 83 | agent=agent 84 | ) 85 | -------------------------------------------------------------------------------- /outputs/stock_analysis_chatgpt4o.md: -------------------------------------------------------------------------------- 1 | ### Comprehensive Investment Recommendation Report for Tesla, Inc. (TSLA) 2 | 3 | --- 4 | 5 | #### **Financial Health** 6 | 7 | **Evaluation of Disclosure Controls and Procedures (10-Q and 10-K Filings)** 8 | 9 | - **Effectiveness**: Tesla’s management, including the CEO and CFO, concluded that as of March 31, 2024, their disclosure controls and procedures were effective at a reasonable assurance level. This ensures timely and accurate disclosures in compliance with SEC rules. 10 | - **Stability in Internal Controls**: There were no material changes in internal control over financial reporting during the quarter ended March 31, 2024. This stability suggests consistent and reliable financial oversight. 11 | 12 | **Quantitative and Qualitative Disclosures about Market Risk** 13 | 14 | - **Foreign Currency Risk**: Tesla operates globally and does not typically hedge foreign currency risks. This could lead to fluctuations in net income due to exchange rate changes. 15 | 16 | --- 17 | 18 | #### **Market Sentiment and News Insights** 19 | 20 | **Recent News Highlights** 21 | 22 | 1. **Trending Stock Analysis**: 23 | 24 | - Tesla has received significant attention recently, indicating strong interest and possibly high volatility. ([Source](https://ca.finance.yahoo.com/news/trending-stock-tesla-inc-tsla-130014696.html)) 25 | 26 | 2. **Earnings Report**: 27 | 28 | - Tesla's recent earnings miss was overshadowed by plans to launch less-expensive vehicles, which could attract a broader customer base and enhance market share. ([Source](https://www.bloomberg.com/news/articles/2024-04-23/tesla-tsla-stumbles-again-as-profit-sales-fall-short-of-estimates)) 29 | 30 | 3. **Commentary by Elon Musk**: 31 | 32 | - Elon Musk urged Warren Buffett to consider holding a stake in Tesla, indicating strong confidence in the company’s future prospects. This could positively influence investor sentiment. ([Source](https://coingape.com/news/stocks/elon-musk-urges-warren-buffet-to-hold-stake-in-tesla-tsla-price-rallies/)) 33 | 34 | --- 35 | 36 | #### **Insider Trading Activity** 37 | 38 | **Recent Insider Transactions** 39 | 40 | - **Nasdaq Insider Activity**: The latest insider trading activities can be found on Nasdaq, detailing insider shares traded. ([Source](https://www.nasdaq.com/market-activity/stocks/tsla/insider-activity)) 41 | - **Yahoo Finance**: Yahoo Finance provides a comprehensive list of recent insider transactions, including shares held, purchased, and sold. ([Source](https://finance.yahoo.com/quote/TSLA/insider-transactions/)) 42 | - **SEC Form 4**: Detailed insider trading activities for Tesla can be reviewed on SEC Form 4. ([Source](https://www.secform4.com/insider-trading/1318605.htm)) 43 | 44 | --- 45 | 46 | #### **Upcoming Events** 47 | 48 | **Earnings Announcements** 49 | 50 | - **Next Earnings Report**: Tesla’s next earnings report is anticipated to provide insights into the company’s financial performance and future outlook. Monitoring this closely will be crucial for making informed investment decisions. 51 | 52 | --- 53 | 54 | ### **Investment Recommendation** 55 | 56 | **Summary** 57 | 58 | - **Financial Health**: Tesla has robust disclosure controls and stable internal financial controls, ensuring reliable financial reporting. 59 | - **Market Sentiment**: Recent news indicates mixed sentiment. While the earnings miss poses a concern, plans for less-expensive vehicles and positive commentary from Elon Musk enhance future growth prospects. 60 | - **Insider Trading**: Reviewing insider trading activities reveals no alarming trends, suggesting confidence from within the company. 61 | - **Upcoming Events**: Keeping an eye on the next earnings report will be critical for assessing short-term performance. 62 | 63 | **Recommendation** 64 | 65 | - **Investment Stance**: **Hold**. Given the current financial health and future growth strategies, Tesla remains a viable investment. However, the unhedged foreign currency risk and recent earnings miss suggest a cautious approach. Investors should monitor upcoming earnings and market developments closely. 66 | - **Strategy**: Maintain current positions in Tesla while carefully observing the company’s financial performance in the next earnings report. Consider increasing holdings if the launch of less-expensive vehicles and other strategic initiatives show positive results. 67 | -------------------------------------------------------------------------------- /3_stock_analysis/tools/sec_tools.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | import requests 4 | 5 | from langchain.tools import tool 6 | from langchain.text_splitter import CharacterTextSplitter 7 | from langchain.embeddings import OpenAIEmbeddings 8 | from langchain_community.vectorstores import FAISS 9 | 10 | from sec_api import QueryApi 11 | from unstructured.partition.html import partition_html 12 | 13 | class SECTools(): 14 | @tool("Search 10-Q form") 15 | def search_10q(data): 16 | """ 17 | Useful to search information from the latest 10-Q form for a 18 | given stock. 19 | The input to this tool should be a pipe (|) separated text of 20 | length two, representing the stock ticker you are interested and what 21 | question you have from it. 22 | For example, `AAPL|what was last quarter's revenue`. 23 | """ 24 | stock, ask = data.split("|") 25 | queryApi = QueryApi(api_key=os.environ['SEC_API_API_KEY']) 26 | query = { 27 | "query": { 28 | "query_string": { 29 | "query": f"ticker:{stock} AND formType:\"10-Q\"" 30 | } 31 | }, 32 | "from": "0", 33 | "size": "1", 34 | "sort": [{ "filedAt": { "order": "desc" }}] 35 | } 36 | 37 | fillings = queryApi.get_filings(query)['filings'] 38 | if len(fillings) == 0: 39 | return "Sorry, I couldn't find any filling for this stock, check if the ticker is correct." 40 | link = fillings[0]['linkToFilingDetails'] 41 | answer = SECTools.__embedding_search(link, ask) 42 | return answer 43 | 44 | @tool("Search 10-K form") 45 | def search_10k(data): 46 | """ 47 | Useful to search information from the latest 10-K form for a 48 | given stock. 49 | The input to this tool should be a pipe (|) separated text of 50 | length two, representing the stock ticker you are interested, what 51 | question you have from it. 52 | For example, `AAPL|what was last year's revenue`. 53 | """ 54 | stock, ask = data.split("|") 55 | queryApi = QueryApi(api_key=os.environ['SEC_API_API_KEY']) 56 | query = { 57 | "query": { 58 | "query_string": { 59 | "query": f"ticker:{stock} AND formType:\"10-K\"" 60 | } 61 | }, 62 | "from": "0", 63 | "size": "1", 64 | "sort": [{ "filedAt": { "order": "desc" }}] 65 | } 66 | 67 | fillings = queryApi.get_filings(query)['filings'] 68 | if len(fillings) == 0: 69 | return "Sorry, I couldn't find any filling for this stock, check if the ticker is correct." 70 | link = fillings[0]['linkToFilingDetails'] 71 | answer = SECTools.__embedding_search(link, ask) 72 | return answer 73 | 74 | def __embedding_search(url, ask): 75 | text = SECTools.__download_form_html(url) 76 | elements = partition_html(text=text) 77 | content = "\n".join([str(el) for el in elements]) 78 | text_splitter = CharacterTextSplitter( 79 | separator = "\n", 80 | chunk_size = 1000, 81 | chunk_overlap = 150, 82 | length_function = len, 83 | is_separator_regex = False, 84 | ) 85 | docs = text_splitter.create_documents([content]) 86 | retriever = FAISS.from_documents( 87 | docs, OpenAIEmbeddings() 88 | ).as_retriever() 89 | answers = retriever.get_relevant_documents(ask, top_k=4) 90 | answers = "\n\n".join([a.page_content for a in answers]) 91 | return answers 92 | 93 | def __download_form_html(url): 94 | headers = { 95 | 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7', 96 | 'Accept-Encoding': 'gzip, deflate, br', 97 | 'Accept-Language': 'en-US,en;q=0.9,pt-BR;q=0.8,pt;q=0.7', 98 | 'Cache-Control': 'max-age=0', 99 | 'Dnt': '1', 100 | 'Sec-Ch-Ua': '"Not_A Brand";v="8", "Chromium";v="120"', 101 | 'Sec-Ch-Ua-Mobile': '?0', 102 | 'Sec-Ch-Ua-Platform': '"macOS"', 103 | 'Sec-Fetch-Dest': 'document', 104 | 'Sec-Fetch-Mode': 'navigate', 105 | 'Sec-Fetch-Site': 'none', 106 | 'Sec-Fetch-User': '?1', 107 | 'Upgrade-Insecure-Requests': '1', 108 | 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36' 109 | } 110 | 111 | response = requests.get(url, headers=headers) 112 | return response.text 113 | -------------------------------------------------------------------------------- /outputs/game_planner_chatgpt4_turbo.py: -------------------------------------------------------------------------------- 1 | import turtle 2 | import time 3 | import random 4 | 5 | delay = 0.1 6 | score = 0 7 | high_score = 0 8 | 9 | # Screen setup 10 | wn = turtle.Screen() 11 | wn.title("Snake Game") 12 | wn.bgcolor("black") 13 | wn.setup(width=600, height=600) 14 | wn.tracer(0) 15 | 16 | # Snake head 17 | head = turtle.Turtle() 18 | head.speed(0) 19 | head.shape("square") 20 | head.color("white") 21 | head.penup() 22 | head.goto(0, 0) 23 | head.direction = "stop" 24 | 25 | # Snake food 26 | food = turtle.Turtle() 27 | food.speed(0) 28 | food.shape("circle") 29 | food.color("red") 30 | food.penup() 31 | food.goto(0, 100) 32 | 33 | segments = [] 34 | 35 | # Scoreboard 36 | sc = turtle.Turtle() 37 | sc.speed(0) 38 | sc.shape("square") 39 | sc.color("white") 40 | sc.penup() 41 | sc.hideturtle() 42 | sc.goto(0, 260) 43 | sc.write("Score: 0 High Score: 0", align="center", 44 | font=("Courier", 24, "normal")) 45 | 46 | # Functions 47 | 48 | 49 | def go_up(): 50 | if head.direction != "down": 51 | head.direction = "up" 52 | 53 | 54 | def go_down(): 55 | if head.direction != "up": 56 | head.direction = "down" 57 | 58 | 59 | def go_left(): 60 | if head.direction != "right": 61 | head.direction = "left" 62 | 63 | 64 | def go_right(): 65 | if head.direction != "left": 66 | head.direction = "right" 67 | 68 | 69 | def move(): 70 | if head.direction == "up": 71 | y = head.ycor() 72 | head.sety(y + 20) 73 | if head.direction == "down": 74 | y = head.ycor() 75 | head.sety(y - 20) 76 | if head.direction == "left": 77 | x = head.xcor() 78 | head.setx(x - 20) 79 | if head.direction == "right": 80 | x = head.xcor() 81 | head.setx(x + 20) 82 | 83 | 84 | # Keyboard bindings 85 | wn.listen() 86 | wn.onkeypress(go_up, "w") 87 | wn.onkeypress(go_down, "s") 88 | wn.onkeypress(go_left, "a") 89 | wn.onkeypress(go_right, "d") 90 | 91 | # Main game loop 92 | while True: 93 | wn.update() 94 | 95 | # Check for a collision with the border 96 | if head.xcor() > 290 or head.xcor() < -290 or head.ycor() > 290 or head.ycor() < -290: 97 | time.sleep(1) 98 | head.goto(0, 0) 99 | head.direction = "stop" 100 | 101 | # Hide the segments 102 | for segment in segments: 103 | segment.goto(1000, 1000) # out of window 104 | segments.clear() 105 | 106 | # Reset the score 107 | score = 0 108 | sc.clear() 109 | sc.write("Score: {} High Score: {}".format(score, high_score), 110 | align="center", font=("Courier", 24, "normal")) 111 | 112 | # Check for a collision with the food 113 | if head.distance(food) < 20: 114 | x = random.randint(-290, 290) 115 | y = random.randint(-290, 290) 116 | food.goto(x, y) 117 | 118 | # Add a segment 119 | new_segment = turtle.Turtle() 120 | new_segment.speed(0) 121 | new_segment.shape("square") 122 | new_segment.color("grey") 123 | new_segment.penup() 124 | segments.append(new_segment) 125 | 126 | # Increase the score 127 | score += 10 128 | if score > high_score: 129 | high_score = score 130 | sc.clear() 131 | sc.write("Score: {} High Score: {}".format(score, high_score), 132 | align="center", font=("Courier", 24, "normal")) 133 | 134 | # Move the end segments first in reverse order 135 | for index in range(len(segments) - 1, 0, -1): 136 | x = segments[index - 1].xcor() 137 | y = segments[index - 1].ycor() 138 | segments[index].goto(x, y) 139 | 140 | # Move segment 0 to where the head is 141 | if len(segments) > 0: 142 | x = head.xcor() 143 | y = head.ycor() 144 | segments[0].goto(x, y) 145 | 146 | move() 147 | 148 | # Check for head collision with the body segments 149 | for segment in segments: 150 | if segment.distance(head) < 20: 151 | time.sleep(1) 152 | head.goto(0, 0) 153 | head.direction = "stop" 154 | 155 | for segment in segments: 156 | segment.goto(1000, 1000) # move segments out of window 157 | segments.clear() 158 | score = 0 159 | sc.clear() 160 | sc.write("Score: {} High Score: {}".format( 161 | score, high_score), align="center", font=("Courier", 24, "normal")) 162 | 163 | time.sleep(delay) 164 | 165 | wn.mainloop() 166 | -------------------------------------------------------------------------------- /3_stock_analysis/stock_analysis_tasks.py: -------------------------------------------------------------------------------- 1 | from crewai import Task 2 | from textwrap import dedent 3 | 4 | 5 | class StockAnalysisTasks(): 6 | def research(self, agent, company): 7 | return Task( 8 | description=dedent(f""" 9 | Collect and summarize recent news articles, press 10 | releases, and market analyses related to the stock and 11 | its industry. 12 | Pay special attention to any significant events, market 13 | sentiments, and analysts' opinions. Also include upcoming 14 | events like earnings and others. 15 | 16 | Your final answer MUST be a report that includes a 17 | comprehensive summary of the latest news, any notable 18 | shifts in market sentiment, and potential impacts on 19 | the stock. Also, make sure to return the stock ticker. 20 | 21 | Make sure to use the most recent data possible. 22 | 23 | Selected company by the customer: {company} 24 | """), 25 | expected_output="A comprehensive summary of the latest news, notable shifts in market sentiment, potential impacts on the stock, and the stock ticker.", 26 | agent=agent 27 | ) 28 | 29 | def financial_analysis(self, agent): 30 | return Task( 31 | description=dedent(f""" 32 | Conduct a thorough analysis of the stock's financial 33 | health and market performance. 34 | This includes examining key financial metrics such as 35 | P/E ratio, EPS growth, revenue trends, and 36 | debt-to-equity ratio. 37 | Also, analyze the stock's performance in comparison 38 | to its industry peers and overall market trends. 39 | 40 | Your final report MUST expand on the summary provided, 41 | including a clear assessment of the stock's financial 42 | standing, its strengths and weaknesses, and how it fares 43 | against its competitors in the current market scenario. 44 | 45 | Make sure to use the most recent data possible. 46 | """), 47 | expected_output="A detailed financial analysis report including key financial metrics, assessment of the stock's financial standing, strengths and weaknesses, and comparison with industry peers.", 48 | agent=agent 49 | ) 50 | 51 | def filings_analysis(self, agent): 52 | return Task( 53 | description=dedent(f""" 54 | Analyze the latest 10-Q and 10-K filings from EDGAR for 55 | the stock in question. 56 | Focus on key sections like Management's Discussion and 57 | Analysis, financial statements, insider trading activity, 58 | and any disclosed risks. 59 | Extract relevant data and insights that could influence 60 | the stock's future performance. 61 | 62 | Your final answer must be an expanded report that also 63 | highlights significant findings from these filings, 64 | including any red flags or positive indicators for your 65 | customer. 66 | """), 67 | expected_output="An expanded report highlighting significant findings from the 10-Q and 10-K filings, including any red flags or positive indicators.", 68 | agent=agent 69 | ) 70 | 71 | def recommend(self, agent): 72 | return Task( 73 | description=dedent(f""" 74 | Review and synthesize the analyses provided by the 75 | Financial Analyst and the Research Analyst. 76 | Combine these insights to form a comprehensive 77 | investment recommendation. 78 | 79 | You MUST consider all aspects, including financial 80 | health, market sentiment, and qualitative data from 81 | EDGAR filings. 82 | 83 | Make sure to include a section that shows insider 84 | trading activity, and upcoming events like earnings. 85 | 86 | Your final answer MUST be a recommendation for your 87 | customer. It should be a full, super detailed report, providing 88 | a clear investment stance and strategy with supporting evidence. 89 | Make it pretty and well formatted for your customer. 90 | """), 91 | expected_output="A comprehensive investment recommendation report including financial health, market sentiment, EDGAR filings data, insider trading activity, and upcoming events.", 92 | agent=agent 93 | ) 94 | -------------------------------------------------------------------------------- /outputs/game_planner_chatgpt4o.py: -------------------------------------------------------------------------------- 1 | import turtle 2 | import time 3 | import random 4 | 5 | delay = 0.1 6 | score = 0 7 | high_score = 0 8 | 9 | # Set up the screen 10 | wn = turtle.Screen() 11 | wn.title("Snake Game") 12 | wn.bgcolor("black") 13 | wn.setup(width=600, height=600) 14 | wn.tracer(0) # Turns off the screen updates 15 | 16 | # Snake head 17 | head = turtle.Turtle() 18 | head.speed(0) 19 | head.shape("square") 20 | head.color("white") 21 | head.penup() 22 | head.goto(0, 0) 23 | head.direction = "stop" 24 | 25 | # Snake food 26 | food = turtle.Turtle() 27 | food.speed(0) 28 | food.shape("circle") 29 | food.color("red") 30 | food.penup() 31 | food.goto(0, 100) 32 | 33 | segments = [] 34 | 35 | # Pen 36 | pen = turtle.Turtle() 37 | pen.speed(0) 38 | pen.shape("square") 39 | pen.color("white") 40 | pen.penup() 41 | pen.hideturtle() 42 | pen.goto(0, 260) 43 | pen.write("Score: 0 High Score: 0", align="center", 44 | font=("Courier", 24, "normal")) 45 | 46 | 47 | # Functions 48 | def go_up(): 49 | if head.direction != "down": 50 | head.direction = "up" 51 | 52 | 53 | def go_down(): 54 | if head.direction != "up": 55 | head.direction = "down" 56 | 57 | 58 | def go_left(): 59 | if head.direction != "right": 60 | head.direction = "left" 61 | 62 | 63 | def go_right(): 64 | if head.direction != "left": 65 | head.direction = "right" 66 | 67 | 68 | def move(): 69 | if head.direction == "up": 70 | y = head.ycor() 71 | head.sety(y + 20) 72 | 73 | if head.direction == "down": 74 | y = head.ycor() 75 | head.sety(y - 20) 76 | 77 | if head.direction == "left": 78 | x = head.xcor() 79 | head.setx(x - 20) 80 | 81 | if head.direction == "right": 82 | x = head.xcor() 83 | head.setx(x + 20) 84 | 85 | 86 | # Keyboard bindings 87 | wn.listen() 88 | wn.onkey(go_up, "w") 89 | wn.onkey(go_down, "s") 90 | wn.onkey(go_left, "a") 91 | wn.onkey(go_right, "d") 92 | 93 | # Main game loop 94 | while True: 95 | wn.update() 96 | 97 | # Check for a collision with the border 98 | if head.xcor() > 290 or head.xcor() < -290 or head.ycor() > 290 or head.ycor() < -290: 99 | time.sleep(1) 100 | head.goto(0, 0) 101 | head.direction = "stop" 102 | 103 | # Hide the segments 104 | for segment in segments: 105 | segment.goto(1000, 1000) 106 | 107 | # Clear the segments list 108 | segments.clear() 109 | 110 | # Reset the score 111 | score = 0 112 | delay = 0.1 113 | 114 | # Update the score display 115 | pen.clear() 116 | pen.write("Score: {} High Score: {}".format(score, high_score), 117 | align="center", font=("Courier", 24, "normal")) 118 | 119 | # Check for a collision with the food 120 | if head.distance(food) < 20: 121 | # Move the food to a random spot 122 | x = random.randint(-290, 290) 123 | y = random.randint(-290, 290) 124 | food.goto(x, y) 125 | 126 | # Add a segment 127 | new_segment = turtle.Turtle() 128 | new_segment.speed(0) 129 | new_segment.shape("square") 130 | new_segment.color("grey") 131 | new_segment.penup() 132 | segments.append(new_segment) 133 | 134 | # Shorten the delay 135 | delay -= 0.001 136 | 137 | # Increase the score 138 | score += 10 139 | 140 | if score > high_score: 141 | high_score = score 142 | 143 | pen.clear() 144 | pen.write("Score: {} High Score: {}".format(score, high_score), 145 | align="center", font=("Courier", 24, "normal")) 146 | 147 | # Move the end segments first in reverse order 148 | for index in range(len(segments) - 1, 0, -1): 149 | x = segments[index - 1].xcor() 150 | y = segments[index - 1].ycor() 151 | segments[index].goto(x, y) 152 | 153 | # Move segment 0 to where the head is 154 | if len(segments) > 0: 155 | x = head.xcor() 156 | y = head.ycor() 157 | segments[0].goto(x, y) 158 | 159 | move() 160 | 161 | # Check for head collision with body segments 162 | for segment in segments: 163 | if segment.distance(head) < 20: 164 | time.sleep(1) 165 | head.goto(0, 0) 166 | head.direction = "stop" 167 | 168 | # Hide the segments 169 | for segment in segments: 170 | segment.goto(1000, 1000) 171 | 172 | # Clear the segments list 173 | segments.clear() 174 | 175 | # Reset the score 176 | score = 0 177 | delay = 0.1 178 | 179 | # Update the score display 180 | pen.clear() 181 | pen.write("Score: {} High Score: {}".format( 182 | score, high_score), align="center", font=("Courier", 24, "normal")) 183 | 184 | time.sleep(delay) 185 | 186 | wn.mainloop() 187 | -------------------------------------------------------------------------------- /2_trip_planner/README.md: -------------------------------------------------------------------------------- 1 | # AI Crew for Trip Planning 2 | ## Introduction 3 | This project is an example using the CrewAI framework to automate the process of planning a trip if you are in doubt between different options. CrewAI orchestrates autonomous AI agents, enabling them to collaborate and execute complex tasks efficiently. 4 | 5 | By [@joaomdmoura](https://x.com/joaomdmoura) 6 | 7 | - [CrewAI Framework](#crewai-framework) 8 | - [Running the script](#running-the-script) 9 | - [Details & Explanation](#details--explanation) 10 | - [Using GPT 3.5](#using-gpt-35) 11 | - [Using Local Models with Ollama](#using-local-models-with-ollama) 12 | - [Contributing](#contributing) 13 | - [Support and Contact](#support-and-contact) 14 | - [License](#license) 15 | 16 | ## CrewAI Framework 17 | CrewAI is designed to facilitate the collaboration of role-playing AI agents. In this example, these agents work together to choose between different of cities and put together a full itinerary for the trip based on your preferences. 18 | 19 | ## Running the Script 20 | It uses GPT-4 by default so you should have access to that to run it. 21 | 22 | ***Disclaimer:** This will use gpt-4 unless you changed it 23 | not to, and by doing so it will cost you money.* 24 | 25 | - **Configure Environment**: Copy ``.env.example` and set up the environment variables for [Browseless](https://www.browserless.io/), [Serper](https://serper.dev/) and [OpenAI](https://platform.openai.com/api-keys) 26 | - **Install Dependencies**: Run `poetry install --no-root`. 27 | - **Execute the Script**: Run `poetry run python main.py` and input your idea. 28 | 29 | ## Details & Explanation 30 | - **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. 31 | - **Key Components**: 32 | - `./main.py`: Main script file. 33 | - `./trip_tasks.py`: Main file with the tasks prompts. 34 | - `./trip_agents.py`: Main file with the agents creation. 35 | - `./tools`: Contains tool classes used by the agents. 36 | 37 | ## Using GPT 3.5 38 | CrewAI allow you to pass an llm argument to the agent construtor, that will be it's brain, so changing the agent to use GPT-3.5 instead of GPT-4 is as simple as passing that argument on the agent you want to use that LLM (in `main.py`). 39 | ```python 40 | from langchain.chat_models import ChatOpenAI 41 | 42 | llm = ChatOpenAI(model='gpt-3.5') # Loading GPT-3.5 43 | 44 | def local_expert(self): 45 | return Agent( 46 | role='Local Expert at this city', 47 | goal='Provide the BEST insights about the selected city', 48 | backstory="""A knowledgeable local guide with extensive information 49 | about the city, it's attractions and customs""", 50 | tools=[ 51 | SearchTools.search_internet, 52 | BrowserTools.scrape_and_summarize_website, 53 | ], 54 | llm=llm, # <----- passing our llm reference here 55 | verbose=True 56 | ) 57 | ``` 58 | 59 | ## Using Local Models with Ollama 60 | The CrewAI framework supports integration with local models, such as Ollama, for enhanced flexibility and customization. This allows you to utilize your own models, which can be particularly useful for specialized tasks or data privacy concerns. 61 | 62 | ### Setting Up Ollama 63 | - **Install Ollama**: Ensure that Ollama is properly installed in your environment. Follow the installation guide provided by Ollama for detailed instructions. 64 | - **Configure Ollama**: Set up Ollama to work with your local model. You will probably need to [tweak the model using a Modelfile](https://github.com/jmorganca/ollama/blob/main/docs/modelfile.md), I'd recommend adding `Observation` as a stop word and playing with `top_p` and `temperature`. 65 | 66 | ### Integrating Ollama with CrewAI 67 | - Instantiate Ollama Model: Create an instance of the Ollama model. You can specify the model and the base URL during instantiation. For example: 68 | 69 | ```python 70 | from langchain.llms import Ollama 71 | ollama_openhermes = Ollama(model="agent") 72 | # Pass Ollama Model to Agents: When creating your agents within the CrewAI framework, you can pass the Ollama model as an argument to the Agent constructor. For instance: 73 | 74 | def local_expert(self): 75 | return Agent( 76 | role='Local Expert at this city', 77 | goal='Provide the BEST insights about the selected city', 78 | backstory="""A knowledgeable local guide with extensive information 79 | about the city, it's attractions and customs""", 80 | tools=[ 81 | SearchTools.search_internet, 82 | BrowserTools.scrape_and_summarize_website, 83 | ], 84 | llm=ollama_openhermes, # Ollama model passed here 85 | verbose=True 86 | ) 87 | ``` 88 | 89 | ### Advantages of Using Local Models 90 | - **Privacy**: Local models allow processing of data within your own infrastructure, ensuring data privacy. 91 | - **Customization**: You can customize the model to better suit the specific needs of your tasks. 92 | - **Performance**: Depending on your setup, local models can offer performance benefits, especially in terms of latency. 93 | 94 | ## License 95 | This project is released under the MIT License. 96 | -------------------------------------------------------------------------------- /outputs/trip_planner_chatgpt4o.md: -------------------------------------------------------------------------------- 1 | # 7-Day Travel Itinerary for Split, Croatia (August 5th - August 12th, 2024) 2 | 3 | ## Overview 4 | 5 | Welcome to Split, Croatia! This 7-day itinerary will guide you through the best experiences Split has to offer, from historical landmarks to beautiful beaches, vibrant nightlife, and rich cultural history. 6 | 7 | ## Day 1: Arrival and Relaxation 8 | 9 | **Weather**: Sunny, 82°F (28°C) 10 | **Packing Suggestions**: Light clothing, sunglasses, hat, sunscreen 11 | 12 | - **Morning**: Arrive in Split and check into your hotel. 13 | - **Accommodation**: [Radisson Blu Resort & Spa](https://www.radissonhotels.com/en-us/hotels/radisson-blu-resort-split) ($150/night) 14 | - **Afternoon**: Explore the Riva Promenade. Enjoy a leisurely stroll, people-watch, and have coffee at a waterfront café. 15 | - **Evening**: Dinner at [Restaurant Zrno Soli](https://www.zrnosoli.com/) - a fine dining experience with a view of the marina. 16 | 17 | **Budget**: 18 | 19 | - Accommodation: $150 20 | - Meals: $50 21 | - Transportation: $20 22 | 23 | ## Day 2: Historical Exploration 24 | 25 | **Weather**: Sunny, 84°F (29°C) 26 | **Packing Suggestions**: Comfortable walking shoes, light clothing, water bottle 27 | 28 | - **Morning**: Visit Diocletian's Palace and Peristyle Square. Explore the ancient palace complex and its narrow streets. 29 | - **Afternoon**: Climb the bell tower of the Cathedral of Saint Domnius for panoramic views of the city. 30 | - **Evening**: Attend a performance at Peristyle Square or the Croatian National Theatre. 31 | 32 | **Budget**: 33 | 34 | - Accommodation: $150 35 | - Meals: $50 36 | - Entrance Fees: $20 37 | - Transportation: $10 38 | 39 | ## Day 3: Beach Day 40 | 41 | **Weather**: Sunny, 85°F (29°C) 42 | **Packing Suggestions**: Swimwear, towel, sunscreen, beach hat 43 | 44 | - **Morning and Afternoon**: Spend the day at Bacvice Beach. Enjoy swimming, sunbathing, and playing "picigin." 45 | - **Evening**: Visit [Marvlvs Library Jazz Bar](https://www.marvlvs-library-jazz-bar.com/) for live jazz music in a cozy atmosphere. 46 | 47 | **Budget**: 48 | 49 | - Accommodation: $150 50 | - Meals: $40 51 | - Beach Activities: $10 52 | - Transportation: $10 53 | 54 | ## Day 4: Cultural Immersion 55 | 56 | **Weather**: Sunny, 83°F (28°C) 57 | **Packing Suggestions**: Comfortable clothing, camera 58 | 59 | - **Morning**: Visit the Green Market and Fish Market to experience local life and purchase fresh produce. 60 | - **Afternoon**: Tour the [Galerija Mestrovic](https://www.mestrovic.hr/). 61 | - **Evening**: Dinner at [Konoba Fetivi](https://konobafetivi.com/) - a traditional Dalmatian tavern. 62 | 63 | **Budget**: 64 | 65 | - Accommodation: $150 66 | - Meals: $50 67 | - Entrance Fees: $10 68 | - Transportation: $10 69 | 70 | ## Day 5: Day Trip 71 | 72 | **Weather**: Sunny, 82°F (28°C) 73 | **Packing Suggestions**: Comfortable clothing, swimwear, sunscreen, hat 74 | 75 | - **Full Day**: Take a boat trip to the Blue Cave or the islands of Hvar and Vis. Enjoy the beautiful scenery and swimming opportunities. 76 | - **Evening**: Return to Split and relax at a local café. 77 | 78 | **Budget**: 79 | 80 | - Accommodation: $150 81 | - Meals: $60 82 | - Boat Trip: $100 83 | - Transportation: $20 84 | 85 | ## Day 6: Nature and Adventure 86 | 87 | **Weather**: Sunny, 84°F (29°C) 88 | **Packing Suggestions**: Hiking shoes, comfortable clothing, water bottle 89 | 90 | - **Morning**: Hike or bike through Marjan Hill. Enjoy stunning views and the natural beauty of the area. 91 | - **Afternoon**: Visit Kastel Gomilica, a charming coastal village with medieval architecture. 92 | - **Evening**: Wine tasting at [Putalj Wine](https://www.putaljwine.com/). 93 | 94 | **Budget**: 95 | 96 | - Accommodation: $150 97 | - Meals: $50 98 | - Wine Tasting: $50 99 | - Transportation: $20 100 | 101 | ## Day 7: Exploration and Farewell 102 | 103 | **Weather**: Sunny, 83°F (28°C) 104 | **Packing Suggestions**: Comfortable clothing, camera 105 | 106 | - **Morning**: Visit the Church of St. Nicholas for a peaceful reflection and stunning frescoes. 107 | - **Afternoon**: Explore any remaining parts of Diocletian’s Palace. 108 | - **Evening**: Enjoy your last dinner in Split with a view of the Adriatic Sea at [Restaurant Dvor](https://www.dvor.hr/). 109 | 110 | **Budget**: 111 | 112 | - Accommodation: $150 113 | - Meals: $60 114 | - Entrance Fees: $10 115 | - Transportation: $10 116 | 117 | ## Day 8: Departure 118 | 119 | **Weather**: Sunny, 82°F (28°C) 120 | **Packing Suggestions**: Comfortable clothing, travel essentials 121 | 122 | - **Morning**: Take a final stroll through the Riva Promenade. 123 | - **Afternoon**: Depart for Atlanta, GA. 124 | 125 | **Budget**: 126 | 127 | - Transportation: $20 128 | - Meals: $40 129 | 130 | ## Overall Budget Breakdown 131 | 132 | - **Accommodation** (7 nights): $1,050 133 | - **Meals**: $400 134 | - **Transportation**: $120 135 | - **Activities and Entrance Fees**: $200 136 | - **Additional Expenses**: $100 137 | 138 | **Total**: $1,870 139 | 140 | ## Packing List 141 | 142 | - Light clothing for warm weather 143 | - Comfortable walking shoes 144 | - Swimwear and beach essentials 145 | - Sunglasses, hat, and sunscreen 146 | - Camera 147 | - Travel documents and essentials 148 | -------------------------------------------------------------------------------- /3_stock_analysis/README.md: -------------------------------------------------------------------------------- 1 | # AI Crew for Stock Analysis 2 | ## Introduction 3 | This project is an example using the CrewAI framework to automate the process of analyzing a stock. CrewAI orchestrates autonomous AI agents, enabling them to collaborate and execute complex tasks efficiently. 4 | 5 | By [@joaomdmoura](https://x.com/joaomdmoura) 6 | 7 | - [CrewAI Framework](#crewai-framework) 8 | - [Running the script](#running-the-script) 9 | - [Details & Explanation](#details--explanation) 10 | - [Using GPT 3.5](#using-gpt-35) 11 | - [Using Local Models with Ollama](#using-local-models-with-ollama) 12 | - [Contributing](#contributing) 13 | - [Support and Contact](#support-and-contact) 14 | - [License](#license) 15 | 16 | ## CrewAI Framework 17 | 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 18 | 19 | ## Running the Script 20 | It uses GPT-4 by default so you should have access to that to run it. 21 | 22 | ***Disclaimer:** This will use gpt-4 unless you changed it 23 | not to, and by doing so it will cost you money.* 24 | 25 | - **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) 26 | - **Install Dependencies**: Run `poetry install --no-root`. 27 | - **Execute the Script**: Run `python main.py` and input your idea. 28 | 29 | ## Details & Explanation 30 | - **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. 31 | - **Key Components**: 32 | - `./main.py`: Main script file. 33 | - `./stock_analysis_tasks.py`: Main file with the tasks prompts. 34 | - `./stock_analysis_agents.py`: Main file with the agents creation. 35 | - `./tools`: Contains tool classes used by the agents. 36 | 37 | ## Using GPT 3.5 38 | CrewAI allow you to pass an llm argument to the agent construtor, that will be it's brain, so changing the agent to use GPT-3.5 instead of GPT-4 is as simple as passing that argument on the agent you want to use that LLM (in `main.py`). 39 | ```python 40 | from langchain.chat_models import ChatOpenAI 41 | 42 | llm = ChatOpenAI(model='gpt-3.5') # Loading GPT-3.5 43 | 44 | def local_expert(self): 45 | return Agent( 46 | role='The Best Financial Analyst', 47 | goal="""Impress all customers with your financial data 48 | and market trends analysis""", 49 | backstory="""The most seasoned financial analyst with 50 | lots of expertise in stock market analysis and investment 51 | strategies that is working for a super important customer.""", 52 | verbose=True, 53 | llm=llm, # <----- passing our llm reference here 54 | tools=[ 55 | BrowserTools.scrape_and_summarize_website, 56 | SearchTools.search_internet, 57 | CalculatorTools.calculate, 58 | SECTools.search_10q, 59 | SECTools.search_10k 60 | ] 61 | ) 62 | ``` 63 | 64 | ## Using Local Models with Ollama 65 | The CrewAI framework supports integration with local models, such as Ollama, for enhanced flexibility and customization. This allows you to utilize your own models, which can be particularly useful for specialized tasks or data privacy concerns. 66 | 67 | ### Setting Up Ollama 68 | - **Install Ollama**: Ensure that Ollama is properly installed in your environment. Follow the installation guide provided by Ollama for detailed instructions. 69 | - **Configure Ollama**: Set up Ollama to work with your local model. You will probably need to [tweak the model using a Modelfile](https://github.com/jmorganca/ollama/blob/main/docs/modelfile.md), I'd recommend adding `Observation` as a stop word and playing with `top_p` and `temperature`. 70 | 71 | ### Integrating Ollama with CrewAI 72 | - Instantiate Ollama Model: Create an instance of the Ollama model. You can specify the model and the base URL during instantiation. For example: 73 | 74 | ```python 75 | from langchain.llms import Ollama 76 | ollama_openhermes = Ollama(model="openhermes") 77 | # Pass Ollama Model to Agents: When creating your agents within the CrewAI framework, you can pass the Ollama model as an argument to the Agent constructor. For instance: 78 | 79 | def local_expert(self): 80 | return Agent( 81 | role='The Best Financial Analyst', 82 | goal="""Impress all customers with your financial data 83 | and market trends analysis""", 84 | backstory="""The most seasoned financial analyst with 85 | lots of expertise in stock market analysis and investment 86 | strategies that is working for a super important customer.""", 87 | verbose=True, 88 | llm=ollama_openhermes, # Ollama model passed here 89 | tools=[ 90 | BrowserTools.scrape_and_summarize_website, 91 | SearchTools.search_internet, 92 | CalculatorTools.calculate, 93 | SECTools.search_10q, 94 | SECTools.search_10k 95 | ] 96 | ) 97 | ``` 98 | 99 | ### Advantages of Using Local Models 100 | - **Privacy**: Local models allow processing of data within your own infrastructure, ensuring data privacy. 101 | - **Customization**: You can customize the model to better suit the specific needs of your tasks. 102 | - **Performance**: Depending on your setup, local models can offer performance benefits, especially in terms of latency. 103 | 104 | ## License 105 | This project is released under the MIT License. 106 | --------------------------------------------------------------------------------