# Cadre multi-agent CrewAI

## Aperçu

[CrewAI](https://github.com/crewAIInc/crewAI) est un framework de pointe pour orchestrer **agents IA autonomes jouant des rôles**, avec **44K+ étoiles sur GitHub**. Contrairement aux systèmes à agent unique, CrewAI vous permet de définir des agents spécialisés (Chercheur, Rédacteur, Développeur, Analyste...) qui collaborent en tant que « équipe » pour accomplir des tâches complexes — chaque agent avec son propre rôle, objectif, histoire de fond et boîte à outils.

Sur **Clore.ai**, CrewAI peut être déployé dans un environnement Dockerisé pour aussi peu que **0,05–0,20 $/h**. Alors que CrewAI lui-même dépend du CPU (il orchestre des appels API), le combiner avec un serveur Ollama ou vLLM local sur le même nœud GPU vous donne un système multi-agents entièrement privé, capable de fonctionner hors ligne.

**Principales capacités :**

* 👥 **Équipes multi-agents** — définir des personas d'agents avec rôles, objectifs et histoires de fond
* 🎯 **Délégation de tâches** — l'agent manager assigne automatiquement les tâches au spécialiste approprié
* 🛠️ **Écosystème d'outils** — recherche web, E/S de fichiers, exécution de code, accès base de données, outils personnalisés
* 🔁 **Séquentiel & Parallèle** — exécuter les tâches dans l'ordre ou lancer des tâches indépendantes simultanément
* 🧠 **Mémoire des agents** — types de mémoire à court terme, long terme, entité et contextuelle
* 🔌 **Indépendant du LLM** — fonctionne avec OpenAI, Anthropic, Google, Ollama, Groq, Azure, et plus
* 📊 **CrewAI Studio** — interface visuelle pour construire des équipes sans code (entreprise)
* 🚀 **Pipelines** — enchaîner plusieurs équipes pour des workflows multi-étapes complexes

***

## Exigences

CrewAI est une bibliothèque Python. Elle s'exécute sur CPU et ne nécessite qu'un environnement Python système 3.10+ ou Docker. Le GPU est optionnel mais permet une inférence locale de modèles très performante.

| Configuration                    | GPU             | VRAM  | RAM système | Disque | Prix Clore.ai    |
| -------------------------------- | --------------- | ----- | ----------- | ------ | ---------------- |
| **Minimale** (APIs cloud)        | Aucun / CPU     | —     | 2 Go        | 10 Go  | ≈ 0,03 $/h (CPU) |
| **Standard**                     | Aucun / CPU     | —     | 4 Go        | 20 Go  | ≈ 0,05 $/h       |
| **+ LLM local (petit)**          | RTX 3080        | 10 Go | 8 Go        | 40 Go  | ≈ 0,15 $/h       |
| **+ LLM local (grand)**          | RTX 3090 / 4090 | 24 Go | 16 Go       | 60 Go  | 0,20–0,35 $/h    |
| **+ LLM local de haute qualité** | A100 40 GB      | 40 Go | 32 Go       | 100 Go | ≈ 0,80 $/h       |

### Clés API

CrewAI fonctionne avec la plupart des principaux fournisseurs de LLM. Vous avez besoin d'au moins une :

* **OpenAI** — GPT-4o (meilleure capacité de raisonnement pour les tâches complexes)
* **Anthropic** — Claude 3.5 Sonnet (excellent pour les équipes axées sur l'écriture)
* **Groq** — Offre gratuite, inférence rapide (Llama 3 70B)
* **composant Ollama** — Entièrement local, aucune clé API requise (voir [Accélération GPU](#gpu-acceleration))

***

## Démarrage rapide

### 1. Louez un serveur Clore.ai

Connectez-vous à [clore.ai](https://clore.ai):

* **CPU uniquement** si vous utilisez des APIs cloud LLM
* **RTX 3090/4090** pour l'inférence Ollama locale
* Accès SSH activé
* Aucune exigence de port spéciale pour l'utilisation CLI (exposez des ports uniquement pour les interfaces web)

### 2. Connectez-vous et préparez

```bash
ssh root@<ip-serveur-clore> -p <port-ssh>

# Mettre à jour le système
apt-get update && apt-get upgrade -y

# Installer Python 3.11 (si non présent)
apt-get install -y python3.11 python3.11-venv python3-pip
python3 --version   # Doit être 3.10+

# Vérifier Docker
docker --version
```

### 3. Option A — Installation directe via pip (la plus rapide)

```bash
# Créer un environnement virtuel
python3 -m venv crewai-env
source crewai-env/bin/activate

# Installer CrewAI avec tous les outils
pip install crewai crewai-tools

# Vérifier l'installation
python -c "import crewai; print(crewai.__version__)"
crewai --version
```

### 4. Option B — Conteneur Docker (recommandé pour la reproductibilité)

```bash
# Créer le répertoire projet
mkdir my-crew && cd my-crew

# Écrire le Dockerfile
cat > Dockerfile << 'EOF'
FROM python:3.11-slim

# Installer les dépendances système
RUN apt-get update && apt-get install -y \
    curl \
    git \
    && rm -rf /var/lib/apt/lists/*

# Définir le répertoire de travail
WORKDIR /app

# Installer CrewAI et outils communs
RUN pip install --no-cache-dir \
    crewai \
    crewai-tools \
    langchain-openai \
    langchain-anthropic \
    python-dotenv

# Copier le code de l'application
COPY . .

# Commande par défaut
CMD ["python", "main.py"]
EOF

# Construire l'image
docker build -t my-crewai-app .
```

### 5. Créez votre première équipe

```bash
# Initialiser un nouveau projet CrewAI en utilisant la CLI
source crewai-env/bin/activate
crewai create crew my-research-crew
cd my-research-crew

# Configurer les clés API
cat > .env << 'EOF'
OPENAI_API_KEY=sk-...
# Ou pour Anthropic :
# ANTHROPIC_API_KEY=sk-ant-...
# Ou pour Ollama (pas de clé nécessaire) :
# OPENAI_API_BASE=http://localhost:11434/v1
# OPENAI_API_KEY=ollama
EOF

# Installer les dépendances du projet
crewai install

# Exécuter l'équipe
crewai run
```

***

## Configuration

### Structure du projet (depuis `crewai create`)

```
my-research-crew/
├── .env                    # Clés API et paramètres
├── pyproject.toml          # Dépendances
├── src/
│   └── my_research_crew/
│       ├── config/
│       │   ├── agents.yaml   # Définitions des agents
│       │   └── tasks.yaml    # Définitions des tâches
│       ├── tools/
│       │   └── custom_tool.py  # Vos outils personnalisés
│       ├── crew.py           # Assemblage de l'équipe
│       └── main.py           # Point d'entrée
```

### agents.yaml — Définissez vos agents

```yaml
researcher:
  role: >
    Analyste de recherche principal
  goal: >
    Découvrir les développements de pointe sur {topic} et synthétiser des insights exploitables
  backstory: >
    Vous êtes un chercheur expert avec un talent pour trouver et connecter l'information
    provenant de sources diverses. Vous avez un sens aigu de la crédibilité et de la pertinence.
  tools:
    - SerperDevTool
    - ScrapeWebsiteTool
  llm: gpt-4o                # Peut être défini par agent
  verbose: true
  max_iter: 15               # Max d'itérations de raisonnement
  memory: true               # Activer la mémoire de l'agent

writer:
  role: >
    Rédacteur technique expert
  goal: >
    Transformer des recherches complexes en contenu clair, convaincant et précis
  backstory: >
    Vous rédigez des explications qui rendent les sujets complexes accessibles sans sacrifier la profondeur.
    Vous citez les sources et structurez le contenu pour une lisibilité maximale.
  llm: claude-3-5-sonnet-20241022
  verbose: true
```

### tasks.yaml — Définissez les tâches

```yaml
research_task:
  description: >
    Recherchez les derniers développements sur {topic} au cours des 6 derniers mois.
    Identifiez les tendances clés, les percées et les implications.
    Compilez au moins 10 sources crédibles.
  expected_output: >
    Un rapport de recherche détaillé avec des conclusions organisées par thème,
    y compris les URL des sources et les dates de publication.
  agent: researcher

writing_task:
  description: >
    En utilisant le rapport de recherche, rédigez un article de blog complet sur {topic}.
    Longueur cible : 1500-2000 mots. Inclure un titre, une introduction, des sections principales,
    et une conclusion avec perspectives futures.
  expected_output: >
    Un article prêt à publier au format Markdown.
  agent: writer
  context:
    - research_task    # La tâche d'écriture reçoit la sortie du chercheur
  output_file: output/blog_post.md
```

### crew\.py — Assemblez l'équipe

```python
from crewai import Agent, Crew, Process, Task
from crewai.project import CrewBase, agent, crew, task
from crewai_tools import SerperDevTool, ScrapeWebsiteTool

@CrewBase
class MyResearchCrew():
    """Équipe de recherche et rédaction"""
    agents_config = 'config/agents.yaml'
    tasks_config = 'config/tasks.yaml'

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

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

    @task
    def research_task(self) -> Task:
        return Task(config=self.tasks_config['research_task'])

    @task
    def writing_task(self) -> Task():
        return Task(
            config=self.tasks_config['writing_task'],
            output_file='output/blog_post.md'
        )

    @crew
    def crew(self) -> Crew:
        return Crew(
            agents=self.agents,
            tasks=self.tasks,
            process=Process.sequential,  # ou Process.hierarchical
            verbose=True,
            memory=True,
            max_rpm=10   # Limiter le nombre d'appels API
        )
```

### Exécution avec Docker Compose (avec Ollama)

```yaml
# docker-compose.yml
version: "3.8"

services :
  crewai:
    build: .
    volumes :
      - ./src:/app/src
      - ./output:/app/output
    environment :
      - OPENAI_API_BASE=http://ollama:11434/v1
      - OPENAI_API_KEY=ollama
      - OPENAI_MODEL_NAME=llama3.1:70b
      - SERPER_API_KEY=${SERPER_API_KEY}
    depends_on :
      - ollama

  ollama:
    image: ollama/ollama:latest
    volumes :
      - ollama_data:/root/.ollama
    ports :
      - "11434:11434"
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: all
              capabilities: [gpu]

volumes :
  ollama_data:
```

```bash
# Démarrer la pile
docker compose up -d ollama

# Récupérer votre modèle
docker compose exec ollama ollama pull llama3.1:70b

# Exécuter votre équipe
docker compose run --rm crewai python src/my_research_crew/main.py
```

***

## Accélération GPU

CrewAI lui-même n'utilise pas le GPU — mais le LLM qu'il appelle oui. Exécutez Ollama ou vLLM sur le même serveur Clore pour une inférence locale accélérée par GPU.

### Installation d'Ollama (recommandée pour la simplicité)

```bash
# Installer Ollama sur l'hôte
curl -fsSL https://ollama.com/install.sh | sh

# Vérifier la détection du GPU
nvidia-smi
ollama run llama3:8b "Test"   # Devrait utiliser le GPU

# Récupérer des modèles pour différents besoins d'agents
ollama pull llama3.1:8b          # Raisonnement rapide et léger
ollama pull llama3.1:70b         # Raisonnement complexe (nécessite A100+)
ollama pull codestral:latest     # Spécialisé pour les agents code
ollama pull nomic-embed-text     # Pour les embeddings mémoire/RAG

# Configurer CrewAI pour utiliser Ollama
export OPENAI_API_BASE=http://localhost:11434/v1
export OPENAI_API_KEY=ollama
export OPENAI_MODEL_NAME=llama3.1:8b
```

### Configurer le LLM de CrewAI par agent

```python
from crewai import Agent, LLM

# Utiliser Ollama pour un agent spécifique
local_llm = LLM(
    model="ollama/llama3.1:8b",
    base_url="http://localhost:11434"
)

# Utiliser l'API cloud pour un autre agent (p.ex. raisonnement complexe)
cloud_llm = LLM(
    model="gpt-4o",
    api_key="sk-..."
)

researcher = Agent(
    role="Researcher",
    goal="Trouver des informations",
    backstory="Chercheur expert",
    llm=local_llm    # Utilise le GPU local
)

strategist = Agent(
    role="Strategist",
    goal="Planifier des actions",
    backstory="Penseur stratégique",
    llm=cloud_llm    # Utilise l'API cloud
)
```

### Recommandations de modèles selon les tâches des agents

| Type de tâche             | Modèle recommandé | VRAM   | Remarques                   |
| ------------------------- | ----------------- | ------ | --------------------------- |
| Recherche + recherche web | Llama 3.1 70B     | 40 Go  | Meilleur raisonnement local |
| Génération de code        | Codestral 22B     | 13 Go  | Spécialisé code             |
| Rédaction                 | Llama 3.1 8B      | 6 Go   | Rapide, bonne qualité       |
| Orchestration complexe    | GPT-4o (API)      | —      | Meilleur en général         |
| Embeddings/mémoire        | nomic-embed-text  | < 1 GB | Requis pour la mémoire      |

> Voir [Ollama sur Clore.ai](https://docs.clore.ai/guides/guides_v2-fr/modeles-de-langage/ollama) et [vLLM sur Clore.ai](https://docs.clore.ai/guides/guides_v2-fr/modeles-de-langage/vllm) pour les guides complets d'installation d'inférence.

***

## Conseils et bonnes pratiques

### Optimisation des coûts

```bash
# Suivre les coûts API LLM avec le suivi d'utilisation intégré de CrewAI
# Ajouter à votre équipe :
result = crew.kickoff(inputs={"topic": "agents IA"})
print(f"Total des tokens utilisés : {result.token_usage}")

# Utiliser des modèles moins chers pour les tâches simples, premium pour les tâches complexes
# Llama 3.1 8B sur Ollama = coût API $0
# GPT-4o = ≈ 0,005 $/1K tokens d'entrée

# Définir max_iter pour éviter les agents incontrôlés
Agent(max_iter=10, max_execution_time=120)  # timeout de 2 minutes

# Mettre en cache les réponses LLM pendant le développement
os.environ["CREWAI_DISABLE_CACHE"] = "false"
```

### Exécution des équipes en service persistant

```bash
# Servir les équipes via un endpoint FastAPI
pip install fastapi uvicorn

cat > server.py << 'EOF'
from fastapi import FastAPI, BackgroundTasks
from my_research_crew.crew import MyResearchCrew
import asyncio

app = FastAPI()
results = {}

@app.post("/run/{topic}")
async def run_crew(topic: str, background_tasks: BackgroundTasks):
    job_id = f"job-{topic}-{len(results)}"
    background_tasks.add_task(execute_crew, job_id, topic)
    return {"job_id": job_id, "status": "started"}

async def execute_crew(job_id: str, topic: str):
    crew = MyResearchCrew().crew()
    result = crew.kickoff(inputs={"topic": topic})
    results[job_id] = str(result)

@app.get("/result/{job_id}")
async def get_result(job_id: str):
    return {"result": results.get(job_id, "pending")}

EOF

# Lancer le serveur
uvicorn server:app --host 0.0.0.0 --port 8080 &

# Déclencher une exécution d'équipe
curl -X POST http://<clore-ip>:8080/run/informatique-quantique
```

### Outils intégrés utiles de CrewAI

```python
from crewai_tools import (
    SerperDevTool,        # Recherche Google via l'API Serper
    ScrapeWebsiteTool,    # Scraping web
    FileReadTool,         # Lire des fichiers locaux
    FileWriterTool,       # Écrire des fichiers
    DirectoryReadTool,    # Lister le contenu d'un répertoire
    CodeInterpreterTool,  # Exécuter du code Python
    GithubSearchTool,     # Rechercher dans les dépôts GitHub
    YoutubeVideoSearchTool, # Rechercher sur YouTube
    PGSearchTool,         # Interroger PostgreSQL
)
```

### Mise en œuvre de l'humain dans la boucle

```python
# Demander une saisie humaine pour une tâche spécifique
task = Task(
    description="Rechercher {topic}",
    expected_output="Rapport de recherche",
    agent=researcher,
    human_input=True    # Met en pause et invite l'utilisateur à donner un retour
)
```

***

## Dépannage

### "openai.AuthenticationError" même avec une clé valide

```bash
# Vérifiez que votre clé API est chargée
python3 -c "import os; from dotenv import load_dotenv; load_dotenv(); print(os.getenv('OPENAI_API_KEY')[:10])"

# Si vous utilisez Ollama, assurez-vous que ces variables sont définies :
export OPENAI_API_BASE=http://localhost:11434/v1
export OPENAI_API_KEY=ollama
export OPENAI_MODEL_NAME=llama3.1:8b

# Vérifier qu'Ollama est accessible
curl http://localhost:11434/v1/models
```

### Agent bloqué dans une boucle de raisonnement

```bash
# Définir une limite stricte sur les itérations
Agent(
    max_iter=10,            # Nombre max d'étapes de raisonnement
    max_execution_time=300  # Timeout strict de 5 minutes
)

# Activer verbose pour voir où il boucle
Agent(verbose=True)

# Vérifier si le modèle prend en charge l'appel d'outils
# Certains modèles plus petits ne le font pas ; utilisez llama3.1 ou mistral-nemo
```

### Les outils CrewAI échouent (SerperDevTool 403)

```bash
# SerperDevTool requiert une clé API gratuite de serper.dev
export SERPER_API_KEY=votre-cle-serper

# Alternative : utilisez DuckDuckGo (aucune clé API requise)
from langchain_community.tools import DuckDuckGoSearchRun
from crewai import tool

@tool("DuckDuckGo Search")
def ddg_search(query: str) -> str:
    """Rechercher sur le web en utilisant DuckDuckGo."""
    return DuckDuckGoSearchRun().run(query)
```

### Erreurs de mémoire (ChromaDB / embeddings)

```bash
# La mémoire de CrewAI utilise ChromaDB pour le stockage vectoriel
# Si cela échoue, vérifiez l'espace disque et les permissions
df -h
ls -la ~/.local/share/crewai/

# Supprimer la mémoire corrompue
rm -rf ~/.local/share/crewai/

# Ou désactiver la mémoire si non nécessaire
Crew(memory=False)

# Si vous utilisez les embeddings Ollama, assurez-vous que le modèle est téléchargé
docker exec ollama ollama pull nomic-embed-text
```

### Échec de la construction Docker sur mismatch ARM/x86

```bash
# Les serveurs Clore.ai sont x86_64 ; spécifiez la plateforme explicitement :
docker build --platform linux/amd64 -t my-crewai-app .

# Ou dans docker-compose.yml :
services :
  crewai:
    platform: linux/amd64
    build: .
```

### Limitation de débit des APIs LLM

```bash
# Réduire les requêtes par minute
Crew(max_rpm=5)   # 5 requêtes par minute

# Ajouter une logique de retry dans la config LLM
LLM(
    model="gpt-4o",
    max_retries=3,
    timeout=60
)
```

***

## Lectures complémentaires

* [Documentation officielle de CrewAI](https://docs.crewai.com)
* [Répertoire GitHub de CrewAI](https://github.com/crewAIInc/crewAI)
* [Documentation des outils CrewAI](https://docs.crewai.com/concepts/tools)
* [Répertoire d'exemples CrewAI](https://github.com/crewAIInc/crewAI-examples)
* [Exécuter Ollama sur Clore.ai](https://docs.clore.ai/guides/guides_v2-fr/modeles-de-langage/ollama)
* [Exécuter vLLM sur Clore.ai](https://docs.clore.ai/guides/guides_v2-fr/modeles-de-langage/vllm)
* [Comparaison GPU Clore.ai](https://docs.clore.ai/guides/guides_v2-fr/premiers-pas/gpu-comparison)
* [Communauté CrewAI Discord](https://discord.com/invite/X4JWnZnxPb)
