Intelligence Artificielle angularforall.com

- CrewAI : orchestrer une equipe d'agents IA

Crewai Agents-Ia Multi-Agents Orchestration-Ia Python Llm Ai-Orchestration Ollama Agentic-Ai Openai Ia-Autonome Tool-Use Ia-Generative Automatisation
CrewAI : orchestrer une equipe d'agents IA

Orchestrez une equipe d'agents IA avec CrewAI : roles Agent, Task et Crew, outils, process sequentiel ou hierarchique, agents locaux via Ollama et maitrise des couts.

Pourquoi une equipe d'agents

Un seul agent IA generaliste peut accomplir beaucoup, mais il atteint vite ses limites sur les taches complexes ou multi-facettes. L'approche multi-agents s'inspire d'une equipe humaine : plutot qu'un employe polyvalent, on assigne des roles specialises qui collaborent.

CrewAI est le framework Python qui rend cette orchestration simple et declarative. Vous definissez des agents avec un role, un objectif et une personnalite, vous leur confiez des taches, et la « crew » les fait collaborer. La specialisation ameliore la qualite : un agent concentre sur la relecture trouve des erreurs qu'un agent generaliste laisse passer.

La difference avec un agent unique : la ou notre article sur les agents IA couvre l'agent autonome, et LangGraph l'orchestration par graphe d'etats, CrewAI raisonne en termes de roles et de collaboration, plus proche de l'organisation d'une equipe.

Les concepts : Agent, Task, Crew

CrewAI repose sur trois briques que l'on assemble.

ConceptRole
AgentUn travailleur IA avec un role, un objectif (goal) et une histoire (backstory)
TaskUne mission precise assignee a un agent, avec une sortie attendue
CrewL'equipe : un ensemble d'agents et de taches orchestres selon un process
ToolUne capacite externe (recherche web, calcul, API) donnee a un agent
ProcessLa strategie d'execution : sequentielle ou hierarchique

CrewAI vs LangGraph

CritereCrewAILangGraph
Modele mentalRoles et collaborationGraphe d'etats
Courbe d'apprentissageDouce, declaratifPlus technique
Controle du fluxImplicite (process)Explicite (transitions)
Cas idealEquipes de roles specialisesWorkflows a branches complexes
LangagePythonPython / TypeScript
Choix rapide : si votre probleme se decrit naturellement comme « une equipe avec des roles », CrewAI sera plus direct. S'il s'agit d'un workflow avec des branches conditionnelles fines et du checkpointing, LangGraph offre plus de controle.

Installation et configuration

Prerequis :
  • Python 3.10+
  • Cle API du LLM (ex: OPENAI_API_KEY)
  • Optionnel : Ollama pour les agents en local
# Installer CrewAI et ses outils
pip install crewai crewai-tools

# Stocker la cle (jamais commitee)
echo "OPENAI_API_KEY=sk-..." >> .env

Premiere crew : recherche + redaction

Construisons une equipe de deux agents : un chercheur qui collecte l'information, et un redacteur qui produit un article a partir de ses trouvailles.

# crew_basic.py — une equipe de deux agents collaboratifs
from crewai import Agent, Task, Crew, Process

# 1. Definir les agents avec leur role, objectif et backstory
chercheur = Agent(
    role="Chercheur technique",
    goal="Rassembler des informations precises et a jour sur {sujet}",
    backstory="Expert en veille technologique, rigoureux et factuel.",
    verbose=True,
)

redacteur = Agent(
    role="Redacteur technique",
    goal="Rediger un article clair et structure a partir des recherches",
    backstory="Pedagogue, tu transformes des notes techniques en contenu accessible.",
    verbose=True,
)

# 2. Definir les taches, chacune assignee a un agent
tache_recherche = Task(
    description="Recherche les points cles sur {sujet}. Liste 5 elements essentiels.",
    expected_output="Une liste a puces de 5 points techniques verifies.",
    agent=chercheur,
)

tache_redaction = Task(
    description="Redige un article de 400 mots a partir des recherches fournies.",
    expected_output="Un article structure avec introduction, corps et conclusion.",
    agent=redacteur,
    context=[tache_recherche],   # recoit la sortie de la tache precedente
)

# 3. Assembler la crew et l'executer
crew = Crew(
    agents=[chercheur, redacteur],
    tasks=[tache_recherche, tache_redaction],
    process=Process.sequential,   # les taches s'enchainent dans l'ordre
)

resultat = crew.kickoff(inputs={"sujet": "les Signals dans Angular 19"})
print(resultat)
Le champ context est central : il transmet la sortie d'une tache a la suivante. Le redacteur recoit ainsi automatiquement les recherches du chercheur, sans glue code manuel.

Donner des outils aux agents

Un agent devient vraiment utile quand il peut agir sur le monde : chercher sur le web, lire un fichier, appeler une API. CrewAI fournit des outils prets a l'emploi et permet d'en creer.

# crew_tools.py — agent equipe d'un outil de recherche web
from crewai import Agent, Task, Crew
from crewai_tools import SerperDevTool   # outil de recherche web

search_tool = SerperDevTool()   # necessite une cle SERPER_API_KEY

chercheur = Agent(
    role="Analyste de marche",
    goal="Trouver des donnees recentes sur {sujet}",
    backstory="Tu exploites la recherche web pour des informations a jour.",
    tools=[search_tool],          # l'agent peut desormais chercher sur le web
    verbose=True,
)

tache = Task(
    description="Recherche les tendances 2026 sur {sujet} et synthetise-les.",
    expected_output="Une synthese de 3 tendances avec sources.",
    agent=chercheur,
)

crew = Crew(agents=[chercheur], tasks=[tache])
print(crew.kickoff(inputs={"sujet": "les frameworks JavaScript"}))

Creer un outil personnalise

# Outil maison : interroger une base interne
from crewai.tools import tool

@tool("Recherche produit")
def recherche_produit(reference: str) -> str:
    """Recupere les details d'un produit par sa reference."""
    # Votre logique metier : appel DB, API interne, etc.
    produit = ma_base.get(reference)
    return f"{produit['nom']} — {produit['prix']} EUR — stock: {produit['stock']}"

# Donner cet outil a un agent
agent_sav = Agent(
    role="Conseiller produit",
    goal="Renseigner les clients sur les produits",
    backstory="Tu connais le catalogue sur le bout des doigts.",
    tools=[recherche_produit],
)

Process sequentiel vs hierarchique

CrewAI propose deux strategies d'orchestration. Le sequentiel enchaine les taches dans l'ordre. Le hierarchique introduit un agent manager qui delegue et coordonne.

# crew_hierarchical.py — un manager coordonne l'equipe
from crewai import Agent, Task, Crew, Process

# Le manager n'execute pas, il delegue et synthetise
redacteur = Agent(role="Redacteur", goal="...", backstory="...")
relecteur = Agent(role="Relecteur qualite", goal="...", backstory="...")
seo = Agent(role="Expert SEO", goal="...", backstory="...")

tache_globale = Task(
    description="Produire un article optimise SEO, relu et de qualite sur {sujet}.",
    expected_output="Un article final pret a publier.",
)

crew = Crew(
    agents=[redacteur, relecteur, seo],
    tasks=[tache_globale],
    process=Process.hierarchical,    # un manager orchestre les delegations
    manager_llm="gpt-4o",            # le LLM qui joue le role de manager
)

print(crew.kickoff(inputs={"sujet": "le RAG en production"}))
Quand passer au hierarchique ? Le sequentiel suffit pour un pipeline lineaire (A puis B puis C). Le hierarchique brille quand l'ordre des taches doit etre decide dynamiquement, ou quand un agent doit arbitrer entre plusieurs specialistes.

Orchestrer des agents en local

Pour la confidentialite ou reduire les couts, CrewAI peut piloter des modeles locaux via Ollama. L'orchestration multi-agents tourne alors entierement sur votre machine.

# crew_local.py — agents propulses par un modele local Ollama
from crewai import Agent, Task, Crew, LLM

# Pointer vers un modele servi par Ollama en local
llm_local = LLM(
    model="ollama/llama3.1",
    base_url="http://localhost:11434",
)

agent = Agent(
    role="Assistant prive",
    goal="Traiter des donnees sensibles sans cloud",
    backstory="Tu travailles entierement en local pour la confidentialite.",
    llm=llm_local,                  # ce modele local pilote l'agent
)

tache = Task(
    description="Resume ce document interne : {document}",
    expected_output="Un resume en 3 points.",
    agent=agent,
)

crew = Crew(agents=[agent], tasks=[tache])
print(crew.kickoff(inputs={"document": texte_confidentiel}))
Les modeles locaux sont plus lents et moins capables que les modeles cloud de pointe. Pour une crew en local, simplifiez les roles et reduisez le nombre d'agents afin de limiter la latence cumulee.

Exposer une crew derriere une API web

Une crew met souvent plusieurs dizaines de secondes a produire son resultat (plusieurs agents, plusieurs appels LLM). On ne l'execute donc jamais dans une requete HTTP synchrone : on la lance en tache de fond et on expose un endpoint de statut que le front interroge. Cote Python, FastAPI fait le job.

# api.py — exposer la crew en tache de fond avec FastAPI
from fastapi import FastAPI, BackgroundTasks
from uuid import uuid4

app = FastAPI()
jobs = {}   # en prod : Redis plutot qu'un dict en memoire

def run_crew(job_id: str, sujet: str):
    jobs[job_id] = {"etat": "en_cours", "resultat": None}
    resultat = crew.kickoff(inputs={"sujet": sujet})   # bloquant, hors requete
    jobs[job_id] = {"etat": "termine", "resultat": str(resultat)}

@app.post("/api/crew/run")
def lancer(sujet: str, bg: BackgroundTasks):
    job_id = str(uuid4())
    jobs[job_id] = {"etat": "en_file", "resultat": None}
    bg.add_task(run_crew, job_id, sujet)   # demarre sans bloquer
    return {"jobId": job_id}               # reponse immediate

@app.get("/api/crew/status/{job_id}")
def statut(job_id: str):
    return jobs.get(job_id, {"etat": "introuvable"})

Cote front, on consomme cette API comme n'importe quel traitement asynchrone. Dans une application Angular, un service encapsule le lancement puis le polling du statut jusqu'a completion.

// crew.service.ts — piloter la crew depuis une app Angular
import { Injectable, inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { interval, switchMap, takeWhile, lastValueFrom } from 'rxjs';

@Injectable({ providedIn: 'root' })
export class CrewService {
  private http = inject(HttpClient);

  async generer(sujet: string): Promise<string> {
    // 1. Lancer la crew : on recupere un jobId immediatement
    const { jobId } = await lastValueFrom(
      this.http.post<{ jobId: string }>('/api/crew/run', { sujet }),
    );

    // 2. Interroger le statut toutes les 2s jusqu'a "termine"
    const flux = interval(2000).pipe(
      switchMap(() => this.http.get<{ etat: string; resultat: string }>(`/api/crew/status/${jobId}`)),
      takeWhile((s) => s.etat !== 'termine', true),   // inclut la derniere emission
    );

    let dernier = { etat: '', resultat: '' };
    await lastValueFrom(flux.pipe(switchMap(async (s) => (dernier = s))));
    return dernier.resultat;
  }
}
En production : remplacez le dictionnaire en memoire par une file de jobs (Celery/Redis cote Python) et stockez les resultats dans une base. Cela permet de scaler horizontalement les workers de crew independamment de votre API web, et de survivre a un redemarrage.

Observabilite : suivre et deboguer

Une crew est une boite a moitie noire : plusieurs agents echangent, et quand le resultat decoit, il faut comprendre quel agent a derape. CrewAI expose des callbacks declenches a chaque etape — branchez-y votre logging pour tracer la collaboration.

# observability.py — tracer chaque etape des agents
import logging
logging.basicConfig(level=logging.INFO)

def log_etape(etape):
    # Appele a chaque action d'agent (pensee, appel d'outil, sortie)
    logging.info("Agent: %s | Action: %s", getattr(etape, "agent", "?"), etape)

crew = Crew(
    agents=[chercheur, redacteur],
    tasks=[tache_recherche, tache_redaction],
    step_callback=log_etape,         # trace fine de chaque etape
    verbose=True,
)
# Lancement non bloquant + remontee de progression vers l'API
async def run_crew_async(job_id: str, sujet: str):
    def on_task_end(output):
        # Mettre a jour la progression apres chaque tache terminee
        jobs[job_id]["progress"] = jobs[job_id].get("progress", 0) + 1

    crew.task_callback = on_task_end
    resultat = await crew.kickoff_async(inputs={"sujet": sujet})
    jobs[job_id] = {"etat": "termine", "resultat": str(resultat)}
Loggez au minimum : l'agent actif, l'outil appele et la sortie de chaque tache. Sur un incident, cette trace permet de cibler le role fautif (un backstory ambigu, un outil qui renvoie du bruit) au lieu de relancer la crew a l'aveugle.

Cas d'usage concrets cote produit

Le multi-agents brille quand une tache se decompose en roles complementaires. Voici des configurations de crew eprouvees pour des fonctionnalites d'application web.

FonctionnaliteComposition de la crewProcess
Generation d'article de blogChercheur + Redacteur + Relecteur SEOSequentiel
Reponse SAV complexeAnalyste demande + Expert produit + Redacteur reponseHierarchique
Analyse de CV / matchingExtracteur + Evaluateur + SyntheseSequentiel
Revue de code automatiseeSecurite + Performance + StyleHierarchique
Resume de reunionTranscripteur + Synthese + Extracteur d'actionsSequentiel
Du prototype au produit : commencez par une crew sequentielle simple branchee sur l'API ci-dessus, mesurez la qualite et la latence sur des cas reels, puis n'ajoutez un agent ou ne passez au hierarchique que si le gain de qualite le justifie face au surcout en tokens.

Bonnes pratiques et couts

Le multi-agents multiplie les appels LLM : chaque agent, chaque etape de raisonnement et chaque appel d'outil consomme des tokens. La latence et le cout grimpent vite.

Maitriser une crew en production :
  • Limiter le nombre d'agents au strict necessaire
  • Utiliser un modele rapide (Groq, gpt-4o-mini) pour les agents simples
  • Reserver les gros modeles aux roles critiques (manager, relecteur)
  • Activer le prompt caching sur les backstories stables
  • Plafonner les iterations pour eviter les boucles d'agents
  • Logger chaque etape pour deboguer la collaboration
  • Definir des expected_output precis pour cadrer chaque agent
Piege classique : empiler les agents par enthousiasme. Trois agents bien definis battent souvent une equipe de huit aux roles flous. Commencez par deux ou trois agents, mesurez la qualite, et n'ajoutez un role que s'il apporte une valeur mesurable.

Erreurs frequentes

L'erreur de conception la plus repandue : des roles et objectifs flous. Un agent dont le goal et la backstory sont vagues produit des resultats generiques et empiete sur le travail des autres. Chaque agent doit avoir une mission unique et un expected_output precis ; c'est cette specialisation qui justifie le surcout du multi-agents face a un agent unique.

Deuxieme piege, fatal en production : executer la crew dans le cycle requete-reponse HTTP. Une crew prend des dizaines de secondes ; la lancer dans un handler synchrone provoque des timeouts et bloque vos workers web. Le pattern tache de fond + endpoint de statut presente plus haut n'est pas optionnel des que la crew est exposee a des utilisateurs.

Enfin, deux derives de cout classiques : empiler les agents par enthousiasme (trois agents nets battent huit agents flous) et oublier de plafonner les iterations, ce qui laisse un agent confus boucler en accumulant les appels LLM. Definissez un max_iter, branchez le step_callback pour tracer la collaboration, et utilisez un modele rapide et bon marche pour les roles secondaires en reservant les gros modeles au manager et au relecteur.

Conclusion

CrewAI rend l'orchestration multi-agents accessible et lisible : on raisonne en roles, objectifs et collaboration, comme avec une equipe humaine. Les briques Agent, Task et Crew suffisent a construire des pipelines de recherche, redaction et relecture qui surpassent un agent unique grace a la specialisation.

Donnez des outils a vos agents pour qu'ils agissent, choisissez le process (sequentiel ou hierarchique) selon la complexite, et n'oubliez pas que chaque agent coute en tokens et en latence. Avec des roles bien definis, un modele adapte par agent et le prompt caching, vous obtenez une equipe d'agents efficace — du cloud jusqu'au 100% local via Ollama. C'est la prochaine etape naturelle apres l'agent unique.

A retenir :
  • Agent + Task + Crew = orchestration multi-agents declarative
  • context transmet la sortie d'une tache a la suivante
  • Outils integres ou maison pour faire agir les agents
  • Process sequentiel pour les pipelines, hierarchique pour la delegation
  • Fonctionne en local via Ollama pour la confidentialite
  • Maitriser couts et latence : peu d'agents, roles precis, caching

Partager