Accueil / Articles

Créer un agent de qualification des responsables en IA en Python à l’aide de FastAPI et Pydantic

Transformez les leads bruts en leads qualifiés : extraction structurée par LLM, validation avec Pydantic, évaluation basée sur des règles, stockage dans PostgreSQL, files d’attente et voie de révision humaine.

Éditeur : REACTAPP.TOP12 min de lecture2818 mots

Sources: I Built an AI Lead Filtering Agent in Python — From Raw Leads to Qualified Customers

La plupart des entreprises ne manquent pas de prospects. Leur problème réside dans le fait de les qualifier. Des centaines de demandes peuvent arriver via des formulaires en ligne, des campagnes par e-mail et des outils de marketing, et quelqu’un doit quand même ouvrir chacune d’elles, lire le message, déterminer ce que souhaite le client, vérifier son budget et décider s’il mérite une attention particulière. À mesure que le volume augmente, ce tri manuel devient coûteux.

La question pratique est de savoir si un agent IA peut prendre en charge les prospects entrants, comprendre leur intention, les tester selon des règles commerciales et diriger ceux qui conviennent vers le service des ventes. C’est possible, mais pas en plaçant chaque prospect dans un LLM et en comptant sur sa réponse. Un système fiable nécessite des résultats structurés, des règles explicites, une validation, un stockage et un flux de travail solide. Les sections suivantes montrent comment en créer un en Python.

Ce que fait le système

Le flux est simple : un lead arrive, le système l’interprète, l’évalue, enregistre le résultat et déclenche l’étape suivante.

Prenons ce message d’un client potentiel :

« Notre équipe commerciale a besoin d’un CRM sur mesure, pour environ 30 utilisateurs, à livrer en deux mois. Quel en serait à peu près le coût ? »

Une personne identifierait immédiatement plusieurs éléments :

  • il existe un besoin commercial clair
  • il s’agit d’un logiciel sur mesure
  • l’équipe compte environ 30 utilisateurs
  • un délai de livraison est prévu
  • le coût est la question principale

Un agent doit extraire les mêmes informations et aider l’équipe commerciale à décider de la prochaine étape. Il ne doit pas supposer que chaque message détaillé constitue un bon lead. Il doit évaluer les informations en fonction des critères réels de qualification de l’entreprise.

L’architecture

Le flux de travail prévu est représenté ci-dessous :

┌──────────────────┐
                  │   Incoming Lead  │
                  │ Website / Email  │
                  └────────┬─────────┘
                           │
                           ▼
                  ┌──────────────────┐
                  │  Lead Ingestion   │
                  │ Validate & Store  │
                  └────────┬─────────┘
                           │
                           ▼
                  ┌──────────────────┐
                  │   AI Extraction   │
                  │ Intent, Need,     │
                  │ Budget, Timeline  │
                  └────────┬─────────┘
                           │
                           ▼
                  ┌──────────────────┐
                  │ Business Rules    │
                  │ Qualification     │
                  └────────┬─────────┘
                           │
                           ▼
                  ┌──────────────────┐
                  │  Lead Scoring     │
                  │ Qualified /       │
                  │ Review / Reject   │
                  └────────┬─────────┘
                           │
                           ▼
                  ┌──────────────────┐
                  │ PostgreSQL        │
                  │ Store Result      │
                  └────────┬─────────┘
                           │
                           ▼
                  ┌──────────────────┐
                  │ Automation        │
                  │ CRM / Email /     │
                  │ Sales Notification│
                  └──────────────────┘

Une décision de conception est plus importante que les autres : séparer la compréhension par l’IA des décisions commerciales. Le LLM extrait les informations provenant du lead, tandis que votre propre code détermine comment ces informations influencent le processus de qualification. Grâce à cette séparation, le système est plus facile à tester, à déboguer et à modifier.

Étape 1 : Déterminer ce qui qualifie un lead

Les règles commerciales précèdent le code. Prenons l’exemple d’une agence de développement logiciel. Elle pourrait considérer qu’un lead est qualifié lorsque :

  1. le client a un véritable besoin en matière de logiciel
  2. ce besoin correspond aux services proposés par l’agence
  3. le message contient suffisamment de détails pour comprendre le projet
  4. le budget ou l’intention d’achat répond aux critères de l’agence
  5. le message n’est pas du spam ni une demande manifestement irrelevante

Ces règles sont indicatives, et une entreprise réelle doit définir ses propres seuils. Un formulaire rempli pourrait indiquer : le service est le développement personnalisé de CRM, le budget est de 500 000 ₹, le délai est de deux mois, la taille de l’entreprise est de 30 utilisateurs, l’intention est élevée, et la décision est qualifiée.

L’IA doit extraire les données. Les règles métier doivent prendre la décision finale.

Étape 2 : Créer le projet Python

Python convient à cette tâche grâce à son écosystème d’API, d’intégrations de LLM, de traitement de données et d’automatisation. La structure du projet est la suivante :

ai-lead-agent/
│
├── app/
│   ├── main.py
│   ├── config.py
│   │
│   ├── agents/
│   │   └── lead_agent.py
│   │
│   ├── schemas/
│   │   └── lead.py
│   │
│   ├── services/
│   │   ├── lead_service.py
│   │   └── scoring_service.py
│   │
│   └── db/
│       └── database.py
│
├── tests/
│   └── test_scoring.py
│
├── requirements.txt
└── .env

Installez les paquets requis :

pip install openai pydantic fastapi uvicorn python-dotenv

Les composants sont les suivants :

  • FastAPI pour l’API backend
  • Pydantic pour la validation structurée
  • l’API OpenAI pour l’exemple de LLM
  • PostgreSQL en tant que base de données de production
  • Python pur pour l’évaluation des leads

Le fournisseur de LLM peut être remplacé par un autre ultérieurement.

Étape 3 : Définir un schéma structuré pour les leads

Une erreur fréquente dans les applications d’IA est d’accepter du texte libre comme sortie finale. Une réponse de ce type est difficile à traiter de manière fiable :

This looks like a good lead.
The customer wants a CRM and seems interested.

L’objectif est un JSON prévisible. Créez app/schemas/lead.py et commencez par les importations :

from typing import Optional, Literal
from pydantic import BaseModel, Field

Ensuite, définissez les modèles, en commençant par le lead entrant et en poursuivant avec l’analyse que le modèle doit retourner :

class LeadInput(BaseModel):
    name: str
    email: str
    company: Optional[str] = None
    message: str
class LeadAnalysis(BaseModel):
    summary: str    service_type: Optional[str] = None    intent: Literal[
        "high",
        "medium",
        "low",
        "unknown"
    ]    budget: Optional[float] = None    currency: Optional[str] = None    timeline: Optional[str] = None    is_spam: bool = False    missing_information: list[str] = Field(
        default_factory=list
    )    qualification_notes: str    recommended_action: Literal[
        "contact_sales",
        "request_more_information",
        "reject",
        "manual_review"
    ]

Désormais, la réponse de l’IA a une forme définie. Si le modèle renvoie une valeur invalide, l’application peut la rejeter ou la gérer, au lieu de stocker silencieusement des données incorrectes.

Étape 4 : Créer la fonction d’analyse des prospects

Ensuite vient app/agents/lead_agent.py. Le modèle doit interpréter ce que dit le prospect et ne doit inventer aucun élément absent. Commencez par les importations :

import json
import os

Ensuite vient la fonction d’analyse. Elle envoie les données au modèle, demande une sortie conforme au schéma et valide ce qui est renvoyé :

from openai import OpenAIfrom app.schemas.lead import (
    LeadInput,
    LeadAnalysis
)
client = OpenAI(
    api_key=os.getenv("OPENAI_API_KEY")
)
SYSTEM_PROMPT = """
You are a lead analysis assistant for a software
development agency.Your task is to analyze incoming customer leads.Extract:
- Customer requirement
- Service type
- Buying intent
- Budget if explicitly mentioned
- Timeline if explicitly mentioned
- Spam indicators
- Missing informationRules:
1. Never invent a budget.
2. Never invent a timeline.
3. If information is missing, return null.
4. Return valid structured JSON.
5. Do not make a final business decision based
   only on assumptions.
"""
def analyze_lead(lead: LeadInput) -> LeadAnalysis:    user_prompt = f"""
    Analyze this incoming lead:    Name: {lead.name}
    Email: {lead.email}
    Company: {lead.company}
    Message: {lead.message}
    """    response = client.chat.completions.create(
        model="gpt-4o-mini",
        temperature=0,
        response_format={
            "type": "json_object"
        },
        messages=[
            {
                "role": "system",
                "content": SYSTEM_PROMPT
            },
            {
                "role": "user",
                "content": user_prompt
            }
        ]
    )    result = json.loads(
        response.choices[0].message.content
    )    return LeadAnalysis.model_validate(result)

Pourquoi la température est-elle à zéro

Pour l’extraction, on cherche de la cohérence, pas de la prose créative. Une température basse réduit les variations entre les réponses, mais ne garantit pas leur exactitude. C’est pourquoi la validation du schéma et les règles métier restent nécessaires.

Les noms des modèles ainsi que les fonctionnalités API évoluent également avec le temps. Lorsque vous mettez en œuvre cette solution en production, choisissez un modèle et une méthode de sortie structurée que votre fournisseur prend en charge actuellement.

Étape 5 : Ajouter les règles de qualification

Cette partie ne devrait pas être entièrement confiée au LLM. Supposons que les critères d’exemple de l’agence soient les suivants :

  • le projet concerne du développement logiciel pertinent
  • si un budget est indiqué, il doit être d’au moins ₹200 000
  • le message n’est pas de la publicité non sollicitée
  • il y a suffisamment d’informations pour comprendre la demande

Créez app/services/scoring_service.py, en commençant par l’importation :

from app.schemas.lead import LeadAnalysis

Ensuite, la fonction de notation, qui commence à zéro, collecte les raisons derrière chaque ajustement et renvoie immédiatement zéro pour le spam :

def score_lead(analysis: LeadAnalysis) -> dict:    score = 0
    reasons = []    if analysis.is_spam:
        return {
            "score": 0,
            "status": "rejected",
            "reasons": ["Spam detected"]
        }    if analysis.service_type:
        score += 25
        reasons.append(
            "Service requirement identified"
        )    if analysis.intent == "high":
        score += 30
        reasons.append(
            "High buying intent"
        )    elif analysis.intent == "medium":
        score += 15
        reasons.append(
            "Medium buying intent"
        )    if analysis.budget is not None:
        if analysis.budget >= 200000:
            score += 25
            reasons.append(
                "Budget meets example threshold"
            )
        else:
            reasons.append(
                "Budget below example threshold"
            )    if analysis.timeline:
        score += 10
        reasons.append(
            "Timeline provided"
        )    if analysis.missing_information:
        score -= 10
        reasons.append(
            "Some information is missing"
        )    score = max(0, min(score, 100))    if score >= 70:
        status = "qualified"    elif score >= 40:
        status = "review"    else:
        status = "unqualified"    return {
        "score": score,
        "status": status,
        "reasons": reasons
    }

Il s’agit d’un système de notation simple et illustratif. Une agence réelle pourrait prendre en compte d’autres facteurs :

  • la taille du projet
  • le secteur d’activité
  • le lieu
  • la disponibilité du service
  • le degré d’urgence pour le client
  • les interactions antérieures
  • la fiabilité du budget indiqué
  • les prospects dupliqués

Testez la fonction de notation sur des exemples réels avant de la laisser rejeter automatiquement les prospects.

Étape 6 : Connecter l’agent à FastAPI

Créez app/main.py et importez FastAPI :

from fastapi import FastAPI

Le reste du fichier relie le schéma, la fonction d’analyse et le service de notation derrière une interface d’accès :

from app.schemas.lead import LeadInput
from app.agents.lead_agent import analyze_lead
from app.services.scoring_service import score_lead
app = FastAPI(
    title="AI Lead Filtering Agent"
)
@app.get("/health")
def health_check():
    return {
        "status": "ok"
    }
@app.post("/analyze-lead")
def analyze_incoming_lead(
    lead: LeadInput
):    analysis = analyze_lead(lead)    score = score_lead(analysis)    return {
        "lead": lead,
        "analysis": analysis,
        "qualification": score
    }

Démarrer le serveur :

uvicorn app.main:app --reload

Ensuite, ouvrez les documents API interactifs :

http://127.0.0.1:8000/docs

De là, vous pouvez soumettre une opportunité et examiner la réponse structurée.

Étape 7 : Essayez une opportunité réaliste

Envoyez une demande de exemple comme celle-ci :

{
  "name": "Rahul Sharma",
  "email": "rahul@example.com",
  "company": "Example Technologies",
  "message": "We need a custom CRM for around 30 users. Our budget is approximately 500000 INR and we want to launch within 2 months."
}

Un résultat de extraction plausible ressemble à ceci :

{
  "summary": "Customer needs a custom CRM.",
  "service_type": "CRM development",
  "intent": "high",
  "budget": 500000,
  "currency": "INR",
  "timeline": "2 months",
  "is_spam": false,
  "missing_information": [],
  "qualification_notes": "Clear requirement, budget, and timeline.",
  "recommended_action": "contact_sales"
}

Le service de notation évalue ensuite les données extraites, en produisant des résultats tels que :

{
  "score": 90,
  "status": "qualified",
  "reasons": [
    "Service requirement identified",
    "High buying intent",
    "Budget meets example threshold",
    "Timeline provided"
  ]
}

Gardez à l’esprit que ce résultat est une illustration de ce à quoi vous pouvez vous attendre, et non une mesure issue d’une exécution réelle de l’API.

Étape 8 : Stocker les prospects dans PostgreSQL

Pour un usage professionnel réel, il ne suffit pas de conserver les résultats uniquement en mémoire ; une persistance est donc nécessaire. Une table simple commence ainsi :

CREATE TABLE leads (
    id BIGSERIAL PRIMARY KEY,

Les colonnes restantes présentent les détails du leader et l’analyse :

    name VARCHAR(150) NOT NULL,    email VARCHAR(255) NOT NULL,    company VARCHAR(255),    message TEXT NOT NULL,    service_type VARCHAR(255),    intent VARCHAR(20),    budget NUMERIC(14, 2),    currency VARCHAR(10),    timeline VARCHAR(100),    is_spam BOOLEAN DEFAULT FALSE,    ai_score INTEGER,    qualification_status VARCHAR(30),    analysis JSONB,    created_at TIMESTAMPTZ DEFAULT NOW()
);

La colonne analysis conserve la sortie structurée initiale de l’IA, ce qui est utile lorsque vous devez diagnostiquer pourquoi un lead a reçu une certaine classification.

Pour le déploiement en production, prévoyez également :

  • un identifiant unique par lead
  • un moyen de détecter les doublons
  • des index couvrant l’état et l’heure de création
  • un chiffrement ainsi qu’un contrôle d’accès strict, étant donné que les données des leads sont sensibles
  • des migrations de schéma
  • un journal d’audit

Étape 9 : Ajouter de l’automatisation

À ce stade, l’agent devient plus qu’une simple API. Imaginez ce flux :

New Lead
   │
   ▼
Save in PostgreSQL
   │
   ▼
Analyze with AI
   │
   ▼
Calculate Qualification
   │
   ├── Qualified ────────► Notify Sales
   │
   ├── Review ───────────► Human Review Queue
   │
   └── Unqualified ─────► Store for Reporting

Lorsqu’un prospect qualifié arrive, le système peut :

  1. stocker le prospect dans la base de données
  2. notifier l’équipe de vente
  3. créer un enregistrement CRM
  4. attribuer un représentant de vente
  5. planifier un suivi
  6. mettre à jour le statut du prospect

La couche d’automatisation peut être n8n, un travailleur en arrière-plan ou un système basé sur des files d’attente. En environnement de production, il n’est pas judicieux de faire dépendre l’ensemble du processus d’une seule requête HTTP synchrone. Une conception plus solide intègre une file d’attente au milieu du processus :

Lead API
   │
   ▼
Message Queue
   │
   ▼
Background Worker
   │
   ▼
AI Analysis
   │
   ▼
Database
   │
   ▼
Automation

Les prospects sont ensuite traités de manière asynchrone et les tâches échouées peuvent être réessayées.

Étape 10 : Ajouter une révision humaine

Ce peut être l’élément le plus important. L’IA peut interpréter à tort un prospect. Prenons ce message comme exemple :

« Pour l’instant, nous comparons les options de CRM et nous n’avons pas de budget défini, bien que nous souhaitions avoir une idée des prix. »

Le modèle pourrait qualifier l’intention comme moyenne ou élevée, tandis que l’entreprise préférerait diriger le prospect vers une personne plutôt que de le marquer automatiquement comme qualifié. C’est la raison de l’existence de trois statuts :

  • Qualifié : le prospect correspond aux critères et est transmis à l’équipe de vente.
  • En révision : le prospect contient des informations utiles, mais c’est un être humain qui doit se prononcer.
  • Non qualifié : le prospect ne répond pas aux critères définis.

La révision humaine est particulièrement utile lorsque :

  • aucun budget n’a été indiqué
  • Le besoin est vague.
  • Le modèle semble incertain quant à sa propre sortie.
  • Les détails du message se contredisent.
  • L’expéditeur travaille dans un secteur que l’entreprise ne dessert pas.

Un bon système d’IA ne cache pas l’incertitude. Il la rend visible.

Ce qui fait de cela un agent

Une simple appel à un LLM se résume à entrée, modèle, sortie :

Input → LLM → Output

Un flux de travail d’agent fait bien plus. Il comprend la tâche reçue, extrait les informations pertinentes, applique des outils ou des règles métier, choisit l’étape suivante, enregistre l’état, déclenche une action, et tente à nouveau ou escalade la situation en cas de problème. Pour le filtre de lead, le chemin complet s’affiche comme ceci :

Incoming Lead
      │
      ▼
AI Analysis
      │
      ▼
Business Rules
      │
      ▼
Qualification Decision
      │
      ▼
Action / Human Review

L’IA n’est qu’un composant. L’application backend rend l’ensemble du processus fiable, et cette distinction est importante.

Améliorations avant la mise en production

Une première version suffit pour visualiser le flux de travail, mais elle ne doit pas être livrée telle quelle.

Traitement en arrière-plan. Exécutez l’analyse des prospects via une file de tâches telle que Celery avec Redis, RQ, une file gérée en cloud ou un système de tâches basé sur une base de données. Cela facilite les tentatives de traitement répétées et gère de grands volumes de données.

Détection des doublons. Un prospect peut arriver deux fois, une fois depuis le site web et une fois à partir d’une campagne d’e-mail. Comparez les adresses e-mail, les noms d’entreprise et autres identifiants.

Versionnement des prompts. Stockez la version du prompt à côté de chaque résultat généré par l’IA. Lorsque les critères de qualification changent, vous pourrez ainsi déterminer quel prompt et quelles règles ont produit un résultat antérieur.

Observabilité. Suivez la latence de l’IA, les erreurs API, l’utilisation des tokens, le coût par lead, la répartition des résultats de qualification et la fréquence à laquelle les humains prennent le contrôle de l’agent.

Un ensemble de données d’évaluation. Collectez des leads réels accompagnés de labels vérifiés par des humains et testez le système à l’aide de ceux-ci. Cela en dit bien plus que de juger l’agent à partir d’un seul exemple positif.

Sécurité. Éloignez complètement les clés API du code frontend, vérifiez chaque demande entrante, protégez les données personnelles et restreignez l’accès aux leads.

La leçon de l’architecture

Créer un agent d’IA ne consiste pas seulement à appeler un LLM. La véritable ingénierie réside autour du modèle : un problème commercial clair, des données structurées, une validation fiable, des règles déterministes, la persistance, l’automatisation, ainsi que l’évaluation et le suivi par des humains. En omettant ces éléments, on obtient un chatbot qui semble intelligent mais qui ne résout pas le problème commercial.

Un filtre de leads ne doit pas se contenter de produire une réponse. Il doit générer un flux de travail utile et traçable. Le modèle comprend les messages clients complexes, Python exécute le flux, les règles commerciales définissent les critères de qualification, PostgreSQL stocke l’état, et l’automatisation relie le résultat à l’équipe de vente. Ensemble, ils transforment une démonstration d’IA en une application fonctionnelle.

Une étape logique suivante consiste à relier l’API à une source de prospects en temps réel, à ajouter des tâches en arrière-plan et à créer un tableau de bord permettant aux commerciaux de vérifier quels prospects sont qualifiés. L’objectif n’est pas de remplacer chaque décision commerciale par l’IA, mais de réduire le travail répétitif afin que les personnes puissent se concentrer sur les prospects qui le méritent.