Accueil / Articles

Création d’un assistant API agent : de l’hackathon à la version bêta.

Un assistant LangGraph qui explique une API, écrit du code et exécute des requêtes en lecture seule : deux modes, une boucle OData auto-réparatrice, une mémoire des artefacts, une évaluation par un juge LLM, un accès auto-service.

Éditeur : REACTAPP.TOP8 min de lecture1818 mots

Sources: From hackathon spark to production reality: building an agentic API assistant

Une équipe qui gère une API de gestion de flotte pour une entreprise de paiements a transformé un prototype issu d’un hackathon en un assistant bêta intégré à son portail de développement. L’idée : éviter que les intégrateurs aient à lire des pages de référence et à les traduire en code, et permettre à un agent conversationnel de gérer l’intégration à leur place. Voici comment un tel assistant est conçu, ce qu’il refuse délibérément de faire, et comment sa qualité est évaluée.

Cet assistant explique les points d’entrée, écrit du code dans n’importe quel langage utilisé par le développeur, planifie des workflows en plusieurs étapes et effectue des requêtes de lecture seule sur des systèmes en temps réel. Il remplace les documents statiques spécifiques à chaque langage ainsi que les index de recherche qui ne font que renvoyer vers des pages.

Pourquoi les documents statiques ne suffisent plus

Le logiciel de gestion des flottes et de la mobilité traite un volume important de données : l’activité des conducteurs, les stations-service, les transactions de cartes et la télémétrie des véhicules. Toute personne qui souhaite l’intégrer doit maîtriser des endpoints REST avancés, une syntaxe de filtrage, un vocabulaire spécifique au domaine ainsi que de longues séquences d’appels dépendants. Tous ces obstacles rendent plus difficile pour les partenaires de se développer avec cette plateforme.

Les développeurs comptaient sur des outils de documentation prêts à l’emploi pour lire les définitions des endpoints et sur des outils de test pour effectuer manuellement des appels. L’équipe conservait également des « recettes », des séquences fixes d’appels montrant comment accomplir des tâches en plusieurs étapes telles que la création d’un compte, l’intégration d’un conducteur ou l’attachement d’une carte. Ces méthodes fonctionnaient, mais trois faiblesses persistaient :

  • Lié à un langage spécifique. Présenter chaque flux de travail en utilisant cURL, Python, .NET, Java ou Go exigeait un travail manuel constant de la part des rédacteurs et des ingénieurs.
  • Brut aux bords. Il est impossible de documenter toutes les permutations de chaque flux de travail, si bien que les guides manquent souvent du cas précis d’un partenaire.
  • Frais de maintenance constants. Dès qu’un schéma API changeait, les pages devenaient obsolètes, ce qui prolongeait le processus d’intégration et alourdissait la file d’attente du support.

De l’idée de hackathon à deux modes

La démonstration de concept est née d’un hackathon interne en décembre 2025, autour d’une seule question : pourquoi demander aux développeurs de transformer des documents en code alors qu’un modèle peut comprendre directement leur intention ? Le résultat fonctionne comme un consultant en intégration toujours disponible, et non comme une boîte de recherche.

Pour des raisons de sécurité opérationnelle, la conception divise l’assistant en deux chemins de traitement distincts.

Mode conseiller gère les explications en une seule étape, les analyses approfondies de la documentation ainsi que la génération de code pour n’importe quel framework, y compris les appels de modification tels que POST, PUT et DELETE. Il génère du code mais ne le met jamais en exécution, ce qui permet à une personne de rester en contrôle de tout ce qui modifie les données.

Mode planification et exécution traite les requêtes de lecture complexes et multi-étapes et les exécute sur la plateforme en direct à l’aide d’outils du Model Context Protocol (MCP) en lecture seule.

Ce que voient réellement les partenaires

Si vous demandez au mode conseiller un extrait de code Python permettant de créer un pilote, il renverra une requête requests avec l’endpoint approprié, les en-têtes, le schéma du corps et un commentaire sur les droits nécessaires. Rien ne touche à l’API de production.

Le mode planification et exécution demande cinq conducteurs dont le prénom est John, et un planificateur réduit l’appel multi-filtre en une seule tâche : récupérer les conducteurs filtrés par prénom. Un exécuteur sélectionne l’outil MCP correspondant, construit les arguments OData ($filter=first_name eq 'John', $top=5), lance une requête GET en lecture seule et stocke la réponse complète dans un entrepôt d’artefacts. Le modèle ne voit qu’un résumé compact, tel qu’un identifiant d’artefact, un comptage de cinq éléments et une brève vue préliminaire. Un synthétiseur rédige ensuite une liste propre des cinq conducteurs correspondants.

Architecture : un cycle d’agents coopératifs

L’assistant est construit sur LangGraph en tant que machine à états cyclique. Un planificateur, des exécuteurs, des validateurs et un synthétiseur se relaient pour planifier, agir et vérifier chaque étape, en transmettant l’état et la mémoire partagés jusqu’à ce que le travail soit terminé. Quatre choix de conception se distinguent.

1. Un proxy en lecture seule pour la sécurité

La sécurité a guidé la conception dès le début. L’assistant ne peut pas exécuter de requêtes modifiant des données au sein de son propre environnement de exécution. Lorsqu’un utilisateur demande "créer une nouvelle carte pour le conducteur X", un routeur envoie la requête au nœud conseiller, qui renvoie un extrait structuré que le développeur peut copier, examiner et exécuter localement. Tout ce qui est exécuté réellement est limité aux requêtes GET. Des outils permettant d’écrire des données existent dans le code du serveur MCP, mais ils sont filtrés avant même que le modèle ne puisse les voir.

2. Orchestration de type superviseur

Le raisonnement et l’exécution se situent à des niveaux différents, coordonnés par un seul superviseur qui décide quel spécialiste interviendra ensuite au sein d’une boucle globale :

  • Une classe mode router classe l’intention et envoie chaque message soit au conseiller, soit au module de planification et d’exécution.
  • Un planificateur décompose une demande complexe en une liste de tâches liées aux paramètres cibles.
  • Un exécutant choisit l’outil MCP pour chaque tâche, assemble les arguments (y compris les filtres OData) et itère avec la couche d’outils jusqu’à ce que la tâche soit terminée ou que les tentatives soient épuisées.
  • Un synthétiseur fusionne les résultats de chaque tâche, que ce soient des données réelles ou des extraits de code de secours, en une seule réponse.

3. Une boucle qui répare son propre OData

Les modèles ont tendance à inventer des options de requête ou à altérer la syntaxe lorsqu’ils rencontrent un langage de filtrage structuré comme OData. L’équipe a choisi OData car il permet des requêtes de correspondance partielle flexibles sur des objets de mobilité complexes sans avoir à coder manuellement chaque combinaison, mais cette flexibilité entraîne des erreurs, c’est pourquoi une boucle de réparation à plusieurs niveaux a été ajoutée.

Si un analyseur de pré-vol identifie un problème de syntaxe, ou si une appel en temps réel renvoie une erreur API, le graphe détecte cet événement, active un compteur de tentatives par tâche et renvoie le message d’erreur exact dans le contexte du modèle. L’exécuteur lit son propre échec et enregistre une nouvelle requête corrigée. Lorsque les tentatives sont épuisées, la tâche revient en mode conseil afin que l’utilisateur obtienne néanmoins quelque chose d’utile.

4. Division de la mémoire en artefacts

Envoyer un gros envoi JSON, par exemple des milliers d’enregistrements d’actifs, dans la conversation épuise rapidement le budget de tokens, nuit à la précision du raisonnement et augmente les coûts. Ainsi, les réponses brutes restent dans un stockage d’artefacts backend isolé, et le modèle ne reçoit que de courts métadonnées de résumé indiquant les IDs des artefacts. Les questions ultérieures permettent d’accéder à des éléments spécifiques en recherchant ces IDs au niveau de la couche d’application, ce qui maintient le contexte du modèle restreint et ciblé.

Évaluation de la qualité

Changer une instruction ou un modèle sans provoquer de dégradation nécessite un benchmark automatisé. Le pipeline de l’équipe utilise un LLM en tant que juge pour répondre à une question par chaque modification : est-ce meilleur ou pire qu’avant ?

Le jeu de données est un ensemble de cas de test créés manuellement, répartis en quatre catégories : génération de code, connaissances factuelles, raisonnement et sécurité. Chaque cas comprend une grille d’évaluation explicite plutôt que simplement une question, permettant ainsi à l’arbitre d’évaluer la qualité de la réponse plutôt que de simplement la comparer à une chaîne de caractères attendue. L’arbitre est toujours un modèle différent de celui qui est testé, et il attribue une note sur une échelle de trois points : 10 pour une réponse correcte, 5 pour une réponse partielle et 0 pour une réponse incorrecte. Chaque exécution ajoute une ligne dans un fichier d’historique, étiqueté avec le commit Git, le modèle testé, le modèle arbitre, l’hash OpenAPI, l’hash du jeu de données et la version de l’instruction, de sorte que toute note peut être retracée jusqu’au code, aux spécifications et à l’instruction exacts qui la sous-tendent.

Selon l’équipe, l’assistant obtient en moyenne environ 9,4 sur 10 selon ce critère au cours des différentes sessions, et cette valeur sert de référence à défendre avant la mise en place de modifications. Cependant, la précision n’est pas le seul critère pris en compte. Chaque session enregistre également le temps de réponse afin de garantir une expérience réactive, ainsi que l’utilisation de tokens, qui correspond directement à la consommation du modèle. Toute modification qui détériore l’un ou l’autre de ces aspects est signalée avant la publication.

Protéger le budget et les capacités

Un assistant disponible en permanence qui interagit avec une API de production nécessite des limites visant à protéger à la fois le budget alloué au modèle et les services en amont. Trois niveaux de contrôle ont été mis en place :

  • Quotas par utilisateur. Les comptes de démonstration permettent 10 messages par jour, ce qui permet aux partenaires curieux de l’essayer sans consommation illimitée de modèles, et les incite à passer à un compte professionnel lorsqu’ils souhaitent effectuer des tâches réelles.
  • Appels dont l’origine est identifiable et traçable. Le trafic des partenaires s’exécute avec leurs propres identifiants, de sorte que chaque appel compte dans leur quota et apparaît dans leur propre journal d’audit. L’assistant ne se fait jamais passer pour un compte de service partagé, ce qui permet de tracer l’utilisation et de détecter les abus.
  • Essais de réparation capables d’interpréter les échecs. Lorsqu’une demande échoue, y compris en cas de réponse de limitation temporaire, le mécanisme de réparation renvoie l’erreur au modèle, augmente le compteur d’essais et planifie de nouveaux essais jusqu’à atteindre le maximum configuré. Lorsque tous les essais ont échoué, le système bascule en mode conseil.

Faciliter l’accès

Construire l’assistant n’était que la moitié du travail. Un accès sécurisé et sans effort était tout aussi important.

Les API de la plateforme utilisaient traditionnellement des identifiants de client standard, ce qui impliquait une configuration manuelle pour chaque nouveau client. Pour un assistant destiné aux partenaires externes, la méthode « soumettre une demande et attendre l’approbation du service technique » n’était pas acceptable. Demander aux développeurs de coller des tokens dans la conversation n’était pas non plus une solution, car cela rendait impossibles de distinguer les appels générés par l’assistant de ceux effectués manuellement, et compliquait l’attribution de l’utilisation ainsi que la surveillance de la sécurité. L’équipe avait besoin d’une stratégie adaptée à deux types d’utilisateurs : des partenaires souhaitant disposer d’un environnement de test sans friction, et ceux prêts à utiliser des données en temps réel, sans avoir à remplir de formulaires de configuration manuelle.

La solution a été un modèle à deux niveaux, auto-service, ajouté au système de connexion normal des développeurs.

  • Mode démo est la configuration par défaut. Les nouveaux utilisateurs peuvent immédiatement interagir avec l’assistant à l’aide de données synthétiques, sans aucune configuration, attente ou formulaire à remplir.
  • Mode partenaire : il s’active lorsque un développeur souhaite une intégration en temps réel. Les identifiants proviennent d’un processus d’autorisation unique et automatisé lié au compte et aux permissions du développeur lui-même. Une fois connecté, chaque demande est associée à cette identité et entièrement traçable, ce qui permet de savoir clairement qui appelle et par quel chemin.

Cela a éliminé le principal goulot d’étranglement lors de l’onboarding. Passer de « J’ai de la curiosité » à « Je fais une intégration » ne nécessite plus d’attendre dans une file d’attente technique.

Prochaines étapes

Le projet a débuté comme une expérience interne et est désormais en version bêta, réduisant le temps d’intégration pour les équipes de développeurs d’entreprise. Il fonctionne dans le portail des développeurs et a déjà intégré son premier groupe de partenaires.

L’orchestrateur lit des schémas OpenAPI standard, ce qui permet à l’architecture de s’adapter horizontalement. Les efforts actuels se concentrent sur la validation approfondie au sein du domaine de la mobilité, mais le noyau de routage est délibérément générique. Le plan d’action prévoit d’appliquer la même couche de conversation à d’autres divisions, telles que les plateformes de paiements et d’avantages sociaux, d’ajouter une validation OData plus poussée pour empêcher davantage de requêtes erronées avant qu’elles ne quittent l’assistant, ainsi que d’explorer la confirmation par un humain pour les opérations d’écriture, afin que l’assistant puisse finalement aider à modifier les workflows en toute sécurité.

Lectures complémentaires

  • Comment LangGraph exécute un graphique : de graph.invoke() jusqu’à la boucle Pregel — Une explication au niveau du code source de graph.invoke, stream, SyncPregelLoop, tick, la préparation des tâches et run_with_retry, ainsi qu’un exemple parallèle illustré à l’aide de versions de canal.