跳到正文
This is Oscar
返回

在 Azure App Service 上使用 Microsoft Agent Framework 1.0 构建多 Agent AI 应用

原文标题:Build Multi-Agent AI Apps on Azure App Service with Microsoft Agent Framework 1.0
原文链接:https://techcommunity.microsoft.com/blog/appsonazureblog/build-multi-agent-ai-apps-on-azure-app-service-with-microsoft-agent-framework-1-/4510017

几个月前,我们发布了一个三部分系列,展示如何使用 Microsoft Agent Framework (MAF) 的预览包(之前称为 AutoGen / Semantic Kernel Agents)在 Azure App Service 上构建多 Agent AI 系统。该系列介绍了异步处理、请求-回复模式以及客户端多 Agent 编排——全部运行在 App Service 上。

从那时起,Microsoft Agent Framework 已达到 1.0 GA——将 AutoGen 和 Semantic Kernel 统一为一个生产就绪的 Agent 平台。本文是基于 GA 版本的全新起点。我们将在稳定的 API 表面上重建旅行规划器示例,指出与预览版相比的破坏性变更,帮助你快速上手。

所有代码都在配套仓库中:seligj95/app-service-multi-agent-maf-otel

MAF 1.0 GA 中的变化

1.0 版本不仅仅是一次版本号的提升。以下是主要变化:

我们的项目引用反映了 GA 技术栈:

<PackageReference Include="Microsoft.Agents.AI" Version="1.0.0" />
<PackageReference Include="Microsoft.Extensions.AI" Version="10.4.1" />
<PackageReference Include="Azure.AI.OpenAI" Version="2.1.0" />

为什么选择 Azure App Service 来运行 AI Agent?

如果你正在使用 Microsoft Agent Framework 进行构建,你需要一个地方来运行你的 Agent。你可以选择 Kubernetes、容器或无服务器方案——但对于大多数 Agent 工作负载而言,Azure App Service 是最佳选择。原因如下:

总结:App Service 让你专注于构建 Agent,而非管理基础设施。由于 MAF 同时支持 .NET 和 Python——两者都是 App Service 上的一等公民——无论你偏好哪种语言,都能轻松使用。

架构概览

该示例是一个旅行规划器,协调六个专业化 Agent 来构建个性化的行程。用户填写一个表单(目的地、日期、预算、兴趣),系统返回一个综合旅行方案,包括天气预报、货币建议、逐日行程安排和预算分解。

img

六个 Agent

四阶段工作流

阶段Agent执行方式
1 — 并行收集Currency, Weather, Local KnowledgeTask.WhenAll
2 — 行程Itinerary Planner顺序执行(使用阶段 1 的上下文)
3 — 预算Budget Optimizer顺序执行(使用阶段 2 的输出)
4 — 组装Coordinator最终合成

基础设施

ChatClientAgent 深入解析

每个 Agent 的核心是来自 Microsoft.Agents.AIChatClientAgent。它用指令、名称、描述和可选的工具集包装了一个 IChatClient(来自 Microsoft.Extensions.AI)。这是客户端编排——你控制聊天历史、生命周期和执行顺序。不会创建服务器端的 Foundry Agent 资源。

以下是示例中所有六个 Agent 使用的 BaseAgent 模式:

// BaseAgent.cs — 带有工具的 Agent 构造函数
Agent = new ChatClientAgent(
    chatClient,
    instructions: Instructions,
    name: AgentName,
    description: Description,
    tools: chatOptions.Tools?.ToList())
    .AsBuilder()
    .UseOpenTelemetry(sourceName: AgentName)
    .Build();

注意构建器管道:.AsBuilder().UseOpenTelemetry(...).Build()。只需一行代码,即可让每个 Agent 接入框架内置的 OpenTelemetry 遥测。我们将在博客第 2 部分中探讨该遥测数据的具体表现。

调用 Agent 同样简单直接:

// BaseAgent.cs — InvokeAsync
public async Task<ChatMessage> InvokeAsync(
    IList<ChatMessage> chatHistory,
    CancellationToken cancellationToken = default)
{
    var response = await Agent.RunAsync(
        chatHistory, session: null, options: null, cancellationToken);

    return response.Messages.LastOrDefault()
        ?? new ChatMessage(ChatRole.Assistant, "No response generated.");
}

需要注意的关键点:

工具集成

我们的两个 Agent——Weather AdvisorCurrency Converter——通过 MAF 工具调用管道调用真实的外部 API。工具使用 Microsoft.Extensions.AI 中的 AIFunctionFactory.Create() 进行注册。

以下是 WeatherAdvisorAgent 连接其工具的方式:

// WeatherAdvisorAgent.cs
private static ChatOptions CreateChatOptions(
    IWeatherService weatherService, ILogger logger)
{
    var chatOptions = new ChatOptions
    {
        Tools = new List<AITool>
        {
            AIFunctionFactory.Create(
                GetWeatherForecastFunction(weatherService, logger))
        }
    };
    return chatOptions;
}

GetWeatherForecastFunction 返回一个 Func<double, double, int, Task<string>>,模型可以使用纬度、经度和天数来调用它。底层实现调用了美国国家气象服务 API 并返回格式化的预报字符串。Currency Converter 与 Frankfurter API 遵循相同的模式。

这是 GA API 最出色的部分之一:你编写一个普通的 C# 方法,用 AIFunctionFactory.Create() 包装它,框架就会自动处理 JSON Schema 生成、函数调用解析和响应路由。

多阶段工作流编排

TravelPlanningWorkflow 类协调所有六个 Agent。关键洞察在于,编排就是 C# 代码——没有 YAML,没有图 DSL,没有特殊的运行时。你来决定 Agent 何时运行、接收什么上下文,以及结果如何在各阶段之间流转。

// 阶段 1:并行信息收集
var gatheringTasks = new[]
{
    GatherCurrencyInfoAsync(request, state, progress, cancellationToken),
    GatherWeatherInfoAsync(request, state, progress, cancellationToken),
    GatherLocalKnowledgeAsync(request, state, progress, cancellationToken)
};
await Task.WhenAll(gatheringTasks);

阶段 1 完成后,结果存储在 WorkflowState 对象中——一个简单的基于字典的容器,保存每个 Agent 的聊天历史和上下文数据:

// WorkflowState.cs
public Dictionary<string, object> Context { get; set; } = new();
public Dictionary<string, List<ChatMessage>> AgentChatHistories { get; set; } = new();

阶段 2-4 顺序运行,每个阶段从前一阶段拉取上下文。例如,Itinerary Planner 接收在阶段 1 中收集的天气和本地知识信息:

var localKnowledge = state.GetFromContext<string>("LocalKnowledge") ?? "";
var weatherAdvice = state.GetFromContext<string>("WeatherAdvice") ?? "";

var itineraryChatHistory = state.GetChatHistory("ItineraryPlanner");
itineraryChatHistory.Add(new ChatMessage(ChatRole.User,
    $"Create a detailed {days}-day itinerary for {request.Destination}..."
    + $"\n\nWEATHER INFORMATION:\n{weatherAdvice}"
    + $"\n\nLOCAL KNOWLEDGE & TIPS:\n{localKnowledge}"));

var itineraryResponse = await _itineraryAgent.InvokeAsync(
    itineraryChatHistory, cancellationToken);

这个模式——并行扇出后接顺序上下文充实——简单、可测试且易于扩展。需要第七个 Agent?将它添加到合适的阶段并连接到 WorkflowState 即可。

异步请求-回复模式

一个包含六次 LLM 调用的多 Agent 工作流(其中一些还涉及工具调用)很容易运行 30-60 秒。这远远超出了典型的 HTTP 超时预期,对于同步请求来说用户体验也不理想。我们使用异步请求-回复模式来解决这个问题:

此模式保持了 API 的快速响应,使繁重的工作可以重试(Service Bus 处理重试和死信),并允许 WebJob 独立运行——你可以重启它而不影响 API。我们在之前的系列中详细介绍了这个模式,这里不再赘述。

使用 azd 部署

该仓库已集成 Azure Developer CLI,支持一条命令完成资源配置和部署:

git clone https://github.com/seligj95/app-service-multi-agent-maf-otel.git
cd app-service-multi-agent-maf-otel
azd auth login
azd up

azd up 通过 Bicep 配置以下资源:

部署完成后,azd 会输出 App Service URL。在浏览器中打开它,填写旅行表单,即可实时观看六个 Agent 协作完成你的旅行方案。

img

下一步

我们现在有了一个生产就绪的多 Agent 应用,运行在 App Service 上并使用 GA 版本的 Microsoft Agent Framework。但你实际上如何观测这些 Agent 在做什么?当六个 Agent 在进行 LLM 调用、调用工具、在各阶段之间传递上下文时——你需要对每一步都有可见性。

下一篇文章中,我们将深入探讨如何使用 OpenTelemetryApplication Insights 中全新的 **Agents(预览版)**视图来为这些 Agent 添加遥测——让你全面掌握 Agent 运行情况、Token 用量、工具调用和模型性能。你已经看到了构建器管道中的 .UseOpenTelemetry() 调用;博客第 2 部分将展示该遥测端到端的效果,以及如何在 Azure 门户中启用全新的 Agents 体验。

敬请期待!

资源


分享到:

上一篇
在 App Service 上使用 OpenTelemetry 和 Application Insights 新 Agents 视图监控 AI Agent
下一篇
卡卡:优雅的加速度