I built a team of AI agents for my after-sales service in 6 Python files

I built a team of AI agents for my after-sales service in 6 Python files

The multi-agent system organizes customer relations into specialized teams to handle complex requests faster and cleaner.

To manage customer relations, companies often use classic chatbots. While these conversational agents are limited to simple tasks, the multi-agent system makes it possible to work in specialized “teams”. Each agent collaborates to resolve complex, intersecting customer issues. The system acts autonomously instead of just responding. The question is how to build one. In this tutorial, we set up a multi-agent after-sales service system step by step, from installation of the environment to deployment, on a concrete case: the request for reimbursement for a broken product.

Let’s take the example of a user requesting a refund following receipt of a broken product. In this case, the Logistics agent will check the delivery, the after-sales service agent will validate the status of the product and the Financial agent will trigger the transfer.

At a technical level, simply, how does a multi-agent system adapted to customer relations work? To maintain the continuity of the exchange, the multi-agent system uses a short-term memory and a long-term memory, via the RAG, for “Retrieval-Augmented Generation”. Interactions are carried out in structured JSON format to guarantee interoperability. Using feedback loops, a “critical agent” can validate the response of a “performing agent” before sending it to the client.

Answer complex queries

To illustrate this, we are going to create a multi-agent system adapted to customer relations. From this perspective, we will set up, step by step, the root folder, the security file, the brain of the system, the engine, the interface and the memory. The final tree in our folder should look like this:

C:UsersadminMonProjetCrew
├── 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)

Note that the venv folder will be created automatically. Let’s also note that to follow this tutorial, we first need Python 3.10 or higher, the main programming language, Pip, the Python package manager, and an API key for an LLM (OpenAI in this case).

1. Preparing the root folder

In Windows, we open the terminal with PowerShell. We create our workspace by typing:

mkdir C:UsersadminMonProjetCrew
Nous nous déplaçons dedans : cd C:UsersadminMonProjetCrew Nous créons un environnement virtuel (venv) :
python -m venv venv. 

We activate it:

.venvScriptsactivate 

We install our library by typing:

pip install crewai langchain-openai streamlit

2. The security file: .env

At the root of the folder, we create a text file and name it .env, without the .txt extension. We save it in “all files”. To get the API key, we go to platform.openai.com. We choose “API”, not “ChatGPT”. Note that OpenAI no longer offers automatic free credits upon registration. For the key to work, you must add a minimum amount. Once the balance is positive, we left-click on “API keys”, then we paste it into the .env file:

OPENAI_API_KEY=sk-proj-VOTRE_CLE_ICI

3. The brain: customer_service_crew.py

We will launch the “brain”: customer_service_crew.py. To do this, we will create a physical file in VS Code. In File > Open Folder…, we select the MyCrewtestProject folder. We click on the “New File” icon (the little + next to your folder name) and name it customer_service_crew.py.

We insert this code there and save it:

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)

We see that the customer’s question (customer_request) will pass from hand to hand (from agent to agent) until the final result. Each of them has a limited scope to avoid errors. The classifier (classifier_agent) sorts and judges the urgency. classify_task must produce a precise format (JSON) for the machine to understand the urgency. The specialist (specialist_agent) has the right to delegate to find the concrete solution. research_task takes the label of the first agent and searches for “how to fix”. The writer (response_agent) transforms raw technical information into a polite and empathetic email. write_response_task takes the “how to fix” and writes the final message.

4. Memory: knowledge file

We create a folder named knowledge at the root of our folder. We insert a PDF file, here “conditions_remboursement.pdf”. In customer_service_crew.py, you will need to configure the Specialist agent to use a reading “tool”, like PDFSearchTool, pointing to this folder.

5. The engine: main.py

This file transforms the Python script into an interactive web application capable of reading PDF documents using RAG. Here, the “library” (pdf_source) points to the conditions_remboursement_exercise.pdf file. Streamlit, a Python library, also helps with data visualization. The name of the PDF must be adapted.

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. The interface: app.py

In VS Code still, we create the app.py file. This file serves as a “conductor”. It notably displays the buttons on the screen.

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.")

Enable agents

To test the “brain”, we type: python main.py. To launch the web application in PowerShell, we type:

python -m streamlit run app.py.

A window opens in the browser. We test by asking questions related to the PDF sent: “I would like to be reimbursed for my order no. 12345 because the product arrived broken. What are the deadlines and conditions?”

The answer is well structured. We see in PowerShell that the classifier agent identifies the “Billing/After-sales service” intent. The specialist reads the conditions_reimbursement.pdf file. The writer lists the steps to the client in a polite manner.

Note that if you plan to often add documents to the knowledge folder, you can ask Python to automatically list all the files that end in .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
)

Put the multi-agent system into production

You can integrate the system with a CRM (Salesforce, HubSpot) or a ticketing tool (Jira Service Management, Freshdesk) to create tickets, update statuses or record interactions.

Jake Thompson
Jake Thompson
Growing up in Seattle, I've always been intrigued by the ever-evolving digital landscape and its impacts on our world. With a background in computer science and business from MIT, I've spent the last decade working with tech companies and writing about technological advancements. I'm passionate about uncovering how innovation and digitalization are reshaping industries, and I feel privileged to share these insights through MeshedSociety.com.

Leave a Comment