GuidesOneMux

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