Accueil / Articles / Au-delà de la boîte de chat : architecture d’un agent IA WhatsApp sur Google ADK

Au-delà de la boîte de chat : architecture d’un agent IA WhatsApp sur Google ADK

Comment un assistant WhatsApp de production combine des agents spécialisés Google ADK, RAG, des outils déterministes, l’état de session, le transfert à un humain et une évaluation basée sur la trajectoire.

2371 mots

La plupart des démos d’IA se résument à une boîte de texte connectée à un modèle : une question est saisie, une réponse fluide est générée, et le public est satisfait. Un produit sur lequel comptent des clients réels présente une liste bien plus longue de exigences. Il doit se souvenir des conversations, travailler avec des données en temps réel de l’entreprise, prendre des actions, surmonter les pannes et transférer le client à un humain lorsque l’automatisation ne suffit pas.

Cet article décrit en détail l’architecture d’un assistant de production qui fonctionne au sein de WhatsApp pour un marché de recharge de véhicules électriques au Sri Lanka. Il sert les conducteurs de véhicules électriques, les propriétaires qui pourraient installer des chargeurs, ainsi que ceux qui souhaitent simplement en apprendre davantage sur la recharge de véhicules électriques. À la fin, vous disposerez d’un plan concret des éléments entourant le modèle, ainsi que d’un ensemble de règles de conception que vous pourrez réutiliser dans votre propre agent, quel que soit le canal dans lequel il fonctionne.

Pourquoi le canal influence le produit

L’équipe a choisi WhatsApp afin que personne n’ait à installer une autre application juste pour poser une question. Les utilisateurs cibles sont déjà présents sur WhatsApp : ils savent comment envoyer un message, partager une localisation, enregistrer un contact et répondre à un message spécifique dans une discussion. Rencontrer les utilisateurs là-bas élimine complètement le problème d’intégration. Au lieu d’apprendre aux gens à utiliser un produit d’IA, l’assistant apparaît dans un outil qu’ils comprennent déjà.

Ce choix impose également des contraintes auxquelles un chatbot en ligne n’est jamais confronté :

  • Les réponses doivent être courtes, car des réponses longues alourdissent l’utilisation sur un téléphone.
  • Les messages doivent arriver à un rythme naturel, et non sous forme d’un long bloc de texte.
  • Les demandes de localisation doivent utiliser l’interface native de partage de localisation de WhatsApp.
  • Les coordonnées de contact doivent apparaître sous forme d’une vraie fiche de contact, et non comme du texte collé.

L’objectif est d’avoir une conversation qui ressemble à celles utilisées nativement sur WhatsApp, et non un chatbot de bureau intégré dans une application de messagerie. Gardez cela à l’esprit pour tout canal : les conventions d’interface de la plateforme font partie des spécifications, et non de simples éléments décoratifs.

Le chemin de la demande depuis le webhook jusqu’à la réponse

Le backend est écrit en Python à l’aide du Google Agent Development Kit (ADK) et de FastAPI. ADK permet de générer un serveur API prêt à l’emploi pour un agent, avec un support intégré pour exécuter les agents, gérer les sessions et transmettre les résultats sous forme d’événements. Ce serveur API fonctionne sur FastAPI et Uvicorn, ce qui facilite son extension avec un webhook WhatsApp personnalisé ainsi que des points de terminaison spécifiques à l’entreprise.

  • Un modèle, comme Gemini.
  • Des instructions qui définissent le rôle et les limites de l’agent.
  • Outils qui lui permettent de rechercher des données ou d’exécuter des actions.
  • Une session qui conserve la mémoire de la conversation.
  • Suivre un seul message du début à la fin rend le design concret :

    1. Un utilisateur envoie un message WhatsApp, et Meta le transmet au webhook FastAPI.
    2. Le backend analyse le message et le reflète dans Chatwoot afin que l’équipe d’assistance puisse suivre la conversation.
    3. Le backend recherche la session correspondant à cet utilisateur et transmet le message à ADK.
    4. ADK exécute le coordinateur, qui dirige la demande : les questions techniques vers l’agent EV, les questions relatives aux revenus vers l’agent tarification, les recherches de stations vers l’agent station.
    5. L’agent choisi soit recherche la base de connaissances Vertex AI, soit utilise un outil, par exemple pour interroger les données des stations, estimer les revenus, envoyer une carte de contact ou demander la localisation de l’utilisateur.
  • Lorsque la réponse est prête, FastAPI la formate en messages WhatsApp courts, les envoie via l’API de Meta et copie la réponse dans Chatwoot.
  • Remarquez à quel point le modèle lui-même occupe une place négligeable dans ce processus : l’analyse, la recherche de session, le routage, le formatage, la livraison et le miroirage relèvent tous de tâches classiques du backend.

    Un coordinateur, trois spécialistes

    L’assistant est organisé comme un coordinateur qui délègue des tâches à trois agents spécialisés :

    • Un agent chargé des infrastructures de véhicules électriques, pour les types de chargeurs, l’installation et les réglementations.
    • Un agent chargé des prix et des aspects commerciaux, pour les questions économiques liées à l’hébergement.
    • Un agent de recherche de stations, pour trouver des endroits de charge.

    Le seul rôle du coordinateur est de comprendre l’intention de l’utilisateur et de transférer la conversation au spécialiste compétent. Une question concernant les types de chargeurs est acheminée vers le service des infrastructures, une demande d’un propriétaire concernant les revenus potentiels est dirigée vers le service des tarifs, et une requête pour trouver des stations près de Galle est envoyée au service de recherche de stations. Ces transferts restent invisibles pour l’utilisateur, qui a l’impression de mener une seule conversation continue avec un seul assistant.

    L’alternative consistait en un seul agent de grande taille doté d’un prompt système long et de tous les outils associés. Cela fonctionne pour un prototype, mais à mesure que les outils et les flux de conversation s’accumulaient, la séparation des responsabilités présentait trois avantages : chaque prompt restait court, il était facile de savoir quel agent pouvait utiliser quel outil, et chaque flux pouvait être testé indépendamment. La séparation d’un coordinateur de ses spécialistes, l’un des modèles documentés d’orchestration des agents, rendait également les modifications moins coûteuses, car le flux de tarification pouvait être révisé sans avoir à modifier la recherche des postes.

    Il existe un coût qu’il convient de mentionner. Chaque décision de routage représente une nouvelle appel à un modèle qui peut échouer, ce qui fait que une question mal routée échoue d’une manière qu’un agent unique ne ferait jamais. C’est l’une des raisons pour lesquelles la stratégie d’évaluation décrite plus loin vérifie quel agent et quelle outil ont été choisis, et non seulement la formulation finale. Pour en savoir plus sur la manière dont le routage et les agents spécialisés s’intègrent, consultez les agents spécialisés, un routeur par mot-clé et l’interruption dans LangGraph.

    Ancre des réponses dans une base de connaissances contrôlée

    L’idée clé est la division du travail. Le modèle continue de composer la réponse, mais les informations proviennent de sources contrôlées par l’entreprise et peuvent être mises à jour sans avoir à réentraîner quoi que ce soit.

    Transformer la conversation en actions

    Le plus grand progrès a été de dépasser simplement la réponse aux questions. L’assistant dispose d’outils qui effectuent réellement des tâches. Il peut :

    • Interroger l’arrière-plan du marché pour savoir combien d’stations de charge existent près d’une ville donnée.
    • Envoyer une demande de localisation via WhatsApp.
    • Envoyer la carte de contact de l’entreprise.
    • Partager l’emplacement du bureau sous forme d’épinglette sur une carte.
    • Estimer les revenus potentiels pour quelqu’un qui envisage d’héberger une station de charge.
    • Marquer une conversation pour qu’un humain s’en occupe lorsque l’utilisateur en a besoin.

    Pourquoi le calcul des revenus repose sur du Python pur

    Le flux de revenus illustre la règle de conception la plus importante du système. L’assistant collecte d’abord des informations sur les biens de l’utilisateur ainsi que ses exigences en matière de facturation au cours d’une conversation. Il calcule ensuite la consommation énergétique mensuelle, les revenus attendus, le coût de l’électricité, le profit mensuel et le profit annuel.

    Ces calculs sont effectués à l’aide de Python déterministe, et non par le modèle linguistique. Les modèles sont peu fiables en matière d’arithmétique, et les chiffres financiers présentés à un client potentiel doivent être reproductibles et auditable. Le modèle gère le dialogue et extrait les données d’entrée ; le code produit les chiffres. Le résultat est transmis via un modèle structuré de WhatsApp, et l’information concernant le client potentiel est enregistrée dans Google Sheets.

    Utilisez le modèle pour les tâches linguistiques et de prise de décision, et utilisez un logiciel ordinaire pour tout ce qui exige une précision absolue.

    Cette règle s’applique bien au-delà des prix : le traitement des dates, la conversion de unités, les vérifications d’éligibilité et tout ce qui a une importance juridique ou financière doivent figurer dans le code appelé par le modèle, et non dans sa sortie.

    L’état de session fait partie de la logique du produit

    Une bonne conversation dépend de ce qui a précédé. L’assistant conserve une session distincte pour chaque numéro WhatsApp, et cette session contient le nom de l’utilisateur, son numéro de téléphone, l’option du menu qu’il a sélectionnée, les messages récents, l’état de sa localisation ainsi que l’ID du dernier message.

    Le stockage de l’ID du dernier message permet au système de comprendre les réponses à un message de menu spécifique, ce que font constamment les utilisateurs WhatsApp. L’état de session permet également aux flux en plusieurs étapes de se dérouler naturellement. Par exemple, le transfert de localisation s’effectue comme suit :

    1. Demander à l’utilisateur s’il souhaite partager sa localisation.
  • Attendez l’arrivée du message de localisation de WhatsApp.
  • Enregistrez les coordonnées dans la session.
  • Reprenez la conversation de configuration là où elle s’est arrêtée.
  • Sans cet état, chaque message serait considéré comme le début d’une nouvelle conversation. La mémoire dans un agent n’est pas une fonction optionnelle ; elle définit le comportement du produit et mérite autant d’attention en termes de conception que n’importe quelle autre fonctionnalité.

    Mise en forme pour un petit écran

    Une leçon surprenante a été que même une réponse techniquement correcte pouvait sembler erronée simplement en raison de sa forme. Les modèles ont tendance à générer de longs paragraphes, des listes Markdown et plusieurs idées regroupées en un seul bloc. Cela se lit bien sur un ordinateur de bureau mais mal dans une bulle de chat.

    Une couche de mise en forme dédiée s’occupe de cela. Elle :

    • Convertit le Markdown en la syntaxe de mise en forme propre à WhatsApp.
    • Détecte les listes cachées au sein d’un texte continu.
  • Les reconstitue sous forme de points lisibles.
  • Divise les réponses longues en plusieurs messages plus courts.
  • De courtes pauses entre les parties donnent au lecteur le temps d’assimiler chaque idée. Il ne s’agit pas de simuler une frappe humaine, mais plutôt d’ajuster le rythme. Les indicateurs de frappe, envoyés via l’API Meta, montrent qu’une réponse est en cours de préparation.

    L’assistant réagit également à certains messages avec un emoji, et le fait de manière sélective. Un modèle léger comme Flash Lite décide si un message mérite une réaction, et si c’est le cas, la réaction est envoyée via l’API Meta. Les messages émotionnels, excitants, amusants ou significatifs peuvent en recevoir une ; les messages routiniers tels que « okay », « thanks » ou des instructions simples n’en reçoivent généralement pas. L’utilisation d’un modèle petit et peu coûteux pour cette décision secondaire permet de maintenir une faible latence et des coûts réduits, tandis que les agents principaux s’occupent du contenu. De tels détails sont mineurs individuellement, mais ensemble ils déterminent si le produit semble naturel.

    Préserver un lien avec un humain

    L’automatisation ne doit jamais devenir un obstacle entre les clients et l’entreprise. Chaque conversation reçue est synchronisée avec Chatwoot, et les réponses de l’assistant y sont également ajoutées, afin que l’équipe d’assistance voie toujours exactement ce qui a été dit.

    Lorsqu’un utilisateur demande à parler à une personne réelle ou montre des signes de frustration, l’assistant déclenche un processus d’intervention humaine qui enregistre la demande, ainsi que la question de l’utilisateur, pour que l’équipe puisse s’en occuper. Comme toute la conversation est déjà reflétée, la personne qui prend le relais n’a pas besoin de demander à l’utilisateur de se répéter.

    L’automatisation doit éliminer le travail répétitif, pas l’accès à une personne.

    Travail de fiabilité en dehors de la conversation

    Le système envoie également des campagnes de modèles WhatsApp sortants, ce qui soulève un problème subtil : une diffusion promotionnelle ne doit jamais interrompre quelqu’un qui est en pleine conversation de support. Avant d’envoyer, le système vérifie quand chaque destinataire a interagi pour la dernière fois avec l’assistant. Ceux qui discutaient il y a peu restent temporairement en dehors du processus : leur message est conservé, enregistré dans SQLite, et mis à disposition d’un point de terminaison de tentative ultérieure qui pourra le envoyer plus tard.

    Autour de cela se trouvent les fonctionnalités peu glamour dont tout service a besoin :

    • Déduplication des messages reçus, car les webhooks peuvent livrer le même événement plus d’une fois.
    • Surveillance de la santé du système.
    • Gestion du renouvellement des tokens d’accès.
    • Contrôles CORS sur les points de terminaison HTTP.
    • Déploiement basé sur Docker.
    • Suivi des erreurs avec Sentry.

    Aucun de ces éléments ne impressionnerait personne lors d’une démonstration. Tous deviennent essentiels dès que la démonstration se transforme en un service sur lequel les clients comptent.

    Tester le comportement, pas seulement le texte

    Les agents sont plus difficiles à tester que les fonctions ordinaires, car la même entrée peut produire des sorties légèrement différentes. Pire encore, les modes de défaillance ne sont pas évidents à partir du texte final. Une réponse peut sembler correcte alors qu’elle a fait appel au mauvais outil, ou l’outil adéquat peut être utilisé mais le résultat communiqué de manière inadéquate.

    Par conséquent, l’ensemble d’évaluation utilise des conversations simulées couvrant des questions relatives à l’infrastructure, aux processus de tarification, ainsi que des échanges entre spécialistes. Les vérifications examinent le parcours suivi par les outils, c’est-à-dire quels agents et outils ont été invoqués dans quel ordre, et non seulement la formulation de la réponse finale.

    Les modifications des prompts sont gérées de la même manière. Au lieu d’éditer manuellement le prompt système, l’équipe a expérimenté une boucle d’optimisation dans laquelle des instructions candidates sont évaluées à l’aide d’un ensemble fixe de conversations, y compris l’optimisation des prompts basée sur GEPA. Ces candidates sont testées contre des questions d’entraînement, et un évaluateur indépendant alimenté par Gemini attribue une note à chaque réponse en fonction de sa précision et de sa personnalité. Cela transforme le travail sur les prompts en quelque chose qui ressemble davantage à l’ingénierie : au lieu de conserver une modification simplement parce qu’elle semble meilleure, on peut comparer le comportement à travers un ensemble de conversations reproductibles. Une précaution s’applique à toute configuration où un modèle sert d’évaluateur : cet évaluateur possède ses propres biais, il est donc utile de vérifier ses notes par rapport au jugement humain avant de lui faire confiance pour des décisions importantes.

    Points clés

    • Le modèle n’est qu’un composant ; la majeure partie du travail d’ingénierie concerne le routage, la récupération des données, l’état du système, les outils, le formatage, la gestion des pannes et leur escalade.
    • Divisez un agent en pleine expansion en un coordinateur et des spécialistes chargés de tâches spécifiques dès que les prompts et les listes d’outils deviennent difficiles à gérer, puis testez le routage lui-même.
    • Fondez les réponses factuelles sur une base de connaissances que vous contrôlez, et conservez les tâches précises telles que les calculs dans du code déterministe.
    • Considérez l’état de la session et le formatage spécifique aux canaux comme faisant partie intégrante de la logique du produit.
    • Préservez toujours un chemin visible et peu contraignant menant à un humain.
    • Évaluez les trajectoires des outils au cours d’un ensemble de conversations fixe afin que les changements de prompts puissent être mesurés plutôt qu’imaginés.

    En enveloppant une requête dans un appel API, on obtient une démonstration. Un agent fiable est un système complet dans lequel les modèles de langage, les données, les outils, la conception du produit et l’ingénierie backend traditionnelle accomplissent chacun la tâche pour laquelle ils sont les plus compétents.

    Lectures complémentaires