Construire un agent de support client LangGraph avec appel d’outils, approbation humaine et limites d’exécution
Un modèle pratique LangGraph pour le triage du support client : orienter les demandes, appeler des outils de recherche, mettre les remboursements en pause pour approbation humaine et limiter l’exécution du graphe.
Sur cette page
Le choix de conception : laisser l’agent rechercher, mais pas finaliser un remboursement
Un agent de support doit pouvoir recueillir les détails d’un achat et trouver les enregistrements correspondants, sans pouvoir émettre lui-même un remboursement. Dans LangGraph, cette distinction peut être exprimée dans le workflow : orienter la demande, appeler si nécessaire des outils de recherche en lecture seule, puis mettre le processus en pause avant l’opération de remboursement afin qu’une personne puisse l’approuver ou la rejeter.
Ce tutoriel construit ce modèle autour du triage du support client. Il utilise LangGraph pour l’orchestration, un modèle conversationnel capable d’appeler des outils pour la recherche, un point de contrôle humain avant le nœud à conséquences et une limite de récursion pour encadrer l’exécution du graphe. Le code est un modèle à adapter, et non une intégration OneMux testée.
Le tutoriel LangSmith fourni pour cet article construit un bot de support pour une boutique de musique numérique avec des sous-graphes distincts pour la recherche et le remboursement. Il décrit l’extraction des informations client et d’achat, la demande d’informations manquantes, ainsi que l’évaluation des réponses finales, des trajectoires d’outils et des étapes individuelles. Son exemple de remboursement utilise la suppression dans une base de données et ignore explicitement l’authentification ainsi que d’autres mesures de sécurité nécessaires en production. Ne reproduisez pas le comportement destructif de cette démonstration dans un système de support en production. Lire le tutoriel LangSmith sur l’évaluation d’un agent complexe.
Prérequis et limites
Installez LangGraph et l’intégration LangChain correspondante pour le fournisseur de modèle de votre choix. Le tutoriel source utilise langgraph et langchain[openai], mais l’exemple ci-dessous laisse volontairement l’initialisation du modèle spécifique au fournisseur. Vous avez également besoin d’une base de données ou d’un service proposant une recherche des achats en lecture seule et une opération de remboursement contrôlée par votre application.
Avant de connecter un modèle, définissez ce que chaque outil peut faire :
- Recherche : renvoyer uniquement les enregistrements que le client authentifié est autorisé à consulter.
- Préparation du remboursement : identifier la transaction et le montant exacts ; ne modifier aucun enregistrement.
- Exécution du remboursement : effectuer l’action approuvée dans le code de l’application, avec autorisation et journalisation d’audit.
Laissez l’authentification du client, l’autorisation, l’idempotence et la politique de remboursement en dehors du pouvoir discrétionnaire du modèle. Un nom de client ou un identifiant de facture généré par un modèle ne constitue pas une preuve d’identité.
Construire un graphe avec un point de contrôle humain
L’exemple utilise un modèle prenant en charge l’appel d’outils, un outil de recherche et un nœud de remboursement distinct. Remplacez les fonctions applicatives indiquées par vos propres appels de service autorisés. Le modèle et le schéma d’outils doivent être pris en charge par le endpoint que vous configurez ; la compatibilité dépend de la prise en charge documentée du endpoint et de ses paramètres. Cet extrait n’établit pas qu’un modèle ou une configuration OneMux donnée a été testé.
from typing import Annotated, Literal
from langchain.tools import tool
from langchain_core.messages import AnyMessage
from langgraph.graph import END, START, StateGraph
from langgraph.graph.message import add_messages
from langgraph.prebuilt import ToolNode, tools_condition
from langgraph.checkpoint.memory import MemorySaver
from langgraph.types import interrupt
from typing_extensions import TypedDict
# Replace with your provider's documented LangChain model setup.
# Confirm that the chosen endpoint supports tool calling and the parameters used.
model = make_your_chat_model().bind_tools([]) # bind the tools below in your application
class State(TypedDict):
messages: Annotated[list[AnyMessage], add_messages]
refund_request: dict | None
approval: str | None
@tool
def find_purchases(customer_reference: str) -> list[dict]:
"""Find purchases for an already authenticated customer."""
return authorized_purchase_lookup(customer_reference)
tools = [find_purchases]
model = make_your_chat_model().bind_tools(tools)
def assistant(state: State):
return {"messages": [model.invoke(state["messages"])]}
def prepare_refund(state: State):
# Build this from validated application data, not model-invented values.
request = build_validated_refund_request(state["messages"])
decision = interrupt({
"type": "refund_approval",
"request": request,
"instruction": "Approve or reject this exact refund request.",
})
if decision != "approve":
return {"approval": "rejected", "refund_request": request}
return {"approval": "approved", "refund_request": request}
def execute_refund(state: State):
if state.get("approval") != "approved":
return {"messages": [{"role": "assistant", "content": "The refund was not approved."}]}
result = issue_refund_safely(state["refund_request"])
return {"messages": [{"role": "assistant", "content": format_refund_result(result)}]}
builder = StateGraph(State)
builder.add_node("assistant", assistant)
builder.add_node("tools", ToolNode(tools))
builder.add_node("prepare_refund", prepare_refund)
builder.add_node("execute_refund", execute_refund)
builder.add_edge(START, "assistant")
builder.add_conditional_edges("assistant", tools_condition)
builder.add_edge("tools", "assistant")
builder.add_edge("prepare_refund", "execute_refund")
builder.add_edge("execute_refund", END)
graph = builder.compile(checkpointer=MemorySaver())
Il s’agit d’un exemple structurel, et non d’un graphe de routage complet : votre application doit orienter une intention de remboursement vérifiée vers prepare_refund et les questions ordinaires vers le chemin assistant/recherche. L’appel interrupt() met le graphe en pause et renvoie la demande d’approbation à l’appelant. Une interface de revue humaine doit afficher le client, la transaction, le montant et le contexte de la politique avant d’envoyer une décision. Reprenez le même thread avec le mécanisme Command(resume=...) de LangGraph et le même identifiant de thread. Persistez les points de contrôle de manière appropriée ; la persistance en mémoire est destinée au développement, pas aux workflows de production durables.
Un point essentiel du contrôle du flux : une interruption est une pause, pas un système d’autorisation. Vérifiez de nouveau la valeur d’approbation dans le nœud d’exécution du remboursement et assurez-vous que le service de remboursement vérifie lui-même l’autorisation, l’éligibilité de la transaction et les demandes en double.
Limiter l’exécution et rendre les erreurs visibles
Transmettez une limite de récursion lors de l’appel du graphe. Elle limite les super-étapes du graphe ; elle ne plafonne ni les tokens du modèle, ni la durée d’exécution des outils, ni le coût des requêtes à la base de données, ni le nombre de demandes utilisateur. Définissez des délais d’expiration et des limites de ressources distincts pour les appels au modèle et aux outils.
from langgraph.errors import GraphRecursionError
config = {
"configurable": {"thread_id": "support-case-123"},
"recursion_limit": 12,
}
try:
result = graph.invoke(
{"messages": [{"role": "user", "content": "I need help with a purchase."}]},
config=config,
)
except GraphRecursionError:
# Return a safe handoff or ask for clarification; log the trace for review.
result = {"status": "needs_human_review"}
Choisissez une limite en fonction du workflow attendu, puis testez à la fois l’exécution normale et les entrées susceptibles de provoquer des boucles. Évitez de relancer silencieusement un graphe arrivé à sa limite : les nouvelles tentatives peuvent répéter des appels d’outils si vos outils ne sont pas idempotents. Les outils de recherche en lecture seule peuvent être relancés plus sûrement que les opérations à effets de bord.
Évaluer le parcours, pas seulement la réponse
Le tutoriel LangSmith fourni identifie trois cibles d’évaluation utiles : la réponse finale (la réponse au client était-elle appropriée ?), la trajectoire (l’agent a-t-il suivi le parcours d’appels d’outils attendu ?) et l’étape individuelle (a-t-il choisi le bon outil pour une décision donnée ?). Pour le triage des remboursements, créez des cas avec des informations d’identité manquantes, plusieurs achats correspondants, une recherche sans résultat, une approbation rejetée et un remboursement approuvé.
Vérifiez que l’agent demande les informations nécessaires au lieu de les inventer ; qu’une recherche ne déclenche pas un remboursement ; et qu’une exécution est impossible sans approbation. Utilisez des services simulés ou de test pour l’évaluation afin que les tests ne modifient pas les véritables enregistrements clients. Le tutoriel source utilise un mode simulé pour ses opérations de base de données, mais décrit sa propre configuration de démonstration — et non une garantie de sécurité en production.
Utiliser OneMux pour accéder aux modèles
OneMux donne accès aux principaux modèles d’IA via une API compatible avec OpenAI. Si vous souhaitez disposer d’une interface API unique pour accéder aux modèles, consultez le guide de démarrage rapide OneMux, la documentation de l’API et les modèles disponibles. La compatibilité de ce workflow dépend de la prise en charge documentée de l’appel d’outils et des paramètres acceptés par le endpoint du modèle sélectionné. Vérifiez ces éléments avant le déploiement ; cet article n’affirme pas que l’exemple LangGraph a été testé avec OneMux.
Limites et résolution des problèmes
- Le modèle n’appelle pas d’outil : vérifiez que le endpoint sélectionné prend en charge l’appel d’outils et que le schéma de l’outil est transmis au format documenté.
- Le graphe boucle : examinez les transitions entre l’assistant et les outils, limitez le nombre d’étapes du graphe et assurez-vous qu’un résultat d’outil terminé modifie la décision suivante.
- L’approbation reprend le mauvais cas : utilisez un identifiant de thread stable associé au dossier de support et vérifiez le point de contrôle avant la reprise.
- Un remboursement est exécuté deux fois : ajoutez l’idempotence à la frontière du service et enregistrez la demande approuvée ainsi que son résultat.
- L’agent expose les enregistrements d’un autre client : corrigez l’autorisation dans le service de recherche ; une instruction dans le prompt ne constitue pas un contrôle d’accès.
Conclusion
LangGraph permet d’exprimer le triage du support sous forme d’étapes de workflow explicites, plutôt que de faire confiance à une seule réponse du modèle pour décider et agir. Maintenez la recherche en lecture seule, mettez les remboursements en pause, validez l’approbation au moment de l’exécution et limitez les étapes du graphe. Évaluez ensuite la réponse ainsi que le parcours suivi par l’agent. Ces contrôles rendent le workflow plus facile à inspecter, mais la sécurité et l’application des politiques en production restent de la responsabilité de l’application.
Sources
- LangSmith : évaluer un agent complexe — source de l’exemple de support pour une boutique de musique, de sa structure recherche/remboursement, de son mode simulé et de ses trois cibles d’évaluation.
FAQ
Comment exiger une approbation humaine avant qu’un agent LangGraph n’émette un remboursement ?
Mettez le graphe en pause avant le nœud d’exécution du remboursement avec une interruption LangGraph, présentez la demande validée à un réviseur, puis reprenez le même point de contrôle uniquement après une décision explicite. Vérifiez également l’approbation dans le nœud d’exécution et appliquez la politique dans le service de remboursement.
Une limite de récursion LangGraph plafonne-t-elle la durée d’exécution des outils ou les tokens du modèle ?
Non. Elle limite les super-étapes du graphe, et non l’utilisation de tokens du modèle, la durée des outils, le coût de la base de données ou le volume des demandes entrantes. Ajoutez des délais d’expiration et des limites de ressources indépendants.
Le modèle peut-il décider si un client est autorisé à obtenir un remboursement ?
Non. Considérez la sortie du modèle comme une entrée non fiable. Authentifiez le client et validez l’accès à la transaction ainsi que l’éligibilité au remboursement dans le code de l’application et des services.
Que faut-il évaluer dans un agent de support client ?
Évaluez la réponse finale, la séquence des appels d’outils et les étapes individuelles de sélection des outils. Incluez des cas d’informations manquantes, d’achat ambigu, d’approbation rejetée et de remboursement approuvé, en utilisant des services de test pour les effets de bord.
Articles liés
Guides
Créer un agent LangGraph à exécution bornée pour l’extraction avec validation de schéma
Créez un workflow LangGraph qui appelle un outil au besoin, s’arrête dans une limite d’exécution définie et renvoie des données structurées validées par un schéma Pydantic.
Guides
RAG agentique avec LangGraph : appels d’outils, attribution des sources et exécution limitée
Construisez un agent LangGraph de questions-réponses sur des documents qui décide quand effectuer une recherche, évalue le contexte, relance les recherches insuffisantes et fournit des réponses attribuées à leurs sources, sans exécution illimitée.
Guides
Créer un workflow n8n de modification de code avec approbation humaine et vérification des tests
Concevez un workflow n8n qui propose des modifications à un dépôt, demande à une personne d’autoriser l’écriture, puis vérifie le commit obtenu à l’aide de tests.
Guides
Cline avec un fournisseur compatible OpenAI pour un triage du support validé par un humain
Configurez Cline avec un fournisseur compatible OpenAI et OneMux pour le triage du support client, tout en soumettant chaque action destinée aux clients à une validation humaine.