Streamlit révolutionne l'interface de réservation IA avec LangGraph

Le brief IA que les pros lisent chaque soir
Les 7 actus IA du jour, décryptées en 5 min. Gratuit.
Inclus dès l'inscription : notre sélection des meilleurs guides & comparatifs IA.
Choisis ton rythme
Gratuit · Pas de spam · Désabonnement en 1 clic
Une nouvelle dimension pour l'agent IA LangGraph
Dans un précédent article, il a été décrit comment un agent IA, basé sur la technologie LangGraph, a été développé pour automatiser les sessions de réservation de services clients en seulement 15 minutes. Cet agent est conçu pour gérer l'ensemble du processus de réservation, imitant ainsi le rôle d'un véritable représentant du service client.
L'agent, construit sur LangGraph, est capable de réaliser plusieurs tâches essentielles. Il répond aux questions des clients, comprend leurs besoins spécifiques, calcule le coût du service et informe le client de ce montant. De plus, il gère l'acceptation ou le refus du client, propose des créneaux horaires optimisés et, enfin, confirme et enregistre le rendez-vous.
De l'interface en ligne de commande à Streamlit
Dans sa première version, l'agent fonctionnait via une interface en ligne de commande Python, principalement utilisée pour tester ses fonctionnalités. Bien que cette méthode ait été efficace pour les tests, elle ne représentait pas la meilleure manière de démontrer une expérience utilisateur orientée client.
Pour ceux qui souhaitent explorer le code source complet de ce projet, il est disponible sur GitHub sous le nom de customer-service-agent. Les utilisateurs sont encouragés à cloner le dépôt et à tester l'agent par eux-mêmes.
Cet article se concentre sur la création d'une interface Streamlit, propre et interactive, qui viendra se greffer sur l'agent LangGraph existant.
Streamlit : Une interface utilisateur améliorée
En termes d'implémentation, Streamlit se distingue peu d'une interface en ligne de commande Python. Les deux servent de cadre pour l'agent LangGraph. Cependant, Streamlit se démarque par sa convivialité et son aspect visuel attrayant.
L'interface en ligne de commande collectait des entrées, invoquait le graphe et affichait les réponses. La page Streamlit, quant à elle, réalise les mêmes opérations tout en affichant des informations structurées extraites de l'état du graphe, telles que les détails actuels de la réservation, le devis, et les boutons d'acceptation.
L'architecture de l'application reste inchangée. Streamlit se contente de présenter l'état à l'utilisateur et de renvoyer les actions de l'utilisateur à l'agent.
Configuration de Streamlit avec Poetry
Pour gérer les dépendances, poetry est utilisé, ce qui permet d'installer Streamlit facilement avec la commande suivante :
poetry add streamlit
Cette commande met à jour les fichiers pyproject.toml et poetry.lock. Ensuite, un nouveau fichier streamlit_app.py est créé.
Le processus commence par l'importation du constructeur de graphe, des modèles et des utilitaires d'observabilité.
from __future__ import annotations
from datetime import datetime
from typing import Any
from uuid import uuid4
import streamlit as st
from dotenv import load_dotenv
from langchain_core.messages import AIMessage, HumanMessage
from langchain_openai import ChatOpenAI
from customer_service_agent.graph import build_graph
from customer_service_agent.models import (
from customer_service_agent.observability import (
create_langfuse_handler,
Séparation logique et initialisation de l'état
Le graphe de l'agent ne contient aucune logique spécifique à Streamlit, ce qui est crucial pour permettre son exécution à partir de différentes interfaces, qu'il s'agisse d'une ligne de commande, d'une API, de WhatsApp ou d'un autre frontend.
Le graphe nécessite l'initialisation d'un Agent State. Ainsi, dans streamlit_app.py, l'état initial est défini comme suit :
INITIAL_STATE: AgentState = {
"booking_details": BookingDetails(),
"calculated_price": None,
"time_options": [],
"selected_slot": None,
"status": "gathering_info",
Après le premier message du client, le checkpointer de LangGraph conserve l'état. Streamlit relance l'ensemble du script Python à chaque interaction utilisateur, ce qui empêche l'utilisation de variables locales. Pour préserver la conversation, session_state est utilisé.
Initialisation de la session
La session est initialisée de la manière suivante :
def initialize_session() -> None:
if "graph" in st.session_state:
llm = ChatOpenAI(
model=os.getenv("OPENAI_MODEL", "[gpt-4o](/dossier/openai)-mini"),
handler = create_langfuse_handler()
st.session_state.graph = build_graph(llm)
st.session_state.handler = handler
st.session_state.config = graph_config(
st.session_state.agent_state = INITIAL_STATE.copy()
st.session_state.started = False
Cette fonction vérifie si le graphe a déjà été créé pour la session de navigateur actuelle. Sans cette vérification, chaque exécution de Streamlit remplacerait le graphe.
La fonction graph_config génère un UUID utilisé comme thread_id, essentiel pour LangGraph afin d'identifier une conversation. Si un nouveau UUID était généré à chaque exécution, LangGraph considérerait chaque message comme une nouvelle conversation.
Gestion de l'entrée utilisateur
La fonction _invoke gère l'entrée utilisateur :
def _invoke(customer_text: str) -> None:
"""Soumettre un tour client au graphe et conserver son dernier état."""
graph_input: dict[str, Any] = {"messages": [HumanMessage(content=customer_text)]}
if not st.session_state.started:
graph_input.update(INITIAL_STATE)
graph_input["messages"] = [HumanMessage(content=customer_text)]
st.session_state.started = True
result = st.session_state.graph.invoke(graph_input, config=st.session_state.config)
st.session_state.agent_state = result
flush_langfuse(st.session_state.handler)
except Exception:
st.session_state.started = bool(st.session_state.agent_state.get("messages"))
st.error("L'assistant n'a pas pu traiter cette demande. Veuillez réessayer.")
Cette fonction envoie l'action du client à l'agent LangGraph et enregistre l'état résultant pour l'interface Streamlit. L'action peut être une entrée de chat ou un clic sur un bouton.
Le message du client est transformé en HumanMessage de LangChain. Les messages utilisent le réducteur add_messages de LangGraph, permettant d'ajouter de nouveaux messages à la conversation existante.
Pour le premier message, le graphe est initialisé avec l'INITIAL_STATE défini précédemment, incluant des détails de réservation vides, des options de planification, un prix et le statut initial.
Exécution et mise à jour de l'état
Chaque nouvelle action client entraîne l'invocation du graphe et la mise à jour de son état avec le résultat :
result = st.session_state.graph.invoke(graph_input, config=st.session_state.config)
st.session_state.agent_state = result
Cela permet de traiter le message du client à travers le graphe. L'état retourné est stocké dans la session de Streamlit pour que la page puisse afficher les derniers détails des messages, le résumé de réservation, le prix, les options de rendez-vous et le statut.
Rendu des composants visuels
Enfin, plusieurs fonctions de rendu (_render...()) sont définies dans streamlit_app.py pour convertir l'état actuel de LangGraph en composants visibles de Streamlit.
def _render_messages(state: AgentState) -> None:
if not state.get("messages"):
with st.chat_message("assistant"):
"Bonjour ! Je peux vous aider à réserver un nettoyage de maison ou de canapé."
"Dites-moi ce dont vous avez besoin, y compris la taille et l'adresse du service."
for message in state["messages"]:
if isinstance(message, HumanMessage):
elif isinstance(message, AIMessage):
role = "assistant"
with st.chat_message(role):
st.write(str(message.content))
Par exemple, la fonction _render_messages affiche l'historique de la conversation sous forme de bulles de chat Streamlit. Elle reçoit la conversation à travers le dernier état de LangGraph en utilisant state["messages"]. Si la conversation n'a pas encore de messages, la fonction affiche un message d'accueil initial.
Mise en œuvre et test de l'interface
Après avoir parcouru streamlit_app.py pour comprendre la structure de la page, il est temps de la voir en action. Pour tester l'agent localement, la commande suivante est utilisée :
poetry run streamlit run customer_service_agent/streamlit_app.py
Cela ouvre une page à l'adresse http://localhost:8501/. La page présente une interface utilisateur interactive et intuitive.
Pour tester l'agent, une OPENAI_API_KEY est nécessaire. Cela implique des frais minimes pour les tests.
Exemple de conversation
Dans un exemple de chat, l'agent demande l'adresse si elle n'est pas fournie dans le premier message. Si l'adresse est incluse dès le début, l'agent n'a pas besoin de la redemander. Après acceptation du devis, l'agent propose trois options de rendez-vous et complète la réservation.
Perspectives d'amélioration
Bien que l'interface actuelle soit fonctionnelle et agréable, il existe encore de nombreuses possibilités d'amélioration pour la rendre plus conviviale. Des fonctionnalités supplémentaires, telles que l'intégration avec WhatsApp, sont envisagées. Ce projet pourrait même évoluer en un produit commercialisable pour certaines entreprises locales.
Restez attentifs aux développements futurs et merci de votre lecture !
Brief IA — L'actualité IA en français
L'essentiel de l'actualité de l'intelligence artificielle, décrypté et expliqué chaque jour.