Advanced

πŸ•ΈοΈ Multi-Agent Orchestration

Build networks of specialised agents where one orchestrator delegates tasks to sub-agents as tools.

Multi-agent systems allow you to compose complex AI behaviour from simpler, specialised pieces. Rather than building one giant agent that tries to do everything, you create a team of focused agents β€” each expert in its domain β€” and let an orchestrator coordinate them.

Agent Framework enables this through the agent-as-tool pattern: call .AsAIFunction() on any agent to convert it into a tool that another agent can invoke. The orchestrator agent receives all available sub-agents as tools and decides autonomously which specialist to delegate to based on the user's request.

This pattern is dynamic β€” unlike sequential workflows, the orchestrator can call sub-agents in any order, call the same one multiple times, combine their outputs, or skip them entirely based on what the task requires.

Key Concepts

  • Agent-as-tool β€” convert any AIAgent to an AIFunction via .AsAIFunction()
  • Orchestrator agent β€” a top-level agent whose tools are other agents
  • name & description β€” critical for the orchestrator to pick the right sub-agent
  • Dynamic delegation β€” the LLM decides at runtime which sub-agents to call and in what order
  • Composability β€” sub-agents can themselves have tools, enabling deep nesting

NuGet Packages

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

Code Sample β€” Weather & News Orchestrator

using System.ComponentModel;
using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;

// --- Tool functions for the specialist agents ---

string GetWeather(
    [Description("The city or location to get weather for")] string location)
    => $"The weather in {location} is sunny with a high of 22Β°C.";

string GetHeadlines(
    [Description("The news category, e.g. 'technology', 'sports', 'business'")] string category)
    => $"Top {category} headline: 'Major breakthrough announced in {category} sector today.'";

var azureClient = new AzureOpenAIClient(
    new Uri(Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT")!),
    new AzureCliCredential());

// --- Specialist Agent 1: Weather ---
AIAgent weatherAgent = azureClient
    .GetChatClient("gpt-4o-mini")
    .AsAIAgent(
        instructions: "You are a weather specialist. Use your tools to provide accurate weather information.",
        name: "WeatherAgent",
        description: "Handles all weather-related questions. Provide a city or location to get a forecast.",
        tools: [AIFunctionFactory.Create(GetWeather)]);

// --- Specialist Agent 2: News ---
AIAgent newsAgent = azureClient
    .GetChatClient("gpt-4o-mini")
    .AsAIAgent(
        instructions: "You are a news specialist. Use your tools to retrieve the latest headlines.",
        name: "NewsAgent",
        description: "Handles all news and current events questions. Provide a category such as technology, sports, or business.",
        tools: [AIFunctionFactory.Create(GetHeadlines)]);

// --- Orchestrator: delegates to specialists as needed ---
AIAgent orchestrator = azureClient
    .GetChatClient("gpt-4o-mini")
    .AsAIAgent(
        instructions: """
            You are a helpful assistant. For weather questions delegate to the WeatherAgent.
            For news questions delegate to the NewsAgent.
            Combine their answers into a single coherent response for the user.
            """,
        tools:
        [
            weatherAgent.AsAIFunction(),
            newsAgent.AsAIFunction()
        ]);

// The orchestrator calls both sub-agents and combines their answers.
Console.WriteLine(await orchestrator.RunAsync(
    "What's the weather like in Amsterdam, and what are the top technology headlines today?"));

Step-by-Step Explanation

  1. Create specialist agents with name and description β€” These strings are passed to the orchestrator LLM as part of the tool schema. The better the description, the more accurately the orchestrator delegates. Think of the description as a job posting for that agent.
  2. Equip specialists with their own tools β€” Each sub-agent can have its own function tools. When the orchestrator calls a sub-agent, the sub-agent internally runs its own tool-call loop before returning its result to the orchestrator.
  3. Register sub-agents with the orchestrator via .AsAIFunction() β€” This converts each AIAgent into an AIFunction. The orchestrator sees them as callable tools, identical to regular function tools from its perspective.
  4. Run a single orchestrator call β€” The orchestrator analyses the request, decides which sub-agents to invoke (and in what order), calls them, receives their results, and synthesises a final response for the user.

Orchestration Flow

User β†’ [Orchestrator]
           β”œβ”€ calls WeatherAgent("Amsterdam") β†’ "Sunny, 22Β°C"
           └─ calls NewsAgent("technology")  β†’ "Major breakthrough..."
       [Orchestrator] combines results β†’ final answer to user βœ“

Next Steps