Partager via


Créer des systèmes collaboratifs multi-agents avec des agents connectés

Les agents connectés dans le service Azure AI Foundry Agent vous permettent de décomposer les tâches complexes en rôles coordonnés et spécialisés, sans avoir besoin d’un orchestrateur personnalisé ou d’une logique de routage codée manuellement. Grâce à cette fonctionnalité, vous pouvez concevoir des systèmes où un agent principal délègue intelligemment à des sous-agents intégrés à des fins, rationalisant les flux de travail tels que le support client, la recherche sur le marché, le résumé juridique et l’analyse financière.

Au lieu de surcharger un agent avec trop de compétences, vous pouvez créer des agents concentrés et réutilisables qui collaborent en toute transparence, ce qui permet de mettre à l’échelle les performances et la facilité de maintenance.

Fonctionnalités

  • Conception simplifiée du flux de travail : décomposez les tâches complexes entre les agents spécialisés afin de réduire la complexité et d’améliorer la clarté.
  • Aucune orchestration personnalisée n’est requise : l’agent principal utilise le langage naturel pour acheminer les tâches, éliminant ainsi la nécessité d’une logique codée en dur.
  • Extensibilité simple : ajoutez de nouveaux agents connectés (par exemple, traduction ou scoring des risques) sans modifier l’agent principal.
  • Amélioration de la fiabilité et de la traçabilité : attribuez des responsabilités ciblées à chaque agent pour faciliter le débogage et améliorer l’audit.
  • Options de configuration flexibles : configurez des agents à l’aide d’une interface sans code dans le portail Foundry ou par programmation via le Kit de développement logiciel (SDK) Python.

Exemple : création d’un agent de révision de contrat modulaire avec des agents connectés

À mesure que vos cas d’usage augmentent en complexité, vous pouvez mettre à l’échelle votre solution IA en affectant des responsabilités spécifiques à plusieurs agents connectés. Cela permet à chaque agent de se spécialiser dans une tâche étroite tandis que l’agent principal coordonne le flux de travail global. Cette conception modulaire améliore la précision, la facilité de maintenance et la traçabilité, en particulier pour les domaines lourds de documents tels que les domaines juridiques, de conformité et d’approvisionnement. Examinons un exemple réel de création d’un Assistant Révision de contrat à l’aide d’agents connectés.

Présentation de l'architecture

Agent principal - coordonateur de contrat

Agit comme interface centrale. Il interprète les invites utilisateur (par exemple, « résumer les clauses », « comparer les brouillons » ou « vérifier la conformité »), détermine le type de tâche et le délègue à l’agent connecté approprié.

  • Outils utilisés : Aucun directement

  • Responsabilités : Classification et délégation des intentions

  • Exemple de description de l’agent :

    « Vous êtes assistant de révision de contrat. Selon la requête de l’utilisateur, déterminez si la tâche implique le résumé des clauses, la comparaison de documents ou la vérification de conformité, et routez-en conséquence.

Agent connecté 1 : récapitulateur de clause

Extrait les sections clés (comme l’arrêt, l’indemnité ou la confidentialité) d’un contrat et les récapitule en langage brut.

  • Outils utilisés :

    • Recherche de fichiers pour récupérer le contrat chargé
    • Interpréteur de code pour analyser le document pour les en-têtes de clause et résumer le contenu
  • Responsabilités : extraction et synthèse des informations

  • Exemple de description de l’agent :

    « Extrayez et résumez les clauses « Résiliation », « Conditions de paiement » et « Indemnité » du contrat fourni. »

Agent connecté 2 : validateur de conformité

Vérifie le contrat par rapport aux normes internes ou aux instructions téléchargées pour identifier les formulations à risque ou non conformes.

  • Outils utilisés :

    • Recherche de fichiers pour accéder aux documents de stratégie interne ou aux modèles de contrat
    • Outil OpenAPI pour appeler une API de règles de conformité interne
    • Azure Function ou Azure Logic Apps pour exécuter des vérifications logiques simples (par exemple, la présence de clause ou les validations de seuil requises)
  • Responsabilités : mise en correspondance des stratégies et indicateur de risque

  • Exemple d’instruction d’invite :

    « Passez en revue ce document par rapport aux directives de conformité de l’entreprise et signalez tout écart par rapport au modèle approuvé. »

Limites

  • Les agents connectés ne peuvent pas appeler des fonctions locales à l’aide de l’outil d’appel de fonction. Nous vous recommandons d’utiliser l’outil OpenAPI ou Azure Functions à la place.
  • Il n’est actuellement pas possible de garantir que les citations seront transmises par des agents connectés. Vous pouvez essayer d’utiliser l’ingénierie rapide combinée avec différents modèles pour essayer et améliorer la possibilité que les citations soient générées par l’agent principal, mais les résultats sont soumis à la variabilité.

Création d’une configuration multi-agent

  1. Accédez à la page Agents dans le portail
  2. Sélectionnez un agent existant dans la liste ou créez-en un.
  3. Faites défiler jusqu’à la section Agents connectés dans le panneau d’installation de l’agent, puis sélectionnez Ajouter +.

Capture d’écran de la page agents dans Azure AI Foundry.

  1. Dans la boîte de dialogue qui s’affiche, choisissez un agent pour l’agent principal auquel déléguer des tâches et décrivez :

    • Sélectionnez un agent existant dans la liste déroulante. Il s’agit de l’agent connecté auquel l’agent principal délègue des tâches.
    • Entrez un nom unique pour l’agent connecté (lettres et traits de soulignement uniquement). Ce nom est utilisé pour l’appel de fonction au niveau de l’API. Conservez-la descriptive et lisible par l’ordinateur pour optimiser la précision du rappel (par exemple, summarize_text, lookup_product_info).
    • Ajoutez une description claire du moment et de la raison pour laquelle l’agent connecté doit être appelé. Cela aide à guider la prise de décision de l’agent principal sur le moment où remettre des tâches aux agents connectés pendant l’exécution.
  2. Sélectionnez Ajouter +

  3. Répétez les étapes 3 à 5 pour ajouter des agents spécialisés supplémentaires à l’agent principal.

  4. Une fois que le ou les agents connectés apparaissent dans le panneau d’installation, faites défiler vers le haut et sélectionnez Essayer dans Playground

  5. Utilisez des invites de test dans "Agent Playground" pour vérifier que l’agent principal achemine correctement les tâches vers les agents connectés lorsque cela est applicable. Par exemple, si vous avez créé un agent principal appelé research_agent, qui n’a pas d’outils configurés et connecté un agent nommé stock_price_bot, essayez une invite comme suit :

    « Qu’est-ce que le cours actuel des actions de Microsoft ? »

    research_agent devrait déléguer cette requête à stock_price_bot en fonction de la description de routage que vous avez définie.

Capture d’écran de l’écran des agents connectés

Utiliser le kit de développement logiciel (SDK) .NET

Remarque

Cela montre une utilisation synchrone. Vous trouverez un exemple asynchrone sur GitHub

Pour permettre à votre agent d’utiliser un agent connecté, vous utilisez ConnectedAgentToolDefinition l’ID de l’agent, le nom et une description.

  1. Tout d’abord, nous devons créer un client d’agent et lire les variables d’environnement, qui seront utilisées dans les étapes suivantes.

    var projectEndpoint = configuration["ProjectEndpoint"];
    var modelDeploymentName = configuration["ModelDeploymentName"];
    
    PersistentAgentsClient client = new(projectEndpoint, new DefaultAzureCredential());
    
  2. Ensuite, nous allons créer l’agent mainAgentprincipal et l’agent connecté stockAgent à l’aide du client de l’agent. Cet agent connecté sera utilisé pour initialiser le ConnectedAgentToolDefinition.

    PersistentAgent stockAgent = client.Administration.CreateAgent(
            model: modelDeploymentName,
            name: "stock_price_bot",
            instructions: "Your job is to get the stock price of a company. If you don't know the realtime stock price, return the last known stock price."
            // tools: [...] tools that would be used to get stock prices
        );
    ConnectedAgentToolDefinition connectedAgentDefinition = new(new ConnectedAgentDetails(stockAgent.Id, stockAgent.Name, "Gets the stock price of a company"));
    
    PersistentAgent mainAgent = client.Administration.CreateAgent(
            model: modelDeploymentName,
            name: "stock_price_bot",
            instructions: "Your job is to get the stock price of a company, using the available tools.",
            tools: [connectedAgentDefinition]
        );
    
    
    
  3. Nous allons maintenant créer le thread, ajouter le message, contenant une question pour l’agent et démarrer l’exécution.

    PersistentAgentThread thread = client.Threads.CreateThread();
    
    // Create message to thread
    PersistentThreadMessage message = client.Messages.CreateMessage(
        thread.Id,
        MessageRole.User,
        "What is the stock price of Microsoft?");
    
    // Run the agent
    ThreadRun run = client.Runs.CreateRun(thread, agent);
    do
    {
        Thread.Sleep(TimeSpan.FromMilliseconds(500));
        run = client.Runs.GetRun(thread.Id, run.Id);
    }
    while (run.Status == RunStatus.Queued
        || run.Status == RunStatus.InProgress);
    
    // Confirm that the run completed successfully
    if (run.Status != RunStatus.Completed)
    {
        throw new Exception("Run did not complete successfully, error: " + run.LastError?.Message);
    }
    
  4. Imprimez les messages de l’agent dans la console dans l’ordre chronologique.

    Pageable<PersistentThreadMessage> messages = client.Messages.GetMessages(
        threadId: thread.Id,
        order: ListSortOrder.Ascending
    );
    
    foreach (PersistentThreadMessage threadMessage in messages)
    {
        Console.Write($"{threadMessage.CreatedAt:yyyy-MM-dd HH:mm:ss} - {threadMessage.Role,10}: ");
        foreach (MessageContent contentItem in threadMessage.ContentItems)
        {
            if (contentItem is MessageTextContent textItem)
            {
                string response = textItem.Text;
                if (textItem.Annotations != null)
                {
                    foreach (MessageTextAnnotation annotation in textItem.Annotations)
                    {
                        if (annotation is MessageTextUriCitationAnnotation urlAnnotation)
                        {
                            response = response.Replace(urlAnnotation.Text, $" [{urlAnnotation.UriCitation.Title}]({urlAnnotation.UriCitation.Uri})");
                        }
                    }
                }
                Console.Write($"Agent response: {response}");
            }
            else if (contentItem is MessageImageFileContent imageFileItem)
            {
                Console.Write($"<image from ID: {imageFileItem.FileId}");
            }
            Console.WriteLine();
        }
    }
    
  5. Nettoyez les ressources en supprimant le thread et l’agent.

    agentClient.DeleteThread(threadId: thread.Id);
    agentClient.DeleteAgent(agentId: agent.Id);
    agentClient.DeleteAgent(agentId: connectedAgent.Id);
    

Création d’une configuration multi-agent

Pour créer une configuration multi-agent, procédez comme suit :

  1. Initialisez l’objet client.

    import os
    from azure.ai.projects import AIProjectClient
    from azure.ai.projects.models import ConnectedAgentTool, MessageRole
    from azure.identity import DefaultAzureCredential
    
    
    project_client = AIProjectClient(
    endpoint=os.environ["PROJECT_ENDPOINT"],
    credential=DefaultAzureCredential(),
    )
    
  2. Créez un agent qui sera connecté à un agent « principal ».

    stock_price_agent = project_client.agents.create_agent(
        model=os.environ["MODEL_DEPLOYMENT_NAME"],
        name="stock_price_bot",
        instructions="Your job is to get the stock price of a company. If you don't know the realtime stock price, return the last known stock price.",
        #tools=... # tools to help the agent get stock prices
    )
    
  3. Initialiser l’outil de l’agent connecté avec l’ID, le nom et la description de l’agent

    connected_agent = ConnectedAgentTool(
        id=stock_price_agent.id, name=connected_agent_name, description="Gets the stock price of a company"
    )
    
  4. Créez l’agent « principal » qui utilisera l’agent connecté.

    agent = project_client.agents.create_agent(
        model=os.environ["MODEL_DEPLOYMENT_NAME"],
        name="my-agent",
        instructions="You are a helpful agent, and use the available tools to get stock prices.",
        tools=connected_agent.definitions,
    )
    
    print(f"Created agent, ID: {agent.id}")
    
  5. Créez un thread et ajoutez-y un message.

    thread = project_client.agents.create_thread()
    print(f"Created thread, ID: {thread.id}")
    
    # Create message to thread
    message = project_client.agents.create_message(
        thread_id=thread.id,
        role=MessageRole.USER,
        content="What is the stock price of Microsoft?",
    )
    print(f"Created message, ID: {message.id}")
    
    
  6. Créez une exécution et attendez qu’elle se termine.

    
    # Create and process Agent run in thread with tools
    run = project_client.agents.create_and_process_run(thread_id=thread.id, agent_id=agent.id)
    print(f"Run finished with status: {run.status}")
    
    if run.status == "failed":
        print(f"Run failed: {run.last_error}")
    
    # Delete the Agent when done
    project_client.agents.delete_agent(agent.id)
    print("Deleted agent")
    
    # Delete the connected Agent when done
    project_client.agents.delete_agent(stock_price_agent.id)
    print("Deleted connected agent")
    
  7. Imprimez la réponse de l’agent. L’agent principal compile les réponses des agents connectés et fournit la réponse. Les réponses de l’agent connecté sont visibles uniquement par l’agent principal, et non par l’utilisateur final.

    # Print the Agent's response message with optional citation
    response_message = project_client.agents.list_messages(thread_id=thread.id).get_last_message_by_role(
        MessageRole.AGENT
    )
    if response_message:
        for text_message in response_message.text_messages:
            print(f"Agent response: {text_message.text.value}")
        for annotation in response_message.url_citation_annotations:
            print(f"URL Citation: [{annotation.url_citation.title}]({annotation.url_citation.url})")