AutoGen .NET 框架入门:用事件驱动模型构建可扩展的多智能体 AI 系统
AutoGen .NET 是微软 AutoGen 多智能体框架的 .NET 实现,定位为"用于构建 AI 智能体与应用的事件驱动编程框架"(docs/dotnet/index.md)。本文以仓库中 docs/dotnet/index.md 这份 .NET 文档门户为主体,完整覆盖其介绍的包体系与安装方式,并结合仓库源码与 GettingStarted 示例 深入讲解智能体(Agent)、消息(Message)、订阅(Subscription)与运行时(Runtime)的核心机制,读完后你将能够在 .NET 应用中定义智能体、完成本地流程编排,并理解分布式 gRPC 运行时的扩展路径。
一、AutoGen .NET 的整体定位
官方文档门户(docs/dotnet/index.md)将 AutoGen .NET 划分为两大板块:
| 板块 | 定位 | 适用场景 |
|---|---|---|
| Core | 事件驱动的编程框架,用于构建可扩展的多智能体 AI 系统 | 业务流程中确定性与动态的智能体工作流、多智能体协作研究、跨语言分布式智能体、与事件驱动/云原生应用集成 |
| AgentChat | 构建对话式单/多智能体应用的编程框架,构建在 Core 之上 | 聊天中心(chat-centric)的对话编排应用 |
文档明确给出的选型建议是:"如果你要构建工作流或分布式智能体系统,请从 Core 开始"(Start here if you are building workflows or distributed agent systems)。
从源码结构看(dotnet/src/Microsoft.AutoGen/),这一分层得到了印证:
Contracts/:核心契约,包含AgentId、AgentProxy、IAgent、IHandle、TopicId、MessageContext等类型定义;Core/:进程内运行时实现,包含BaseAgent、InProcessRuntime、AgentsApp、TypeSubscriptionAttribute等;Core.Grpc/:分布式系统的 .NET 客户端运行时,API 与 Core 保持一致;RuntimeGateway.Grpc/:分布式系统的服务端网关,支持多网关管理智能体集群并实现 Python 与 .NET 智能体的跨语言互操作;AgentHost/:基于 .NET Aspire 的宿主工程,用于托管 gRPC 服务;Extensions/:对 Aspire、Microsoft.Extensions.AI(MEAI)、Semantic Kernel 的集成扩展;AgentChat/:对话编排实现,含RoundRobinGroupChat、ChatAgentBase、终止条件(Terminations)等;Agents/:一组可直接使用的默认智能体(如InferenceAgent、ConsoleAgent、FileAgent)。
二、包体系与安装方式
2.1 Core 与 AgentChat 两条安装路径
文档门户给出的 Core 安装命令(docs/dotnet/index.md):
dotnet add package Microsoft.AutoGen.Contracts
dotnet add package Microsoft.AutoGen.Core
# optionally - for distributed agent systems:
dotnet add package Microsoft.AutoGen.RuntimeGateway.Grpc
dotnet add package Microsoft.AutoGen.AgentHost
# other optional packages
dotnet add package Microsoft.AutoGen.Agents
dotnet add package Microsoft.AutoGen.Extensions.Aspire
dotnet add package Microsoft.AutoGen.Extensions.MEAI
dotnet add package Microsoft.AutoGen.Extensions.SemanticKernel
即:Contracts + Core 是单进程内编写并运行智能体的最小集合;RuntimeGateway.Grpc + AgentHost 面向跨进程、跨语言的分布式场景;Agents 与三个 Extensions.* 包为可选增强。
更详细的安装文档 Installation 补充了三种等价方式,并给出了带版本号(0.4.0-dev.1)的示例:
dotnet add package Microsoft.AutoGen.Contracts --version 0.4.0-dev.1
dotnet add package Microsoft.AutoGen.Core --version 0.4.0-dev.1
Package Manager 方式:
PM> NuGet\Install-Package Microsoft.AutoGen.Contracts -Version 0.4.0-dev.1
PM> NuGet\Install-Package Microsoft.AutoGen.Core -Version 0.4.0-dev.1
或直接写入 csproj 的 PackageReference:
<PackageReference Include="Microsoft.AutoGen.Contracts" Version="0.4.0-dev.1" />
<PackageReference Include="Microsoft.AutoGen.Core" Version="0.4.0-dev.1" />
该文档还明确了各包的职责边界:
- Microsoft.AutoGen.AgentChat —— 在 Core SDK 之上实现聊天中心的多智能体编排;
- Microsoft.AutoGen.Agents —— 提供少量开箱即用的默认智能体;
- Microsoft.AutoGen.Extensions —— 对 Aspire、Microsoft.Extensions.AI、Semantic Kernel 的扩展支持;
- Microsoft.AutoGen.Core.Grpc —— 分布式系统中智能体的 .NET 客户端运行时,API 与
Microsoft.AutoGen.Core相同,意味着"从单进程切到分布式,API 不变"; - Microsoft.AutoGen.RuntimeGateway.Grpc —— 分布式系统的 .NET 服务端,可运行多个网关来管理智能体集群,并启用跨语言互操作;
- Microsoft.AutoGen.AgentHost —— 托管 gRPC 服务的 .NET Aspire 工程。
2.2 从源码结构印证包边界
对照 dotnet/src/Microsoft.AutoGen/ 下的工程划分,每个 NuGet 包都对应一个 csproj:Microsoft.AutoGen.Contracts.csproj、Microsoft.AutoGen.Core.csproj、Microsoft.AutoGen.Core.Grpc.csproj、Microsoft.AutoGen.RuntimeGateway.Grpc.csproj、Microsoft.AutoGen.AgentHost.csproj、Microsoft.AutoGen.AgentChat.csproj、Microsoft.AutoGen.Agents.csproj,以及 Extensions/ 下的 Microsoft.AutoGen.Extensions.Aspire.csproj、Microsoft.AutoGen.Extensions.MEAI.csproj、Microsoft.AutoGen.Extensions.SemanticKernel.csproj。这与文档中的包清单一一对应,可以确认文档描述的就是当前仓库实际的构建产物。
分布式网关内部还依赖 Orleans(见 RuntimeGateway.Grpc/Services/Orleans/ 下的 RegistryGrain.cs、MessageRegistryGrain.cs 等),从源码结构看,网关用 Orleans 的 Grain 来实现智能体注册表与消息注册表的分布式状态管理。
三、核心概念速览:AgentId、Topic 与订阅
在动手写代码前,需要理解三个基础类型(均位于 Microsoft.AutoGen.Contracts,即 Contracts 工程):
- AgentId:智能体实例在运行时(含分布式运行时)中的唯一标识,充当接收消息的"地址"。从 AgentId.cs 可见,它由
Type与Key两个字段组成,支持type/key字符串互转(AgentId.FromStr),并带有严格校验:Type必须匹配^[a-zA-Z_][a-zA-Z0-9_]*$(字母/数字/下划线且不能以数字开头),Key只能包含 ASCII 32–126 的可见字符。 - TopicId:消息的发布目标主题。智能体先订阅某个主题,才能收到发布到该主题上的消息。
- 订阅(Subscription):分为按类型订阅(
[TypeSubscription("topic")])与按类型前缀订阅([TypePrefixSubscription],实现见 TypePrefixSubscriptionAttribute.cs),使智能体"响应某类消息并产出某类消息"。
四、实战:Modifier / Checker 倒计时示例
官方 Tutorial 定义了两个智能体 Modifier 与 Checker,共同完成从 10 倒数到 1 的计数流程:Modifier 修改计数,Checker 检查计数并在到达 1 时停止应用。完整示例代码位于 dotnet/samples/GettingStarted/。
4.1 定义消息类型
消息就是普通的 C# 类。示例用 CountMessage 传递当前计数,用 CountUpdate 传递更新后的计数(CountMessage.cs、CountUpdate.cs):
namespace GettingStartedSample;
public class CountMessage
{
public int Content { get; set; }
}
namespace GettingStartedSample;
public class CountUpdate
{
public int NewCount { get; set; }
}
教程强调:把消息类型拆分为强类型类,才能构建"智能体响应某些类型、产出某些类型"的工作流——这正是类型化订阅(type subscription)的基础。
4.2 继承 BaseAgent 创建智能体
AutoGen 中,智能体是一个能收发消息的类,消息到达后做什么由智能体自身逻辑决定。定义方式是继承 Microsoft.AutoGen.Core.BaseAgent:
using Microsoft.AutoGen.Contracts;
using Microsoft.AutoGen.Core;
public class Modifier(
AgentId id,
IAgentRuntime runtime,
) :
BaseAgent(id, runtime, "MyAgent", null),
{
}
AgentId 和 IAgentRuntime 总是由运行时注入构造函数并转发给基类;另两个参数是智能体描述与可选的 logger。这一机制在 BaseAgent.cs 中得到确认:基类构造函数保存 Id、Runtime、Description,并在构造时通过 ReflectInvokers() 反射收集智能体实现的所有 IHandle<> / IHandle<,> 接口,建立"消息类型 → HandlerInvoker"的字典。
4.3 实现 Handler 并添加订阅
要让 Modifier 收到 CountMessage、修改计数后产出 CountUpdate,需要实现 IHandle<CountMessage> 接口,并用 [TypeSubscription] 特性声明订阅主题:
[TypeSubscription("default")]
public class Modifier(
// ...
) :
BaseAgent(...),
IHandle<CountMessage>
{
public async ValueTask HandleAsync(CountMessage item, MessageContext messageContext)
{
// ...
}
}
[TypeSubscription("default")] 把智能体绑定到名为 default 的主题;没有这一步,消息不会投递给智能体。消息到达时,BaseAgent.OnMessageAsync(BaseAgent.cs)会先取消息的运行时类型,从 handlerInvokers 字典查找匹配的 invoker 并调用,找不到则返回 null——也就是说,类型不匹配的消息会被静默忽略。
4.4 发布消息与传入自定义参数
Handler 内通过 PublishMessageAsync 把结果发布到指定主题;教程还演示了如何向智能体传入自定义参数(一个用于修改计数的函数):
public async ValueTask HandleAsync(CountMessage item, MessageContext messageContext)
{
int newValue = item.Content - 1;
Console.WriteLine($"\nModifier:\nModified {item.Content} to {newValue}");
CountUpdate updateMessage = new CountUpdate { NewCount = newValue };
await this.PublishMessageAsync(updateMessage, topic: new TopicId("default"));
}
PublishMessageAsync 最终委托给 Runtime.PublishMessageAsync(见 BaseAgent.cs),并自动带上 sender: this.Id。SendMessageAsync 则用于点对点 RPC 式投递,二者共同构成智能体的通信原语。
Modifier 的完整最终实现(Modifier.cs)通过构造函数注入 ModifyF modifyFunc 使"如何修改计数"可配置:
using ModifyF = System.Func<int, int>;
namespace GettingStartedSample;
[TypeSubscription("default")]
public class Modifier(
AgentId id,
IAgentRuntime runtime,
ModifyF modifyFunc
) :
BaseAgent(id, runtime, "Modifier", null),
IHandle<CountMessage>
{
public async ValueTask HandleAsync(CountMessage item, MessageContext messageContext)
{
int newValue = modifyFunc(item.Content);
Console.WriteLine($"\nModifier:\nModified {item.Content} to {newValue}");
CountUpdate updateMessage = new CountUpdate { NewCount = newValue };
await this.PublishMessageAsync(updateMessage, topic: new TopicId("default"));
}
}
4.5 Checker:检查条件并停止应用
Checker 订阅同一个 default 主题,响应 CountUpdate。未达终止条件时,它把新计数包装成 CountMessage 重新发布,驱动下一轮迭代;达到条件时则通过依赖注入获得的 IHostApplicationLifetime 停止整个应用(Checker.cs):
[TypeSubscription("default")]
public class Checker(
AgentId id,
IAgentRuntime runtime,
IHostApplicationLifetime hostApplicationLifetime,
TerminationF runUntilFunc
) :
BaseAgent(id, runtime, "Modifier", null),
IHandle<CountUpdate>
{
public async ValueTask HandleAsync(CountUpdate item, MessageContext messageContext)
{
if (!runUntilFunc(item.NewCount))
{
Console.WriteLine($"\nChecker:\n{item.NewCount} passed the check, continue.");
await this.PublishMessageAsync(new CountMessage { Content = item.NewCount }, new TopicId("default"));
}
else
{
Console.WriteLine($"\nChecker:\n{item.NewCount} failed the check, stopping.");
hostApplicationLifetime.StopApplication();
}
}
}
这里体现了 Core 的"消息循环"工作流模式:CountMessage → Modifier → CountUpdate → Checker → CountMessage → ...,直到 Checker 判定 x <= 1 触发停机。
4.6 组装与启动:AgentsAppBuilder
应用入口(Program.cs)分三步。
第一步,定义修改与终止两个函数:
using ModifyF = System.Func<int, int>;
using TerminationF = System.Func<int, bool>;
ModifyF modifyFunc = (int x) => x - 1;
TerminationF runUntilFunc = (int x) =>
{
return x <= 1;
};
第二步,创建 builder:指定使用进程内运行时、把函数注册为单例服务、注册两个智能体类,然后构建并启动:
AgentsAppBuilder appBuilder = new AgentsAppBuilder();
appBuilder.UseInProcessRuntime();
appBuilder.Services.TryAddSingleton(modifyFunc);
appBuilder.Services.TryAddSingleton(runUntilFunc);
appBuilder.AddAgent<Checker>("Checker");
appBuilder.AddAgent<Modifier>("Modifier");
var app = await appBuilder.BuildAsync();
await app.StartAsync();
UseInProcessRuntime() 对应 InProcessRuntime.cs 实现的本地运行时;换成 gRPC 运行时后,智能体即可分布在多个进程/语言中,而上述 API 保持不变(由 AgentsAppBuilderExtensions.cs 提供的扩展方法接入)。
第三步,用初始消息 CountMessage { Content = 10 } 启动流程,发布到智能体所订阅的 default 主题,然后等待应用关闭:
await app.PublishMessageAsync(new CountMessage
{
Content = 10
}, new TopicId("default"));
// Run until application shutdown
await app.WaitForShutdownAsync();
运行后控制台会看到从 10 到 1 的倒数输出。教程还给出了三个练手方向:改变初始计数;把修改函数改成"递增"(记得同步修改 Checker 的终止条件);新增一个只负责输出到控制台的智能体(提示:定义新的消息类型并订阅 default 主题)。
五、分布式与扩展路径
文档门户给出的分布式包组合(Microsoft.AutoGen.RuntimeGateway.Grpc + Microsoft.AutoGen.AgentHost)在源码中的落点是:
- 客户端侧:GrpcAgentRuntime.cs 与
GrpcMessageRouter.cs实现远程消息路由,配合ProtobufMessageSerializer.cs、ProtobufSerializationRegistry.cs完成消息的 Protobuf 序列化/反序列化——这也是跨语言互操作的技术基础(消息按 Protobuf 编码在 Python 与 .NET 智能体之间流转); - 服务端侧:
RuntimeGateway.Grpc/Services/Grpc/下的GrpcGatewayService.cs、GrpcWorkerConnection.cs提供 gRPC 网关与 worker 连接管理,Services/Orleans/下的RegistryGrain.cs、MessageRegistryGrain.cs、MessageRegistryQueue.cs维护注册表与消息队列的分布式状态; - 宿主侧:AgentHost 工程(含
Dockerfile与Program.cs)提供了可直接部署的 gRPC 服务宿主。
仓库中还有配套的跨语言测试与示例可作参考:test/Microsoft.AutoGen.Core.Grpc.Tests/(含 messages.proto)以及 dotnet/samples/GettingStartedGrpc/(含 message.proto 的 gRPC 版倒计时示例),test/Microsoft.AutoGen.Integration.Tests/ 下则包含 Aspire AppHost 场景的集成测试(如 HelloAppHostIntegrationTests.cs)。
在生态集成方面,Extensions/ 目录提供了三个方向的官方扩展:
- Aspire(
Extensions/Aspire/AspireHostingExtensions.cs):与 .NET Aspire 应用模型集成,仓库的dotnet/samples/Hello/与dotnet/samples/dev-team/两个 Aspire 示例工程展示了完整的 AppHost 编排形态; - MEAI(
Extensions/MEAI/MEAIHostingExtensions.cs):对接 Microsoft.Extensions.AI 的聊天补全服务; - SemanticKernel(
Extensions/SemanticKernel/SemanticKernelHostingExtensions.cs):与 Semantic Kernel 集成。
六、小结与适用前提
- 包选择:单进程内的事件驱动智能体工作流只需
Microsoft.AutoGen.Contracts+Microsoft.AutoGen.Core;跨进程/跨语言(Python ↔ .NET)集群再引入Microsoft.AutoGen.RuntimeGateway.Grpc+Microsoft.AutoGen.AgentHost,客户端可替换为 API 相同的Microsoft.AutoGen.Core.Grpc。 - 编程模型:定义强类型消息类 → 继承
BaseAgent并实现IHandle<T>→ 用[TypeSubscription("topic")]绑定主题 → 通过AgentsAppBuilder(UseInProcessRuntime()或 gRPC 运行时)注册并启动 → 向主题发布初始消息驱动流程。 - 适用前提:文档中安装命令示例的版本为
0.4.0-dev.1(开发预览版本),生产环境应核对 NuGet 上对应的稳定版本;AgentChat在文档门户中标注为"Coming soon"(即将推出),其功能细节以 Installation 文档 与Microsoft.AutoGen.AgentChat.csproj的实际能力为准。
想继续深入,建议按以下顺序阅读仓库文件:Tutorial(完整教学)、Installation(包清单)、dotnet/samples/GettingStarted/Program.cs(最小可运行示例)、dotnet/src/Microsoft.AutoGen/Core/BaseAgent.cs(智能体基类与消息分派原理)、dotnet/src/Microsoft.AutoGen/Contracts/AgentId.cs(智能体身份规范)。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00