Skip to content

Latest commit

 

History

History
391 lines (273 loc) · 14.6 KB

File metadata and controls

391 lines (273 loc) · 14.6 KB

01 Sequential Pattern

In a sequential pattern, agents work one after another in a defined pipeline, where each agent's output feeds into the next. This approach works well for tasks that follow a natural progression, like content creation workflows, staged data transformations, or step-by-step analysis.

Scenario

You're writing a technical blog post with agents – research agent, outliner agent, writer agent, and editor agent.

Architecture - Sequential Pattern

Get the repository root

  1. Get the $REPOSITORY_ROOT variable first.

    # zsh/bash
    REPOSITORY_ROOT=$(git rev-parse --show-toplevel)
    # PowerShell
    $REPOSITORY_ROOT = git rev-parse --show-toplevel

Copy the start project

  1. If you already have the workshop directory, rename or remove it first.

  2. Run the setup script to copy the start project to the workshop directory.

    # zsh/bash
    bash $REPOSITORY_ROOT/scripts/setup.sh --session 01-sequential-pattern
    # PowerShell
    & $REPOSITORY_ROOT/scripts/setup.ps1 -Session 01-sequential-pattern

Deploy agents

  1. Make sure you're in the workshop directory.

    cd $REPOSITORY_ROOT/workshop
  2. Open src/MultiAgentWorkshop.PromptAgent/appsettings.json, find the comment line // Add agents, and add the Agents property underneath it.

    {
      ...
      // Add agents
      "Agents": [
        "research-agent",
        "outliner-agent",
        "writer-agent",
        "editor-agent"
      ]
      ...
    }
  3. Navigate to the resources-foundry directory.

    pushd resources-foundry
  4. Run the following command to provision and deploy the agents defined above to Microsoft Foundry.

    azd up

    While provisioning, you'll be asked to enter an environment name, Azure subscription, and location.

  5. Once provisioning and deployment are done, run the following command to confirm that the agents have been deployed successfully.

    # zsh/bash
    az cognitiveservices agent list \
        -a $(azd env get-value FOUNDRY_NAME) \
        -p $(azd env get-value FOUNDRY_PROJECT_NAME) \
        --query "[].id" -o tsv
    # PowerShell
    az cognitiveservices agent list `
        -a $(azd env get-value FOUNDRY_NAME) `
        -p $(azd env get-value FOUNDRY_PROJECT_NAME) `
        --query "[].id" -o tsv

    You should see the four agent names.

    editor-agent
    writer-agent
    outliner-agent
    research-agent
    
  6. Navigate back to the workshop directory.

    popd

Configure Aspire orchestration

  1. Make sure you're in the workshop directory.

    cd $REPOSITORY_ROOT/workshop
  2. Verify that all the necessary agent information has been recorded.

    dotnet user-secrets --project ./src/MultiAgentWorkshop.AppHost list

    You should see the AZURE_TENANT_ID, FOUNDRY_NAME, FOUNDRY_PROJECT_NAME, FOUNDRY_RESOURCE_GROUP, and Foundry:Project:Endpoint values.

  3. Open src/MultiAgentWorkshop.AppHost/appsettings.json, find the comment line // Add agents, and add the Agents property underneath it.

    {
      ...
      // Add agents
      "Agents": [
        "research-agent",
        "outliner-agent",
        "writer-agent",
        "editor-agent"
      ]
      ...
    }
  4. Open src/MultiAgentWorkshop.AppHost/AppHost.cs, find the comment // Add resource for Microsoft Foundry and add the code right underneath it. This adds the Microsoft Foundry project connection details.

    // Add resource for Microsoft Foundry
    var foundry = builder.AddFoundryConnectionString("foundry");

    Let's break down the code.

    • builder.AddFoundryConnectionString("foundry"): This adds the Microsoft Foundry connection string through the extension method AddFoundryConnectionString().
  5. In the same file, find the comment // Add resource for agents on Microsoft Foundry and add the code right underneath it. This exposes the list of agent details to the referencing application.

    // Add resource for agents on Microsoft Foundry
    var agents = builder.AddFoundryAgentsConnectionString("agents");

    Let's break down the code.

    • builder.AddFoundryAgentsConnectionString("agents"): This adds the list of agent details through the extension method AddFoundryAgentsConnectionString().
  6. In the same file, find the comment // Add backend agent service and add the code right underneath it. This defines the backend agent service that references the foundry resource – all the Microsoft Foundry connection details are passed to the backend agent service app.

    // Add backend agent service
    var agent = builder.AddProject<Projects.MultiAgentWorkshop_Agent>("agent")
                       .WithReference(foundry)
                       .WaitFor(foundry);

    Let's break down the code.

    • builder.AddProject<Projects.MultiAgentWorkshop_Agent>("agent"): This adds the backend agent service app as a .NET project.
    • .WithReference(foundry): This references the foundry connection string resource created above, which passes the Microsoft Foundry connection details to the backend agent service app.
    • .WaitFor(foundry): This keeps dependency activation order so that this agent project resource won't be activated until the foundry connection resource is up and running.
  7. In the same file, find the comment // Add frontend web UI and add the code right underneath it. This defines the frontend web UI that references both the agents and agent resources – the agent details and backend connection details are both passed to the frontend web UI app.

    // Add frontend web UI
    var webUI = builder.AddProject<Projects.MultiAgentWorkshop_WebUI>("webui")
                       .WithExternalHttpEndpoints()
                       .WithReference(agents)
                       .WithReference(agent)
                       .WaitFor(agents)
                       .WaitFor(agent);

    Let's break down the code.

    • builder.AddProject<Projects.MultiAgentWorkshop_WebUI>("webui"): This adds the frontend web UI app as a .NET project.
    • .WithExternalHttpEndpoints(): This exposes this frontend web UI app to the Internet, which is publicly accessible.
    • .WithReference(agents): This references the agents connection string resource created above, which passes the list of agents to the frontend web UI app.
    • .WithReference(agent): This references the backend agent service app, which passes the connection details to the frontend web UI app.
    • .WaitFor(agents): This keeps dependency activation order so that this webui project resource won't be activated until the agents connection resource is up and running.
    • .WaitFor(agent): This keeps dependency activation order so that this webui project resource won't be activated until the agent project resource is up and running.

Implement sequential pattern on backend agent service

  1. Make sure you're in the workshop directory.

    cd $REPOSITORY_ROOT/workshop
  2. Open src/MultiAgentWorkshop.Agent/Program.cs, find the comment // Create AIProjectClient instance with EntraID authentication and add the code right underneath it. This connects to the Microsoft Foundry project.

    // Create AIProjectClient instance with EntraID authentication
    var credential = new DefaultAzureCredential(new DefaultAzureCredentialOptions() { TenantId = config["AZURE_TENANT_ID"] });
    var projectClient = new AIProjectClient(endpoint: new Uri(endpoint!), tokenProvider: credential);

    Let's break down the code.

    • new DefaultAzureCredential(...): This logs in to Azure without an API key. It uses your Azure CLI login or Azure Developer CLI login details on your local machine, and Managed Identity when the app is deployed to Azure.
    • new AIProjectClient(endpoint, credential): This connects to the Microsoft Foundry project instance using the endpoint and login details.
  3. In the same file, find the comment // Register all agents passed from Aspire and add the code right underneath it. This pulls the agent details from the Microsoft Foundry project and registers them in the IoC container as singleton services.

    // Register all agents passed from Aspire
    foreach (var agentName in agentNames!)
    {
        var agentRecord = await projectClient.AgentAdministrationClient
                                             .GetAgentAsync(agentName);
        var agent = projectClient.AsAIAgent(agentRecord);
    
        builder.Services.AddKeyedSingleton<AIAgent>(agentName, agent);
    }

    Let's break down the code.

    • We already know the list of agents but only know their names. Therefore, the code runs the foreach loop for each agent.
    • projectClient.AgentAdministrationClient.GetAgentAsync(agentName): Using each agent's information, this creates an ProjectsAgentRecord instance.
    • projectClient.AsAIAgent(agentRecord): This connects to the actual agent using the reference details.
    • builder.Services.AddKeyedSingleton<AIAgent>(agentName, agent): This registers the agent instance as a singleton service.
  4. In the same file, find the comment // Build a sequential workflow pattern with the agents registered and add the code right underneath it.

    // Build a sequential workflow pattern with the agents registered
    builder.AddWorkflow("publisher", (sp, key) => AgentWorkflowBuilder.BuildSequential(
        workflowName: key,
        agents: [.. agentNames!.Select(name => sp.GetRequiredKeyedService<AIAgent>(name))]
    )).AddAsAIAgent("publisher");

    Let's break down the code.

    • builder.AddWorkflow("publisher", ...).AddAsAIAgent("publisher"): This adds the multi-agent workflow as another agent instance named publisher and registers it as a singleton.

    • AgentWorkflowBuilder.BuildSequential(...): This is the sequential workflow builder that uses the same name, publisher.

      Note that it adds multiple agents from the previously registered services in the order declared by the agentNames array.

  5. In the same file, find the comment // Map AGUI to the publisher workflow agent and add the code right underneath it. The workflow is exposed as an API endpoint at ag-ui so that the frontend web UI can communicate with this backend agent service app.

    // Map AGUI to the publisher workflow agent
    app.MapAGUI(
        pattern: "ag-ui",
        aiAgent: app.Services.GetRequiredKeyedService<AIAgent>("publisher")
    );

Implement sequential pattern on frontend web UI

  1. Make sure you're in the workshop directory.

    cd $REPOSITORY_ROOT/workshop
  2. Open src/MultiAgentWorkshop.WebUI/Program.cs, find the comment // Register all agents passed from Aspire and add the code right underneath it. This registers all the agent details so that the web UI knows which agent is responding.

    // Register all agents passed from Aspire
    builder.Services.AddSingleton(agentNames!);
  3. In the same file, find the comment // Register the backend agent service as an HTTP client and add the code right underneath it. Aspire already provides the frontend web UI app with the connection details for the backend agent service.

    // Register the backend agent service as an HTTP client
    builder.Services.AddHttpClient("agent", client =>
    {
        client.BaseAddress = new Uri("https+http://agent");
    });
  4. In the same file, find the comment // Register AGUI client and add the code right underneath it. Using this AGUI client, the frontend web UI app communicates with the backend agent service app via the ag-ui endpoint.

    // Register AGUI client
    builder.Services.AddChatClient(sp => new AGUIChatClient(
        httpClient: sp.GetRequiredService<IHttpClientFactory>().CreateClient("agent"),
        endpoint: "ag-ui")
    );

Run Aspire

  1. Make sure you're in the workshop directory.

    cd $REPOSITORY_ROOT/workshop
  2. Make sure you've already logged in to Azure using both Azure CLI and Azure Developer CLI. If you're unsure, follow this step again.

  3. Run the following command to start all apps through Aspire.

    dotnet watch run --project ./src/MultiAgentWorkshop.AppHost
  4. The Aspire dashboard opens automatically.

    Aspire Dashboard

    Click the backend agent service app.

  5. When the Dev UI page opens, change the agent to publisher and click the "Configure & Run" button.

    Microsoft Agent Framework Dev UI - Sequential pattern

  6. Send any request.

    Microsoft Agent Framework Dev UI - Send request

    See the result and how the workflow progresses on the left-hand side of the screen.

    Microsoft Agent Framework Dev UI - Workflow run

  7. Go back to the Aspire dashboard and click the web UI app.

    Aspire Dashboard

  8. Send any request.

    Microsoft Agent Framework Chat UI - Send request

    See the result.

  9. Press Ctrl+C to terminate all running apps.

Deploy to Azure

  1. Make sure you're in the workshop directory.

    cd $REPOSITORY_ROOT/workshop
  2. Run the following command to provision and deploy both the frontend web UI and backend agent service apps to Azure.

    azd up

    While provisioning, you'll be asked to enter an environment name, Azure subscription, and location.

  3. Once completed, you'll see the web UI application URL on the terminal screen. Open it in your web browser and send a request.

    Microsoft Agent Framework on Azure Container Apps - Send request

    See the result.

  4. Once everything is done, remove all the apps and agents from Azure.

    # Delete both the web UI and agent service apps.
    azd down --purge --force
    
    # Delete all agents and the Microsoft Foundry resource.
    cd resources-foundry
    azd down --purge --force

Congratulations! 🎉 You've just completed the first multi-agent orchestration scenario - the sequential pattern. Let's move on!

👈 00: Setup | 02: Concurrent Pattern 👉