Partager via


Agent IA

Les agents IA sont conçus pour effectuer des tâches spécifiques, répondre aux questions et automatiser des processus pour les utilisateurs. La complexité de ces agents est très variable, allant de simples chatbots à des copilotes, en passant par des assistants IA avancés sous la forme de systèmes numériques ou robotiques capables d'exécuter des flux de travail complexes de manière autonome. Cet article fournit des présentations conceptuelles et des exemples d’implémentation détaillés sur les agents IA.

Que sont les agents IA ?

Contrairement aux modèles de langage volumineux autonomes (LLMs) ou aux systèmes logiciels/matériels basés sur des règles, l’agent IA possède les fonctionnalités courantes suivantes :

  • Planification. L’agent IA peut planifier et séquencer des actions pour atteindre des objectifs spécifiques. L’intégration des LLM a révolutionné leurs capacités de planification.
  • Utilisation d’outils. L’agent IA avancé peut utiliser différents outils, tels que l’exécution de code, la recherche et les fonctionnalités de calcul, pour effectuer efficacement des tâches. L’utilisation des outils est souvent effectuée par le biais d’appels de fonction.
  • Perception. L'agent d'IA peut percevoir et traiter des informations provenant de son environnement, y compris des données visuelles, auditives et autres données sensorielles, ce qui le rend plus interactif et plus conscient du contexte.
  • Mémoire. L'agent IA possède la capacité de se souvenir des interactions passées (utilisation d'outils et perception) et des comportements (utilisation d'outils et planification). Il stocke ces expériences et procède même à une auto-réflexion pour éclairer les actions futures. Cette composante de la mémoire permet la continuité et l'amélioration des performances de l'agent au fil du temps.

Remarque

L’utilisation du terme « mémoire » dans le contexte de l’agent IA ne doit pas être confondue avec le concept de mémoire ordinateur (comme la mémoire volatile, non volatile et persistante).

Copilotes

Les copilotes sont un type d’agent IA conçu pour travailler avec les utilisateurs plutôt que de fonctionner indépendamment. Contrairement aux agents entièrement automatisés, les copilotes fournissent des suggestions et des recommandations pour aider les utilisateurs à accomplir leurs tâches. Par exemple, lorsqu’un utilisateur écrit un e-mail, un copilote peut suggérer des expressions, des phrases ou des paragraphes. L’utilisateur peut également demander au copilote de trouver des informations pertinentes dans d’autres e-mails ou fichiers pour prendre en charge la suggestion (voir génération augmentée de récupération). L’utilisateur peut accepter, rejeter ou modifier les passages suggérés.

Agents autonomes

Les agents autonomes peuvent fonctionner de manière plus indépendante. Lorsque vous mettez en place des agents autonomes pour vous assister dans la composition des e-mails, vous pouvez leur permettre d'effectuer les tâches suivantes :

  • Consulter des e-mails, des conversations, des fichiers et d’autres informations internes et publiques liées à l’objet
  • Effectuer une analyse qualitative ou quantitative sur les informations collectées et tirer des conclusions pertinentes pour l’e-mail
  • Écrire l’e-mail complet en fonction des conclusions et incorporer des preuves de soutien
  • Joindre des fichiers pertinents à l’e-mail
  • Passez en revue l’e-mail pour vous assurer que toutes les informations incorporées sont exactes et que les assertions sont valides
  • Sélectionnez les destinataires appropriés pour « À », « Cc » et/ou « Cci » et recherchez leurs adresses e-mail
  • Planifier une heure appropriée pour envoyer l’e-mail
  • Effectuer des suivis si les réponses sont attendues, mais non reçues

Vous pouvez configurer les agents pour effectuer chacune des étapes ci-dessus avec ou sans approbation humaine.

Systèmes multi-agents

Actuellement, la stratégie dominante pour atteindre des agents autonomes performants consiste à utiliser des systèmes multi-agents. Dans les systèmes multi-agents, plusieurs agents autonomes, sous forme numérique ou robotisée, interagissent ou collaborent pour atteindre des objectifs individuels ou collectifs. Les agents du système peuvent fonctionner indépendamment et posséder leurs propres connaissances ou informations. Chaque agent peut également avoir la capacité de percevoir son environnement, de prendre des décisions et d’exécuter des actions en fonction de ses objectifs.

Principales caractéristiques des systèmes multi-agents :

  • Autonome : chaque agent fonctionne indépendamment, prenant ses propres décisions sans intervention ou contrôle humain direct par d’autres agents.
  • Interactif : les agents communiquent et collaborent entre eux pour partager des informations, négocier et coordonner leurs actions. Cette interaction peut se produire via différents protocoles et canaux de communication.
  • Orienté vers les objectifs : les agents d'un système multi-agents sont conçus pour atteindre des objectifs spécifiques, qui peuvent être alignés sur des objectifs individuels ou sur un objectif commun partagé par les agents.
  • Distribué : les systèmes multi-agents fonctionnent de manière distribuée, sans point de contrôle unique. Cette répartition améliore la robustesse, la scalabilité et l'efficacité des ressources du système.

Un système multi-agent offre les avantages suivants sur un copilote ou une seule instance d’inférence LLM :

  • Raisonnement dynamique : par rapport à la chaîne de pensées ou aux systèmes d’invite à pensées multiples, les systèmes multi-agents permettent une navigation dynamique par le biais de différents chemins de raisonnement.
  • Capacités sophistiquées : les systèmes multi-agents peuvent gérer des problèmes complexes ou à grande échelle en effectuant des processus décisionnels approfondis et en distribuant des tâches entre plusieurs agents.
  • Mémoire améliorée : les systèmes multi-agents avec mémoire peuvent surmonter les fenêtres contextuelles des modèles de langage volumineux, ce qui permet de mieux comprendre et de conserver les informations.

Implémenter l’agent IA

Raisonnement et planification

Le raisonnement et la planification complexes sont les caractéristiques des agents autonomes avancés. Les frameworks d’agents autonomes populaires incorporent une ou plusieurs des méthodologies suivantes pour le raisonnement et la planification :

Auto-demande Améliore la chaîne de pensée en ayant le modèle explicitement se poser (et répondre) des questions de suivi avant de répondre à la question initiale.

Raison et Acte (ReAct) Utiliser les machines virtuelles LLM pour générer des traces de raisonnement et des actions spécifiques aux tâches de manière entrelacée. Les traces de raisonnement aident le modèle à induire, suivre et mettre à jour des plans d’action, ainsi que gérer les exceptions, tandis que les actions lui permettent d’interagir avec des sources externes, telles que des bases de connaissances ou des environnements, pour collecter des informations supplémentaires.

Planifier et résoudre Concevoir un plan pour diviser l’ensemble de la tâche en tâches subordonnées plus petites, puis effectuer les tâches subordonnées en fonction du plan. Cela atténue les erreurs de calcul, les erreurs manquantes et les erreurs d’incompréhension sémantique qui sont souvent présentes dans une chaîne de pensée nulle (CoT).

Réflexion/auto-critique Les agents de réflexion reflètent verbalement les signaux de commentaires des tâches, puis conservent leur propre texte réfléchissant dans une mémoire tampon de mémoire épisodique pour induire une meilleure prise de décision dans les essais suivants.

Frameworks

Différents frameworks et outils peuvent faciliter le développement et le déploiement de l’agent IA.

Pour l’utilisation et la perception des outils qui ne nécessitent pas de planification et de mémoire sophistiquées, certaines infrastructures d’orchestrateur LLM populaires sont LangChain, LlamaIndex, Flux d’invite et noyau sémantique.

Pour les flux de travail avancés et autonomes de planification et d’exécution, AutoGen propulse la vague multi-agent qui a commencé fin 2022. LesAPI Assistant d’OpenAI permettent à leurs utilisateurs de créer des agents en mode natif dans l’écosystème GPT. Agents LangChain et Agents LlamaIndex ont également émergé en même temps.

Conseil

Consultez la section exemple d’implémentation à la fin de cet article pour obtenir un didacticiel sur la création d’un système multi-agent simple à l’aide de l’un des frameworks populaires et d’un système de mémoire d’agent unifié.

Système de mémoire de l’agent IA

La pratique courante pour l’expérimentation d’applications améliorées par l’IA en 2022 à 2024 utilise des systèmes de gestion de base de données autonomes pour différents flux de travail ou types de données. Par exemple, une base de données en mémoire pour la mise en cache, une base de données relationnelle pour les données opérationnelles (y compris les journaux de suivi/activité et l’historique des conversations LLM) et un base de données vectorielle pure pour la gestion de l’incorporation.

Toutefois, cette pratique d’utilisation d’un web complexe de bases de données autonomes peut nuire aux performances de l’agent IA. L’intégration de toutes ces bases de données disparates dans un système de mémoire cohérent, interopérable et résilient pour l’agent IA est un défi important en soi. De plus, la plupart des services de base de données fréquemment utilisés ne sont pas optimaux pour la vitesse et l’extensibilité dont ont besoin les systèmes d’agent IA. Les faiblesses individuelles de ces bases de données sont accentuées dans les systèmes multi-agents :

Bases de données en mémoire

Les bases de données en mémoire sont excellentes pour la vitesse, mais peuvent avoir des difficultés avec la persistance des données à grande échelle requise par l’agent IA.

Bases de données relationnelles

Les bases de données relationnelles ne sont pas idéales pour les modalités variées et les schémas fluides des données gérées par les agents. De plus, les bases de données relationnelles nécessitent des efforts manuels et même des temps d’arrêt pour gérer l’approvisionnement, le partitionnement et le partitionnement.

Bases de données vectorielles pures

Les bases de données vectorielles pures ont tendance à être moins efficaces pour les opérations transactionnelles, les mises à jour en temps réel et les charges de travail distribuées. Les bases de données vectorielles pures populaires offrent généralement

  • aucune garantie sur les lectures et les écritures
  • débit d’ingestion limité
  • faible disponibilité (inférieure à 99,9 % ou panne annualisée de près de 9 heures ou plus)
  • un niveau de cohérence (éventuelle)
  • index vectoriel en mémoire gourmand en ressources
  • options limitées pour l’architecture mutualisée
  • sécurité limitée

La section suivante explique plus en détail ce qui rend un système robuste de mémoire de l’agent IA.

La mémoire peut créer ou interrompre des agents

Tout comme les systèmes de gestion de base de données efficaces sont essentiels aux performances des applications logicielles, il est essentiel de fournir des agents alimentés par LLM avec des informations pertinentes et utiles pour guider leur inférence. Les systèmes de mémoire robustes permettent d’organiser et de stocker différents types d’informations que les agents peuvent récupérer au moment de l’inférence.

Actuellement, les applications basées sur LLM utilisent souvent génération augmentée par récupération qui utilise la recherche sémantique de base ou la recherche vectorielle pour récupérer des passages ou des documents. Recherche vectorielle peut être utile pour rechercher des informations générales, mais il peut ne pas capturer le contexte, la structure ou les relations spécifiques pertinents pour une tâche ou un domaine particulier.

Par exemple, si la tâche consiste à écrire du code, la recherche vectorielle peut ne pas être en mesure de récupérer l’arborescence de syntaxe, la disposition du système de fichiers, les résumés de code ou les signatures d’API qui sont importantes pour générer du code cohérent et correct. De même, si la tâche consiste à utiliser des données tabulaires, la recherche vectorielle peut ne pas être en mesure de récupérer le schéma, les clés étrangères, les procédures stockées ou les rapports utiles pour interroger ou analyser les données.

Tisser un réseau de bases de données autonomes en mémoire, relationnelles et vectorielles n'est pas non plus une solution optimale pour les différents types de données. Cette approche peut fonctionner pour les systèmes d’agent prototypage ; toutefois, cela ajoute de la complexité et des goulots d’étranglement des performances qui peuvent entraver les performances des agents autonomes avancés.

Par conséquent, un système de mémoire robuste doit avoir les caractéristiques suivantes :

Multimodèle (partie I)

Les systèmes de mémoire de l’agent IA doivent fournir différentes collections qui stockent des métadonnées, des relations, des entités, des résumés ou d’autres types d’informations qui peuvent être utiles pour différentes tâches et domaines. Ces collections peuvent être basées sur la structure et le format des données, telles que des documents, des tables ou du code, ou elles peuvent être basées sur le contenu et la signification des données, telles que des concepts, des associations ou des étapes procédurales.

En fonctionnement

Les systèmes de mémoire doivent fournir différentes banques de mémoire qui stockent des informations pertinentes pour l’interaction avec l’utilisateur et l’environnement. Ces informations peuvent inclure l’historique des conversations, les préférences utilisateur, les données sensorielles, les décisions prises, les faits appris ou d’autres données opérationnelles mises à jour avec une fréquence élevée et à des volumes élevés. Ces banques de mémoire peuvent aider les agents à mémoriser des informations à court terme et à long terme, à éviter de répéter ou à se contredire eux-mêmes, et à maintenir la cohérence des tâches. Ces exigences doivent rester valables même si les agents exécutent successivement une multitude de tâches sans rapport les unes avec les autres. Dans les cas les plus avancés, les agents peuvent également jouer avec de nombreux plans de branches qui divergent ou convergent en différents points.

Partageable mais aussi séparable

Au niveau de la macro, les systèmes de mémoire doivent permettre à plusieurs agents IA de collaborer sur un problème ou de traiter différents aspects du problème en fournissant une mémoire partagée accessible à tous les agents. La mémoire partagée peut faciliter l’échange d’informations et la coordination des actions entre les agents. En même temps, le système de mémoire doit permettre aux agents de conserver leur propre personnage et caractéristiques, comme leurs collections uniques d’invites et de souvenirs.

Multimodèle (partie II)

Non seulement les systèmes de mémoire sont critiques pour les agents IA ; ils sont également importants pour les humains qui développent, maintiennent et utilisent ces agents. Par exemple, les humains peuvent avoir besoin de superviser les flux de travail de planification et d’exécution des agents en quasi-temps réel. Pendant la supervision, les humains peuvent donner des conseils ou modifier en ligne les dialogues ou les monologues des agents. Les humains peuvent également avoir besoin d’auditer le raisonnement et les actions des agents pour vérifier la validité de la sortie finale. Les interactions entre l'homme et l'agent se font probablement dans des langages naturels ou de programmation, tandis que les agents « pensent », « apprennent » et « se souviennent » par le biais d'incorporations. Cette différence modale de données pose une autre exigence sur la cohérence des systèmes de mémoire entre les modalités de données.

Création d’un système de mémoire d’agent IA robuste

Les caractéristiques ci-dessus nécessitent que les systèmes de mémoire de l’agent IA soient hautement évolutifs et rapides. L'assemblage minutieux d'une pléthore de bases de données disparates en mémoire, relationnelles et vectorielles peut fonctionner pour les premières applications basées sur l'IA ; cependant, cette approche ajoute de la complexité et des goulets d'étranglement qui peuvent entraver les performances des agents autonomes avancés.

À la place de toutes les bases de données autonomes, Azure Cosmos DB peut servir de solution unifiée pour les systèmes de mémoire de l’agent IA. Sa robustesse a activé le service ChatGPT d’OpenAI pour effectuer une mise à l’échelle dynamique avec une fiabilité élevée et une faible maintenance. Alimenté par un moteur atome-record-séquence, il s'agit du premier service de base de données NoSQL, relationnelles, et vectorielles distribué à l'échelle mondiale qui offre un mode sans serveur. Les agents IA basés sur Azure Cosmos DB bénéficient d’une vitesse, d’une mise à l’échelle et d’une simplicité.

Vitesse

Azure Cosmos DB fournit une latence en millisecondes à un chiffre, ce qui le rend hautement adapté aux processus nécessitant un accès et une gestion rapides des données, notamment la mise en cache (traditionnelle et sémantique), les transactions et les charges de travail opérationnelles. Cette faible latence est cruciale pour les agents d’IA qui doivent effectuer un raisonnement complexe, prendre des décisions en temps réel et fournir des réponses immédiates. En outre, l'utilisation de l'algorithme DiskANN de pointe permet une recherche vectorielle précise et rapide avec une consommation de mémoire réduite de 95 %.

Mise à l’échelle

Conçu pour une distribution mondiale et une évolutivité horizontale, et offrant une prise en charge des E/S multirégionales et du multitenancy, ce service garantit que les systèmes de mémoire peuvent se développer de manière transparente et suivre la croissance rapide des agents et des données qui leur sont associées. Sa garantie de disponibilité de 99,999 % soutenue par le contrat SLA (moins de 5 minutes de temps d’arrêt par an, contrastant 9 heures ou plus pour les services de base de données vectorielles pures) constitue une base solide pour les charges de travail critiques. En même temps, ses différents modèles de service comme capacité de réserve ou serverless réduisent considérablement les coûts financiers.

Simplicité

Ce service simplifie la gestion et l’architecture des données en intégrant plusieurs fonctionnalités de base de données dans une plateforme unique et cohérente.

Ses fonctionnalités de base de données vectorielles intégrées peuvent stocker, indexer et interroger des incorporations en même temps que les données correspondantes dans des langages naturels ou de programmation, ce qui permet une plus grande cohérence des données, une mise à l’échelle et des performances.

Sa flexibilité prend facilement en charge les modalités variées et les schémas fluides des métadonnées, des relations, des entités, des résumés, de l’historique des conversations, des préférences utilisateur, des données sensorielles, des décisions, des faits appris ou d’autres données opérationnelles impliquées dans les flux de travail de l’agent. La base de données indexe automatiquement toutes les données sans nécessiter de schéma ou de gestion des index, ce qui permet aux agents IA d’effectuer des requêtes complexes rapidement et efficacement.

Enfin, son service entièrement géré élimine la surcharge liée à l’administration de la base de données, notamment les tâches telles que la mise à l’échelle, la mise à jour corrective et les sauvegardes. Ainsi, les développeurs peuvent se concentrer sur la création et l’optimisation des agents IA sans se soucier de l’infrastructure de données sous-jacente.

Fonctionnalités avancées

Azure Cosmos DB intègre des fonctionnalités avancées telles que le flux de modification, ce qui permet de suivre et de répondre aux modifications apportées aux données en temps réel. Cette fonctionnalité est utile pour les agents IA qui doivent réagir rapidement à de nouvelles informations.

En outre, la prise en charge intégrée des écritures multi-maîtres permet une disponibilité et une résilience élevées, garantissant le fonctionnement continu des agents d'intelligence artificielle, même en cas de défaillance régionale.

Les cinq niveaux de cohérence disponibles (de fort à éventuel) peuvent également répondre à différentes charges de travail distribuées en fonction des exigences du scénario.

Conseil

Vous pouvez choisir parmi deux API Azure Cosmos DB pour créer votre système de mémoire d’agent IA : Azure Cosmos DB for NoSQL et Azure Cosmos DB for MongoDB basé sur vCore. L’ancien offre une disponibilité de 99,999 % et trois algorithmes de recherche vectorielle: IVF, HNSW et DiskANN de pointe. Ce dernier fournit une disponibilité de 99,995 % et deux algorithmes de recherche vectorielle: IVF et HNSW.

Exemple d’implémentation

Cette section explore l’implémentation d’un agent autonome pour traiter les demandes et réservations des voyageurs dans une application de voyage CruiseLine.

Les chatbots ont été un concept de longue date, mais les agents IA avancent au-delà de la conversation humaine de base pour effectuer des tâches basées sur le langage naturel, nécessitant traditionnellement une logique codée. Cet agent de voyage IA utilise l’infrastructure LangChain Agent pour la planification de l’agent, l’utilisation des outils et la perception. Son système de mémoire unifiée utilise la base de données vectorielle et les fonctionnalités de magasin de documents d’Azure Cosmos DB pour répondre aux demandes des voyageurs et faciliter les réservations de voyage, en garantissant vitesse, mise à l’échelle et simplicité. Il fonctionne dans un back-end FastAPI Python et prend en charge les interactions utilisateur via une interface utilisateur React JS.

Prérequis

  • Si vous n’avez pas d’abonnement Azure, vous pouvez essayer azure Cosmos DB gratuitement pendant 30 jours sans créer de compte Azure ; aucune carte de crédit n’est requise et aucun engagement n’est suivi lorsque la période d’essai se termine.
  • Configurez le compte pour l’API OpenAI ou Azure OpenAI Service.
  • Créez un cluster vCore dans Azure Cosmos DB for MongoDB en suivant ce démarrage rapide.
  • IDE pour le développement, tel que VS Code.
  • Python 3.11.4 installé sur l’environnement de développement.

Téléchargez le projet

Tous les exemples de jeux de données et de code sont disponibles sur GitHub. Dans ce référentiel, vous trouverez les dossiers suivants :

  • Chargeur: ce dossier contient du code Python pour le chargement d’exemples de documents et d’incorporations vectorielles dans Azure Cosmos DB.
  • api: ce dossier contient Python FastAPI pour Hosting Travel AI Agent.
  • web : le dossier contient l’interface web avec React JS.

Charger des documents de voyage dans Azure Cosmos DB

Le dépôt GitHub contient un projet Python situé dans le référentiel chargeur destiné au chargement des exemples de documents de voyage dans Azure Cosmos DB. Cette section configure le projet pour charger les documents.

Configurer l’environnement pour le chargeur

Configurez votre environnement virtuel Python dans le référentiel du chargeur en exécutant ce qui suit :

    python -m venv venv

Activez votre environnement et installez les dépendances dans le référentiel du chargeur de :

    venv\Scripts\activate
    python -m pip install -r requirements.txt

Créez un fichier nommé .env dans le référentiel chargeur pour stocker les variables d’environnement suivantes.

    OPENAI_API_KEY="**Your Open AI Key**"
    MONGO_CONNECTION_STRING="mongodb+srv:**your connection string from Azure Cosmos DB**"

Charger des documents et des vecteurs

Le fichier Python main.py sert de point d’entrée central pour le chargement de données dans Azure Cosmos DB. Ce code traite les exemples de données de voyage à partir du référentiel GitHub, y compris des informations sur les navires et les destinations. En outre, il génère des packages d’itinéraires de voyage pour chaque navire et destination, ce qui permet aux voyageurs de les réserver à l’aide de l’agent IA. CosmosDBLoader est chargé de créer des collections, des incorporations vectorielles et des index dans l’instance Azure Cosmos DB.

main.py

from cosmosdbloader import CosmosDBLoader
from itinerarybuilder import ItineraryBuilder
import json


cosmosdb_loader = CosmosDBLoader(DB_Name='travel')

#read in ship data
with open('documents/ships.json') as file:
        ship_json = json.load(file)

#read in destination data
with open('documents/destinations.json') as file:
        destinations_json = json.load(file)

builder = ItineraryBuilder(ship_json['ships'],destinations_json['destinations'])

# Create five itinerary pakages
itinerary = builder.build(5)

# Save itinerary packages to Cosmos DB
cosmosdb_loader.load_data(itinerary,'itinerary')

# Save destinations to Cosmos DB
cosmosdb_loader.load_data(destinations_json['destinations'],'destinations')

# Save ships to Cosmos DB, create vector store
collection = cosmosdb_loader.load_vectors(ship_json['ships'],'ships')

# Add text search index to ship name
collection.create_index([('name', 'text')])

Chargez les documents, les vecteurs et créez des index en exécutant simplement la commande suivante à partir du répertoire du chargeur :

    python main.py

Sortie :

--build itinerary--
--load itinerary--
--load destinations--
--load vectors ships--

Créer un agent IA de voyage avec Python FastAPI

L’agent de voyage IA est hébergé dans une API back-end à l’aide de Python FastAPI, ce qui facilite l’intégration à l’interface utilisateur front-end. Le projet API traite les demandes des agents en basant les invites LLM sur la couche de données, en particulier les vecteurs et les documents dans Azure Cosmos DB. En outre, l’agent utilise différents outils, en particulier les fonctions Python fournies au niveau de la couche de service API. Cet article se concentre sur le code nécessaire pour les agents IA dans le code de l’API.

Le projet d’API dans le référentiel GitHub est structuré comme suit :

  • Modèle - composants de modélisation des données à l'aide de modèles pydantiques.
  • Web - composants de la couche web responsables de l'acheminement des demandes et de la gestion de la communication.
  • Service - composants de la couche de service responsables de la logique commerciale primaire et de l'interaction avec la couche de données ; LangChain Agent et Agent Tools.
  • Données - composants de la couche de données responsables de l'interaction avec Azure Cosmos DB pour le stockage des documents MongoDB et la recherche vectorielle.

Configurer l’environnement pour l’API

Python version 3.11.4 a été utilisée pour le développement et le test de l’API.

Configurez votre environnement virtuel Python dans le répertoire API.

    python -m venv venv

Activez votre environnement et installez des dépendances à l’aide du fichier de configuration requise dans le répertoire api :

    venv\Scripts\activate
    python -m pip install -r requirements.txt

Créez un fichier nommé .env dans le répertoire api pour stocker vos variables d’environnement.

    OPENAI_API_KEY="**Your Open AI Key**"
    MONGO_CONNECTION_STRING="mongodb+srv:**your connection string from Azure Cosmos DB**"

Avec l’environnement configuré et les variables configurés, nous sommes prêts à lancer le serveur FastAPI. Exécutez la commande suivante à partir du répertoire api pour lancer le serveur.

    python app.py

Le serveur FastAPI démarre sur le bouclage localhost 127.0.0.1 port 8000 par défaut. Vous pouvez accéder aux documents Swagger à l’aide de l’adresse localhost suivante : http://127.0.0.1:8000/docs

Utiliser une session pour la mémoire de l’agent IA

Il est impératif que l’Agent de voyage ait la possibilité de référencer des informations précédemment fournies au sein de la conversation en cours. Cette capacité est communément appelée « mémoire » dans le contexte de LLMs, qui ne doit pas être confondue avec le concept de mémoire ordinateur (comme la mémoire volatile, non volatile et persistante).

Pour atteindre cet objectif, nous utilisons l’historique des messages de conversation, qui est stocké en toute sécurité dans notre instance Azure Cosmos DB. Chaque session de conversation aura son historique stocké à l’aide d’un ID de session pour s’assurer que seuls les messages de la session de conversation actuelle sont accessibles. Cette nécessité est la raison de l’existence d’une méthode « Get Session » dans notre API. Il s’agit d’une méthode d’espace réservé pour gérer les sessions web afin d’illustrer l’utilisation de l’historique des messages de conversation.

Capture d'écran de Python FastAPI - Obtenir la Session. Cliquez sur Essayer pour /session/.

{
  "session_id": "0505a645526f4d68a3603ef01efaab19"
}

Pour l’agent IA, nous devons uniquement simuler une session. Par conséquent, la méthode abandonnée renvoie simplement un identifiant de session généré pour le suivi de l'historique des messages. Dans la pratique, cette session sera stockée dans Azure Cosmos DB et potentiellement dans React JS localStorage.

web/session.py

    @router.get("/")
    def get_session():
        return {'session_id':str(uuid.uuid4().hex)}

Démarrer une conversation avec l’agent de voyage IA

Utilisons l’ID de session obtenu à partir de l’étape précédente pour lancer un nouveau dialogue avec notre agent IA pour valider ses fonctionnalités. Nous allons effectuer notre test en soumettant l’expression suivante : « Je veux prendre des vacances reposantes »

Capture d'écran de Python FastAPI - Agent Chat. Cliquez sur Essayer pour /agent/agent_chat.

Exemple de paramètre

{
  "input": "I want to take a relaxing vacation.",
  "session_id": "0505a645526f4d68a3603ef01efaab19"
}

L’exécution initiale aboutit à une recommandation pour la croisière Tranquil Breeze et la Fantasy Seas Adventure Cruise, car elles sont prévues pour être les croisières les plus « détendues » disponibles par le biais de la recherche vectorielle. Ces documents ont le score le plus élevé pour similarity_search_with_score qui est appelé dans la couche de données de notre API, data.mongodb.travel.similarity_search().

Les scores de recherche de similarité sont affichés sous forme de sortie de l’API à des fins de débogage.

Sortie lors de l’appel de data.mongodb.travel.similarity_search()

0.8394561085977978
0.8086545112328692
2

Conseil

Si les documents ne sont pas retournés pour la recherche vectorielle, modifiez la limite de similarity_search_with_score ou la valeur du filtre de score si nécessaire ([doc for doc, score in docs if score >=.78]). dans data.mongodb.travel.similarity_search()

L’appel du « agent_chat » pour la première fois crée une collection nommée « historique » dans Azure Cosmos DB pour stocker la conversation par session. Cet appel permet à l’agent d’accéder à l’historique des messages de conversation stocké en fonction des besoins. Les exécutions suivantes de « agent_chat » avec les mêmes paramètres produisent des résultats variables, car elles proviennent de la mémoire.

Procédure pas à pas de l’agent IA

Lors de l’intégration de l’agent IA dans l’API, les composants de recherche web sont chargés de lancer toutes les requêtes. Ceci est suivi du service de recherche, et enfin des composants de données. Dans notre cas spécifique, nous utilisons la recherche de données MongoDB, qui se connecte à Azure Cosmos DB. Les couches facilitent l'échange des composants du modèle, le code de l'agent d'IA et de l'outil d'agent d'IA résidant dans la couche de service. Cette approche a été implémentée pour permettre l’échange transparent des sources de données et étendre les fonctionnalités de l’agent IA avec des fonctionnalités supplémentaires, plus complexes ou des « outils ».

Capture d'écran des couches FastAPI de l'agent de voyage AI.

Couche de service

La couche de service constitue la pierre angulaire de notre logique métier principale. Dans ce scénario particulier, la couche de service joue un rôle crucial en tant que référentiel du code de l'agent LangChain, facilitant l'intégration transparente des invites de l'utilisateur avec les données de Azure Cosmos DB, la mémoire de conversation et les fonctions de l'agent pour notre agent IA.

La couche de service utilise un module de modèle singleton pour gérer les initialisations liées à l’agent dans le fichier init.py.

service/init.py

from dotenv import load_dotenv
from os import environ
from langchain.globals import set_llm_cache
from langchain_openai import ChatOpenAI
from langchain_mongodb.chat_message_histories import MongoDBChatMessageHistory
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.runnables.history import RunnableWithMessageHistory
from langchain.agents import AgentExecutor, create_openai_tools_agent
from service import TravelAgentTools as agent_tools

load_dotenv(override=False)


chat : ChatOpenAI | None=None
agent_with_chat_history : RunnableWithMessageHistory | None=None

def LLM_init():
    global chat,agent_with_chat_history
    chat = ChatOpenAI(model_name="gpt-3.5-turbo-16k",temperature=0)
    tools = [agent_tools.vacation_lookup, agent_tools.itinerary_lookup, agent_tools.book_cruise ]

    prompt = ChatPromptTemplate.from_messages(
    [
        (
            "system",
            "You are a helpful and friendly travel assistant for a cruise company. Answer travel questions to the best of your ability providing only relevant information. In order to book a cruise you will need to capture the person's name.",
        ),
        MessagesPlaceholder(variable_name="chat_history"),
        ("user", "Answer should be embedded in html tags. {input}"),
         MessagesPlaceholder(variable_name="agent_scratchpad"),
    ]
    )

    #Answer should be embedded in html tags. Only answer questions related to cruise travel, If you can not answer respond with \"I am here to assist with your travel questions.\". 


    agent = create_openai_tools_agent(chat, tools, prompt)
    agent_executor  = AgentExecutor(agent=agent, tools=tools, verbose=True)

    agent_with_chat_history = RunnableWithMessageHistory(
        agent_executor,
        lambda session_id: MongoDBChatMessageHistory( database_name="travel",
                                                 collection_name="history",
                                                   connection_string=environ.get("MONGO_CONNECTION_STRING"),
                                                   session_id=session_id),
        input_messages_key="input",
        history_messages_key="chat_history",
)

LLM_init()

Le fichier init.py commence par lancer le chargement des variables d’environnement à partir d’un fichier .env .env utilisant la méthode load_dotenv(override=False). Ensuite, une variable globale nommée agent_with_chat_history est instanciée pour l’agent, destinée à être utilisée par notre TravelAgent.py. La méthode LLM_init() est appelée pendant l’initialisation du module pour configurer notre agent IA pour la conversation via la couche web d’API. L’objet OpenAI Chat est instancié à l’aide du modèle GPT-3.5, incorporant des paramètres spécifiques tels que le nom du modèle et la température. L’objet de conversation, la liste des outils et le modèle d’invite sont combinés pour générer un AgentExecutor, qui fonctionne comme notre agent de voyage AI. Enfin, l’agent avec l’historique, agent_with_chat_history, est établi à l’aide de RunnableWithMessageHistory avec l’historique des conversations (MongoDBChatMessageHistory), ce qui lui permet de conserver un historique de conversation complet via Azure Cosmos DB.

Prompt

L’invite LLM a commencé initialement avec la simple déclaration « Vous êtes un assistant de voyage utile et convivial pour une compagnie de croisière. » Toutefois, grâce à des tests, il a été déterminé que des résultats plus cohérents pourraient être obtenus en incluant l’instruction « Répondre aux questions de voyage au mieux de votre capacité, en fournissant uniquement des informations pertinentes. Pour réserver une croisière, capturer le nom de la personne est essentiel. » Les résultats sont présentés au format HTML pour améliorer l’attrait visuel dans l’interface web.

Outils d’agent

Outils sont des interfaces qu’un agent peut utiliser pour interagir avec le monde, souvent par le biais d’appels de fonction.

Lors de la création d’un agent, il est essentiel de le fournir avec un ensemble d’outils qu’il peut utiliser. L’élément décoratif @tool offre l’approche la plus simple pour définir un outil personnalisé. Par défaut, l’élément décoratif utilise le nom de la fonction comme nom d’outil, bien que cela puisse être remplacé en fournissant une chaîne comme premier argument. De plus, l’élément décoratif utilisera la documentation de la fonction comme description de l’outil, ce qui nécessite la mise en service d’une docstring.

service/TravelAgentTools.py

from langchain_core.tools import tool
from langchain.docstore.document import Document
from data.mongodb import travel
from model.travel import Ship


@tool
def vacation_lookup(input:str) -> list[Document]:
    """find information on vacations and trips"""
    ships: list[Ship] = travel.similarity_search(input)
    content = ""

    for ship in ships:
        content += f" Cruise ship {ship.name}  description: {ship.description} with amenities {'/n-'.join(ship.amenities)} "

    return content

@tool
def itinerary_lookup(ship_name:str) -> str:
    """find ship itinerary, cruise packages and destinations by ship name"""
    it = travel.itnerary_search(ship_name)
    results = ""

    for i in it:
        results += f" Cruise Package {i.Name} room prices: {'/n-'.join(i.Rooms)} schedule: {'/n-'.join(i.Schedule)}"

    return results


@tool
def book_cruise(package_name:str, passenger_name:str, room: str )-> str:
    """book cruise using package name and passenger name and room """
    print(f"Package: {package_name} passenger: {passenger_name} room: {room}")

    # LLM defaults empty name to John Doe 
    if passenger_name == "John Doe":
        return "In order to book a cruise I need to know your name."
    else:
        if room == '':
            return "which room would you like to book"            
        return "Cruise has been booked, ref number is 343242"

Dans le fichier TravelAgentTools.py, trois outils spécifiques sont définis. Le premier outil, vacation_lookup, effectue une recherche vectorielle sur Azure Cosmos DB à l’aide d’un similarity_search pour récupérer des documents pertinents liés au voyage. Le deuxième outil, itinerary_lookup, récupère les détails et les planifications d’un bateau de croisière spécifié. Enfin, book_cruise est responsable de la réservation d’un forfait de croisière pour un passager. Des instructions spécifiques (« Pour réserver une croisière, je dois connaître votre nom. ») peuvent être nécessaires pour garantir la capture du nom et du numéro de chambre du passager pour la réservation du forfait de croisière. Et ce, bien que de telles instructions aient été incluses dans l'invitation à participer au programme LLM.

Agent IA

Le concept fondamental des agents sous-jacents consiste à utiliser un modèle de langage pour sélectionner une séquence d’actions à exécuter.

service/TravelAgent.py

from .init import agent_with_chat_history
from model.prompt import PromptResponse
import time
from dotenv import load_dotenv

load_dotenv(override=False)


def agent_chat(input:str, session_id:str)->str:

    start_time = time.time()

    results=agent_with_chat_history.invoke(
    {"input": input},
    config={"configurable": {"session_id": session_id}},
    )

    return  PromptResponse(text=results["output"],ResponseSeconds=(time.time() - start_time))

Le fichier TravelAgent.py est simple, car agent_with_chat_historyet ses dépendances (outils, invites et LLM) sont initialisés et configurés dans le fichier init.py. Dans ce fichier, l’agent est appelé à l’aide de l’entrée reçue de l’utilisateur, ainsi que l’ID de session pour la mémoire de conversation. Par la suite, PromptResponse (modèle/invite) est retourné avec la sortie et le temps de réponse de l’agent.

Intégrer l’agent IA à l’interface utilisateur React JS

Avec le chargement réussi des données et l’accessibilité de notre agent IA via notre API, nous pouvons maintenant terminer la solution en établissant une interface utilisateur web à l’aide de React JS pour notre site web de voyage. En exploitant les fonctionnalités de React JS, nous pouvons illustrer l’intégration transparente de notre agent IA dans un site de voyage, ce qui améliore l’expérience utilisateur avec un assistant de voyage conversationnel pour les demandes de renseignements et les réservations.

Configurer l’environnement pour React JS

Installez Node.js et les dépendances avant de tester l’interface React.

Exécutez la commande suivante à partir du répertoire web pour effectuer une nouvelle installation des dépendances de projet, cela peut prendre un certain temps.

    npm ci

Ensuite, il est essentiel de créer un fichier nommé .env dans le répertoire web pour faciliter le stockage des variables d’environnement. Ensuite, vous devez inclure les détails suivants dans le fichier .env nouvellement créé.

REACT_APP_API_HOST=http://127.0.0.1:8000

À présent, nous avons la possibilité d’exécuter la commande suivante à partir du répertoire web pour lancer l’interface utilisateur web React.

    npm start

L’exécution de la commande précédente lance l’application web React JS. Capture d’écran de l’application web React JS Travel.

Procédure pas à pas de l’interface web React JS

Le projet web du dépôt GitHub est une application simple qui facilite l’interaction utilisateur avec notre agent IA. Les composants principaux requis pour converser avec l’agent sont TravelAgent.js et ChatLayout.js. Le fichier Main.js sert de module central ou de page d’accueil utilisateur.

Capture d’écran de l’interface JS.

Principal

Le composant principal sert de gestionnaire central de l’application, agissant comme point d’entrée désigné pour le routage. Dans la fonction de rendu, elle produit du code JSX pour délimiter la mise en page principale. Cette disposition englobe les éléments d’espace réservé pour l’application, tels que les logos et les liens, une section qui héberge le composant de l’agent de voyage (plus d’informations à venir) et un pied de page contenant un exemple d’exclusion de responsabilité concernant la nature de l’application.

main.js

    import React, {  Component } from 'react'
import { Stack, Link, Paper } from '@mui/material'
import TravelAgent from './TripPlanning/TravelAgent'

import './Main.css'

class Main extends Component {
  constructor() {
    super()

  }

  render() {
    return (
      <div className="Main">
        <div className="Main-Header">
          <Stack direction="row" spacing={5}>
            <img src="/mainlogo.png" alt="Logo" height={'120px'} />
            <Link
              href="#"
              sx={{ color: 'white', fontWeight: 'bold', fontSize: 18 }}
              underline="hover"
            >
              Ships
            </Link>
            <Link
              href="#"
              sx={{ color: 'white', fontWeight: 'bold', fontSize: 18 }}
              underline="hover"
            >
              Destinations
            </Link>
          </Stack>
        </div>
        <div className="Main-Body">
          <div className="Main-Content">
            <Paper elevation={3} sx={{p:1}} >
            <Stack
              direction="row"
              justifyContent="space-evenly"
              alignItems="center"
              spacing={2}
            >
              
                <Link href="#">
                  <img
                    src={require('./images/destinations.png')} width={'400px'} />
                </Link>
                <TravelAgent ></TravelAgent>
                <Link href="#">
                  <img
                    src={require('./images/ships.png')} width={'400px'} />
                </Link>
              
              </Stack>
              </Paper>
          </div>
        </div>
        <div className="Main-Footer">
          <b>Disclaimer: Sample Application</b>
          <br />
          Please note that this sample application is provided for demonstration
          purposes only and should not be used in production environments
          without proper validation and testing.
        </div>
      </div>
    )
  }
}

export default Main

Agent de voyage

Le composant Agent de voyage a un objectif simple de capturer les entrées utilisateur et d’afficher des réponses. Il joue un rôle clé dans la gestion de l’intégration à l’agent IA back-end, principalement en capturant des sessions et en transférant des invites utilisateur à notre service FastAPI. Les réponses obtenues sont stockées dans un tableau pour l’affichage, facilitée par le composant Disposition de conversation.

TripPlanning/TravelAgent.js

import React, { useState, useEffect } from 'react'
import { Button, Box, Link, Stack, TextField } from '@mui/material'
import SendIcon from '@mui/icons-material/Send'
import { Dialog, DialogContent } from '@mui/material'
import ChatLayout from './ChatLayout'
import './TravelAgent.css'

export default function TravelAgent() {
  const [open, setOpen] = React.useState(false)
  const [session, setSession] = useState('')
  const [chatPrompt, setChatPrompt] = useState(
    'I want to take a relaxing vacation.',
  )
  const [message, setMessage] = useState([
    {
      message: 'Hello, how can I assist you today?',
      direction: 'left',
      bg: '#E7FAEC',
    },
  ])

  const handlePrompt = (prompt) => {
    setChatPrompt('')
    setMessage((message) => [
      ...message,
      { message: prompt, direction: 'right', bg: '#E7F4FA' },
    ])
    console.log(session)
    fetch(process.env.REACT_APP_API_HOST + '/agent/agent_chat', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ input: prompt, session_id: session }),
    })
      .then((response) => response.json())
      .then((res) => {
        setMessage((message) => [
          ...message,
          { message: res.text, direction: 'left', bg: '#E7FAEC' },
        ])
      })
  }

  const handleSession = () => {
    fetch(process.env.REACT_APP_API_HOST + '/session/')
      .then((response) => response.json())
      .then((res) => {
        setSession(res.session_id)
      })
  }

  const handleClickOpen = () => {
    setOpen(true)
  }

  const handleClose = (value) => {
    setOpen(false)
  }

  useEffect(() => {
    if (session === '') handleSession()
  }, [])

  return (
    <Box>
      <Dialog onClose={handleClose} open={open} maxWidth="md" fullWidth="true">
        <DialogContent>
          <Stack>
            <Box sx={{ height: '500px' }}>
              <div className="AgentArea">
                <ChatLayout messages={message} />
              </div>
            </Box>
            <Stack direction="row" spacing={0}>
              <TextField
                sx={{ width: '80%' }}
                variant="outlined"
                label="Message"
                helperText="Chat with AI Travel Agent"
                defaultValue="I want to take a relaxing vacation."
                value={chatPrompt}
                onChange={(event) => setChatPrompt(event.target.value)}
              ></TextField>
              <Button
                variant="contained"
                endIcon={<SendIcon />}
                sx={{ mb: 3, ml: 3, mt: 1 }}
                onClick={(event) => handlePrompt(chatPrompt)}
              >
                Submit
              </Button>
            </Stack>
          </Stack>
        </DialogContent>
      </Dialog>
      <Link href="#" onClick={() => handleClickOpen()}>
        <img src={require('.././images/planvoyage.png')} width={'400px'} />
      </Link>
    </Box>
  )
}

Cliquez sur « Planifier sans effort votre voyage » pour lancer l’assistant voyage.

Disposition de conversation

Le composant Disposition de conversation, comme indiqué par son nom, supervise l’organisation de la conversation. Il traite systématiquement les messages de conversation et implémente la mise en forme désignée spécifiée dans l’objet JSON du message.

TripPlanning/ChatLayout.py

import React from 'react'
import {  Box, Stack } from '@mui/material'
import parse from 'html-react-parser'
import './ChatLayout.css'

export default function ChatLayout(messages) {
  return (
    <Stack direction="column" spacing="1">
      {messages.messages.map((obj, i = 0) => (
        <div className="bubbleContainer" key={i}>
          <Box
            key={i++}
            className="bubble"
            sx={{ float: obj.direction, fontSize: '10pt', background: obj.bg }}
          >
            <div>{parse(obj.message)}</div>
          </Box>
        </div>
      ))}
    </Stack>
  )
}

Les invites utilisateur sont sur le côté droit et en bleu coloré, tandis que les réponses de l’Agent d’IA de voyage sont sur le côté gauche et le vert coloré. Comme vous pouvez le voir dans l’image ci-dessous, les réponses au format HTML sont prises en compte dans la conversation. Capture d’écran de Conversation.

Lorsque votre agent IA est prêt à passer en production, vous pouvez utiliser la mise en cache sémantique pour améliorer les performances des requêtes de 80 % et réduire les coûts d’appel de LLM/API. Consultez ce billet de blog pour savoir comment implémenter mise en cache sémantique. Capture d’écran de la mise en cache sémantique.

Remarque

Si vous souhaitez contribuer à cet article, n’hésitez pas à cliquer sur le bouton crayon en haut à droite de l’article. Si vous avez des questions ou des commentaires spécifiques sur cet article, vous pouvez contacter cosmosdbgenai@microsoft.com

Étapes suivantes

Essai gratuit de 30 jours sans abonnement Azure

Essai gratuit de 90 jours et jusqu’à 6 000 $ de crédits de débit avec Azure AI Advantage