J'ai construit une équipe d'agents IA pour mon SAV en 6 fichiers Python
Pour gérer la relation client, les entreprises se servent souvent de chatbots classiques. Alors que ces agents conversationnels se trouvent limités à des tâches simples, le système multi-agents permet de travailler en "équipes" spécialisées. Chaque agent collabore pour résoudre des problèmes clients complexes et croisés. Le système agit de manière autonome au lieu de simplement répondre. Reste à savoir comment en construire un. Dans ce tutoriel, nous montons pas à pas un système multi-agents pour le SAV, de l'installation de l'environnement jusqu'au déploiement, sur un cas concret : la demande de remboursement d'un produit cassé.
Prenons l’exemple d’un utilisateur demandant un remboursement suite à la réception d’un produit cassé. Dans ce cas, l'agent Logistique va vérifier la livraison, l'agent SAV valider l'état du produit et l’agent Financier déclencher le virement.
Au niveau technique, simplement, comment fonctionne un système multi-agents adapté à la relation client ? Pour maintenir la continuité de l'échange, le système multi-agents utilise une mémoire à court terme et une mémoire à long terme, via le RAG, pour "Retrieval-Augmented Generation". Les interactions s’effectuent au format JSON structuré pour garantir l'interopérabilité. Grâce à des boucles de rétroaction, un "agent critique" peut valider la réponse d'un "agent exécutant" avant l'envoi au client.
Répondre à des requêtes complexes
Afin d’illustrer cela, nous allons créer un système multi-agents adapté à la relation client. Dans cette perspective, nous allons mettre en place, étape par étape, le dossier racine, le fichier de sécurité, le cerveau du système, le moteur, l’interface et la mémoire. L’arborescence finale dans notre dossier devrait ressembler à cela :
C:\Users\admin\MonProjetCrew\ ├── venv/ # L’environnement Python isolé ├── knowledge/ # Les PDF et guides internes ├── .env # La clé API secrète ├── customer_service_crew.py # La définition des Agents et des Tâches ├── main.py # Pour tester en mode console └── app.py # Pour lancer l'interface Web (Streamlit)
Notons que le dossier venv se créera automatiquement. Indiquons aussi que pour suivre ce tutoriel, nous avons auparavant besoin de Python 3.10 ou supérieur, le langage de programmation principal, de Pip , e gestionnaire de paquets Python, et d’une clé API pour un LLM (OpenAI dans ce cas).
1. Préparation du dossier racine
Sous Windows, nous ouvrons le terminal avec PowerShell. Nous créons notre espace de travail en tapant :
mkdir C:\Users\admin\MonProjetCrew
Nous nous déplaçons dedans : cd C:\Users\admin\MonProjetCrew Nous créons un environnement virtuel (venv) : python -m venv venv.
Nous l’activons :
.\venv\Scripts\activate
Nous installons notre bibliothèque en tapant :
pip install crewai langchain-openai streamlit
2. Le fichier de sécurité : .env
À la racine du dossier, nous créons un fichier texte et le nommons .env, sans extension .txt. Nous l’enregistrons dans "tous les fichiers". Pour avoir la clé API, nous allons sur platform.openai.com. Nous choisissons "API", et non "ChatGPT". Notons qu’OpenAI n'offre plus de crédits gratuits automatiques à l'inscription. Pour que la clé fonctionne, il faut ajouter un montant minimum. Une fois le solde positif, nous cliquons à gauche sur "API keys", puis nous la collons dans le fichier .env :
OPENAI_API_KEY=sk-proj-VOTRE_CLE_ICI
3. Le cerveau : customer_service_crew.py
Nous allons lancer le "cerveau" : customer_service_crew.py. Pour cela, nous allons créer un fichier physique dans VS Code. Dans File > Open Folder... (Fichier > Ouvrir le dossier), nous sélectionnons le dossier MonProjetCrewtest. Nous cliquons sur l'icône "Nouveau fichier" (le petit + à côté du nom de votre dossier) et le nommons customer_service_crew.py.
Nous y insérons ce code et l’enregistrons :
Python
import os
from crewai import Agent, Task, Crew, Process
from dotenv import load_dotenv
load_dotenv() # Charge les variables d'environnement du fichier .env
# 1. Définition des Agents
classifier_agent = Agent(
role='Classificateur de Demandes Client',
goal='Analyser les demandes clients entrantes, identifier l\'intention (technique, facturation, information) et le niveau d\'urgence (faible, moyen, élevé).',
backstory='Expert en analyse sémantique, il est le premier point de contact avec le client. Sa mission est de comprendre rapidement la nature de chaque requête pour la diriger vers le bon spécialiste.',
verbose=True,
allow_delegation=False # Cet agent ne délègue pas, il classifie
)
specialist_agent = Agent(
role='Spécialiste Support Technique',
goal='Fournir des solutions précises aux problèmes techniques identifiés par le classificateur, en utilisant une base de connaissances interne.',
backstory='Ingénieur expérimenté, il maîtrise les produits et services de l\'entreprise. Il est capable de diagnostiquer et de proposer des solutions techniques détaillées.',
verbose=True,
allow_delegation=True # Peut déléguer si besoin de plus d'informations
)
response_agent = Agent(
role='Rédacteur de Réponses Client',
goal='Formuler des réponses claires, concises, professionnelles et empathiques basées sur les informations fournies par les autres agents.',
backstory='Maître de la communication écrite, il s\'assure que chaque réponse client est parfaitement rédigée, respecte le ton de l\'entreprise et apporte une solution satisfaisante.',
verbose=True,
allow_delegation=False # Cet agent rédige la réponse finale
)
# 2. Définition des Tâches
classify_task = Task(
description='Analyser la demande client suivante : "{{ customer_request }}" pour déterminer son intention et son urgence.',
expected_output='Un dictionnaire JSON avec les clés "intention" (e.g., "technique", "facturation", "information") et "urgence" (e.g., "faible", "moyen", "élevé").',
agent=classifier_agent
)
research_task = Task(
description='Basé sur l\'intention "{{ intention }}" et l\'urgence "{{ urgence }}" de la demande client, rechercher la solution la plus pertinente. La demande originale était : "{{ customer_request }}".',
expected_output='Un résumé détaillé de la solution trouvée, incluant les étapes à suivre ou les informations pertinentes.',
agent=specialist_agent
)
write_response_task = Task(
description='Rédiger une réponse professionnelle et empathique au client. La demande originale était : "{customer_request}"',
expected_output='Le texte complet de l\'email de réponse au client.',
agent=response_agent,
context=[research_task] # <--- C'est cette ligne qui permet au rédacteur de recevoir la "solution" trouvée par l'agent précédent
)
# 3. Assemblage du Crew
customer_service_crew = Crew(
agents=[classifier_agent, specialist_agent, response_agent],
tasks=[classify_task, research_task, write_response_task],
process=Process.sequential, # Les tâches s'exécutent séquentiellement
verbose=True
)
# 4. Lancement du processus
customer_request = "Mon internet ne fonctionne plus depuis ce matin, et j'ai un rendez-vous important en visio dans 1 heure !"
# Exécution de la première tâche pour obtenir l'intention et l'urgence
initial_output = customer_service_crew.kickoff(inputs={'customer_request': customer_request})
print("\n### Réponse Finale du Système Multi-Agents :\n")
print(initial_output)
On voit que la question du client (customer_request) va passer de main en main (d'agent en agent) jusqu'au résultat final. Chacun d’entre eux possède un périmètre limité pour éviter les erreurs. Le classificateur (classifier_agent) trie et juge l'urgence. classify_task doit produire un format précis (JSON) pour que la machine comprenne l'urgence. Le spécialiste (specialist_agent) a le droit de déléguer pour trouver la solution concrète. research_task prend l'étiquette du premier agent et cherche le "comment réparer". Le rédacteur (response_agent) transforme des informations techniques brutes en un email poli et empathique. write_response_task prend le "comment réparer" et rédige le message final.
4. La mémoire : dossier knowledge
Nous créons un dossier nommé knowledge à la racine de notre dossier. Nous y glissons un fichier PDF, ici "conditions_remboursement.pdf". Dans customer_service_crew.py, vous devrez configurer l'agent Spécialiste pour qu'il utilise un "outil" de lecture, comme PDFSearchTool, pointant vers ce dossier.
5. Le moteur : main.py
Ce fichier transforme le script Python en une application web interactive capable de lire les documents PDF grâce au RAG. Ici, la "bibliothèque" (pdf_source) pointe vers le fichier conditions_remboursement_exercice.pdf. Streamlit, une bibliothèque Python, aide aussi pour la visualisation de données. Le nom du PDF est à adapter.
import os
import streamlit as st
from dotenv import load_dotenv
from crewai import Agent, Task, Crew
# --- NOUVEAU : Import pour le PDF ---
from crewai.knowledge.source.pdf_knowledge_source import PDFKnowledgeSource
# 1. Configuration de la page
st.set_page_config(page_title="Mon Assistant SAV", layout="centered")
st.title("???? Chat avec l'expert Remboursements")
load_dotenv()
# --- NOUVEAU : Configuration de la source de connaissances ---
pdf_source = PDFKnowledgeSource(
item_id="politique_remboursement",
file_paths=["conditions_remboursement_exercice.pdf"]
)
# 2. Zone de saisie pour l'utilisateur
user_question = st.text_input("Posez votre question sur les remboursements :", placeholder="Ex: Quel est le délai pour un remboursement ?")
# 3. Créer l'agent (Modifié pour utiliser le Knowledge)
chercheur = Agent(
role="Expert en Service Client",
goal="Fournir des réponses précises basées exclusivement sur les documents de remboursement fournis",
backstory="Tu travailles au service après-vente. Ta force est de trouver la règle exacte dans les PDF pour aider les clients.",
verbose=True,
allow_delegation=False,
knowledge_sources=[pdf_source] # <--- On lie le PDF à l'agent ici
)
# 4. Lancer l'action
if st.button("Envoyer"):
if user_question:
with st.spinner("Recherche dans les documents en cours..."):
tache = Task(
description=f"En utilisant les documents à ta disposition, réponds à cette question : {user_question}",
agent=chercheur,
expected_output="Une réponse claire, polie et basée sur les faits du document."
)
# Note : On ajoute le knowledge au niveau de la Crew également
equipe = Crew(
agents=[chercheur],
tasks=[tache],
knowledge_sources=[pdf_source]
)
resultat = equipe.kickoff()
st.markdown("---")
st.subheader("Réponse officielle :")
st.write(resultat.raw)
else:
st.warning("Veuillez entrer une question.")
6. L'interface : app.py
Dans VS Code toujours, nous créons le fichier app.py. Ce fichier sert de "chef d'orchestre". Il affiche notamment les boutons à l'écran.
import streamlit as st
from customer_service_crew import customer_service_crew
st.title("Assistant Client Intelligent ????")
# Zone de saisie
customer_request = st.text_area("Collez la demande du client ici :")
if st.button("Générer une réponse"):
if customer_request: # On vérifie que le champ n'est pas vide
with st.spinner("Les agents analysent la demande..."):
# On lance votre CrewAI avec les inputs
result = customer_service_crew.kickoff(inputs={'customer_request': customer_request})
st.subheader("Proposition de réponse :")
st.write(result.raw)
st.success("Analyse terminée !")
else:
st.warning("Veuillez coller une demande client avant de générer.")
Activer les agents
Pour tester le "cerveau", nous tapons : python main.py. Pour lancer l'application web dans PowerShell, nous tapons :
python -m streamlit run app.py.
Une fenêtre s’ouvre dans le navigateur. Nous testons en posant des questions en rapport avec le PDF envoyé : "Je souhaite être remboursé pour ma commande n°12345 car le produit est arrivé cassé. Quels sont les délais et les conditions ?"

La réponse est bien structurée. On voit dans PowerShell que l'agent classificateur identifie l'intention "Facturation/SAV". Le spécialiste lit le fichier conditions_remboursement.pdf. Le rédacteur liste les étapes au client de manière polie.
Notons qu’au cas où vous auriez prévu d'ajouter souvent des documents dans le dossier knowledge, on peut demander à Python de lister automatiquement tous les fichiers qui finissent par .pdf.
import os
# On récupère automatiquement tous les fichiers PDF du dossier knowledge
folder_path = "knowledge"
pdf_files = [os.path.join(folder_path, f) for f in os.listdir(folder_path) if f.endswith('.pdf')]
pdf_source = PDFKnowledgeSource(
item_id="base_connaissance_globale",
file_paths=pdf_files
)
Mettre le système multi-agents en production
Vous pouvez intégrer le système à un CRM (Salesforce, HubSpot) ou à un outil de ticketing (Jira Service Management, Freshdesk) pour créer des tickets, mettre à jour des statuts ou enregistrer les interactions.
