Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,017 changes: 1,017 additions & 0 deletions 3_crew/RealMadrid_Next_Best_Fit/AGENTS.md

Large diffs are not rendered by default.

54 changes: 54 additions & 0 deletions 3_crew/RealMadrid_Next_Best_Fit/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Realmadridnextbestfit Crew

Welcome to the Realmadridnextbestfit Crew project, powered by [crewAI](https://crewai.com). This template is designed to help you set up a multi-agent AI system with ease, leveraging the powerful and flexible framework provided by crewAI. Our goal is to enable your agents to collaborate effectively on complex tasks, maximizing their collective intelligence and capabilities.

## Installation

Ensure you have Python >=3.10 <3.14 installed on your system. This project uses [UV](https://docs.astral.sh/uv/) for dependency management and package handling, offering a seamless setup and execution experience.

First, if you haven't already, install uv:

```bash
pip install uv
```

Next, navigate to your project directory and install the dependencies:

(Optional) Lock the dependencies and install them by using the CLI command:
```bash
crewai install
```
### Customizing

**Add your `OPENAI_API_KEY` into the `.env` file**

- Modify `src/realmadridnextbestfit/config/agents.yaml` to define your agents
- Modify `src/realmadridnextbestfit/config/tasks.yaml` to define your tasks
- Modify `src/realmadridnextbestfit/crew.py` to add your own logic, tools and specific args
- Modify `src/realmadridnextbestfit/main.py` to add custom inputs for your agents and tasks

## Running the Project

To kickstart your crew of AI agents and begin task execution, run this from the root folder of your project:

```bash
$ crewai run
```

This command initializes the RealMadridNextBestFit Crew, assembling the agents and assigning them tasks as defined in your configuration.

This example, unmodified, will run the create a `report.md` file with the output of a research on LLMs in the root folder.

## Understanding Your Crew

The RealMadridNextBestFit Crew is composed of multiple AI agents, each with unique roles, goals, and tools. These agents collaborate on a series of tasks, defined in `config/tasks.yaml`, leveraging their collective skills to achieve complex objectives. The `config/agents.yaml` file outlines the capabilities and configurations of each agent in your crew.

## Support

For support, questions, or feedback regarding the Realmadridnextbestfit Crew or crewAI.
- Visit our [documentation](https://docs.crewai.com)
- Reach out to us through our [GitHub repository](https://github.com/joaomdmoura/crewai)
- [Join our Discord](https://discord.com/invite/X4JWnZnxPb)
- [Chat with our docs](https://chatg.pt/DWjSBZn)

Let's create wonders together with the power and simplicity of crewAI.
1 change: 1 addition & 0 deletions 3_crew/RealMadrid_Next_Best_Fit/output/final_player.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"name":"Harry Kane","reason":"Harry Kane is chosen for his proven goal-scoring record and experience at a top club. His physical presence and ability to finish suits a variety of tactical setups including quick counter-attacks, providing a reliable target up front. Kane's fitness status is currently excellent with a low risk of injury, ensuring availability for key matches.","key_attruibutes":{"name":"Harry Kane","age":30,"height":188.0,"matches_played":12,"goals":8,"fitness_status":1,"estimated_wage":"€480,769 weekly"}}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"name":"Harry Kane","age":30,"height":188.0,"matches_played":12,"goals":8,"fitness_status":1,"estimated_wage":"€480,769 weekly"}
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
trending_player_finder:
role: >
Football Scout specialized in {region}
goal: >
Identify a raw list of 5 trending, high-performing attacking football players currently playing in {region}.
backstory: >
You are an elite talent spotter with a deep network across {region}. You scan local sports media,
transfer rumors, and current match forms to find breakout players generating massive hype and who can potentially help Real Madrid win the UCL.
Your only job is to provide a clean list of names for the analyst to investigate.
llm: openai/gpt-4o-mini


research_analyst:
role: >
Head of Football Analytics
goal: >
Gather deep, objective statistical and financial data for the 5 scouted attacking players.
backstory: >
You are a clinical data scientist who judges players purely by the numbers. For each player provided by the scout, you extract their match appearances, goals scored over the last 3 seasons, physical fitness history, injury-prone statistics, technical attributes, and current wage details. You provide a cold, unbiased statistical profile for each player without making tactical judgments.
llm: openai/gpt-4o-mini

coach:
role: >
Head Coach of Real Madrid
goal: >
Evaluate the scouted players to select the absolute best tactical fit for the team's attack.
backstory: >
You are a legendary, tactically brilliant football manager. You analyze players based on how
they fit into Real Madrid's signature style (such as rapid counter-attacks, fluid movement,
and high-pressure matches). You review the Analyst's data to judge a player's style of play,
on-field attitude, big-game mentality, and tactical adaptability. Your job is to cut the list
down and recommend the single best player who can immediately start in your starting eleven.
llm: openai/gpt-4o-mini

manager:
role: >
President of Real Madrid
goal: >
Orchestrate the scouting workflow and give final boardroom approval based on strict financial and club policies.
backstory: >
You are a visionary, data-driven club President. While you respect the Head Coach's tactical desires, your job is to look at the long-term future and financial health of Real Madrid. You enforce three unyielding boardroom constraints:
1) The player must be a maximum of 28 years old.
2) The player must already be proven at a big club.
3) The player must not require an unrealistic or irresponsible transfer fee.
You crictically review the crew's work and if you think the analysis or final chose player is not the
right one for some reason you find apt, pass on your feedback and send it back to crew for adjustments.
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
trending_player_task:
description: >
Conduct thorough research about attacking football players (strikers or wingers)
currently playing in {region}. Make sure you find interesting, trending,
and highly relevant targets given the current year is {current_year}.
expected_output: >
A clean list with exactly 5 bullet points of the most trending attacking players
in {region}, detailing their current club and market buzz.
agent: trending_player_finder

research_task:
description: >
Take the list of 5 players from the scouting task. Briefly find their basic data
for ONLY the most recent season. Keep your research shallow and quick.
Collect only: total goals, total matches played, current fitness status, and estimated wage.
Do not write background stories or detailed histories.
expected_output: >
A single markdown table containing 5 rows (one per player) with exactly 5 columns:
Player Name, Matches, Goals, Fitness, and Estimated Wage.
agent: research_analyst
context :
- trending_player_task
output_file: output/research_report.json

coach_task:
description: >
Review the compact statistics table provided by the research task. Evaluate the 5 players
based on their basic metrics. Select the single best attacking option that fits
Real Madrid's quick counter-attacking style. Do not write a long essay.
expected_output: >
A concise paragraph of exactly 3 to 4 sentences. State the selected player's name,
how they fit your tactical formation, and a brief note on their current fitness risk.
agent: coach
context :
- research_task
output_file: output/final_player.md

104 changes: 104 additions & 0 deletions 3_crew/RealMadrid_Next_Best_Fit/src/realmadridnextbestfit/crew.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
from typing import List

from pydantic import BaseModel, Field

from crewai import Agent, Crew, Process, Task
from crewai.project import CrewBase, agent, crew, task
from crewai.agents.agent_builder.base_agent import BaseAgent
from crewai_tools import SerperDevTool
from crewai.memory import Memory


class TrendingPlayer(BaseModel):
name : str = Field(description="Name of the football player")
current_club : str = Field(description="Name of the club the player plays for")

class ScoutingOutput(BaseModel):
listOfPlayers : List[TrendingPlayer] = Field(description='list of 5 chosen players')

class PlayersStats(BaseModel):
name : str = Field(description='name of the player')
age : int = Field(description='age of the player')
height : float = Field(description='height of the player in cms')
matches_played : int = Field(description='total matches player by the player')
goals : int = Field(description='total goals scored by the player')
fitness_status : int = Field(description="Current injury status or physical fitness note.")
estimated_wage : str = Field(description='Estimated weekly or yearly wage.')

class chosenPlayer(BaseModel):
name: str = Field(description='name of the player')
reason : str = Field(description= 'Reason for selecting this player amoung 4 others')
key_attruibutes : PlayersStats = Field(description='Players attributes')

@CrewBase
class Realmadridnextbestfit():
"""Realmadridnextbestfit crew"""

agents_config = 'config/agents.yaml'
tasks_config = 'config/tasks.yaml'


@agent
def trending_player_finder(self) -> Agent:
return Agent(config=self.agents_config['trending_player_finder'], tools=[SerperDevTool()], verbose=True,
memory=True)

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

@agent
def coach(self) -> Agent:
return Agent(config=self.agents_config['coach'], verbose=True, memory=True )


@task
def trending_player_task(self) -> Task:
return Task(config=self.tasks_config['trending_player_task'],
verbose=True,
output_pydantic=ScoutingOutput)

@task
def research_task(self) -> Task:
return Task(config=self.tasks_config['research_task'],
verbose=True,
output_pydantic=PlayersStats)

@task
def coach_task(self) -> Task:
return Task(config=self.tasks_config['coach_task'],
verbose=True,
output_pydantic=chosenPlayer)


@crew
def crew(self) -> Crew:
"""Creates the Realmadridnextbestfit crew"""

manager = Agent(config=self.agents_config['manager'],
verbose=True,
allow_delegation=True)

return Crew(
agents=self.agents, # Automatically created by the @agent decorator
tasks=self.tasks, # Automatically created by the @task decorator
process=Process.hierarchical,
verbose=True,
manager_agent=manager,

# Enables the unified short, long, and entity memory systems automatically
memory=True,

# Customizes the global storage f`older directory (Replaces path="./memory/")
storage_handler=None, # Leave None to let CrewAI handle DB structures internally

# This configures your 'text-embedding-3-small' model globally for all memory types
embedder={
"provider": "openai",
"config": {
"model": "text-embedding-3-small"
}
}
)
# process=Process.hierarchical, # In case you wanna use that instead https://docs.crewai.com/how-to/Hierarchical/

28 changes: 28 additions & 0 deletions 3_crew/RealMadrid_Next_Best_Fit/src/realmadridnextbestfit/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/usr/bin/env python
import sys
import warnings
import os

from datetime import datetime

from realmadridnextbestfit.crew import Realmadridnextbestfit

warnings.filterwarnings("ignore", category=SyntaxWarning, module="pysbd")


def run():
"""
Run the crew.
"""
inputs = {
'region' : 'Europe',
'current_year' : '2026'
}

result = Realmadridnextbestfit().crew().kickoff(inputs=inputs)


print(result.raw)

if __name__ == '__main__':
run()
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from crewai.tools import BaseTool
from typing import Type
from pydantic import BaseModel, Field


class MyCustomToolInput(BaseModel):
"""Input schema for MyCustomTool."""
argument: str = Field(..., description="Description of the argument.")

class MyCustomTool(BaseTool):
name: str = "Name of my tool"
description: str = (
"Clear description for what this tool is useful for, your agent will need this information to use it."
)
args_schema: Type[BaseModel] = MyCustomToolInput

def _run(self, argument: str) -> str:
# Implementation goes here
return "this is an example of a tool output, ignore it and move along."