From 2b7528e4598f675b202c0183825bc4c1e86a16e1 Mon Sep 17 00:00:00 2001 From: dloman118 <99347459+dloman118@users.noreply.github.com> Date: Tue, 16 Jul 2024 09:43:43 -0400 Subject: [PATCH] CrewAI Mixture of Agents Cookbook --- .../Mixture-of-Agents-Crew-AI-Groq.ipynb | 740 ++++++++++++++++++ 1 file changed, 740 insertions(+) create mode 100644 crewai-mixture-of-agents/Mixture-of-Agents-Crew-AI-Groq.ipynb diff --git a/crewai-mixture-of-agents/Mixture-of-Agents-Crew-AI-Groq.ipynb b/crewai-mixture-of-agents/Mixture-of-Agents-Crew-AI-Groq.ipynb new file mode 100644 index 0000000..638044f --- /dev/null +++ b/crewai-mixture-of-agents/Mixture-of-Agents-Crew-AI-Groq.ipynb @@ -0,0 +1,740 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "6613d551-2164-4824-a4de-1c4d021b61a9", + "metadata": {}, + "source": [ + "# MLB Editorial Crew: Mixture of Agents with Crew AI and Groq" + ] + }, + { + "cell_type": "markdown", + "id": "444802de-1d9f-4a5d-873d-2aeca7cea4ca", + "metadata": {}, + "source": [ + "In this notebook, we will showcase the concept of [Mixture of Agents (MoA)](https://arxiv.org/pdf/2406.04692) using [Crew AI](https://www.crewai.com/) and Groq. The Mixture of Agents approach involves leveraging multiple AI agents, each equipped with different language models, to collaboratively complete a task. By combining the strengths and perspectives of various models, we can achieve a more robust and nuanced result. In our project, multiple MLB Writer agents, each utilizing a different language model (llama3-8b-8192, gemma2-9b-it, and mixtral-8x7b-32768), will independently generate game recap articles based on game data collected from other Crew AI agents. These diverse outputs will then be aggregated by an MLB Editor agent, which will synthesize the best elements from each article to create a final, polished game recap. This process not only demonstrates the power of collaborative AI but also highlights the effectiveness of integrating multiple models to enhance the quality of the generated content." + ] + }, + { + "cell_type": "markdown", + "id": "226eaba9-16a9-432c-9ad3-67bb54c9a053", + "metadata": {}, + "source": [ + "### Setup" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "98f4f68d-d596-4f10-a72f-f7027e3f37f4", + "metadata": {}, + "outputs": [], + "source": [ + "# Import packages\n", + "import os\n", + "import statsapi\n", + "import datetime\n", + "from datetime import date, timedelta, datetime\n", + "import pandas as pd\n", + "import numpy as np\n", + "from crewai_tools import tool\n", + "from crewai import Agent, Task, Crew, Process\n", + "from langchain_groq import ChatGroq" + ] + }, + { + "cell_type": "markdown", + "id": "cee9fc13-e27d-4e93-95df-57c87f5a8df4", + "metadata": {}, + "source": [ + "We will configure multiple LLMs using (Langchain Groq)[https://python.langchain.com/v0.2/docs/integrations/chat/groq/], each requiring a Groq API Key for access which you can create (here)[https://console.groq.com/keys]. These models include different versions of Meta's LLaMA 3 and other specialized models like Google's Gemma 2 and Mixtral. Each model will be used by different agents to generate diverse outputs for the MLB game recap." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "1cd20615-fe84-4b35-bb39-2e4d7f388b35", + "metadata": {}, + "outputs": [], + "source": [ + "llm_llama70b=ChatGroq(model_name=\"llama3-70b-8192\")\n", + "llm_llama8b=ChatGroq(model_name=\"llama3-8b-8192\")\n", + "llm_gemma2=ChatGroq(model_name=\"gemma2-9b-it\")\n", + "llm_mixtral = ChatGroq(model_name=\"mixtral-8x7b-32768\")" + ] + }, + { + "cell_type": "markdown", + "id": "cfe24034-9aa0-4f7d-90aa-d310dd5e685e", + "metadata": {}, + "source": [ + "### Define Tools" + ] + }, + { + "cell_type": "markdown", + "id": "81fbc977-f417-4bfa-953d-05bc41a184e6", + "metadata": {}, + "source": [ + "First, we will define specialized tools to equip some of the agents with to assist in gathering and processing MLB game data. These tools are designed to fetch game information and player boxscores via the [MLB-Stats API](https://github.com/toddrob99/MLB-StatsAPI). By providing these tools to our agents, they can call them with relevant information provided by the user prompt and infuse our MLB game recaps with accurate, up-to-date external information.\n", + "\n", + "- **get_game_info**: Fetches high-level information about an MLB game, including teams, scores, and key players.\n", + "- **get_batting_stats**: Retrieves detailed player batting statistics for a specified MLB game.\n", + "- **get_pitching_stats**: Retrieves detailed player pitching statistics for a specified MLB game.\n", + "\n", + "For more information on tool use/function calling with Groq, check out this (Function Calling 101 cookbook post)[https://github.com/groq/groq-api-cookbook/blob/main/function-calling-101-ecommerce/Function-Calling-101-Ecommerce.ipynb]." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "a1099020-ce9e-41ba-a477-760281d07f4f", + "metadata": {}, + "outputs": [], + "source": [ + "@tool\n", + "def get_game_info(game_date: str, team_name: str) -> str:\n", + " \"\"\"Gets high-level information on an MLB game.\n", + " \n", + " Params:\n", + " game_date: The date of the game of interest, in the form \"yyyy-mm-dd\". If no specific date is mentioned, this should be 1900-01-01\n", + " team_name: MLB team name. Both full name (e.g. \"New York Yankees\") or nickname (\"Yankees\") are valid. If multiple teams are mentioned, use the first one\n", + " \"\"\"\n", + " sched = statsapi.schedule(start_date=game_date,end_date=game_date)\n", + " sched_df = pd.DataFrame(sched)\n", + " game_info_df = sched_df[sched_df['summary'].str.contains(team_name, case=False, na=False)]\n", + "\n", + " game_id = str(game_info_df.game_id.tolist()[0])\n", + " home_team = game_info_df.home_name.tolist()[0]\n", + " home_score = game_info_df.home_score.tolist()[0]\n", + " home_starter = game_info_df.home_probable_pitcher.tolist()[0]\n", + " away_team = game_info_df.away_name.tolist()[0]\n", + " away_score = game_info_df.away_score.tolist()[0]\n", + " away_starter = game_info_df.away_probable_pitcher.tolist()[0]\n", + " winning_team = game_info_df.winning_team.tolist()[0]\n", + " series_status = game_info_df.series_status.tolist()[0]\n", + "\n", + " game_info = '''\n", + " Game ID: {game_id}\n", + " Home Team: {home_team}\n", + " Home Score: {home_score}\n", + " Home Starting Pitcher: {home_starter}\n", + " Away Team: {away_team}\n", + " Away Score: {away_score}\n", + " Away Starting Pitcher: {away_starter}\n", + " Winning Team: {winning_team}\n", + " Series Status: {series_status}\n", + " '''.format(game_id = game_id, home_team = home_team, home_score = home_score, home_starter = home_starter, \n", + " away_team = away_team, away_score = away_score, away_starter = away_starter, \\\n", + " series_status = series_status, winning_team = winning_team)\n", + "\n", + " return game_info\n", + "\n", + "\n", + "@tool \n", + "def get_batting_stats(game_id: str) -> str:\n", + " \"\"\"Gets player boxscore batting stats for a particular MLB game\n", + " \n", + " Params:\n", + " game_id: The 6-digit ID of the game\n", + " \"\"\"\n", + " boxscores=statsapi.boxscore_data(game_id)\n", + " player_info_df = pd.DataFrame(boxscores['playerInfo']).T.reset_index()\n", + "\n", + " away_batters_box = pd.DataFrame(boxscores['awayBatters']).iloc[1:]\n", + " away_batters_box['team_name'] = boxscores['teamInfo']['away']['teamName']\n", + "\n", + " home_batters_box = pd.DataFrame(boxscores['homeBatters']).iloc[1:]\n", + " home_batters_box['team_name'] = boxscores['teamInfo']['home']['teamName']\n", + "\n", + " batters_box_df = pd.concat([away_batters_box, home_batters_box]).merge(player_info_df, left_on = 'name', right_on = 'boxscoreName')\n", + " return str(batters_box_df[['team_name','fullName','position','ab','r','h','hr','rbi','bb','sb']])\n", + "\n", + "\n", + "@tool \n", + "def get_pitching_stats(game_id: str) -> str:\n", + " \"\"\"Gets player boxscore pitching stats for a particular MLB game\n", + " \n", + " Params:\n", + " game_id: The 6-digit ID of the game\n", + " \"\"\"\n", + " boxscores=statsapi.boxscore_data(game_id)\n", + " player_info_df = pd.DataFrame(boxscores['playerInfo']).T.reset_index()\n", + "\n", + " away_pitchers_box = pd.DataFrame(boxscores['awayPitchers']).iloc[1:]\n", + " away_pitchers_box['team_name'] = boxscores['teamInfo']['away']['teamName']\n", + "\n", + " home_pitchers_box = pd.DataFrame(boxscores['homePitchers']).iloc[1:]\n", + " home_pitchers_box['team_name'] = boxscores['teamInfo']['home']['teamName']\n", + "\n", + " pitchers_box_df = pd.concat([away_pitchers_box,home_pitchers_box]).merge(player_info_df, left_on = 'name', right_on = 'boxscoreName')\n", + " return str(pitchers_box_df[['team_name','fullName','ip','h','r','er','bb','k','note']])\n" + ] + }, + { + "cell_type": "markdown", + "id": "5410103f-5afa-4b33-a834-01212d7dc0e5", + "metadata": {}, + "source": [ + "### Define Agents" + ] + }, + { + "cell_type": "markdown", + "id": "2e0e09f2-e772-4c45-b29e-5bf2b9c91efc", + "metadata": {}, + "source": [ + "In CrewAI, agents are autonomous entities designed to perform specific roles and achieve particular goals. Each agent uses a language model (LLM) and may have specialized tools to help execute tasks. Here are the agents in this demonstration:\n", + "\n", + "- **MLB Researcher**: Uses the `get_game_info` tool to gather high-level game information.\n", + "- **MLB Statistician**: Retrieves player batting and pitching boxscore stats using the `get_batting_stats` and `get_pitching_stats` tools.\n", + "- **MLB Writers**: Three agents, each using different LLMs (LLaMA-8b, Gemma-9b, Mixtral-8x7b), to write game recap articles.\n", + "- **MLB Editor**: Edits the articles from the writers to create the final game recap." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "54a40307-bfc5-4636-aa98-14f49513c611", + "metadata": {}, + "outputs": [], + "source": [ + "mlb_researcher = Agent(\n", + " llm=llm_llama70b,\n", + " role=\"MLB Researcher\",\n", + " goal=\"Identify and return info for the MLB game related to the user prompt by returning the exact results of the get_game_info tool\",\n", + " backstory=\"An MLB researcher that identifies games for statisticians to analyze stats from\",\n", + " tools=[get_game_info],\n", + " verbose=True,\n", + " allow_delegation=False\n", + ")\n", + "\n", + "mlb_statistician = Agent(\n", + " llm=llm_llama70b,\n", + " role=\"MLB Statistician\",\n", + " goal=\"Retrieve player batting and pitching stats for the game identified by the MLB Researcher\",\n", + " backstory=\"An MLB Statistician analyzing player boxscore stats for the relevant game\",\n", + " tools=[get_batting_stats, get_pitching_stats],\n", + " verbose=True,\n", + " allow_delegation=False\n", + ")\n", + "\n", + "mlb_writer_llama = Agent(\n", + " llm=llm_llama8b,\n", + " role=\"MLB Writer\",\n", + " goal=\"Write a detailed game recap article using the provided game information and stats\",\n", + " backstory=\"An experienced and honest writer who does not make things up\",\n", + " tools=[], # The writer does not need additional tools\n", + " verbose=True,\n", + " allow_delegation=False\n", + ")\n", + "\n", + "mlb_writer_gemma = Agent(\n", + " llm=llm_gemma2,\n", + " role=\"MLB Writer\",\n", + " goal=\"Write a detailed game recap article using the provided game information and stats\",\n", + " backstory=\"An experienced and honest writer who does not make things up\",\n", + " tools=[], # The writer does not need additional tools\n", + " verbose=True,\n", + " allow_delegation=False\n", + ")\n", + "\n", + "mlb_writer_mixtral = Agent(\n", + " llm=llm_mixtral,\n", + " role=\"MLB Writer\",\n", + " goal=\"Write a detailed game recap article using the provided game information and stats\",\n", + " backstory=\"An experienced and honest writer who does not make things up\",\n", + " tools=[], # The writer does not need additional tools\n", + " verbose=True,\n", + " allow_delegation=False\n", + ")\n", + "\n", + "mlb_editor = Agent(\n", + " llm=llm_llama70b,\n", + " role=\"MLB Editor\",\n", + " goal=\"Edit multiple game recap articles to create the best final product.\",\n", + " backstory=\"An experienced editor that excels at taking the best parts of multiple texts to create the best final product\",\n", + " tools=[], # The writer does not need additional tools\n", + " verbose=True,\n", + " allow_delegation=False\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "94a4e2a9-42ce-4936-bf93-ecf7706ab3d2", + "metadata": {}, + "source": [ + "### Define Tasks" + ] + }, + { + "cell_type": "markdown", + "id": "369a3040-bcaf-48f4-b864-292eb718775f", + "metadata": {}, + "source": [ + "Tasks in Crew AI are specific assignments given to agents, detailing the actions they need to perform to achieve a particular goal. Tasks can have dependencies, context, and can be executed asynchronously to ensure efficient workflow. Here, we define several tasks that our agents will execute to generate and refine an MLB game recap.\n", + "\n", + "- **collect_game_info**: This task gathers high-level information about an MLB game based on the user prompt. It is handled by the MLB Researcher agent and uses the `get_game_info` tool. This task must be completed before any other tasks can begin.\n", + "\n", + "- **retrieve_batting_stats**: This task retrieves detailed player batting stats for the identified game. It depends on the completion of collect_game_info and can be executed asynchronously. This task runs in parallel with `retrieve_pitching_stats` and is handled by the MLB Statistician agent.\n", + "\n", + "- **retrieve_pitching_stats**: This task retrieves detailed player pitching stats for the identified game. It also depends on the completion of `collect_game_info` and can be executed asynchronously. This task runs in parallel with `retrieve_batting_stats` and is handled by the MLB Statistician agent.\n", + "\n", + "- **write_game_recap**: Three separate tasks handled by different MLB Writer agents (using LLaMA-8b, Gemma-9b, Mixtral-8x7b). Each writer generates a game recap article using the data collected. These tasks depend on the completion of `collect_game_info`, `retrieve_batting_stats`, and `retrieve_pitching_stats`. They can be executed asynchronously and run in parallel with each other.\n", + "\n", + "- **edit_game_recap**: This task involves synthesizing the best parts of the three game recap articles into a final, polished article. It is handled by the MLB Editor agent and depends on the completion of all previous tasks." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "8d81eabd-a25b-4126-b6f5-286a8e0a32f2", + "metadata": {}, + "outputs": [], + "source": [ + "collect_game_info = Task(\n", + " description='''\n", + " Identify the correct game related to the user prompt and return game info using the get_game_info tool. \n", + " Unless a specific date is provided in the user prompt, use {default_date} as the game date\n", + " User prompt: {user_prompt}\n", + " ''',\n", + " expected_output='High-level information of the relevant MLB game',\n", + " agent=mlb_researcher\n", + ")\n", + "\n", + "retrieve_batting_stats = Task(\n", + " description='Retrieve ONLY boxscore batting stats for the relevant MLB game',\n", + " expected_output='A table of batting boxscore stats',\n", + " agent=mlb_statistician,\n", + " async_execution=True,\n", + " dependencies=[collect_game_info],\n", + " context=[collect_game_info]\n", + ")\n", + "\n", + "retrieve_pitching_stats = Task(\n", + " description='Retrieve ONLY boxscore pitching stats for the relevant MLB game',\n", + " expected_output='A table of pitching boxscore stats',\n", + " agent=mlb_statistician,\n", + " async_execution=True,\n", + " dependencies=[collect_game_info],\n", + " context=[collect_game_info]\n", + ")\n", + "\n", + "write_game_recap_llama = Task(\n", + " description='''\n", + " Write a game recap article using the provided game information and stats.\n", + " Key instructions:\n", + " - Include things like final score, top performers and winning/losing pitcher.\n", + " - Use ONLY the provided data and DO NOT make up any information, such as specific innings when events occurred, that isn't explicitly from the provided input.\n", + " - Do not print the box score\n", + " ''',\n", + " expected_output='An MLB game recap article',\n", + " agent=mlb_writer_llama,\n", + " async_execution=True,\n", + " dependencies=[collect_game_info, retrieve_batting_stats, retrieve_pitching_stats],\n", + " context=[collect_game_info, retrieve_batting_stats, retrieve_pitching_stats]\n", + ")\n", + "\n", + "write_game_recap_gemma = Task(\n", + " description='''\n", + " Write a game recap article using the provided game information and stats.\n", + " Key instructions:\n", + " - Include things like final score, top performers and winning/losing pitcher.\n", + " - Use ONLY the provided data and DO NOT make up any information, such as specific innings when events occurred, that isn't explicitly from the provided input.\n", + " - Do not print the box score\n", + " ''',\n", + " expected_output='An MLB game recap article',\n", + " agent=mlb_writer_gemma,\n", + " async_execution=True,\n", + " dependencies=[collect_game_info, retrieve_batting_stats, retrieve_pitching_stats],\n", + " context=[collect_game_info, retrieve_batting_stats, retrieve_pitching_stats]\n", + ")\n", + "\n", + "write_game_recap_mixtral = Task(\n", + " description='''\n", + " Write a succinct game recap article using the provided game information and stats.\n", + " Key instructions:\n", + " - Structure with the following sections:\n", + " - Introduction (game result, winning/losing pitchers, top performer on the winning team)\n", + " - Other key performers on the winning team\n", + " - Key performers on the losing team\n", + " - Conclusion (including series result)\n", + " - Use ONLY the provided data and DO NOT make up any information, such as specific innings when events occurred, that isn't explicitly from the provided input.\n", + " - Do not print the box score or write out the section names\n", + " ''',\n", + " expected_output='An MLB game recap article',\n", + " agent=mlb_writer_mixtral,\n", + " async_execution=True,\n", + " dependencies=[collect_game_info, retrieve_batting_stats, retrieve_pitching_stats],\n", + " context=[collect_game_info, retrieve_batting_stats, retrieve_pitching_stats]\n", + ")\n", + "\n", + "edit_game_recap = Task(\n", + " description='''\n", + " You will be provided three game recap articles from multiple writers. Take the best of\n", + " all three to output the optimal final article.\n", + " \n", + " Pay close attention to the original instructions:\n", + "\n", + " Key instructions:\n", + " - Structure with the following sections:\n", + " - Introduction (game result, winning/losing pitchers, top performer on the winning team)\n", + " - Other key performers on the winning team\n", + " - Key performers on the losing team\n", + " - Conclusion (including series result)\n", + " - Use ONLY the provided data and DO NOT make up any information, such as specific innings when events occurred, that isn't explicitly from the provided input.\n", + " - Do not print the box score or write out the section names\n", + "\n", + " It is especially important that no false information, such as any inning or the inning in which an event occured, \n", + " is present in the final product. If a piece of information is present in one article and not the others, it is probably false\n", + " ''',\n", + " expected_output='An MLB game recap article',\n", + " agent=mlb_editor,\n", + " dependencies=[collect_game_info, retrieve_batting_stats, retrieve_pitching_stats],\n", + " context=[collect_game_info, retrieve_batting_stats, retrieve_pitching_stats]\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "17398354-29fa-427a-8ec9-a2c7b8e94ef8", + "metadata": {}, + "source": [ + "### Define and Execute Crew" + ] + }, + { + "cell_type": "markdown", + "id": "4cb5bae8-60cc-4fe3-862b-878c5c7fdfcd", + "metadata": {}, + "source": [ + "In this final step, we define and execute our Crew, which consists of the agents and tasks we've set up. The Crew class orchestrates the workflow, ensuring that tasks are completed in the correct order and that dependencies are respected. By running the kickoff method, we provide user input to initiate the process, and the Crew handles the rest, from data collection to generating and editing the final game recap." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "af295e70-10b4-40b4-979f-6a1d912672a6", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2024-07-16 09:22:23,799 - 4308862336 - __init__.py-__init__:521 - WARNING: Overriding of current TracerProvider is not allowed\n" + ] + } + ], + "source": [ + "crew = Crew(\n", + " agents=[mlb_researcher, mlb_statistician, mlb_writer_llama, mlb_writer_gemma, mlb_writer_mixtral, mlb_editor],\n", + " tasks=[\n", + " collect_game_info, \n", + " retrieve_batting_stats, retrieve_pitching_stats,\n", + " write_game_recap_llama, write_game_recap_gemma, write_game_recap_mixtral,\n", + " edit_game_recap\n", + " ],\n", + " verbose=False\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "d56d9ff7-e337-40c4-b2c1-e2f69940ce41", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\n", + "\u001b[1m> Entering new CrewAgentExecutor chain...\u001b[0m\n", + "\u001b[32;1m\u001b[1;3mThought: I need to identify the correct game related to the user prompt and return game info using the get_game_info tool.\n", + "\n", + "Action: get_game_info\n", + "Action Input: {\"game_date\": \"2024-07-14\", \"team_name\": \"Yankees\"}\u001b[0m\u001b[95m \n", + "\n", + "\n", + " Game ID: 747009\n", + " Home Team: Baltimore Orioles\n", + " Home Score: 6\n", + " Home Starting Pitcher: Dean Kremer\n", + " Away Team: New York Yankees\n", + " Away Score: 5\n", + " Away Starting Pitcher: Carlos Rodón\n", + " Winning Team: Baltimore Orioles\n", + " Series Status: NYY wins 2-1\n", + " \n", + "\u001b[00m\n", + "\u001b[32;1m\u001b[1;3mThought: I now know the final answer\n", + "\n", + "Final Answer: \n", + " Game ID: 747009\n", + " Home Team: Baltimore Orioles\n", + " Home Score: 6\n", + " Home Starting Pitcher: Dean Kremer\n", + " Away Team: New York Yankees\n", + " Away Score: 5\n", + " Away Starting Pitcher: Carlos Rodón\n", + " Winning Team: Baltimore Orioles\n", + " Series Status: NYY wins 2-1\u001b[0m\n", + "\n", + "\u001b[1m> Finished chain.\u001b[0m\n", + "\n", + "\n", + "\u001b[1m> Entering new CrewAgentExecutor chain...\u001b[0m\n", + "\u001b[32;1m\u001b[1;3mI need to retrieve the player boxscore batting stats for the game with ID 747009.\n", + "\n", + "Action: get_batting_stats\n", + "Action Input: {\"game_id\": \"747009\"}\u001b[0m\u001b[95m \n", + "\n", + " team_name fullName position ab r h hr rbi bb sb\n", + "0 Yankees Ben Rice 1B 5 1 1 1 3 0 0\n", + "1 Yankees DJ LeMahieu 1B 0 0 0 0 0 0 0\n", + "2 Yankees Juan Soto RF 5 0 0 0 0 0 0\n", + "3 Yankees Aaron Judge DH 2 0 0 0 0 2 0\n", + "4 Yankees Alex Verdugo LF 4 0 0 0 0 1 0\n", + "5 Yankees Gleyber Torres 2B 3 0 1 0 0 0 0\n", + "6 Yankees Austin Wells C 3 0 0 0 0 1 0\n", + "7 Yankees Anthony Volpe SS 4 1 1 0 0 0 0\n", + "8 Yankees Trent Grisham CF 3 2 3 1 2 1 0\n", + "9 Yankees Oswaldo Cabrera 3B 3 1 1 0 0 1 0\n", + "10 Orioles Gunnar Henderson SS 5 1 1 1 2 0 0\n", + "11 Orioles Adley Rutschman DH 4 1 0 0 0 1 0\n", + "12 Orioles Ryan Mountcastle 1B 5 0 1 0 0 0 1\n", + "13 Orioles Anthony Santander RF 4 1 2 1 1 0 0\n", + "14 Orioles Cedric Mullins CF 1 0 1 0 2 0 0\n", + "15 Orioles Jordan Westburg 3B 3 0 0 0 0 1 0\n", + "16 Orioles Austin Hays LF 4 0 0 0 0 0 0\n", + "17 Orioles Jorge Mateo 2B 3 0 2 0 0 0 0\n", + "18 Orioles Kyle Stowers PH 1 0 1 0 0 0 0\n", + "19 Orioles Colton Cowser RF 3 1 0 0 0 1 0\n", + "20 Orioles James McCann C 2 1 0 0 0 1 0\n", + "21 Orioles Ryan O'Hearn PH 0 1 0 0 0 1 0\n", + "\u001b[00m\n", + "\u001b[32;1m\u001b[1;3mThought: I need to retrieve the player boxscore batting stats for the game with ID 747009.\n", + "\n", + "Action: get_batting_stats\n", + "Action Input: {\"game_id\": \"747009\"}\u001b[0m\u001b[95m \n", + "\n", + "I tried reusing the same input, I must stop using this action input. I'll try something else instead.\n", + "\n", + "\n", + "\u001b[00m\n", + "\u001b[32;1m\u001b[1;3mThought: I have already retrieved the player boxscore batting stats for the game with ID 747009.\n", + "\n", + "Final Answer: \n", + "team_name fullName position ab r h hr rbi bb sb\n", + "0 Yankees Ben Rice 1B 5 1 1 1 3 0 0\n", + "1 Yankees DJ LeMahieu 1B 0 0 0 0 0 0 0\n", + "2 Yankees Juan Soto RF 5 0 0 0 0 0 0\n", + "3 Yankees Aaron Judge DH 2 0 0 0 0 2 0\n", + "4 Yankees Alex Verdugo LF 4 0 0 0 0 1 0\n", + "5 Yankees Gleyber Torres 2B 3 0 1 0 0 0 0\n", + "6 Yankees Austin Wells C 3 0 0 0 0 1 0\n", + "7 Yankees Anthony Volpe SS 4 1 1 0 0 0 0\n", + "8 Yankees Trent Grisham CF 3 2 3 1 2 1 0\n", + "9 Yankees Oswaldo Cabrera 3B 3 1 1 0 0 1 0\n", + "10 Orioles Gunnar Henderson SS 5 1 1 1 2 0 0\n", + "11 Orioles Adley Rutschman DH 4 1 0 0 0 1 0\n", + "12 Orioles Ryan Mountcastle 1B 5 0 1 0 0 0 1\n", + "13 Orioles Anthony Santander RF 4 1 2 1 1 0 0\n", + "14 Orioles Cedric Mullins CF 1 0 1 0 2 0 0\n", + "15 Orioles Jordan Westburg 3B 3 0 0 0 0 1 0\n", + "16 Orioles Austin Hays LF 4 0 0 0 0 0 0\n", + "17 Orioles Jorge Mateo 2B 3 0 2 0 0 0 0\n", + "18 Orioles Kyle Stowers PH 1 0 1 0 0 0 0\n", + "19 Orioles Colton Cowser RF 3 1 0 0 0 1 0\n", + "20 Orioles James McCann C 2 1 0 0 0 1 0\n", + "21 Orioles Ryan O'Hearn PH 0 1 0 0 0 1 0\u001b[0m\n", + "\n", + "\u001b[1m> Finished chain.\u001b[0m\n", + "\n", + "\n", + "\u001b[1m> Entering new CrewAgentExecutor chain...\u001b[0m\n", + "\u001b[32;1m\u001b[1;3mI need to retrieve the boxscore pitching stats for the game with ID 747009.\n", + "\n", + "Action: get_pitching_stats\n", + "Action Input: {\"game_id\": \"747009\"}\u001b[0m\u001b[95m \n", + "\n", + " team_name fullName ip h r er bb k note\n", + "0 Yankees Carlos Rodón 4.0 4 2 2 3 7 \n", + "1 Yankees Tommy Kahnle 1.0 1 1 1 0 1 \n", + "2 Yankees Michael Tonkin 1.1 0 0 0 0 3 \n", + "3 Yankees Luke Weaver 1.0 1 0 0 0 1 \n", + "4 Yankees Jake Cousins 0.2 0 0 0 0 1 \n", + "5 Yankees Clay Holmes 0.2 2 3 0 2 1 (L, 1-4)(BS, 6)\n", + "6 Orioles Dean Kremer 4.2 4 2 2 2 4 \n", + "7 Orioles Jacob Webb 1.0 0 0 0 1 1 \n", + "8 Orioles Cionel Pérez 1.0 1 0 0 0 2 (H, 13)\n", + "9 Orioles Yennier Cano 1.1 1 0 0 1 0 (H, 24)\n", + "10 Orioles Craig Kimbrel 1.0 1 3 3 2 1 (W, 6-2)(BS, 5)\n", + "\u001b[00m\n", + "\u001b[32;1m\u001b[1;3mThought:\n", + "I now know the final answer\n", + "\n", + "Final Answer:\n", + " team_name fullName ip h r er bb k note\n", + "0 Yankees Carlos Rodón 4.0 4 2 2 3 7 \n", + "1 Yankees Tommy Kahnle 1.0 1 1 1 0 1 \n", + "2 Yankees Michael Tonkin 1.1 0 0 0 0 3 \n", + "3 Yankees Luke Weaver 1.0 1 0 0 0 1 \n", + "4 Yankees Jake Cousins 0.2 0 0 0 0 1 \n", + "5 Yankees Clay Holmes 0.2 2 3 0 2 1 (L, 1-4)(BS, 6)\n", + "6 Orioles Dean Kremer 4.2 4 2 2 2 4 \n", + "7 Orioles Jacob Webb 1.0 0 0 0 1 1 \n", + "8 Orioles Cionel Pérez 1.0 1 0 0 0 2 (H, 13)\n", + "9 Orioles Yennier Cano 1.1 1 0 0 1 0 (H, 24)\n", + "10 Orioles Craig Kimbrel 1.0 1 3 3 2 1 (W, 6-2)(BS, 5)\u001b[0m\n", + "\n", + "\u001b[1m> Finished chain.\u001b[0m\n", + "\n", + "\n", + "\u001b[1m> Entering new CrewAgentExecutor chain...\u001b[0m\n", + "\u001b[32;1m\u001b[1;3mI'm excited to take on this task! I have all the necessary information and stats to write a detailed game recap article. I'll make sure to follow the provided format and not make up any information that isn't explicitly stated. I'm confident that my final answer will be a great and complete game recap article.\n", + "\n", + "Final Answer:\n", + "\n", + "Baltimore Orioles Edge New York Yankees 6-5 in Thrilling Contest\n", + "\n", + "The Baltimore Orioles came out on top in a back-and-forth contest against the New York Yankees, taking the series opener 6-5. Dean Kremer got the start for the Orioles and pitched 4.2 innings, allowing 4 hits and 2 earned runs while striking out 4.\n", + "\n", + "The Yankees got on the board first in the top of the 2nd inning, with Ben Rice hitting a solo homer to give his team a 1-0 lead. The Orioles responded in the bottom of the 3rd, with Gunnar Henderson driving in two runs with a single to give his team a 2-1 lead.\n", + "\n", + "The Yankees tied the game in the top of the 5th, with Trent Grisham hitting a two-run homer to make it 2-2. The Orioles regained the lead in the bottom of the 5th, with Anthony Santander hitting a solo homer to make it 3-2.\n", + "\n", + "The Yankees tied the game again in the top of the 8th, with Oswaldo Cabrera driving in a run with a single to make it 3-3. The Orioles scored three runs in the bottom of the 8th, thanks to an RBI single from Cedric Mullins and a two-run homer from Ryan O'Hearn, to take a 6-3 lead.\n", + "\n", + "The Yankees threatened in the top of the 9th, with Clay Holmes loading the bases with two outs. Craig Kimbrel came in to close the game and gave up a three-run homer to Aaron Judge, making it 6-5. However, Kimbrel was able to get the final out and earn the save, securing the win for the Orioles.\n", + "\n", + "Dean Kremer was credited with the win, improving his record to 6-2. Clay Holmes took the loss, falling to 1-4.\u001b[0m\n", + "\n", + "\u001b[1m> Finished chain.\u001b[0m\n", + "\n", + "\n", + "\u001b[1m> Entering new CrewAgentExecutor chain...\u001b[0m\n", + "\u001b[32;1m\u001b[1;3mThought: I now can give a great answer\n", + "Final Answer: \n", + "\n", + "The Baltimore Orioles edged out the New York Yankees in a thrilling 6-5 victory, taking the final game of the series despite the Yankees ultimately winning 2-1. \n", + "\n", + "Dean Kremer started for the Orioles and pitched 4.2 innings, giving up 4 hits and 2 runs while striking out 4. Craig Kimbrel earned the win, his sixth of the season, pitching a scoreless ninth inning despite giving up a hit and walking two. \n", + "\n", + "The Orioles offense was led by Anthony Santander, who went 2-for-4 with a home run and an RBI. Gunnar Henderson also contributed with a hit and run scored, while Jorge Mateo had two hits and scored a run.\n", + "\n", + "Carlos Rodón started for the Yankees and pitched 4 innings, giving up 4 hits and 2 runs. Clay Holmes took the loss, his fourth of the season, after giving up 3 runs in the bottom of the ninth. \n", + "\n", + "Trent Grisham was the offensive standout for the Yankees, going 3-for-4 with 3 hits, a home run, and 2 RBIs. \n", + "\n", + "\n", + "\u001b[0m\n", + "\n", + "\u001b[1m> Finished chain.\u001b[0m\n", + "\n", + "\n", + "\u001b[1m> Entering new CrewAgentExecutor chain...\u001b[0m\n", + "\u001b[32;1m\u001b[1;3mI now have all the necessary information to write a succinct game recap article.\n", + "\n", + "Final Answer:\n", + "In a thrilling matchup, the Baltimore Orioles emerged victorious with a score of 6-5 against the New York Yankees. Dean Kremer secured the win for the Orioles, while Carlos Rodón was tagged with the loss for the Yankees.\n", + "\n", + "The Orioles' offense was led by Gunnar Henderson, who went 5-for-5 with a home run, a run scored, and an RBI. Other key contributors for the Orioles included Adley Rutschman (1 run, 1 walk), Ryan Mountcastle (1 hit, 1 walk, 1 run), Anthony Santander (2 hits, 1 RBI, 1 run), and Cedric Mullins (1 hit, 2 walks, 1 run).\n", + "\n", + "For the Yankees, Ben Rice had a solid performance at the plate, going 5-for-5 with a run scored, an RBI, and a home run. Trent Grisham and Oswaldo Cabrera also contributed with 2 hits and 1 RBI each.\n", + "\n", + "Despite the Yankees taking a 2-1 series lead, the Orioles managed to turn things around in the final game, securing a much-needed win.\u001b[0m\n", + "\n", + "\u001b[1m> Finished chain.\u001b[0m\n", + "\n", + "\n", + "\u001b[1m> Entering new CrewAgentExecutor chain...\u001b[0m\n", + "\u001b[32;1m\u001b[1;3m\u001b[0m\u001b[32;1m\u001b[1;3mThought: I now can give a great answer\n", + "\n", + "Final Answer:\n", + "\n", + "The Baltimore Orioles edged the New York Yankees 6-5 in the final game of the series, despite being down 2-1 in the series. Dean Kremer earned the win for the Orioles, while Clay Holmes took the loss for the Yankees.\n", + "\n", + "Anthony Santander was the top performer for the Orioles, going 2-for-4 with a home run and an RBI. Gunnar Henderson also had a strong game, hitting a home run and driving in two runs. Cedric Mullins added two RBIs for the Orioles.\n", + "\n", + "For the Yankees, Trent Grisham had a standout game, going 3-for-3 with a home run and two RBIs. Ben Rice also hit a home run and drove in three runs. Anthony Volpe added a hit and a run scored for the Yankees.\n", + "\n", + "In the end, the Orioles' strong performance was enough to secure the win, despite a late-inning rally from the Yankees. The Yankees won the series 2-1, but the Orioles closed out the series with a hard-fought victory.\u001b[0m\n", + "\n", + "\u001b[1m> Finished chain.\u001b[0m\n" + ] + } + ], + "source": [ + "user_prompt = 'Write a recap of the Yankees game on July 14, 2024'\n", + "result = crew.kickoff(inputs={\"user_prompt\": user_prompt, \"default_date\": datetime.now().date() - timedelta(1)})" + ] + }, + { + "cell_type": "markdown", + "id": "473f0384-f9d2-4d4f-ac1d-e3adaf0f8238", + "metadata": {}, + "source": [ + "As you can see from the output, each of our MLB Writer agents made various mistakes in their game recaps: hallucinating the sequence of events (like the specific innings in which events occured, which it couldn't infer from the data provided), incorrect data analysis (Gunnar Henderson did not go 5-5), or poor formatting (i.e. not including the series result in the conclusion. However, by leveraging the results of all three articles our editing agent solves these issues and delivers a factual recap that follows all of our instructions." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "3a36393a-0352-4438-bfd5-659c929ed282", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The Baltimore Orioles edged the New York Yankees 6-5 in the final game of the series, despite being down 2-1 in the series. Dean Kremer earned the win for the Orioles, while Clay Holmes took the loss for the Yankees.\n", + "\n", + "Anthony Santander was the top performer for the Orioles, going 2-for-4 with a home run and an RBI. Gunnar Henderson also had a strong game, hitting a home run and driving in two runs. Cedric Mullins added two RBIs for the Orioles.\n", + "\n", + "For the Yankees, Trent Grisham had a standout game, going 3-for-3 with a home run and two RBIs. Ben Rice also hit a home run and drove in three runs. Anthony Volpe added a hit and a run scored for the Yankees.\n", + "\n", + "In the end, the Orioles' strong performance was enough to secure the win, despite a late-inning rally from the Yankees. The Yankees won the series 2-1, but the Orioles closed out the series with a hard-fought victory.\n" + ] + } + ], + "source": [ + "print(result)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1dd97a0d-97f4-4c8b-befc-985411bf8b76", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}