Agent Framework da Microsoft para salvar o Natal

· 12 min de leitura

Introdução

Encontrar os presentes de Natal perfeitos pode ser estressante. Entre o brainstorming de ideias para presentes, a comparação de preços entre lojas e a garantia de que tudo chegue no prazo, as compras de fim de ano rapidamente se tornam cansativas. E se pudéssemos delegar essas tarefas a agentes especializados de IA que trabalham juntos? Nesta postagem, exploraremos como usar o Agent Framework da Microsoft para construir um sistema multiagente onde cada agente se especializa em uma tarefa específica, desde a geração de ideias de presentes até a comparação de preços, tudo coordenado por meio de fluxos de trabalho.

Calendário Festivo de Tecnologia 2025

Este projeto faz parte da minha sessão no Festive Tech Calendar 2025, um evento comunitário incrível que celebra a tecnologia durante as festas de fim de ano. Você pode encontrar mais sobre o evento em Sessionize.

O que é o Agent Framework da Microsoft?

O Agent Framework é a solução da Microsoft para construir, orquestrar e implantar agentes de IA e sistemas multiagentes. Ele fornece uma base flexível para a criação de agentes que podem trabalhar sequencialmente, simultaneamente ou por meio de padrões de transferência. A estrutura oferece suporte aos modelos OpenAI, Azure OpenAI e Microsoft Foundry, tornando-a incrivelmente versátil.

Os principais recursos incluem:

  • Orquestração multiagente: bate-papo em grupo, padrões sequenciais, simultâneos e de transferência
  • Ecossistema de plug-ins: Estenda com funções nativas, OpenAPI e Model Context Protocol (MCP)
  • Suporte ao fluxo de trabalho: crie pipelines de agentes complexos com executores e bordas

Pré-requisitos

Antes de mergulhar no código, certifique-se de ter:

-.NET 9

  • Acesso Azure OpenAI (ou chave API OpenAI)
  • Visual Studio ou Código do Visual Studio

Instale os pacotes necessários (observe que o sinalizador --prerelease é necessário durante a visualização):

dotnet add package Microsoft.Agents.AI.OpenAI --prerelease
dotnet add package Microsoft.Agents.AI.Workflows --prerelease
dotnet add package Azure.AI.OpenAI
dotnet add package Azure.Identity
dotnet add package Azure.AI.Agents.Persistent --prerelease

Os agentes de compras de presentes

Nosso localizador de presentes de Natal será composto por três agentes especializados trabalhando juntos:

  1. Agente de ideias para presentes - Gera sugestões criativas de presentes com base no perfil do destinatário
  2. Agente de comparação de preços - Encontra os melhores preços em diferentes lojas
  3. Agente de Resumo - Compila as recomendações finais

Os modelos

Vamos começar definindo nossos modelos de dados que fluirão pelo pipeline do agente:

public class GiftRecipient
{
    public string Name { get; set; } = string.Empty;
    public int Age { get; set; }
    public List<string> Interests { get; set; } = [];
    public decimal Budget { get; set; }
}

public class GiftIdea
{
    public string Name { get; set; } = string.Empty;
    public string Description { get; set; } = string.Empty;
    public string Category { get; set; } = string.Empty;
    public decimal EstimatedPrice { get; set; }
}

public class PriceResult
{
    public string GiftName { get; set; } = string.Empty;
    public string Store { get; set; } = string.Empty;
    public decimal Price { get; set; }
    public string Url { get; set; } = string.Empty;
}

public class GiftRecommendation
{
    public GiftIdea Gift { get; set; } = new();
    public List<PriceResult> Prices { get; set; } = [];
    public PriceResult? BestDeal { get; set; }
}

Construindo os Agentes

A beleza do Agent Framework é a facilidade de criar agentes especializados. Cada agente é simplesmente um ChatClientAgent com um prompt de sistema específico que define sua experiência.

using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.Workflows;
using Microsoft.Extensions.AI;

public static class ChristmasAgentFactory
{
    public static AIAgent CreateGiftIdeaAgent(IChatClient chatClient)
    {
        return new ChatClientAgent(
            chatClient,
            @"You are a creative Christmas gift advisor. When given information about a person 
            (age, interests, budget), you suggest thoughtful and personalized gift ideas.
            
            For each suggestion, provide:
            - Gift name
            - Brief description of why it's a good fit
            - Category (Electronics, Books, Fashion, Home, Experience, etc.)
            - Estimated price range
            
            Always suggest 3-5 gift options within the specified budget.
            Format your response as a structured list.");
    }

    public static AIAgent CreatePriceComparisonAgent(IChatClient chatClient)
    {
        return new ChatClientAgent(
            chatClient,
            @"You are a price comparison specialist. Given a list of gift ideas, 
            you research and compare prices from different online retailers.
            
            For each gift, provide:
            - Store name (Amazon, Best Buy, Target, Walmart, etc.)
            - Current price
            - Any available discounts or deals
            
            Always highlight the best deal for each item.
            Consider shipping costs and delivery times for Christmas.");
    }

    public static AIAgent CreateSummaryAgent(IChatClient chatClient)
    {
        return new ChatClientAgent(
            chatClient,
            @"You are a gift recommendation summarizer. Take the gift ideas and price 
            comparisons and create a final recommendation report.
            
            Your summary should:
            - Rank gifts by value (quality vs price)
            - Highlight the top pick with reasoning
            - Include total cost estimate
            - Add any tips for holiday shopping
            
            Make the summary cheerful and festive!");
    }
}

Criando o fluxo de trabalho

Agora vem a parte divertida: conectar nossos agentes em um fluxo de trabalho sequencial. O Agent Framework fornece WorkflowBuilder e AgentWorkflowBuilder para compor agentes em diferentes padrões.

public static class ChristmasGiftWorkflow
{
    public static async Task RunAsync()
    {
        // Set up the Azure OpenAI client
        var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT") 
            ?? throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT is not set.");
        var deploymentName = Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT_NAME") 
            ?? "gpt-4o-mini";
        
        var chatClient = new AzureOpenAIClient(
            new Uri(endpoint), 
            new DefaultAzureCredential())
            .GetChatClient(deploymentName)
            .AsIChatClient();

        // Create our specialized agents
        AIAgent giftIdeaAgent = ChristmasAgentFactory.CreateGiftIdeaAgent(chatClient);
        AIAgent priceAgent = ChristmasAgentFactory.CreatePriceComparisonAgent(chatClient);
        AIAgent summaryAgent = ChristmasAgentFactory.CreateSummaryAgent(chatClient);

        // Build a sequential workflow: Ideas -> Prices -> Summary
        var workflow = AgentWorkflowBuilder.BuildSequential(
            "ChristmasGiftFinder",
            [giftIdeaAgent, priceAgent, summaryAgent]);

        // Define our gift recipient
        var recipient = new GiftRecipient
        {
            Name = "Mom",
            Age = 55,
            Interests = ["gardening", "cooking", "reading", "yoga"],
            Budget = 100
        };

        var prompt = $@"Find Christmas gifts for {recipient.Name}, 
            age {recipient.Age}, who enjoys {string.Join(", ", recipient.Interests)}. 
            Budget: ${recipient.Budget}";

        // Execute the workflow with streaming
        await using StreamingRun run = await InProcessExecution.StreamAsync(
            workflow, 
            new ChatMessage(ChatRole.User, prompt));

        // Send the turn token to start processing
        await run.TrySendMessageAsync(new TurnToken(emitEvents: true));

        // Watch for workflow events
        await foreach (WorkflowEvent evt in run.WatchStreamAsync())
        {
            if (evt is AgentRunUpdateEvent agentUpdate)
            {
                Console.Write(agentUpdate.Data);
            }
            else if (evt is WorkflowOutputEvent outputEvent)
            {
                Console.WriteLine("\n🎄 Final Recommendations:");
                Console.WriteLine(outputEvent.Data);
            }
        }
    }
}

Executando Agentes Simultaneamente

E se quisermos procurar presentes para várias pessoas ao mesmo tempo? O Agent Framework oferece suporte à execução simultânea, o que é perfeito para este cenário:

public static async Task FindGiftsForEveryoneAsync(IChatClient chatClient, List<GiftRecipient> recipients)
{
    // Create an agent for each recipient
    var agents = recipients.Select(r => new ChatClientAgent(
        chatClient,
        $@"Find the perfect Christmas gift for {r.Name} (age {r.Age}), 
           who loves {string.Join(", ", r.Interests)}. Budget: ${r.Budget}.
           Provide one well-researched recommendation with price."
    )).ToList();

    // Build a concurrent workflow - all agents run in parallel
    var workflow = AgentWorkflowBuilder.BuildConcurrent(
        "FamilyGiftFinder",
        agents);

    await using StreamingRun run = await InProcessExecution.StreamAsync(
        workflow, 
        new ChatMessage(ChatRole.User, "Find gifts now!"));

    await run.TrySendMessageAsync(new TurnToken(emitEvents: true));

    await foreach (WorkflowEvent evt in run.WatchStreamAsync())
    {
        if (evt is WorkflowOutputEvent output)
        {
            Console.WriteLine("🎁 All gift recommendations ready!");
            Console.WriteLine(output.Data);
        }
    }
}

Executores personalizados para mais controlePara cenários mais complexos, você pode criar executores personalizados que oferecem controle refinado sobre o fluxo de trabalho:

public sealed class GiftValidatorExecutor : Executor<List<ChatMessage>, List<ChatMessage>>
{
    public GiftValidatorExecutor() : base("GiftValidator") { }

    public override async ValueTask<List<ChatMessage>> HandleAsync(
        List<ChatMessage> messages,
        IWorkflowContext context,
        CancellationToken cancellationToken = default)
    {
        var lastMessage = messages.LastOrDefault()?.Text ?? "";
        
        // Validate that suggestions are within budget
        if (lastMessage.Contains("over budget", StringComparison.OrdinalIgnoreCase))
        {
            Console.WriteLine("⚠️ Some suggestions exceeded budget, filtering...");
            // Add validation logic here
        }

        Console.WriteLine("✅ Gift suggestions validated!");
        return messages;
    }
}

Você pode então inserir este executor em seu fluxo de trabalho:

var validator = new GiftValidatorExecutor();

var workflow = new WorkflowBuilder(giftIdeaAgent)
    .AddEdge(giftIdeaAgent, validator)
    .AddEdge(validator, priceAgent)
    .AddEdge(priceAgent, summaryAgent)
    .WithOutputFrom(summaryAgent)
    .Build();

Adicionando pesquisa real na Web com o Bing Grounding

Até o momento, nossos agentes geram respostas baseadas no conhecimento do modelo de IA. Mas e se quisermos pesquisar na web os preços e a disponibilidade reais dos produtos? É aqui que entra o Grounding with Bing Search. É uma ferramenta disponível no Microsoft Foundry (anteriormente Azure AI Foundry) que permite que seus agentes incorporem dados públicos da Web em tempo real ao gerar respostas.

Primeiro, você precisará criar um recurso Grounding with Bing Search no Portal do Azure. Certifique-se de criá-lo no mesmo grupo de recursos do seu projeto de IA.

A beleza do Grounding with Bing Search é que ele se integra diretamente aos Azure AI Agents. O agente decide quando usar a ferramenta de pesquisa com base na consulta do usuário, pesquisa na web e usa os resultados para gerar uma resposta fundamentada.

using Azure.AI.Agents.Persistent;
using Azure.Identity;

public static class BingGroundingSetup
{
    public static async Task<PersistentAgent> CreateAgentWithBingGroundingAsync(
        string projectEndpoint,
        string modelDeploymentName,
        string bingConnectionId)
    {
        // Create the Persistent Agents client
        var agentClient = new PersistentAgentsClient(projectEndpoint, new DefaultAzureCredential());

        // Configure the Bing Grounding tool
        var bingGroundingTool = new BingGroundingToolDefinition(
            new BingGroundingSearchToolParameters(
                [new BingGroundingSearchConfiguration(bingConnectionId)]
            )
        );

        // Create the agent with Bing Grounding enabled
        var agent = await agentClient.Administration.CreateAgentAsync(
            model: modelDeploymentName,
            name: "ChristmasPriceHunter",
            instructions: @"You are a Christmas gift price comparison specialist.
                
                When given gift ideas, use Bing to search for:
                - Current prices at major retailers (Amazon, Best Buy, Target, Walmart)
                - Available discounts and holiday deals
                - Shipping times to ensure delivery before Christmas
                
                Always provide URLs to the products you find.
                Highlight the best deals and recommend where to buy.",
            tools: [bingGroundingTool]
        );

        return agent;
    }
}

Criando um agente de comparação de preços com pesquisa real

Agora vamos criar um comparador de preços completo que pesquisa na web informações reais sobre produtos:

using Azure.AI.Agents.Persistent;
using Azure.Identity;

public class ChristmasPriceAgent
{
    private readonly PersistentAgentsClient _client;
    private readonly string _modelDeployment;
    private readonly string _bingConnectionId;

    public ChristmasPriceAgent(string projectEndpoint, string modelDeployment, string bingConnectionId)
    {
        _client = new PersistentAgentsClient(projectEndpoint, new DefaultAzureCredential());
        _modelDeployment = modelDeployment;
        _bingConnectionId = bingConnectionId;
    }

    public async Task<string> FindGiftPricesAsync(string giftIdeas)
    {
        // Create agent with Bing Grounding
        var bingTool = new BingGroundingToolDefinition(
            new BingGroundingSearchToolParameters(
                [new BingGroundingSearchConfiguration(_bingConnectionId)]
            )
        );

        var agent = await _client.Administration.CreateAgentAsync(
            model: _modelDeployment,
            name: "PriceHunter",
            instructions: @"Search the web for current prices on the given gift ideas. 
                For each gift, find prices from at least 2-3 different stores.
                Include direct links to the products.
                Note any Christmas sales or discounts available.",
            tools: [bingTool]
        );

        try
        {
            // Create a thread for the conversation
            var thread = await _client.Threads.CreateThreadAsync();

            // Add the gift ideas as a message
            await _client.Messages.CreateMessageAsync(
                thread.Id,
                MessageRole.User,
                $"Find current prices for these gift ideas: {giftIdeas}"
            );

            // Run the agent
            var run = await _client.Runs.CreateRunAsync(thread.Id, agent.Id);

            // Wait for completion
            do
            {
                await Task.Delay(500);
                run = await _client.Runs.GetRunAsync(thread.Id, run.Id);
            }
            while (run.Status == RunStatus.Queued || run.Status == RunStatus.InProgress);

            // Get the response
            var messages = _client.Messages.GetMessages(thread.Id);
            var response = messages
                .Where(m => m.Role == MessageRole.Agent)
                .SelectMany(m => m.ContentItems)
                .OfType<MessageTextContent>()
                .FirstOrDefault();

            // Clean up
            await _client.Threads.DeleteThreadAsync(thread.Id);

            return response?.Text ?? "No results found.";
        }
        finally
        {
            // Clean up the agent
            await _client.Administration.DeleteAgentAsync(agent.Id);
        }
    }
}

Integrando o Bing Grounding ao fluxo de trabalho

Veja como usar o agente de preços do Bing em um fluxo de trabalho completo para encontrar presentes:

public static async Task RunWithBingGroundingAsync()
{
    var projectEndpoint = Environment.GetEnvironmentVariable("PROJECT_ENDPOINT")!;
    var modelDeployment = Environment.GetEnvironmentVariable("MODEL_DEPLOYMENT_NAME") ?? "gpt-4o";
    var bingConnectionId = Environment.GetEnvironmentVariable("BING_CONNECTION_ID")!;
    // Connection ID format: /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.CognitiveServices/accounts/{account}/projects/{project}/connections/{connection}

    Console.WriteLine("🔍 Searching the web for real prices with Bing Grounding...\n");

    var priceAgent = new ChristmasPriceAgent(projectEndpoint, modelDeployment, bingConnectionId);

    // First, generate gift ideas (could come from another agent)
    var giftIdeas = "1. Milwaukee cordless drill set, 2. Weber portable grill, 3. Carhartt beanie";

    // Search for real prices
    var priceResults = await priceAgent.FindGiftPricesAsync(giftIdeas);

    Console.WriteLine("📊 Price Comparison Results:");
    Console.WriteLine(priceResults);
    Console.WriteLine("\n🎁 Happy Shopping! 🎁");
}

Processando citações dos resultados do Bing

Um aspecto importante do Grounding with Bing Search é que as respostas incluem citações com links para os sites de origem. Veja como extraí-los e exibi-los:

public static void ProcessBingGroundingResponse(IEnumerable<PersistentThreadMessage> messages)
{
    foreach (var message in messages.Where(m => m.Role == MessageRole.Agent))
    {
        foreach (var content in message.ContentItems)
        {
            if (content is MessageTextContent textContent)
            {
                var response = textContent.Text;

                // Process URL citations
                if (textContent.Annotations != null)
                {
                    foreach (var annotation in textContent.Annotations)
                    {
                        if (annotation is MessageTextUriCitationAnnotation uriAnnotation)
                        {
                            // Replace citation placeholder with markdown link
                            response = response.Replace(
                                uriAnnotation.Text,
                                $" [{uriAnnotation.UriCitation.Title}]({uriAnnotation.UriCitation.Uri})"
                            );
                        }
                    }
                }

                Console.WriteLine(response);
            }
        }
    }
}

Agora, quando o agente de comparação de preços é executado, ele usa o Grounding with Bing Search para encontrar listas de produtos reais, preços atuais e ofertas disponíveis na web ao vivo. O agente decide automaticamente quando pesquisar com base na consulta e retorna respostas fundamentadas com citações adequadas.

O Programa Completo

Veja como tudo acontece em Program.cs:

using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.Workflows;
using Microsoft.Extensions.AI;

Console.WriteLine("🎄 Christmas Gift Finder - Powered by AI Agents 🎄\n");

var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT")!;
var deployment = Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT_NAME") ?? "gpt-4o-mini";

var chatClient = new AzureOpenAIClient(new Uri(endpoint), new DefaultAzureCredential())
    .GetChatClient(deployment)
    .AsIChatClient();

// Create the agent team
var ideaAgent = ChristmasAgentFactory.CreateGiftIdeaAgent(chatClient);
var priceAgent = ChristmasAgentFactory.CreatePriceComparisonAgent(chatClient);
var summaryAgent = ChristmasAgentFactory.CreateSummaryAgent(chatClient);

// Build the workflow
var workflow = AgentWorkflowBuilder.BuildSequential(
    "ChristmasGiftWorkflow",
    [ideaAgent, priceAgent, summaryAgent]);

Console.Write("Who are you shopping for? ");
var recipientName = Console.ReadLine() ?? "Someone special";

Console.Write("What are their interests? ");
var interests = Console.ReadLine() ?? "general";

Console.Write("What's your budget? $");
var budget = Console.ReadLine() ?? "50";

var prompt = $"Find Christmas gifts for {recipientName} who enjoys {interests}. Budget: ${budget}";

Console.WriteLine("\n🔍 Searching for the perfect gifts...\n");

await using var run = await InProcessExecution.StreamAsync(
    workflow,
    new ChatMessage(ChatRole.User, prompt));

await run.TrySendMessageAsync(new TurnToken(emitEvents: true));

await foreach (var evt in run.WatchStreamAsync())
{
    switch (evt)
    {
        case AgentRunUpdateEvent update:
            Console.Write(update.Update.Text);
            break;
        case WorkflowOutputEvent output:
            Console.WriteLine("\n\n🎁 Happy Shopping! 🎁");
            break;
    }
}

Conclusão

O Agent Framework da Microsoft torna surpreendentemente fácil a construção de sistemas multiagentes, onde cada agente é especializado em uma tarefa específica. Ao coordenar estes agentes através de fluxos de trabalho, podemos resolver problemas complexos como as compras de Natal de uma forma estruturada e eficiente.

O que torna isso ainda mais poderoso é a capacidade de adicionar recursos do mundo real por meio de ferramentas. Ao integrar o Grounding com o Bing Search do Microsoft Foundry, nosso agente de comparação de preços pode realmente pesquisar na Web preços, ofertas e disponibilidade atuais, transformando um simples chatbot de IA em um assistente de compras verdadeiramente útil com citações adequadas.

O suporte da estrutura para padrões sequenciais, simultâneos e de transferência significa que você pode projetar sistemas de agentes que atendam exatamente às suas necessidades. Seja para encontrar presentes, planejar viagens ou qualquer outra tarefa de várias etapas, o Agent Framework fornece os blocos de construção para que isso aconteça.Nesta época de festas, deixe os agentes de IA cuidarem da pesquisa enquanto você se concentra em embrulhar presentes e aproveitar o tempo com a família!

Código Fonte

Os conceitos mostrados nesta postagem são baseados nos exemplos oficiais do Agent Framework. Você pode explorar mais exemplos no repositório GitHub do Microsoft Agent Framework.

Boas festas e boa codificação! 🎄