Construção de sistemas colaborativos e multi-agentes com Connected Agents (clássico)

Nota

Este documento refere-se ao portal Microsoft Foundry (clássico).

Os Agentes (clássicos) estão agora obsoletos e serão descontinuados a 31 de março de 2027. Use os novos agentes no Serviço de Agentes Foundry da Microsoft, disponível para o público em geral. Siga o guia de migração para atualizar as suas cargas de trabalho.

Nota

Esta ferramenta está disponível apenas em 2025-05-15-preview API. Recomendamos vivamente que migre para usar os 2025-11-15-previewfluxos de trabalho da versão da API para orquestração multi-agente.

Os agentes ligados no Foundry Agent Service permitem-lhe dividir tarefas complexas em funções coordenadas e especializadas — sem necessidade de um orquestrador personalizado ou lógica de encaminhamento codificada manualmente. Com esta capacidade, pode conceber sistemas onde um agente principal delegue inteligentemente a subagentes construídos para esse fim, simplificando fluxos de trabalho como apoio ao cliente, pesquisa de mercado, resumo jurídico e análise financeira.

Em vez de sobrecarregar um agente com demasiadas competências, pode construir agentes focados e reutilizáveis que colaboram de forma fluida — escalando tanto o desempenho como a manutenção.

Características

  • Design simplificado de fluxos de trabalho: Decomponha tarefas complexas entre agentes especializados para reduzir a complexidade e melhorar a clareza.
  • Não é necessária orquestração personalizada: O agente principal utiliza linguagem natural para encaminhar tarefas, eliminando a necessidade de lógica codificada fixamente.
  • Extensibilidade fácil: Adicionar novos agentes ligados (por exemplo, translação ou pontuação de risco) sem modificar o agente principal.
  • Fiabilidade e rastreabilidade melhoradas: Atribuir responsabilidades focadas a cada agente para facilitar a depuração e melhor auditabilidade.
  • Opções de configuração flexíveis: Configurar agentes usando uma interface no-code no portal Foundry ou programaticamente através do SDK Python.

Exemplo: construir um agente modular de revisão de contratos com agentes ligados

À medida que os seus casos de uso crescem em complexidade, pode escalar a sua solução de IA atribuindo responsabilidades específicas a múltiplos agentes ligados. Isto permite que cada agente se especialize numa tarefa específica, enquanto o agente principal coordena o fluxo de trabalho global. Este design modular melhora a precisão, a manutenção e a rastreabilidade — especialmente para áreas com muitos documentos como jurídico, conformidade e aquisições. Vamos apresentar um exemplo real de como construir um Assistente de Revisão de Contratos usando agentes ligados.

Visão Geral da Arquitetura

Agente principal – orquestrador contratado

Funciona como a interface central. Interpreta os prompts do utilizador (como "resumir cláusulas", "comparar rascunhos" ou "verificar a conformidade"), determina o tipo de tarefa e delega-o ao agente ligado apropriado.

  • Ferramentas Usadas: Nenhuma diretamente

  • Responsabilidades: Classificação e delegação de intenções

  • Exemplo de Descrição do Agente:

    "És assistente de revisão de contratos. Dependendo da consulta do utilizador, determine se a tarefa envolve resumo de cláusulas, comparação de documentos ou verificação de conformidade, e encaminhe em conformidade."

Agente ligado 1: sumário de cláusulas

Extrai secções-chave (como Rescisão, Indemnização ou Confidencialidade) de um contrato e resume-as em linguagem simples.

  • Ferramentas Utilizadas:

    • Pesquisa de ficheiros para recuperar o contrato carregado
    • Interpretador de Código para analisar o documento em busca de cabeçalhos de cláusulas e resumir o conteúdo
  • Responsabilidades: Extração e sumarização de informação

  • Exemplo de descrição do agente:

    Extrair e resumir as cláusulas de 'Rescisão', 'Termos de pagamento' e 'Indemnização' do contrato fornecido.

Agente ligado 2: validador de conformidade

Verifica o contrato em relação às normas internas ou diretrizes carregadas para identificar linguagem arriscada ou não conforme.

  • Ferramentas Utilizadas:

    • Pesquisa de Ficheiros para aceder a documentos internos de políticas ou modelos de contratos
    • Ferramenta OpenAPI para chamar uma API interna de regras de conformidade
    • Azure Function ou Azure Logic Apps para executar verificações lógicas simples (por exemplo, presença obrigatória de cláusulas ou validações de limiar)
  • Responsabilidades: Correspondência de políticas e sinalização de risco

  • Exemplo de Instrução por Prompt:

    "Revise este documento em conformidade com as diretrizes de conformidade da empresa e sinalize quaisquer desvios ao modelo aprovado."

Limitações

  • Agentes ligados não podem chamar funções locais usando a ferramenta de chamada de funções. Recomendamos usar a ferramenta OpenAPI ou Funções do Azure em vez disso.
  • Atualmente, não é possível garantir que as citações serão transmitidas por agentes conectados. Pode tentar usar a engenharia de prompts combinada com diferentes modelos para tentar melhorar a possibilidade de citações serem geradas pelo agente principal, mas os resultados podem variar.
  • Os agentes ligados têm uma profundidade máxima de 2. Um agente pai pode ter múltiplos irmãos subagentes, mas subagentes não podem ter os seus próprios subagentes. Exceder esta profundidade resulta num Assistant Tool Call Depth Error.

Criação de uma configuração multi-agente

  1. Navegue até à página de Agentes no portal
  2. Selecione um agente existente da lista ou crie um novo.
  3. Desça até à secção Agentes Conectados no painel de configuração do agente e selecione Adicionar +.

Uma captura de ecrã da página dos agentes na Microsoft Foundry.

  1. No diálogo que aparece, escolha um agente para o agente principal delegar tarefas e descreva:

    • Selecione um agente existente no menu dropdown. Este é o agente ligado a quem o agente principal delega tarefas.
    • Introduza um nome único para o agente ligado (apenas letras e sublinhas). Este nome é usado para chamadas de funções ao nível da API. Mantém-na descritiva e legível por máquina para maximizar a precisão da recordação (por exemplo, summarize_text, lookup_product_info).
    • Adicione uma descrição clara de quando e porquê o agente ligado deve ser invocado. Isto ajuda a orientar a tomada de decisão do agente principal sobre quando entregar tarefas aos agentes ligados durante a execução.
  2. Selecionar Adicionar +

  3. Repita os passos 3–5 para adicionar agentes especializados adicionais ao agente principal.

  4. Assim que os agentes ligados aparecerem no painel de configuração, desloce-se para cima e selecione Tentar no Playground

  5. Utilize prompts de teste no Agent Playground para validar se o agente principal encaminha corretamente as tarefas para os agentes conectados, quando aplicável. Por exemplo, se criou um agente principal chamado research_agent, que não tem ferramentas configuradas, e ligou um agente chamado stock_price_bot, tente um prompt como:

    "Qual é o preço atual da ação da Microsoft?"

    O research_agent deve delegar este pedido a stock_price_bot com base na descrição do encaminhamento que definiu.

Uma captura de ecrã da tela de agentes conectados

Usa o SDK .NET

Nota

Isto mostra um uso síncrono. Pode encontrar um exemplo assíncrono em GitHub

Para permitir que o seu Agente use um agente ligado, utiliza ConnectedAgentToolDefinition juntamente com o ID do agente, nome e uma descrição.

  1. Primeiro, precisamos de criar o cliente agente e ler as variáveis de ambiente, que serão usadas nos próximos passos.

    var projectEndpoint = configuration["ProjectEndpoint"];
    var modelDeploymentName = configuration["ModelDeploymentName"];
    
    PersistentAgentsClient client = new(projectEndpoint, new DefaultAzureCredential());
    
  2. De seguida, vamos criar o agente mainAgentprincipal e o agente ligado stockAgent usando o agente cliente. Este agente ligado será usado para inicializar o 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. Agora vamos criar o tópico, adicionar a mensagem, contendo uma pergunta para o agente, e iniciar a execução.

    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. Imprime as mensagens do agente para a consola por ordem cronológica.

    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. Limpe os recursos eliminando o thread e o agente.

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

Criação de uma configuração multi-agente

Para criar uma configuração multi-agente, siga estes passos:

  1. Inicialize o objeto cliente.

    import os
    from azure.ai.projects import AIProjectClient
    from azure.ai.agents.models import ConnectedAgentTool, MessageRole
    from azure.identity import DefaultAzureCredential
    
    
    project_client = AIProjectClient(
    endpoint=os.environ["PROJECT_ENDPOINT"],
    credential=DefaultAzureCredential(),
    )
    
  2. Crie um agente que esteja ligado a um agente "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. Inicializar a ferramenta do agente conectado com o ID do agente, nome e descrição

    connected_agent = ConnectedAgentTool(
        id=stock_price_agent.id, name=stock_price_agent.name, description="Gets the stock price of a company"
    )
    
  4. Cria o agente "principal" que vai usar o agente ligado.

    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. Cria um tópico e adiciona uma mensagem a ele.

    thread = project_client.agents.threads.create()
    print(f"Created thread, ID: {thread.id}")
    
    # Create message to thread
    message = project_client.agents.messages.create(
        thread_id=thread.id,
        role=MessageRole.USER,
        content="What is the stock price of Microsoft?",
    )
    print(f"Created message, ID: {message.id}")
    
    
  6. Cria uma corrida e espera que ela termine.

    
    # Create and process Agent run in thread with tools
    run = project_client.agents.runs.create_and_process(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. Imprime a resposta do agente. O agente principal compila as respostas dos agentes ligados e fornece a resposta. As respostas do agente ligado são visíveis apenas para o agente principal, e não para o utilizador final.

    # Print the Agent's response message with optional citation
    response_message = project_client.agents.messages.get_last_message_by_role(
        thread_id=thread.id, 
        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})")
    

Publicar agentes conectados no Azure

Depois de testares os teus agentes ligados, podes publicá-los no Azure para uso em produção. O processo de publicação para agentes ligados tem uma diferença fundamental em relação à publicação de agentes individuais: tanto o agente principal como todos os agentes ligados devem ser publicados separadamente como Aplicações de Agente.

Considerações específicas dos agentes conectados

  • Publique cada agente individualmente: Publique primeiro os agentes ligados, depois o agente principal. Cada um recebe o seu próprio endpoint estável e Identidade de Agente.
  • O encaminhamento continua a funcionar: Após a publicação, o agente principal encaminha automaticamente para os agentes conectados publicados usando os seus IDs de Agente no ConnectedAgentToolDefinitionarquivo . Não são necessárias alterações de código.
  • Gestão de identidade: Agentes conectados publicados recebem a sua própria identidade de agente. Reconfigure as permissões para quaisquer recursos do Azure a que os seus agentes conectados acedam, pois as permissões de identidade de desenvolvimento partilhada não são transferidas.

Para instruções completas de publicação, incluindo como publicar agentes através do portal ou da API REST, configuração de autenticação e consumo de agentes publicados, consulte no Microsoft Foundry.