Das Agent Framework von Microsoft soll Weihnachten retten

· 11 Min. Lesezeit

Einführung

Die Suche nach den perfekten Weihnachtsgeschenken kann stressig sein. Zwischen dem Brainstorming von Geschenkideen, dem Preisvergleich in verschiedenen Geschäften und der Sicherstellung, dass alles pünktlich ankommt, wird der Weihnachtseinkauf schnell überwältigend. Was wäre, wenn wir diese Aufgaben an spezialisierte KI-Agenten delegieren könnten, die zusammenarbeiten? In diesem Beitrag untersuchen wir, wie Sie mit dem Agent Framework von Microsoft ein Multi-Agenten-System aufbauen, in dem sich jeder Agent auf eine bestimmte Aufgabe spezialisiert, von der Generierung von Geschenkideen bis zum Preisvergleich, alles koordiniert durch Arbeitsabläufe.

Festlicher Tech-Kalender 2025

Dieses Projekt ist Teil meiner Sitzung beim Festive Tech Calendar 2025, einem tollen Community-Event zur Feier der Technologie während der Feiertage. Mehr über die Veranstaltung finden Sie auf Sessionize.

Was ist das Agent Framework von Microsoft?

Das Agent Framework ist Microsofts Lösung zum Erstellen, Orchestrieren und Bereitstellen von KI-Agenten und Multiagentensystemen. Es bietet eine flexible Grundlage für die Erstellung von Agenten, die sequentiell, gleichzeitig oder über Übergabemuster arbeiten können. Das Framework unterstützt OpenAI-, Azure OpenAI- und Microsoft Foundry-Modelle und ist dadurch unglaublich vielseitig.

Zu den Hauptmerkmalen gehören:

  • Multi-Agent-Orchestrierung: Gruppenchat, sequentielle, gleichzeitige und Übergabemuster
  • Plugin-Ökosystem: Erweitern mit nativen Funktionen, OpenAPI und Model Context Protocol (MCP)
  • Workflow-Unterstützung: Erstellen Sie komplexe Agent-Pipelines mit Executoren und Edges

Voraussetzungen

Bevor Sie in den Code eintauchen, stellen Sie sicher, dass Sie Folgendes haben:

  • .NET 9
  • Azure OpenAI-Zugriff (oder OpenAI-API-Schlüssel)
  • Visual Studio oder Visual Studio Code

Installieren Sie die erforderlichen Pakete (beachten Sie, dass in der Vorschau das Flag --prerelease erforderlich ist):

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

Die Gift-Shopping-Agenten

Unser Weihnachtsgeschenkfinder besteht aus drei spezialisierten Agenten, die zusammenarbeiten:

  1. Geschenkideen-Agent – Erstellt kreative Geschenkvorschläge basierend auf dem Profil des Empfängers
  2. Preisvergleichsagent – Findet die besten Preise in verschiedenen Geschäften
  3. Zusammenfassungsagent – Stellt die endgültigen Empfehlungen zusammen

Die Modelle

Beginnen wir mit der Definition unserer Datenmodelle, die durch die Agent-Pipeline fließen:

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; }
}

Aufbau der Agenten

Das Schöne am Agent Framework ist, wie einfach es ist, spezialisierte Agenten zu erstellen. Jeder Agent ist einfach ein ChatClientAgent mit einer spezifischen Systemaufforderung, die sein Fachwissen definiert.

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!");
    }
}

Erstellen des Workflows

Jetzt kommt der spaßige Teil: die Verbindung unserer Agenten in einen sequentiellen Workflow. Das Agent Framework bietet WorkflowBuilder und AgentWorkflowBuilder, um Agenten in verschiedenen Mustern zusammenzustellen.

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);
            }
        }
    }
}

Agenten gleichzeitig ausführen

Was ist, wenn wir für mehrere Personen gleichzeitig nach Geschenken suchen möchten? Das Agent Framework unterstützt die gleichzeitige Ausführung, was perfekt für dieses Szenario ist:

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);
        }
    }
}

Benutzerdefinierte Executoren für mehr KontrolleFür komplexere Szenarien können Sie benutzerdefinierte Executoren erstellen, die Ihnen eine detaillierte Kontrolle über den Workflow ermöglichen:

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;
    }
}

Anschließend können Sie diesen Executor in Ihren Workflow einfügen:

var validator = new GiftValidatorExecutor();

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

Hinzufügen einer echten Websuche mit Bing Grounding

Bisher generieren unsere Agenten Antworten basierend auf dem Wissen des KI-Modells. Was aber, wenn wir im Internet nach tatsächlichen Produktpreisen und -verfügbarkeiten suchen möchten? Hier kommt Grounding with Bing Search ins Spiel. Dabei handelt es sich um ein in Microsoft Foundry (ehemals Azure AI Foundry) verfügbares Tool, mit dem Ihre Agenten bei der Generierung von Antworten öffentliche Webdaten in Echtzeit einbeziehen können.

Zuerst müssen Sie im [Azure-Portal](https://portal.azure.com/#create/Microsoft.BingGroundingSearch eine Ressource „Grounding with Bing Search“ erstellen. Stellen Sie sicher, dass Sie es in derselben Ressourcengruppe wie Ihr KI-Projekt erstellen.

Erdung mit der Bing-Suche einrichten

Das Schöne an Grounding mit Bing Search ist, dass es direkt in Azure AI Agents integriert werden kann. Der Agent entscheidet anhand der Anfrage des Benutzers, wann er das Suchtool verwendet, durchsucht das Web und generiert anhand der Ergebnisse eine fundierte Antwort.

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;
    }
}

Erstellen eines Preisvergleichsagenten mit echter Suche

Lassen Sie uns nun einen vollständigen Preisvergleichsagenten erstellen, der das Internet nach echten Produktinformationen durchsucht:

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);
        }
    }
}

Integration von Bing Grounding in den Workflow

So verwenden Sie den von Bing unterstützten Preisagenten in einem vollständigen Geschenksuche-Workflow:

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! 🎁");
}

Zitate aus Bing-Ergebnissen verarbeiten

Ein wichtiger Aspekt von Grounding mit Bing Search besteht darin, dass die Antworten Zitate mit Links zu den Quellwebsites enthalten. So extrahieren und zeigen Sie sie an:

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);
            }
        }
    }
}

Wenn der Preisvergleichsagent jetzt ausgeführt wird, verwendet er Grounding with Bing Search, um echte Produktlisten, aktuelle Preise und verfügbare Angebote im Live-Web zu finden. Der Agent entscheidet automatisch anhand der Anfrage, wann eine Suche durchgeführt werden soll, und gibt fundierte Antworten mit korrekten Zitaten zurück.

Das komplette Programm

So kommt in Program.cs alles zusammen:

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;
    }
}

Fazit

Das Agent Framework von Microsoft macht es überraschend einfach, Systeme mit mehreren Agenten zu erstellen, bei denen jeder Agent auf eine bestimmte Aufgabe spezialisiert ist. Indem wir diese Agenten durch Arbeitsabläufe koordinieren, können wir komplexe Probleme wie Weihnachtseinkäufe strukturiert und effizient angehen.

Was dies noch leistungsfähiger macht, ist die Möglichkeit, mithilfe von Tools reale Funktionen hinzuzufügen. Durch die Integration von Grounding mit Bing Search von Microsoft Foundry kann unser Preisvergleichsagent das Internet tatsächlich nach aktuellen Preisen, Angeboten und Verfügbarkeit durchsuchen – und verwandelt so einen einfachen KI-Chatbot in einen wirklich nützlichen Einkaufsassistenten mit korrekten Zitaten.

Die Unterstützung des Frameworks für sequentielle, gleichzeitige und Übergabemuster bedeutet, dass Sie Agentensysteme entwerfen können, die genau Ihren Anforderungen entsprechen. Ganz gleich, ob es um die Suche nach Geschenken, die Planung von Reisen oder eine andere mehrstufige Aufgabe geht, das Agent Framework stellt die Bausteine ​​bereit, um dies zu ermöglichen.Überlassen Sie diese Weihnachtszeit den KI-Agenten die Recherche, während Sie sich auf das Verpacken von Geschenken und das Genießen der Zeit mit der Familie konzentrieren!

Quellcode

Die in diesem Beitrag gezeigten Konzepte basieren auf den offiziellen Agent Framework-Beispielen. Weitere Beispiele finden Sie im Microsoft Agent Framework GitHub-Repository.

Frohe Feiertage und viel Spaß beim Programmieren! 🎄