Titelbild zum Beitrag Multi-Agent-Orchestrierung mit dem Microsoft Agent Framework

Blogbeitrag

Multi-Agent-Orchestrierung mit dem Microsoft Agent Framework

AI

Ich stelle die Demo-Anwendung aus meiner Session beim Global Azure 2026 in München vor und zeige, wie das Microsoft Agent Framework Sessions, Tools und Multi-Agent-Workflows zusammenführt.

Beim Global Azure 2026 in München durfte ich die Session “More than just a Prompt: Multi-Agent Orchestration with the Microsoft Agent Framework” halten. Für diesen Vortrag habe ich die kleine Demo-Anwendung maf-demo-console geschrieben, mit der sich die wichtigsten Orchestrierungsmuster im Microsoft Agent Framework Schritt für Schritt zeigen lassen. Genau diese Demo möchte ich in diesem Beitrag näher vorstellen.

Wenn du zuerst den Event-Kontext lesen möchtest, findest du ihn in meinem Rückblick auf das Global Azure in München .

Wer über Agenten spricht, landet schnell beim Prompt. Wer über belastbare Anwendungen spricht, landet früher oder später bei Orchestrierung. Genau dort wird dieses Repository interessant: Es zeigt nicht nur, wie man einen einzelnen Agenten an ein Modell hängt, sondern wie aus Rollen, Sessions, Tools und Workflows ein belastbares Multi-Agent-System wird.

Was ist das Microsoft Agent Framework?

Das Microsoft Agent Framework , kurz MAF, liefert eine strukturierte Abstraktion für agentische Anwendungen in .NET und Python.

Im Kern geht es um vier Dinge:

  • Agenten als fachliche Rollen mit klaren Instructions
  • Sessions für Zustand und Gesprächskontext über mehrere Turns
  • Tools für den Zugriff auf externe Funktionen und Live-Daten
  • Workflows für Orchestrierung: sequentiell, parallel, per Handoff, als Group Chat oder planner-gesteuert

In diesem Repo wird das sehr greifbar. Die einzelnen Demos basieren auf IChatClient, daraus werden per AsAIAgent(...) konkrete Agenten gebaut. Für komplexere Abläufe kommen dann AgentWorkflowBuilder, GroupChatManager und das Streaming von WorkflowEvents dazu.

Das ist der entscheidende Unterschied zu einer losen Sammlung von Prompts: Die Zusammenarbeit der Agenten wird als Ausführungsmodell codiert.

Technisch ist das Projekt angenehm klar aufgebaut. Es nutzt unter anderem die folgenden NuGet-Packages:

Die Demo-Konsole ist dabei mehr als nur UI. Sie macht sichtbar, welcher Agent wann arbeitet, wann ein Handoff passiert, welche Lane parallel läuft und wann ein Workflow terminiert. Genau das macht das Repository so wertvoll für alle, die Agentensysteme nicht nur konsumieren, sondern auch verstehen wollen.

Warum dieses Repo mehr ist als eine Demo

Die Samples sind nicht nach API-Features sortiert, sondern nach realistischen Mustern. Genau das macht das Projekt angenehm zugänglich. Statt stumpf “Hier ist Methode X” abzuhaken, beantwortet es Fragen wie:

  • Wann reicht ein einzelner Agent?
  • Wann brauche ich Session State?
  • Wann sollte ein Agent Tools statt Halluzinationen nutzen?
  • Wann ist eine feste Pipeline sinnvoll?
  • Wann ist Parallelisierung besser?
  • Wann muss die Verantwortung dynamisch an Spezialisten übergeben werden?
  • Wann ist eine Diskussion unter Agenten näher an der Realität als ein starrer Ablauf?
  • Und wann sollte ein Lead-Agent den Plan selbst zur Laufzeit steuern?

Genau diese Progression macht das Repository zu einem sehr guten Lernpfad.

Die Samples im Detail

Schauen wir uns diese Lernkurve deshalb einmal der Reihe nach an.

Demo 01: Simple Agent

Datei: src/MAFDemo/Demos/01_SimpleAgent.cs

Das erste Sample ist bewusst klein gehalten, wirkt aber nicht wie ein triviales Hello World. Ein Azure-OpenAI-basierter Chat-Client wird in einen Agenten verwandelt, der aus einer Reiseanfrage einen ausgearbeiteten Vorschlag macht. Technisch ist das die Baseline des gesamten Repos: IChatClient rein, AsAIAgent(...) drauf, RunStreamingAsync(...) ausführen.

IChatClient chatClient = ChatClientHelper.CreateAzureOpenAIChatClient();

AIAgent writer = chatClient.AsAIAgent(
    name: "cruise-planner",
    instructions: "You are a helpful agent to help with cruise plans.");

await foreach (var update in writer.RunStreamingAsync(travelRequest))
{
    // Streamt die Antwort direkt in die Konsole
}

Der Use-Case ist simpel, aber realistisch: aus einer unstrukturierten Eingabe schnell einen brauchbaren ersten Entwurf erzeugen. Genau dafür ist ein einzelner Agent ideal. Kein Session State, keine Tools, kein Orchestrierungs-Overhead. Nur eine Rolle, eine Aufgabe, ein Ergebnis.

Interessant ist weniger die Komplexität als die Aussage: Bevor wir Multi-Agent-Topologien bauen, sollten wir wissen, wie klein die Lösung sein darf.

Demo 02: Simple Agent with Conversation Thread

Datei: src/MAFDemo/Demos/02_SimpleAgentWithConversationThread.cs

Hier wird aus einer Einmalantwort ein Gespräch mit Gedächtnis. Das Sample erzeugt über CreateSessionAsync() eine AgentSession, hält den Kontext über mehrere Turns und serialisiert den Session State sogar explizit mit SerializeSessionAsync(...).

Der Use-Case ist extrem relevant für die Praxis: Projektkontext, der nicht bei jedem Prompt neu erklärt werden soll. Im Demo-Szenario merkt sich der Agent etwa Kunde, Rollout-Kontext und bevorzugten Kommunikationsstil und nutzt diese Informationen in Folgefragen weiter.

AgentSession session = await assistantAgent.CreateSessionAsync();

await assistantAgent.RunStreamingAsync(
    userContext,
    session);

JsonElement serializedSession =
    await assistantAgent.SerializeSessionAsync(session);

Das ist der Punkt, an dem aus “LLM-Aufruf” eine Anwendung wird. Wer Copiloten, Delivery-Assistenten oder technische Projektassistenten baut, braucht genau dieses Muster: Zustand nicht nur im Text hoffen, sondern in Sessions kontrolliert führen.

Demo 03: Simple Agent with Different Providers

Datei: src/MAFDemo/Demos/03_SimpleAgentWithDifferentProviders.cs

Eines der stärksten Samples im Repo, weil es Architektur statt Feature-Demo zeigt. Dasselbe Agent-Muster läuft hier über drei unterschiedliche Backends:

  • Azure OpenAI
  • Ollama
  • GitHub Models

Der Clou steckt in ChatClientHelper.cs: Die verschiedenen Provider werden alle auf IChatClient normalisiert. Der Rest des Codes bleibt fast identisch. Genau so sollte Provider-Abstraktion aussehen: nicht in Marketing-Folien, sondern in einem austauschbaren Interface.

AIAgent azureAgent = ChatClientHelper
    .CreateAzureOpenAIChatClient(config)
    .AsAIAgent(name: "azure-storyteller", instructions: storytellerInstructions);

AIAgent ollamaAgent = ChatClientHelper
    .CreateOllamaChatClient(config)
    .AsAIAgent(name: "ollama-storyteller", instructions: storytellerInstructions);

Der Use-Case dahinter ist strategisch: Teams wollen oft nicht von einem einzigen Modellanbieter oder Hosting-Modell abhängen. Vielleicht läuft Produktion auf Azure OpenAI, lokale Entwicklung über Ollama und Experimente über GitHub Models. Dieses Sample zeigt, dass der Agent-Layer davon weitgehend entkoppelt werden kann.

Außerdem schön gelöst: Fehler pro Provider werden isoliert behandelt. Fällt ein Backend aus, laufen die anderen weiter. Das ist keine Nebensache, sondern ein sehr realistisches Robustheitsmuster.

Demo 04: Agents with Tools

Datei: src/MAFDemo/Demos/04_AgentsWithTools.cs

Hier wird die Demo zum ersten Mal richtig praxisnah. Der Agent antwortet nicht nur aus Modellwissen, sondern bekommt Werkzeuge an die Hand. Konkret werden zwei Funktionen als AIFunction registriert:

  • Wetterabfrage über OpenWeatherMap
  • aktuelle Ortszeit über GeoTimeZone und Zeitzonenauflösung

Der Agent erhält klare Instructions, diese Tools bei Wetter- oder Zeitfragen zu verwenden. Das ist ein klassischer Grounding-Use-Case: Fakten nicht erfinden, sondern nachschlagen.

Technisch gefällt an diesem Sample besonders, dass es nicht nur den Happy Path zeigt. Die Implementierung enthält saubere Fehlerbehandlung für API-Ausfälle, Timeouts und nicht auflösbare Orte. Genau dort trennt sich Demo von brauchbarem Muster.

AIFunction weatherTool = AIFunctionFactory.Create(GetWeatherAsync);
AIFunction currentTimeTool = AIFunctionFactory.Create(GetCurrentTimeAsync);

AIAgent weatherAssistant = chatClient.AsAIAgent(
    name: "weather-assistant",
    instructions: "Use the available tools whenever the user asks for weather or time information.",
    tools: [weatherTool, currentTimeTool]);

Der praktische Use-Case ist offensichtlich: Support-Assistenten, Travel-Agents, Ops-Copiloten oder interne Helfer, die Live-Daten in Antworten integrieren müssen. Ohne Tools bleibt ein Agent eloquent. Mit Tools wird er nützlich.

Demo 05: Multi-Agent Workflow (Sequential)

Datei: src/MAFDemo/Demos/05_MultiAgentWorkflowSequential.cs

Ab hier beginnt die eigentliche Orchestrierungsreise. In dieser Demo wird mit AgentWorkflowBuilder.BuildSequential(...) eine feste Pipeline aus vier Spezialisten gebaut:

  • ScopeAnalyst
  • SolutionDrafter
  • ArchitectureReviewer
  • ExecutiveEditor

Das Muster ist bewusst klassisch: Ein Input wird Schritt für Schritt veredelt. Erst Scope, dann Lösung, dann technische Prüfung, dann sprachliche Verdichtung für Leadership.

Workflow pipeline = AgentWorkflowBuilder.BuildSequential(
    scopeAnalyst,
    solutionDrafter,
    architectureReviewer,
    executiveEditor);

await using StreamingRun run = await InProcessExecution.Concurrent.RunStreamingAsync(
    pipeline,
    initialMessages,
    Guid.NewGuid().ToString(),
    CancellationToken.None);

Der Use-Case: planbare Delivery-Artefakte. Wenn klar ist, dass ein Ergebnis immer durch dieselben Qualitätsstufen laufen soll, ist ein sequenzieller Workflow oft besser als ein einzelner Agent mit einem riesigen Prompt. Die Rollen werden explizit, die Verantwortung wird sichtbar und Zwischenergebnisse lassen sich leichter inspizieren.

Spannend ist auch die Ausführung: Das Sample streamt WorkflowEvents und zeigt, welcher Executor gerade arbeitet und welches Zwischenresultat entsteht. So wird Multi-Agent-Orchestrierung debuggbar. Genau das fehlt vielen “AI Demos”.

Demo 06: Multi-Agent Workflow (Concurrent)

Datei: src/MAFDemo/Demos/06_MultiAgentWorkflowConcurrent.cs

Das Gegenstück zur Pipeline ist der Fan-out. Mit AgentWorkflowBuilder.BuildConcurrent(...) analysieren hier mehrere Spezialisten dieselbe Eingabe gleichzeitig:

  • LeadershipBrief
  • RiskLens
  • SignalSpotter

Alle drei blicken auf dasselbe Rollout-Update, aber aus verschiedenen Perspektiven. Das ist ein großartiger Use-Case für parallele Agenten: nicht nacheinander denselben Text umformulieren, sondern unabhängig unterschiedliche Sichten erzeugen.

Workflow concurrent = AgentWorkflowBuilder.BuildConcurrent(
    [leadershipBrief, riskLens, signalSpotter],
    null);

await using StreamingRun run = await InProcessExecution.Concurrent.RunStreamingAsync(
    concurrent,
    initialMessages,
    Guid.NewGuid().ToString(),
    CancellationToken.None);

In der Praxis ist das wertvoll für Decision Memos, Incident Reviews, Produktfreigaben oder Statusauswertungen. Leadership will eine verdichtete Sicht. Risk will Risiken und Maßnahmen. Analytics will Signale und Trends. Warum sollte ein Agent das seriell und in einer Stimme erledigen, wenn drei Rollen parallel bessere Spezialisierung liefern?

Das Sample macht außerdem Laufzeiten sichtbar: Start, aktive Lanes, Result-Previews, Completion. Man sieht also nicht nur dass parallel gearbeitet wird, sondern auch wie.

Demo 07: Multi-Agent Workflow (Handoff)

Datei: src/MAFDemo/Demos/07_MultiAgentWorkflowHandoff.cs

Jetzt wird es deutlich realistischer. Nicht jeder Prozess ist eine feste Pipeline, und nicht jede Aufgabe lässt sich sauber parallelisieren. Manche Themen wechseln unterwegs den Besitzer. Genau dafür gibt es hier ein Handoff-Modell.

Die Demo baut den Workflow mit CreateHandoffBuilderWith(...) auf und definiert explizite Übergaben zwischen:

  • IdentityLead
  • SecurityLead
  • SupportLead
  • RolloutLead

Das Entscheidende: Die Handoffs sind nicht generisch, sondern mit konkreten Gründen modelliert. Wenn Auditierbarkeit und Missbrauchsresistenz dominieren, geht es zu Security. Wenn Enablement und Kommunikation relevant werden, übernimmt Support. Wenn Sequencing, Feature Flags und Rollout-Sicherheit im Zentrum stehen, kommt Rollout ins Spiel.

Workflow handoffWorkflow = AgentWorkflowBuilder
    .CreateHandoffBuilderWith(identityLead)
    .WithHandoff(identityLead, securityLead,
        "Hand off when authorization, abuse prevention, auditability, or compliance controls dominate.")
    .WithHandoff(identityLead, supportLead,
        "Hand off when operator readiness, communications, or support workflow design need specialist input.")
    .WithHandoff(rolloutLead, identityLead,
        "Hand off when rollout planning is complete and the final response can be assembled.")
    .Build();

Der Use-Case ist überall dort stark, wo Verantwortung dynamisch wandert: Identity-Rollouts, Incident-Kommunikation, Customer Escalations oder Governance-Fragen. Dieses Muster fühlt sich sofort näher an echter Teamarbeit an als eine starre Kette.

Besonders gelungen: Die Konsole visualisiert die Baton-Trail, also wer an wen übergibt und warum. Damit wird Orchestrierung nicht zur Black Box, sondern zur nachvollziehbaren Entscheidungslogik.

Demo 08: Multi-Agent Workflow (Group Chat)

Datei: src/MAFDemo/Demos/08_MultiAgentWorkflowGroupChat.cs

Dieses Sample ist wahrscheinlich das lebendigste im ganzen Repo. Statt Pipeline oder Handoff wird hier eine Incident-Bridge simuliert. Drei Rollen diskutieren denselben Vorfall:

  • BridgeLead
  • IdentityEngineer
  • ReliabilityEngineer

Technisch basiert das auf CreateGroupChatBuilderWith(...) und einem RoundRobinGroupChatManager. Die Termination ist elegant gelöst: Der Chat läuft, bis ein Marker wie FINAL UPDATE: auftaucht oder die maximale Iterationszahl erreicht ist.

Workflow groupChatWorkflow = AgentWorkflowBuilder
    .CreateGroupChatBuilderWith(static agents =>
    {
        RoundRobinGroupChatManager manager = new(
            agents,
            static (_, history, _) => new ValueTask<bool>(
                ContainsMarker(history, "FINAL UPDATE:")));

        manager.MaximumIterationCount = 8;
        return manager;
    })
    .AddParticipants([bridgeLead, identityEngineer, reliabilityEngineer])
    .Build();

Der Use-Case liegt auf der Hand: Situationen, in denen Spezialisten nicht nur liefern, sondern aufeinander reagieren müssen. Bei Störungen, War Rooms, Architektur-Diskussionen oder Eskalationen ist das oft das bessere Modell als ein linearer Ablauf. Die Qualität entsteht hier durch das Wechselspiel der Perspektiven.

Was ich daran mag: Der Lead-Agent wird nicht als allwissender Erzähler verwendet, sondern als Moderator. Das ist ein viel glaubwürdigeres Multi-Agent-Muster.

Demo 09: Multi-Agent Workflow (Magentic / Planner-led)

Datei: src/MAFDemo/Demos/09_MagenticPlannerWorkflow.cs

Das letzte Sample ist für mich das architektonische Highlight. Hier plant ein Lead-Agent die Arbeit nicht nur inhaltlich, sondern steuert die Orchestrierung selbst. Der DeliveryLead formuliert einen Arbeitsplan, delegiert exakt einen Spezialisten mit ASSIGN: und BRIEF:, sammelt Antworten ein und beendet den Workflow mit DECISION:.

Die Spezialisten sind:

  • IdentityArchitect
  • RiskAnalyst
  • RolloutEngineer

Besonders spannend ist die technische Umsetzung. Statt nur ein Standard-Pattern zu verwenden, implementiert das Repo einen eigenen PlannerDirectedGroupChatManager. Dieser Manager:

  • analysiert die letzte Assistenznachricht
  • parst Delegationshinweise per Regex
  • wählt den nächsten Agenten dynamisch
  • fällt notfalls auf eine definierte Reihenfolge zurück
  • terminiert, sobald der Lead mit DECISION: abschließt

Das ist genau die Stelle, an der aus Framework-Nutzung Framework-Verständnis wird. Der Use-Case dafür sind komplexe Vorhaben, bei denen der nächste beste Schritt nicht im Voraus feststeht: Architekturentwürfe, Delivery-Proposals, Sanierungspläne, Security-Reviews oder tiefere Analyse-Workflows.

if (string.Equals(lastAssistantMessage.AuthorName, _leadAgentName, StringComparison.Ordinal))
{
    PlannerDirective? directive = PlannerDirective.TryParse(lastAssistantMessage.Text);

    if (directive?.NextAgent is not null &&
        _agentsByName.TryGetValue(directive.NextAgent, out AIAgent? delegatedAgent))
    {
        return new ValueTask<AIAgent>(delegatedAgent);
    }
}

Mit anderen Worten: Dieses Sample zeigt nicht nur Multi-Agent-Orchestrierung. Es zeigt agentische Steuerung der Orchestrierung.

Was man aus dem Projekt mitnehmen kann

Für mich ist die Stärke dieses Repos nicht nur, dass es viele Samples enthält. Die eigentliche Qualität liegt darin, dass die Samples eine saubere Lernkurve bilden:

  1. Ein Agent beantwortet eine Aufgabe.
  2. Derselbe Agent bekommt Gedächtnis.
  3. Der Agent wird provider-unabhängig.
  4. Der Agent nutzt Tools.
  5. Mehrere Agenten arbeiten in einer festen Pipeline.
  6. Mehrere Agenten arbeiten parallel.
  7. Verantwortung wird dynamisch übergeben.
  8. Agenten diskutieren als Team.
  9. Ein Lead-Agent plant und dirigiert das Ganze selbst.

Das ist ein sehr guter Weg, um Multi-Agent-Systeme nicht als Buzzword, sondern als Designraum zu begreifen.

Fazit

Dieses GitHub-Projekt ist für mich ein starkes Beispiel dafür, wie man das Microsoft Agent Framework praxisnah erklären kann. Es startet bewusst klein, bleibt verständlich und wird genau dort richtig spannend, wo Orchestrierung als erstklassiges Konzept sichtbar wird.

Wenn du nur sehen willst, wie man schnell einen Agenten baut, wirst du hier genauso fündig wie dann, wenn du verstehen willst, wie aus Agenten ein System wird.

Und genau deshalb war das Repo für meine Session beim Global Azure 2026 in München so passend: Es zeigt, dass moderne Agentensysteme eben mehr als nur ein Prompt sind. Sie brauchen Rollen, Zustände, Werkzeuge, Übergaben und ein Ausführungsmodell. Kurz gesagt: Sie brauchen Architektur.

Weiterempfehlen

Diesen Beitrag teilen

Wenn dir der Beitrag gefallen hat: gern weiterreichen. Gute Links dürfen sich ruhig schnell verbreiten.

Vorheriger/Nächster Beitrag

Titelbild zum Beitrag Rückblick: Global Azure in München 2026 Nächster Beitrag Rückblick: Global Azure in München 2026
Titelbild zum Beitrag Vergleiche OpenAI-Modelle Side-by-Side mit Blazor Server Vergleiche OpenAI-Modelle Side-by-Side mit Blazor Server Titelbild zum Beitrag PicCaptionr erhält ein großes Update: Jetzt mit .NET 10 und den neuesten OpenAI-Modellen PicCaptionr erhält ein großes Update: Jetzt mit .NET 10 und den neuesten OpenAI-Modellen Titelbild zum Beitrag KI-Videos mit Sora-2 und .NET erstellen KI-Videos mit Sora-2 und .NET erstellen Titelbild zum Beitrag Ollama bringt Cloud-Modelle Ollama bringt Cloud-Modelle
Lust auf ein kurzes digitales Hallo? Wenn du eine Idee teilen, eine Frage loswerden oder ein Projekt anschieben willst: mein Posteingang ist deutlich zuverlässiger als Brieftauben. [email protected] Mail schicken