Brahim Bousnguar

Projet perso

Where's my sofa?

Un agent de service client sur MuleSoft Agent Fabric, avec son propre serveur MCP

Comment ça marche
La configuration

Where's my sofa? est un agent de service client pour un magasin de meubles qui fabrique la plupart de ses pièces sur commande. Les clients lui demandent où en est leur commande, déplacent une livraison réservée ou signalent un dommage, en A2A. Il tourne sur MuleSoft Agent Fabric, et tout ce qu'il touche passe par Mule : un serveur MCP devant une System API.

Mon métier, c'est l'intégration MuleSoft, et il n'y a pas encore d'agent dedans. MuleSoft avance vite sur les agents (Agent Fabric, Agent Script, un connecteur MCP), alors j'ai construit le plus petit vrai cas d'usage possible, de bout en bout, en API-led. Le magasin, ses produits et ses clients sont inventés.

Le modèle classe, le graphe décide

Un meuble fait sur commande, c'est un bon test pour un agent. « Où est mon canapé ? » demande de croiser la commande, l'étape de fabrication à l'atelier et la réservation de livraison. Et certaines décisions ne doivent jamais revenir à un modèle : à qui appartient la commande, quels créneaux sont libres, et qu'une livraison à moins de 48 heures ne bouge plus.

Le broker est donc un graphe Agent Script, et le modèle ne reçoit que ce qui demande du langage :

  • understandRequest fait un seul appel LLM, sans outil : intention, numéro de commande, email, créneau souhaité.
  • Un routeur, sans LLM, choisit le chemin et vérifie que le numéro de commande et l'email sont là.
  • orderStatus n'a que les deux outils de son chemin, avec l'email lié par le graphe : le modèle ne peut pas viser la commande de quelqu'un d'autre.
  • Pour déplacer une livraison, un exécuteur lit les créneaux libres, un appel LLM choisit celui qui correspond, et un autre exécuteur la déplace. Le modèle choisit un créneau mais n'appelle jamais l'outil, et quand il faut demander quel créneau convient, la question est une réponse fixe.
  • Les réclamations, et les livraisons trop proches pour être déplacées, vont à des exécuteurs qui ouvrent un dossier avec des arguments fixes. Aucun modèle ne décide si un dossier est ouvert.

Les règles vivent dans la System API. Un mauvais email reçoit la même 404 qu'une commande inexistante : l'API ne confirme jamais qu'un numéro de commande existe.

Ce qu'il y a dedans

  • sofa-orders-sapi : une System API Mule sur un ERP simulé, avec ses règles en DataWeave.
  • sofa-care-mcp : une app Mule sur le connecteur MCP 1.7, cinq outils sur la System API, et une clé d'API vérifiée à l'ouverture de chaque session MCP.
  • Le broker Care Desk, déployé par Agent Fabric derrière Omni Gateway : contrôle du client ID, 60 requêtes par heure et par client pour plafonner la facture LLM, et un contexte utilisateur pour que chaque appelant ait sa propre mémoire de conversation.
  • gpt-5-mini via OpenRouter, avec un effort de raisonnement faible.

Ce qui a cassé

L'agent répondait parfois aux clients avec son propre raisonnement. Agent Fabric fait tourner ses nœuds LLM avec un humain dans la boucle : quand le modèle estime qu'il lui manque une information, la tâche s'arrête pour attendre le client, et le raisonnement du modèle devient la réponse. La solution a été de retirer cette décision au modèle : il remplit des champs, le graphe décide, et chaque question au client est une réponse fixe. Et le connecteur MCP 1.6 gardait un flux SSE ouvert pour chaque réponse, si bien que la découverte des outils par le broker expirait derrière la gateway. Le connecteur 1.7 répond avec un seul corps JSON.

L'éval vérifie le système, pas la réponse

Une réponse peut sonner juste et faire la mauvaise chose. scripts/eval.py envoie huit messages clients et photographie chaque créneau de livraison et chaque dossier de la System API avant et après chacun. Un déplacement ne passe que si cette commande-là a bougé vers ce créneau-là, et rien d'autre. Une injection de prompt sur la commande de quelqu'un d'autre ne passe que si rien n'a bougé.

Toute l'histoire, avec les passes d'éval : Un agent de service client sur MuleSoft Agent Fabric, où le modèle ne fait que parler.

Le lancer

Le dépôt contient les deux apps Mule, le réseau d'agents et les scripts de déploiement. Avec une org Anypoint qui a Agent Fabric, une connected app et une clé OpenRouter :

scripts/deploy-apps.sh                                                     # les deux apps Mule sur CloudHub 2.0
SETUP_GATEWAY=1 SOFA_CARE_MCP_URL=https://... scripts/deploy-network.sh    # gateway, publication, broker
scripts/ask.py                                                             # lui parler en A2A

demo/server.py sert la page de la vidéo : la conversation à côté des données de la System API.

Texte brut: wheres-my-sofa.md · Tous les projets

Contact

Écrivez-moi.

b.bousnguar@gmail.com

Intégration SAP Commerce Cloud, MuleSoft et Salesforce · Nantes · FR / EN