Dans ce tutoriel je vais vous montrer comment faire vos premiers pas avec les agents IA
Contents
Savez vous ce qu’est un agent IA?
Tout le monde parle d’agent IA mais je pense que beaucoup ne savent pas ce qu’est vraiment un agent IA.
Un agent IA est un programme propulsé par un LLM (Claude, chatGPT etc) et qui a reçu un prompt bien spécifique pour exécuter une tâche précise. Il est capable d’agir sur des informations, chercher des information via Google, manipuler des fichiers, à la différence de l’IA que vous connaissez qui ne fait que répondre à votre question.
Un agent IA est capable de communiquer avec d’autres agents IA au sein d’une équipe, il est hautement spécialisé, il peut tourner en mode séquentiel ou parallèle, et à la fin livrer un travail d’équipe dirigé par un manager.
Qu’est ce que le framework CrewAI ?
C’est une librairie Python, qui va s’occuper d’orchestrer les agents IA, les faire communiquer entre eux. La version actuelle au moment où j’écris cet article est la version 1.14 (méfiez vous des tuto périmés que vous donne les LLM et mêm le cours officiel de CrewAI !). Le site officiel de CrewAI est ici.
Pourquoi utiliser des agent IA?
L’utilisation d’agent IA spécialisé va rendre un meilleur travail qu’un LMM tout seul.
Exemple basique avec l’analyse
Pour utiliser CrewAI, il vous faut 3 chose : les agents, les tâches (Task) et le Crew. On va aussi affecter un LLM à chaque agent, et on peut affecter un LLM différent au manager des agents.
Mise en place de l’environnement virtuel et installation des paquets
Pour chaque projet il est important de mettre en place un environnement virtuel pour isoler les librairies de l’installation globale de python. Ainsi allez dans un endroit qui vous plait pour votre projet.
# dans un répertoire dédié à votre projet faites la création de l'environnement virtuel #creation de l'environnement virtuel python -m venv venv #Puis dans votre environnement virtuel python -m pip install crewai crewai-tools python-dotenv un fichier .env.example
Usage du script
pour faire simple une action est passée par défaut python run.py Mais vous pouvez passez en argument une autre action le script prend jusqu'à 4 arguments. python run.py --stock TSLA --risk High --strategy "Swing Trading"
Description de ce qui se passe quand vous lancez le script
1. Le Manager LLM lit les tâches et décide qui fait quoi et dans quel ordre.
2. Les agents s’exécutent en séquence, chacun produisant un « thought process » visible :
Thought:→ l’agent réfléchit à ce qu’il doit faireAction:→ il décide d’utiliser un outil (scraping, recherche…)Action Input:→ les paramètres qu’il passe à l’outilObservation:→ le résultat retourné par l’outilFinal Answer:→ sa conclusion pour cette tâche
3. Le Manager valide chaque résultat avant de passer à la tâche suivante.
4. Les 4 agents travaillent dans l’ordre :
- Data Analyst → analyse le marché AAPL
- Trading Strategy Developer → propose des stratégies
- Trade Advisor → planifie l’exécution
- Risk Advisor → évalue les risques et produit le rapport final
Tout cet output verbose c’est le « raisonnement » des agents rendu visible — c’est ce qui rend crewAI intéressant à observer. Tu peux mettre verbose=False sur les agents et le crew pour n’avoir que le résultat final.
Comment crewAI scripte un agent
data_analyst_agent = Agent(
role="Data Analyst",
goal=(
"Monitor and analyze market data in real-time "
"to identify trends and predict market movements."
),
backstory=(
"Specializing in financial markets, this agent "
"uses statistical modeling and machine learning "
"to provide crucial insights. With a knack for data, "
"the Data Analyst Agent is the cornerstone for "
"informing trading decisions."
),
verbose=True,
allow_delegation=True,
tools=tools,
llm=llm,
)
Le backstory est le texte qui décrite (prompte) l’agent. Le paramètre llm indique le LLM à utiliser. allow_delegation permet à un agent de confier sa mission à un autre agent dès lors qu’il pense qu’il n’est pas le mieux dans une tâche. Si vous débutez mettez à False. tools quant à lui est une liste d’outils (qu’il faut déclarer) pour que l’agent puisse le solliciter pour faire autre chose que de répondre comme un LMM basiquement. Dans la section 5 on a tools = [scrape_tool, search_tool]. Pour Serper il vous faudra aller sur leur site créer un compte et obtenir une clé API. Il vous faut aussi une clé API openAI.
Voir la liste des outils potentiels
python -c "import crewai_tools; print(dir(crewai_tools))" # va vous donner une grande liste d'outils ['AIMindTool', 'ApifyActorsTool', 'ArxivPaperTool', 'BedrockInvokeAgentTool', 'BedrockKBRetrieverTool', 'BraveImageSearchTool', 'BraveLLMContextTool', 'BraveLocalPOIsDescriptionTool', 'BraveLocalPOIsTool', 'BraveNewsSearchTool', 'BraveSearchTool', 'BraveVideoSearchTool', 'BraveWebSearchTool', 'BrightDataDatasetTool', 'BrightDataSearchTool', 'BrightDataWebUnlockerTool', 'BrowserbaseLoadTool', 'CSVSearchTool', 'CodeDocsSearchTool', 'ComposioTool', 'ContextualAICreateAgentTool', 'ContextualAIParseTool', 'ContextualAIQueryTool', 'ContextualAIRerankTool', 'CouchbaseFTSVectorSearchTool', 'CrewaiPlatformTools', 'DOCXSearchTool', 'DallETool', 'DatabricksQueryTool', 'DaytonaExecTool', 'DaytonaFileTool', 'DaytonaPythonTool', 'DirectoryReadTool', 'DirectorySearchTool', 'E2BExecTool', 'E2BFileTool', 'E2BPythonTool', 'EXASearchTool', 'EnterpriseActionTool', 'FileCompressorTool', 'FileReadTool', 'FileWriterTool', 'FirecrawlCrawlWebsiteTool', 'FirecrawlScrapeWebsiteTool', 'FirecrawlSearchTool', 'GenerateCrewaiAutomationTool', 'GithubSearchTool', 'HyperbrowserLoadTool', 'InvokeCrewAIAutomationTool', 'JSONSearchTool', 'JinaScrapeWebsiteTool', 'LinkupSearchTool', 'LlamaIndexTool', 'MCPServerAdapter', 'MDXSearchTool', 'MergeAgentHandlerTool', 'MongoDBVectorSearchConfig', 'MongoDBVectorSearchTool', 'MultiOnTool', 'MySQLSearchTool', 'NL2SQLTool', 'OCRTool', 'OxylabsAmazonProductScraperTool', 'OxylabsAmazonSearchScraperTool', 'OxylabsGoogleSearchScraperTool', 'OxylabsUniversalScraperTool', 'PDFSearchTool', 'ParallelSearchTool', 'PatronusEvalTool', 'PatronusLocalEvaluatorTool', 'PatronusPredefinedCriteriaEvalTool', 'QdrantVectorSearchTool', 'RagTool', 'S3ReaderTool', 'S3WriterTool', 'ScrapeElementFromWebsiteTool', 'ScrapeWebsiteTool', 'ScrapegraphScrapeTool', 'ScrapegraphScrapeToolSchema', 'ScrapflyScrapeWebsiteTool', 'SeleniumScrapingTool', 'SerpApiGoogleSearchTool', 'SerpApiGoogleShoppingTool', 'SerperDevTool', 'SerperScrapeWebsiteTool', 'SerplyJobSearchTool', 'SerplyNewsSearchTool', 'SerplyScholarSearchTool', 'SerplyWebSearchTool', 'SerplyWebpageToMarkdownTool', 'SingleStoreSearchTool', 'SnowflakeConfig', 'SnowflakeSearchTool', 'SpiderTool', 'StagehandTool', 'TXTSearchTool', 'TavilyExtractorTool', 'TavilySearchTool', 'VisionTool', 'WeaviateVectorSearchTool', 'WebsiteSearchTool', 'XMLSearchTool', 'YoutubeChannelSearchTool', 'YoutubeVideoSearchTool', 'ZapierActionTool', 'ZapierActionTools', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', '__version__', 'adapters', 'aws', 'rag', 'security', 'tools']
verbose permet d’afficher dans le terminal ce qui se passe. le goal répond à « pourquoi tu existes dans cette équipe », la tâche répond à « qu’est-ce que tu fais maintenant », alors que le backstory décrit l’agent.
Les Task
data_analysis_task = Task(
description=(
"Continuously monitor and analyze market data for "
"the selected stock ({stock_selection}). "
"Use statistical modeling and machine learning to "
"identify trends and predict market movements."
),
expected_output=(
"Insights and alerts about significant market "
"opportunities or threats for {stock_selection}."
),
agent=data_analyst_agent,
)
expected_out est une instruction envoyée au LLM. Il y a différents niveau de contrainte, détaillées ci-dessous :
Niveau 1 : il faut être très précis
# vague
expected_output="Un rapport d'analyse."
# précis
expected_output=(
"Un rapport structuré avec exactement ces sections : "
"1) Tendances actuelles, 2) Opportunités, 3) Risques, "
"4) Recommandation finale en une phrase. "
"Format markdown, maximum 500 mots."
)
Niveau 2 : ajouter un guardrail (validation automatique)
task = Task(
description="Analyse le stock {stock_selection}.",
expected_output="Un rapport avec tendances, opportunités et risques.",
agent=analyst,
guardrail=(
"Le rapport doit contenir les mots 'tendances', 'opportunités' "
"et 'risques'. Il doit faire au moins 200 mots."
)
)
Niveau 3 : forcer un formation JSON avec Pydantic (le plus strict)
from pydantic import BaseModel
from typing import List
class AnalysisReport(BaseModel):
tendances: List[str]
opportunites: List[str]
risques: List[str]
recommandation: str
task = Task(
description="Analyse le stock {stock_selection}.",
expected_output="Un rapport d'analyse structuré.",
agent=analyst,
output_pydantic=AnalysisReport, # force le format
)
# Accès au résultat structuré après kickoff :
result = crew.kickoff(inputs={"stock_selection": "AAPL"})
print(result.pydantic.recommandation)
print(result.pydantic.risques)
Voici le code source intégral
"""
run.py — Analyse financière multi-agents avec crewAI v1.x
----------------------------------------------------------
Compatible : crewai >= 1.0 (testé sur 1.14)
Installation :
pip install crewai crewai-tools python-dotenv
Fichier .env requis :
OPENAI_API_KEY=sk-...
SERPER_API_KEY=... (optionnel, pour la recherche web)
Usage :
python run.py
python run.py --stock TSLA --risk High --strategy "Swing Trading"
"""
import os
import argparse
from dotenv import load_dotenv
# ── 1. Variables d'environnement ─────────────────────────────────────────────
load_dotenv()
if not os.getenv("OPENAI_API_KEY"):
raise EnvironmentError(
"OPENAI_API_KEY manquant !\n"
"Crée un fichier .env avec : OPENAI_API_KEY=sk-..."
)
# ── 2. Arguments CLI ──────────────────────────────────────────────────────────
parser = argparse.ArgumentParser(description="Analyse financière multi-agents crewAI v1.x")
parser.add_argument("--stock", default="AAPL", help="Ticker boursier (défaut: AAPL)")
parser.add_argument("--capital", default="100000", help="Capital initial (défaut: 100000)")
parser.add_argument("--risk", default="Medium", choices=["Low", "Medium", "High"])
parser.add_argument("--strategy", default="Day Trading", help="Stratégie de trading")
args = parser.parse_args()
# ── 3. Imports crewAI v1.x ───────────────────────────────────────────────────
# CHANGEMENT v1.x : on n'importe plus depuis langchain_openai
# crewAI gère le LLM en interne via LiteLLM
from crewai import Agent, Task, Crew, Process, LLM
from crewai_tools import ScrapeWebsiteTool, SerperDevTool
# ── 4. LLM ───────────────────────────────────────────────────────────────────
# CHANGEMENT v1.x : on utilise crewai.LLM au lieu de langchain_openai.ChatOpenAI
# Le préfixe "openai/" est la convention LiteLLM
llm = LLM(
model="openai/gpt-4o-mini", # ou "openai/gpt-4o", "openai/gpt-3.5-turbo"
temperature=0.7,
api_key=os.getenv("OPENAI_API_KEY"),
)
# LLM dédié au manager (peut être le même ou un modèle plus puissant)
manager_llm = LLM(
model="openai/gpt-4o-mini",
temperature=0.7,
api_key=os.getenv("OPENAI_API_KEY"),
)
# ── 5. Outils ────────────────────────────────────────────────────────────────
# SerperDevTool nécessite SERPER_API_KEY dans .env
# Sans clé, les agents raisonnent sur leurs connaissances sans chercher sur le web
search_tool = SerperDevTool()
scrape_tool = ScrapeWebsiteTool()
tools = [scrape_tool, search_tool]
# ── 6. Agents ────────────────────────────────────────────────────────────────
# CHANGEMENT v1.x : on passe `llm=` explicitement à chaque agent
data_analyst_agent = Agent(
role="Data Analyst",
goal=(
"Monitor and analyze market data in real-time "
"to identify trends and predict market movements."
),
backstory=(
"Specializing in financial markets, this agent "
"uses statistical modeling and machine learning "
"to provide crucial insights. With a knack for data, "
"the Data Analyst Agent is the cornerstone for "
"informing trading decisions."
),
verbose=True,
allow_delegation=True,
tools=tools,
llm=llm,
)
trading_strategy_agent = Agent(
role="Trading Strategy Developer",
goal=(
"Develop and test various trading strategies based "
"on insights from the Data Analyst Agent."
),
backstory=(
"Equipped with a deep understanding of financial "
"markets and quantitative analysis, this agent "
"devises and refines trading strategies. It evaluates "
"the performance of different approaches to determine "
"the most profitable and risk-averse options."
),
verbose=True,
allow_delegation=True,
tools=tools,
llm=llm,
)
execution_agent = Agent(
role="Trade Advisor",
goal=(
"Suggest optimal trade execution strategies "
"based on approved trading strategies."
),
backstory=(
"This agent specializes in analyzing the timing, price, "
"and logistical details of potential trades. By evaluating "
"these factors, it provides well-founded suggestions for "
"when and how trades should be executed to maximize "
"efficiency and adherence to strategy."
),
verbose=True,
allow_delegation=True,
tools=tools,
llm=llm,
)
risk_management_agent = Agent(
role="Risk Advisor",
goal=(
"Evaluate and provide insights on the risks "
"associated with potential trading activities."
),
backstory=(
"Armed with a deep understanding of risk assessment models "
"and market dynamics, this agent scrutinizes the potential "
"risks of proposed trades. It offers a detailed analysis of "
"risk exposure and suggests safeguards to ensure that "
"trading activities align with the firm's risk tolerance."
),
verbose=True,
allow_delegation=True,
tools=tools,
llm=llm,
)
# ── 7. Tâches ────────────────────────────────────────────────────────────────
# Les {accolades} sont remplacées par les valeurs de `inputs` au kickoff
data_analysis_task = Task(
description=(
"Continuously monitor and analyze market data for "
"the selected stock ({stock_selection}). "
"Use statistical modeling and machine learning to "
"identify trends and predict market movements."
),
expected_output=(
"Insights and alerts about significant market "
"opportunities or threats for {stock_selection}."
),
agent=data_analyst_agent,
)
strategy_development_task = Task(
description=(
"Develop and refine trading strategies based on "
"the insights from the Data Analyst and "
"user-defined risk tolerance ({risk_tolerance}). "
"Consider trading preferences ({trading_strategy_preference})."
),
expected_output=(
"A set of potential trading strategies for {stock_selection} "
"that align with the user's risk tolerance."
),
agent=trading_strategy_agent,
context=[data_analysis_task], # reçoit le résultat de la tâche précédente
)
execution_planning_task = Task(
description=(
"Analyze approved trading strategies to determine the "
"best execution methods for {stock_selection}, "
"considering current market conditions and optimal pricing."
),
expected_output=(
"Detailed execution plans suggesting how and when to "
"execute trades for {stock_selection}."
),
agent=execution_agent,
context=[strategy_development_task],
)
risk_assessment_task = Task(
description=(
"Evaluate the risks associated with the proposed trading "
"strategies and execution plans for {stock_selection}. "
"Provide a detailed analysis of potential risks "
"and suggest mitigation strategies."
),
expected_output=(
"A comprehensive risk analysis report detailing potential "
"risks and mitigation recommendations for {stock_selection}."
),
agent=risk_management_agent,
context=[strategy_development_task, execution_planning_task],
output_file="result_{stock_selection}.md", # sauvegarde automatique
markdown=True,
)
# ── 8. Crew ───────────────────────────────────────────────────────────────────
# CHANGEMENT v1.x :
# - manager_llm prend un objet crewai.LLM (plus de ChatOpenAI)
# - Process.hierarchical toujours supporté
financial_trading_crew = Crew(
agents=[
data_analyst_agent,
trading_strategy_agent,
execution_agent,
risk_management_agent,
],
tasks=[
data_analysis_task,
strategy_development_task,
execution_planning_task,
risk_assessment_task,
],
manager_llm=manager_llm,
process=Process.hierarchical,
verbose=True,
)
# ── 9. Inputs et lancement ────────────────────────────────────────────────────
financial_trading_inputs = {
"stock_selection": args.stock,
"initial_capital": args.capital,
"risk_tolerance": args.risk,
"trading_strategy_preference": args.strategy,
"news_impact_consideration": True,
}
print("\n" + "=" * 60)
print(" ANALYSE FINANCIÈRE MULTI-AGENTS — crewAI v1.x")
print("=" * 60)
print(f" Ticker : {financial_trading_inputs['stock_selection']}")
print(f" Capital : ${financial_trading_inputs['initial_capital']}")
print(f" Risque : {financial_trading_inputs['risk_tolerance']}")
print(f" Stratégie : {financial_trading_inputs['trading_strategy_preference']}")
print("=" * 60)
print("\n⚡ Démarrage... (peut prendre 2–5 minutes)\n")
result = financial_trading_crew.kickoff(inputs=financial_trading_inputs)
print("\n" + "=" * 60)
print(" RÉSULTAT FINAL")
print("=" * 60 + "\n")
print(result)
print(f"\n✅ Rapport sauvegardé dans : result_{args.stock.lower()}.md")
