Découvrez comment créer et déployer des agents LLM à l'aide d'outils à l'aide des modèles AWS SageMaker JumpStart Foundation.


Les agents LLM (Large Language Model) sont des programmes qui étendent les capacités des LLM autonomes avec 1) un accès à des outils externes (API, fonctions, webhooks, plugins, etc.) et 2) la possibilité de planifier et d'exécuter des tâches de manière autonome. -mode dirigée. Souvent, les LLM doivent interagir avec d’autres logiciels, bases de données ou API pour accomplir des tâches complexes. Par exemple, un chatbot administratif qui planifie des réunions nécessiterait l'accès aux calendriers et aux e-mails des employés. Avec l'accès aux outils, les agents LLM peuvent devenir plus puissants, au prix d'une complexité supplémentaire.

Dans cet article, nous présentons les agents LLM et montrons comment créer et déployer un agent LLM de commerce électronique à l'aide d'Amazon SageMaker JumpStart et d'AWS Lambda. L'agent utilisera des outils pour offrir de nouvelles fonctionnalités, telles que répondre aux questions sur les retours (« Mon retour est-il rtn001 traitée ? ») et fournir des mises à jour sur les commandes (« Pourriez-vous me dire si la commande 123456 a été envoyé?"). Ces nouvelles fonctionnalités nécessitent que les LLM récupèrent des données à partir de plusieurs sources de données (ordres, Retour) et effectuez une génération augmentée de récupération (RAG).

Pour alimenter l'agent LLM, nous utilisons un Flan-UL2 modèle déployé en tant que point de terminaison SageMaker et utilise des outils de récupération de données construits avec AWS Lambda. L'agent peut ensuite être intégré à Amazon Lex et utilisé comme chatbot sur des sites Web ou sur AWS Connect. Nous concluons l'article avec les éléments à prendre en compte avant de déployer des agents LLM en production. Pour une expérience entièrement gérée pour la création d'agents LLM, AWS fournit également la fonctionnalité d'agents pour Amazon Bedrock (en version préliminaire).

Un bref aperçu des architectures d'agents LLM

Les agents LLM sont des programmes qui utilisent les LLM pour décider quand et comment utiliser les outils nécessaires pour effectuer des tâches complexes. Grâce à des outils et à des capacités de planification de tâches, les agents LLM peuvent interagir avec des systèmes externes et surmonter les limitations traditionnelles des LLM, telles que les limites de connaissances, les hallucinations et les calculs imprécis. Les outils peuvent prendre diverses formes, telles que des appels d'API, des fonctions Python ou des plugins basés sur des webhooks. Par exemple, un LLM peut utiliser un « plugin de récupération » pour récupérer le contexte pertinent et effectuer du RAG.

Alors, qu'est-ce que cela signifie pour un LLM de choisir des outils et de planifier des tâches ? Il existe de nombreuses approches (telles que Réagir, MRKL, Formeur d'outils, CâlinsGPT, et Agent transformateurs) à l'utilisation des LLM avec des outils, et les progrès se produisent rapidement. Mais un moyen simple consiste à inviter un LLM avec une liste d'outils et à lui demander de déterminer 1) si un outil est nécessaire pour satisfaire la requête de l'utilisateur, et si c'est le cas, 2) de sélectionner l'outil approprié. Une telle invite ressemble généralement à l'exemple suivant et peut inclure quelques exemples pour améliorer la fiabilité du LLM dans la sélection du bon outil.

''' Votre tâche consiste à sélectionner un outil pour répondre à une question d'utilisateur. Vous avez accès aux outils suivants. recherche : rechercher une réponse dans la FAQ ordre : commander des articles noop : aucun outil n'est nécessaire {quelques exemples de plans} Question : {input} Outil : '''

Des approches plus complexes impliquent l'utilisation d'un LLM spécialisé capable de décoder directement les « appels API » ou « l'utilisation d'outils », tels que GorilleLLM. Ces LLM affinés sont formés sur des ensembles de données de spécification d'API pour reconnaître et prédire les appels d'API en fonction des instructions. Souvent, ces LLM nécessitent des métadonnées sur les outils disponibles (descriptions, yaml ou schéma JSON pour leurs paramètres d'entrée) afin de générer des invocations d'outils. Cette approche est adoptée par les agents d'Amazon Bedrock et Appels de fonctions OpenAI. Notez que les LLM doivent généralement être suffisamment volumineux et complexes pour montrer la capacité de sélection d'outils.

Architecture d'agent LLM typique

En supposant que les mécanismes de planification des tâches et de sélection des outils soient choisis, un programme d'agent LLM typique fonctionne dans l'ordre suivant :

  1. Demande de l'utilisateur – Le programme prend une entrée utilisateur telle que « Où est ma commande 123456?" à partir d'une application client.
  2. Planifier les prochaines actions et sélectionner les outils à utiliser – Ensuite, le programme utilise une invite pour que le LLM génère l'action suivante, par exemple : « Recherchez le tableau des commandes en utilisant CommandesAPI.» Le LLM est invité à suggérer un nom d'outil tel que CommandesAPI à partir d'une liste prédéfinie d'outils disponibles et de leurs descriptions. Alternativement, le LLM pourrait être invité à générer directement un appel API avec des paramètres d'entrée tels que CommandesAPI(12345).
    1. Notez que l'action suivante peut impliquer ou non l'utilisation d'un outil ou d'une API. Dans le cas contraire, le LLM répondrait aux entrées de l'utilisateur sans incorporer de contexte supplémentaire provenant des outils ou renverrait simplement une réponse prédéfinie telle que « Je ne peux pas répondre à cette question ».
  3. Demande d'outil d'analyse – Ensuite, nous devons analyser et valider la prédiction outil/action proposée par le LLM. La validation est nécessaire pour garantir que les noms d'outils, les API et les paramètres de requête ne sont pas hallucinés et que les outils sont correctement invoqués conformément aux spécifications. Cette analyse peut nécessiter un appel LLM distinct.
  4. Outil d'appel – Une fois que le(s) nom(s) et paramètre(s) d'outil valides sont assurés, nous invoquons l'outil. Il peut s'agir d'une requête HTTP, d'un appel de fonction, etc.
  5. Analyser la sortie – La réponse de l'outil peut nécessiter un traitement supplémentaire. Par exemple, un appel d'API peut entraîner une longue réponse JSON, dans laquelle seul un sous-ensemble de champs intéresse le LLM. Extraire les informations dans un format propre et standardisé peut aider le LLM à interpréter le résultat de manière plus fiable.
  6. Interpréter la sortie – Compte tenu du résultat de l'outil, le LLM est à nouveau invité à lui donner un sens et à décider s'il peut générer la réponse finale à l'utilisateur ou si des actions supplémentaires sont nécessaires.
  7. Terminer ou passer à l'étape 2 – Soit renvoyer une réponse finale, soit une réponse par défaut en cas d’erreurs ou de délais d’attente.

Différents frameworks d'agents exécutent différemment le flux de programme précédent. Par exemple, Réagir combine la sélection d'outils et la génération de réponses finales en une seule invite, au lieu d'utiliser des invites distinctes pour la sélection d'outils et la génération de réponses. En outre, cette logique peut être exécutée en un seul passage ou dans une instruction while (la « boucle d'agent »), qui se termine lorsque la réponse finale est générée, qu'une exception est levée ou qu'un délai d'attente se produit. Ce qui reste constant, c'est que les agents utilisent le LLM comme pièce maîtresse pour orchestrer la planification et les invocations d'outils jusqu'à la fin de la tâche. Nous montrons ensuite comment implémenter une boucle d'agent simple à l'aide des services AWS.

Vue d'ensemble de la solution

Pour cet article de blog, nous implémentons un agent LLM de support e-commerce qui fournit deux fonctionnalités optimisées par des outils :

  • Outil de récupération du statut de retour – Répondez aux questions sur l’état des retours telles que « Qu’arrive-t-il à mon retour ? rtn001?"
  • Outil de récupération du statut des commandes – Suivez l'état des commandes, par exemple « Quel est l'état de ma commande ? 123456?"

L'agent utilise efficacement le LLM comme routeur de requêtes. Étant donné une requête (« Quel est le statut de la commande ? 123456?"), sélectionnez l'outil de récupération approprié pour effectuer une requête sur plusieurs sources de données (c'est-à-dire les retours et les commandes). Nous effectuons le routage des requêtes en demandant au LLM de choisir parmi plusieurs outils de récupération, qui sont responsables de l'interaction avec une source de données et de la récupération du contexte. Cela étend le modèle RAG simple, qui suppose une seule source de données.

Les deux outils de récupération sont des fonctions Lambda qui prennent un identifiant (numéro de commande ou ID de retour) en entrée, récupère un objet JSON à partir de la source de données et convertit le JSON en une chaîne de représentation conviviale pouvant être utilisée par LLM. La source de données dans un scénario réel pourrait être une base de données NoSQL hautement évolutive telle que DynamoDB, mais cette solution utilise du Python simple. Dicté avec des exemples de données à des fins de démonstration.

Des fonctionnalités supplémentaires peuvent être ajoutées à l'agent en ajoutant des outils de récupération et en modifiant les invites en conséquence. Cet agent peut être testé en tant que service autonome qui s'intègre à n'importe quelle interface utilisateur via HTTP, ce qui peut être réalisé facilement avec Amazon Lex.

Vue d'ensemble de la solution

Voici quelques détails supplémentaires sur les composants clés :

  1. Point de terminaison d’inférence LLM – Le cœur d’un programme d’agent est un LLM. Nous utiliserons le hub de modèles de fondation SageMaker JumpStart pour déployer facilement le Flan-UL2 modèle. SageMaker JumpStart facilite le déploiement de points de terminaison d'inférence LLM sur des instances SageMaker dédiées.
  2. Orchestrateur d'agents – L'agent Orchestrator orchestre les interactions entre le LLM, les outils et l'application client. Pour notre solution, nous utilisons une fonction AWS Lambda pour piloter ce flux et employons les éléments suivants comme fonctions d'assistance.
    • Planificateur de tâches (outils) – Le planificateur de tâches utilise le LLM pour suggérer l'un des éléments suivants : 1) demande de retours, 2) demande de commande ou 3) aucun outil. Nous utilisons uniquement une ingénierie rapide et Flan-UL2 modèle tel quel sans réglage fin.
    • Analyseur d'outils - L'analyseur d'outils garantit que la suggestion d'outil du planificateur de tâches est valide. Nous veillons notamment à ce qu'un seul numéro de commande ou ID de retour peut être analysé. Sinon, nous répondons avec un message par défaut.
    • Répartiteur d'outils – Le répartiteur d'outils appelle des outils (fonctions Lambda) à l'aide des paramètres valides.
    • Analyseur de sortie – L'analyseur de sortie nettoie et extrait les éléments pertinents de JSON dans une chaîne lisible par l'homme. Cette tâche est effectuée à la fois par chaque outil de récupération ainsi qu'au sein de l'orchestrateur.
    • Interpréteur de sortie – La responsabilité de l'interpréteur de sortie est de 1) interpréter le résultat de l'invocation de l'outil et 2) de déterminer si la demande de l'utilisateur peut être satisfaite ou si des étapes supplémentaires sont nécessaires. Dans ce dernier cas, une réponse finale est générée séparément et renvoyée à l’utilisateur.

Examinons maintenant un peu plus en détail les composants clés : l'orchestrateur d'agents, le planificateur de tâches et le répartiteur d'outils.

Orchestrateur d'agents

Vous trouverez ci-dessous une version abrégée de la boucle d'agent dans la fonction Lambda de l'orchestrateur d'agent. La boucle utilise des fonctions d'assistance telles que planificateur_de tâches ou outil_parser, pour modulariser les tâches. La boucle ici est conçue pour s'exécuter au maximum deux fois pour éviter que le LLM ne soit bloqué dans une boucle inutilement longue.

#.. imports ..
MAX_LOOP_COUNT = 2 # stop the agent loop after up to 2 iterations
# ... helper function definitions ...
def agent_handler(event):
    user_input = event["query"]
    print(f"user input: {user_input}") 
    
    final_generation = ""
    is_task_complete = False
    loop_count = 0 

    # start of agent loop
    while not is_task_complete and loop_count < MAX_LOOP_COUNT:
        tool_prediction = task_planner(user_input)
        print(f"tool_prediction: {tool_prediction}")  
        
        tool_name, tool_input, tool_output, error_msg = None, None, "", ""

        try:
            tool_name, tool_input = tool_parser(tool_prediction, user_input)
            print(f"tool name: {tool_name}") 
            print(f"tool input: {tool_input}") 
        except Exception as e:
            error_msg = str(e)
            print(f"tool parse error: {error_msg}")  
    
        if tool_name is not None: # if a valid tool is selected and parsed 
            raw_tool_output = tool_dispatch(tool_name, tool_input)
            tool_status, tool_output = output_parser(raw_tool_output)
            print(f"tool status: {tool_status}")  

            if tool_status == 200:
                is_task_complete, final_generation = output_interpreter(user_input, tool_output) 
            else:
                final_generation = tool_output
        else: # if no valid tool was selected and parsed, either return the default msg or error msg
            final_generation = DEFAULT_RESPONSES.NO_TOOL_FEEDBACK if error_msg == "" else error_msg
    
        loop_count += 1

    return {
        'statusCode': 200,
        'body': final_generation
    }

Planificateur de tâches (prédiction d'outils)

L'orchestrateur d'agents utilise planificateur de tâches pour prédire un outil de récupération basé sur l'entrée de l'utilisateur. Pour notre agent LLM, nous utiliserons simplement l'ingénierie rapide et quelques invites pour enseigner cette tâche au LLM dans son contexte. Des agents plus sophistiqués pourraient utiliser un LLM affiné pour la prédiction des outils, ce qui dépasse le cadre de cet article. L'invite est la suivante :

tool_selection_prompt_template = """ Votre tâche consiste à sélectionner les outils appropriés pour satisfaire la saisie de l'utilisateur. Si aucun outil n'est requis, choisissez "no_tool". Les outils disponibles sont : return_inquiry : base de données d'informations sur le statut d'une déclaration spécifique, qu'elle soit en attente, traitée, etc. order_inquiry : informations sur le statut d'une commande spécifique, telles que le statut d'expédition, le produit, le montant, etc. no_tool : aucun outil n'est nécessaire pour répondre à la saisie de l'utilisateur. Vous pouvez suggérer plusieurs outils, séparés par une virgule. Exemples : user : " Quelles sont vos heures d'ouverture ?" outil : utilisateur no_tool : "La commande 12345 a-t-elle été expédiée ?" outil : utilisateur order_inquiry : "Le retour ret812 a-t-il été traité ?" outil : retours_inquiry utilisateur : "De combien de jours ai-je avant de retourner les commandes ?" outil : return_inquiry user : "Quel était le total de la commande 38745 ?" outil : order_inquiry user : "Puis-je retourner ma commande 38756 en fonction de la politique du magasin ?" outil : order_inquiry user : "Bonjour" outil : no_tool user : "Êtes-vous une IA ?" Outil : utilisateur no_tool : "Quel temps fait-il ?" Outil : utilisateur no_tool : "Quel est l'état du remboursement de la commande 12347 ?" Outil : utilisateur order_inquiry : "Quel est l'état du remboursement du retour ret172 ?" Outil : saisie de l'utilisateur return_inquiry : {} outil: """

Répartiteur d'outils

Le mécanisme de répartition des outils fonctionne via sinon logique pour appeler les fonctions Lambda appropriées en fonction du nom de l'outil. Ce qui suit est outil_dispatch implémentation de la fonction d'assistance. Il est utilisé à l'intérieur du agent boucle et renvoie la réponse brute de la fonction Lambda de l'outil, qui est ensuite nettoyée par un analyseur_de sortie fonction.


def tool_dispatch(tool_name, tool_input):
    #...
     
    tool_response = None 

    if tool_name == "returns_inquiry":
        tool_response = lambda_client.invoke(
            FunctionName=RETURNS_DB_TOOL_LAMBDA,
            InvocationType="RequestResponse",
            Payload=json.dumps({
              "returnId": tool_input  
            })
        )
    elif tool_name == "order_inquiry":
        tool_response = lambda_client.invoke(
            FunctionName=ORDERS_DB_TOOL_LAMBDA,
            InvocationType="RequestResponse",
            Payload=json.dumps({
                "orderId": tool_input
            })
        )
    else:
        raise ValueError("Invalid tool invocation")
        
    return tool_response

Déployer la solution

Conditions préalables importantes – Pour commencer le déploiement, vous devez remplir les conditions préalables suivantes :

  • Accès à AWS Management Console via un utilisateur pouvant lancer les piles AWS CloudFormation
  • Familiarité avec la navigation dans AWS Lambda et AmazonLex consoles
  • Flan-UL2 nécessite un seul ml.g5.12xlarge pour le déploiement, ce qui peut nécessiter une augmentation des limites de ressources via un ticket de support. Dans notre exemple, nous utilisons nous-est-1 en tant que Région, assurez-vous donc d'augmenter le quota de service (si nécessaire) dans nous-est-1.

Déployer à l'aide de CloudFormation – Vous pouvez déployer la solution pour nous-est-1 en cliquant sur le bouton ci-dessous :

Pile de lancement

Le déploiement de la solution prendra environ 20 minutes et créera un LLMAgentStack pile, qui :

  • déploie le point de terminaison SageMaker à l'aide Flan-UL2 modèle de SageMaker JumpStart ;
  • déploie trois fonctions Lambda : LLMAgentOrchestreur, LLMAgentReturnsTool, LLMAgentOrdersTool; et
  • déploie un AWSLex bot pouvant être utilisé pour tester l'agent : Sagemaker-Jumpstart-Flan-LLM-Agent-Fallback-Bot.

Testez la solution

La pile déploie un bot Amazon Lex portant le nom Sagemaker-Jumpstart-Flan-LLM-Agent-Fallback-Bot. Le bot peut être utilisé pour tester l’agent de bout en bout. Voici un guide complet supplémentaire pour tester les robots AWS Amazon Lex avec une intégration Lambda et comment l'intégration fonctionne à un niveau élevé. Mais en bref, le bot Amazon Lex est une ressource qui fournit une interface utilisateur rapide pour discuter avec l'agent LLM exécuté dans une fonction Lambda que nous avons créée (LLMAgentOrchestreur).

Les exemples de cas de test à prendre en compte sont les suivants :

  • Demande de commande valide (par exemple, « Quel article a été commandé pour 123456?" »
    • La commande « 123456 » est une commande valide, nous devons donc nous attendre à une réponse raisonnable (par exemple « Savon à base de plantes »).
  • Demande de retour valide pour un retour (par exemple, « Quand est mon retour rtn003 traité?")
    • Nous devons nous attendre à une réponse raisonnable sur le statut du retour.
  • Sans rapport avec les retours ou les commandes (par exemple, « Quel temps fait-il en Écosse en ce moment ? »)
    • Une question non pertinente pour les retours ou les commandes, donc une réponse par défaut doit être renvoyée (« Désolé, je ne peux pas répondre à cette question. »)
  • Demande de commande invalide (par exemple, « Quel article a été commandé pour 383833?" »
    • L'identifiant 383832 n'existe pas dans l'ensemble de données des commandes et nous devrions donc échouer normalement (par exemple, "Commande introuvable. Veuillez vérifier votre identifiant de commande.")
  • Demande de retour invalide (par exemple : « Quand est-ce que je reviens rtn123 traité?")
    • De même, id rtn123 n'existe pas dans l'ensemble de données de retour et devrait donc échouer normalement.
  • Demande de retour non pertinente (par exemple : « Quel est l'impact du retour rtn001 sur la paix mondiale ? »)
    • Cette question, même si elle semble concerner une ordonnance valide, n'est pas pertinente. Le LLM est utilisé pour filtrer les questions dont le contexte n'est pas pertinent.

Pour exécuter ces tests vous-même, voici les instructions.

  1. Sur la console Amazon Lex (Console AWS > Amazon Lex), accédez au bot intitulé Sagemaker-Jumpstart-Flan-LLM-Agent-Fallback-Bot. Ce bot a déjà été configuré pour appeler le LLMAgentOrchestreur Fonction Lambda chaque fois que le Intention de repli est déclenché.
  2. Dans le volet de navigation, choisissez Intentions.
    navigation intentionnelle
  3. Choisir Construire dans le coin supérieur droit
    Lex Bot démarre la construction
  4. 4. Attendez la fin du processus de construction. Une fois l'opération terminée, vous recevez un message de réussite, comme le montre la capture d'écran suivante.
    construire le statut terminé
  5. Testez le bot en saisissant les cas de test.
    Redimensionnement de la capture d'écran du bot ML 15042

Nettoyer

Pour éviter des frais supplémentaires, supprimez les ressources créées par notre solution en suivant ces étapes :

  • Sur le AWS CloudFormation console, sélectionnez la pile nommée LLMAgentStack (ou le nom personnalisé que vous avez choisi).
  • Choisir Supprimer
  • Vérifiez que la pile est supprimée de la console CloudFormation.

Important: vérifiez à nouveau que la pile est supprimée avec succès en vous assurant que le Flan-UL2 Le point final d’inférence est supprimé.

  • Pour vérifier, allez sur Console AWS > Sagemaker > Points de terminaison > Inférence page.
  • La page doit répertorier tous les points de terminaison actifs.
  • S'assurer sm-jumpstart-flan-bot-endpoint n'existe pas comme la capture d'écran ci-dessous.

sagemaker nettoyer

Considérations pour la production

Le déploiement d'agents LLM en production nécessite de prendre des mesures supplémentaires pour garantir la fiabilité, les performances et la maintenabilité. Voici quelques considérations avant de déployer des agents en production :

  • Sélection du modèle LLM pour alimenter la boucle d'agent : Pour la solution discutée dans cet article, nous avons utilisé un Flan-UL2 modèle sans réglage fin pour effectuer la planification des tâches ou la sélection des outils. En pratique, l'utilisation d'un LLM optimisé pour générer directement des requêtes d'outils ou d'API peut augmenter la fiabilité et les performances, ainsi que simplifier le développement. Nous pourrions affiner un LLM sur les tâches de sélection d'outils ou utiliser un modèle qui décode directement les jetons d'outils comme Toolformer.
    • L’utilisation de modèles affinés peut également simplifier l’ajout, la suppression et la mise à jour des outils disponibles pour un agent. Avec des approches basées uniquement sur les invites, la mise à jour des outils nécessite de modifier chaque invite dans l'orchestrateur d'agents, telles que celles pour la planification des tâches, l'analyse des outils et la répartition des outils. Cela peut être fastidieux et les performances peuvent se dégrader si trop d'outils sont fournis dans le contexte du LLM.
  • Fiabilité et performances : Les agents LLM peuvent ne pas être fiables, en particulier pour les tâches complexes qui ne peuvent être réalisées en quelques boucles. L'ajout de validations de sortie, de nouvelles tentatives, la structuration des sorties des LLM en JSON ou yaml et l'application de délais d'attente pour fournir des trappes de sortie pour les LLM bloqués dans des boucles peuvent améliorer la fiabilité.

Conclusion

Dans cet article, nous avons exploré comment créer un agent LLM capable d'utiliser plusieurs outils à partir de zéro, en utilisant l'ingénierie d'invites de bas niveau, les fonctions AWS Lambda et SageMaker JumpStart comme éléments de base. Nous avons discuté en détail de l'architecture des agents LLM et de la boucle d'agent. Les concepts et l'architecture de solution présentés dans cet article de blog peuvent convenir aux agents qui utilisent un petit nombre d'outils prédéfinis. Nous avons également discuté de plusieurs stratégies d'utilisation des agents en production. Agents for Bedrock, qui est en version préliminaire, fournit également une expérience gérée pour la création d'agents avec une prise en charge native des appels d'outils agents.


A propos de l'auteur

John HwangJohn Hwang est un architecte d'IA générative chez AWS avec un accent particulier sur les applications LLM (Large Language Model), les bases de données vectorielles et la stratégie de produits d'IA générative. Il est passionné par l'aide aux entreprises dans le développement de produits IA/ML et par l'avenir des agents et copilotes LLM. Avant de rejoindre AWS, il était chef de produit chez Alexa, où il a contribué à introduire l'IA conversationnelle sur les appareils mobiles, ainsi que négociant en produits dérivés chez Morgan Stanley. Il est titulaire d'une licence en informatique de l'Université de Stanford.



Lien source

Laisser une réponse

Votre adresse email ne sera pas publiée. Les champs requis sont indiqués *

Vous pouvez utiliser ces balises et attributs HTML : <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

fr_FRFrench