AutoGen .NET Core 实战指南:从 BaseAgent 事件处理到分布式运行时与 Aspire 编排
AutoGen .NET 版本(AutoGen Core for .NET)的编程模型与其 Python 版本保持一致:以“消息 + 主题 + 事件处理”为核心,通过 BaseAgent 派生实现自定义智能体,再用 AgentsAppBuilder 把智能体挂载到进程内或分布式运行时上运行。读完本篇,你将掌握 .NET 版 AutoGen 的完整上手路径:NuGet 包安装、编写并注册 Agent、用 AgentsAppBuilder 启动应用并投递消息、配置日志,以及通过 Microsoft.AutoGen.AgentHost 与 .NET Aspire 编排跨进程、跨语言(Python/.NET)的分布式 Agent 系统。
核心概念:与 Python 版本对齐的编程模型
AutoGen Core for .NET 沿用了其 Python 对应版本的相同概念与约定。官方文档的建议是:在理解 .NET 版本的概念之前,可先阅读 Python 版本文档;除特别说明外,Python 版本中的概念均可映射到 .NET 版本。两个语言版本之间的重要差异记录在 Differences from Python 一节中,而只影响某一语言的内容(例如依赖注入、Host Builder 模式)则不在差异文档中赘述。
一个值得注意的差异(同样在差异文档中说明):当一个 Agent 向自己订阅的主题发布消息时,默认不会收到自己发出的消息——这与 Python 运行时行为一致;但在 .NET 的 InProcessRuntime 中,可将 DeliverToSelf 属性设为 true 以允许 Agent 收到自己发布的消息(对应 AgentsAppBuilder.UseInProcessRuntime(deliverToSelf: true) 的第二个参数)。
安装:获取 .NET SDK 包
AutoGen .NET SDK 可以以 NuGet 包形式获取(NuGet 上的包名为 Microsoft.AutoGen),也可以直接克隆仓库使用。最小安装只需要以下两个包:
dotnet add package Microsoft.AutoGen.Contracts
dotnet add package Microsoft.AutoGen.Core
Microsoft.AutoGen.Contracts:定义IAgentRuntime、BaseAgent、IHandle<T>、AgentId、TopicId、MessageContext等核心契约类型,源码位于 Contracts 项目。Microsoft.AutoGen.Core:提供InProcessRuntime(进程内运行时)、AgentsAppBuilder、AgentsApp等运行时实现,源码位于 Core 项目。
更完整的安装说明(包括各相关包的取舍)见 Installation。快速上手的最佳途径是浏览仓库 samples 目录下的示例代码,其中 dotnet/samples/Hello 与 dotnet/samples/GettingStarted 是本文后续示例的直接来源。
创建 Agent:继承 BaseAgent 并实现 IHandle<T>
创建 Agent 的方式是继承 BaseAgent 并为你关心的事件实现事件处理器。文档给出的最小示例如下:
public class MyAgent : BaseAgent, IHandle<MyMessage>
{
// ...
public async ValueTask HandleAsync(MyMessage item, MessageContext context)
{
// ...logic here...
}
}
通过继承 BaseAgent,你获得了运行时(Runtime)与日志(_logger)等基础设施;通过实现 IHandle<T>,可以简洁地为自定义消息类型定义事件处理方法。
源码视角:事件处理器是如何被发现与分发的
从 BaseAgent.cs 的实现可以看到这套机制的细节:
BaseAgent构造函数在初始化时调用ReflectInvokers(),扫描当前类实现的所有IHandle<>/IHandle<,>泛型接口,为每种消息类型创建一个HandlerInvoker,存入Dictionary<Type, HandlerInvoker>(见 BaseAgent.cs#L60-L81)。- 运行时收到消息后,
OnMessageAsync按消息类型查表分发到对应处理器,未注册的消息类型直接返回null(见 BaseAgent.cs#L83-L93)。 BaseAgent本身提供SendMessageAsync(点对点发送)与PublishMessageAsync(向主题发布)两个方法,均委托给注入的IAgentRuntime,发送方身份自动填充为this.Id(见 BaseAgent.cs#L95-L104)。- 此外
BaseAgent实现了ISaveState,并内置ActivitySource(Microsoft.AutoGen.Core.Agent)用于 OpenTelemetry 追踪。
一个更完整的真实示例是 HelloAgent:它通过 [TypeSubscription("HelloTopic")] 属性订阅主题,并实现了三个处理器——NewMessageReceived(收到消息后转发一条 ConversationClosed)、ConversationClosed(打印告别语,若未设置 STAY_ALIVE_ON_GOODBYE=true 则发布 Shutdown)、Shutdown(调用 IHostApplicationLifetime.StopApplication() 关闭宿主)。这展示了 AutoGen 中“一切皆消息”的编排风格:Agent 间的状态推进完全由消息流驱动。
在应用里运行 Agent:AgentsAppBuilder
在应用内运行 Agent 使用 AgentsAppBuilder。文档示例展示了如何在应用中运行一个 HelloAgent:
AgentsAppBuilder appBuilder = new AgentsAppBuilder()
.UseInProcessRuntime(deliverToSelf: true)
.AddAgent<HelloAgent>("HelloAgent");
var app = await appBuilder.BuildAsync();
// start the app by publishing a message to the runtime
await app.PublishMessageAsync(new NewMessageReceived
{
Message = "Hello from .NET"
}, new TopicId("HelloTopic"));
// Wait for shutdown
await app.WaitForShutdownAsync();
源码视角:AgentsAppBuilder 的构建流程
AgentsApp.cs 揭示了该 API 的底层行为:
AgentsAppBuilder内部封装了一个HostApplicationBuilder(.NET Generic Host),因此你可以直接访问appBuilder.Services(IServiceCollection)与appBuilder.Configuration,把 Agent 所需的依赖注册进去(见 AgentsApp.cs#L13-L26)。UseInProcessRuntime(bool deliverToSelf = false)将InProcessRuntime注册为IAgentRuntime单例,并将其作为IHostedService托管,从而随宿主启动(见 AgentsApp.cs#L32-L41)。AddAgent<TAgent>(agentType, ...)只是登记一个注册委托;BuildAsync()阶段才真正执行RegisterAgentTypeAsync与RegisterImplicitAgentSubscriptionsAsync,把 Agent 类型及其隐式订阅(如[TypeSubscription])写入运行时(见 AgentsApp.cs#L75-L86)。AgentsApp.PublishMessageAsync具有“按需自启动”特性:如果应用尚未运行,会先调用StartAsync()再向运行时发布消息(见 AgentsApp.cs#L127-L136)——这就是文档示例中省略显式StartAsync()的原因。
完整示例:GettingStarted 计数器
仓库中的 GettingStarted 示例 演示了“多 Agent + 依赖注入”的完整流程:Checker 与 Modifier 两个 Agent 协作,从 10 开始递减直到 1。关键代码如下:
using Microsoft.AutoGen.Contracts;
using Microsoft.AutoGen.Core;
using Microsoft.Extensions.DependencyInjection.Extensions;
// 把业务依赖注入到宿主
appBuilder.Services.TryAddSingleton(modifyFunc);
appBuilder.Services.TryAddSingleton(runUntilFunc);
// 注册两个 Agent(key 即 AgentType)
appBuilder.AddAgent<Checker>("Checker");
appBuilder.AddAgent<Modifier>("Modifier");
var app = await appBuilder.BuildAsync();
await app.StartAsync();
// 向 "default" 主题发布初始消息,触发整条消息链
await app.PublishMessageAsync(new CountMessage
{
Content = 10
}, new TopicId("default"));
// Run until application shutdown
await app.WaitForShutdownAsync();
该示例中 Checker/Modifier 分别订阅消息类型并发布下一条消息(CountUpdate),体现了与 Hello 示例一致的消息链模式。
.NET SDK 的两种运行时
.NET SDK 提供两类运行时:
- InMemory Single Process Runtime(进程内运行时):即
InProcessRuntime,适合单进程应用; - Remote Distributed Runtime(分布式运行时):面向云端部署,支持 Python 与 .NET 编写的 Agent 在同一个分布式系统中互相通信。分布式运行时基于 Microsoft Orleans 提供弹性、持久化以及与 Azure Event Hubs 等消息服务的集成;跨语言(xlang)通信要求 Agent 的消息可序列化为 CloudEvents,消息通过 gRPC 以 CloudEvents 格式交换,运行时负责保证消息被投递到正确的 Agent。
客户端侧:接入分布式运行时
要在应用中使用分布式运行时,需要添加:
dotnet add package Microsoft.AutoGen.Core.Grpc
这是运行在你应用内、连接分布式系统的包(源码位于 Core.Grpc 项目)。
服务端侧:运行 Agent Host 后端
运行后端/服务端需要两个包:
dotnet add package Microsoft.AutoGen.RuntimeGateway
dotnet add package Microsoft.AutoGen.AgentHost
可以独立以后端进程方式运行:
dotnet run --project Microsoft.AutoGen.AgentHost
也可以把后端嵌入到自己的应用中:
using Microsoft.AutoGen.RuntimeGateway;
using Microsoft.AutoGen.AgentHost;
var autogenBackend = await Microsoft.AutoGen.RuntimeGateway.Grpc.Host.StartAsync(local: false, useGrpc: true);
此外,还可以把运行时作为 dotnet tool 安装使用:
dotnet pack --no-build --configuration Release --output './output/release' -bl
dotnet tool install --add-source ./output/release Microsoft.AutoGen.AgentHost
# run the tool
# dotnet agenthost
# or just...
agenthost
相关源码可参考 RuntimeGateway.Grpc 项目 与 AgentHost 项目。
使用 .NET Aspire 编排多进程分布式系统
Hello.AppHost 示例 展示了如何用 .NET Aspire 把“多个 Agent + 运行时”编排为独立进程组成的分布式系统,并同时拉起一个 Python Agent 演示跨语言协作(对应 core_xlang_hello_python_agent 示例):
using Microsoft.Extensions.Hosting;
var builder = DistributedApplication.CreateBuilder(args);
var backend = builder.AddProject<Projects.Microsoft_AutoGen_AgentHost>("backend").WithExternalHttpEndpoints();
var client = builder.AddProject<Projects.HelloAgent>("HelloAgentsDotNET")
.WithReference(backend)
.WithEnvironment("AGENT_HOST", backend.GetEndpoint("https"))
.WithEnvironment("STAY_ALIVE_ON_GOODBYE", "true")
.WaitFor(backend);
// xlang is over http for now - in prod use TLS between containers
builder.AddPythonApp("HelloAgentsPython", "../../../../python/samples/core_xlang_hello_python_agent", "hello_python_agent.py", "../../.venv")
.WithReference(backend)
.WithEnvironment("AGENT_HOST", backend.GetEndpoint("http"))
.WithEnvironment("STAY_ALIVE_ON_GOODBYE", "true")
.WithEnvironment("GRPC_DNS_RESOLVER", "native")
.WithOtlpExporter()
.WaitFor(client);
using var app = builder.Build();
await app.StartAsync();
var url = backend.GetEndpoint("http").Url;
Console.WriteLine("Backend URL: " + url);
await app.WaitForShutdownAsync();
要点解读:
backend即Microsoft.AutoGen.AgentHost项目,作为 Orleans 网关对外暴露 HTTP 端点;- .NET 客户端
HelloAgentsDotNET通过环境变量AGENT_HOST指向后端端点(此示例中走 https),并用WaitFor(backend)声明启动顺序; - Python 应用通过
AddPythonApp注册,当前 xlang 走 http(示例注释提醒:生产环境容器间应使用 TLS),并额外设置GRPC_DNS_RESOLVER=native; - 更丰富的 Aspire + XLang 示例可在 Microsoft.AutoGen.Integration.Tests.AppHosts 目录中找到。
配置日志
SDK 使用 Microsoft.Extensions.Logging 框架进行日志输出。文档推荐了一个包含实用默认值的 appsettings.json:
{
"Logging": {
"LogLevel": {
"Default": "Warning",
"Microsoft.Hosting.Lifetime": "Information",
"Microsoft.AspNetCore": "Information",
"Microsoft": "Information",
"Microsoft.Orleans": "Warning",
"Orleans.Runtime": "Error",
"Grpc": "Information"
}
},
"AllowedHosts": "*",
"Kestrel": {
"EndpointDefaults": {
"Protocols": "Http2"
}
}
}
各配置项的作用:默认日志级别为 Warning 以降噪;Orleans.Runtime 提到 Error 避免 Orleans 内部日志刷屏;Grpc 保持 Information 便于观察分布式消息通道;Kestrel 端点强制 Http2 协议是 gRPC 传输的前提。
用 Protocol Buffers 定义消息类型
如果消息要走 InProcessRuntime 以外的运行时,则必须以 Protocol Buffers 消息形式定义,因为跨进程消息使用 Protocol Buffers 进行序列化/反序列化(未来可能放宽为支持转换器或自定义序列化机制)。要点是:将 .proto 文件纳入项目后会自动生成对应的 C# 消息类,具体做法(引入 Grpc.Tools、配置 <Protobuf Include="..."/>、定义 message、对生成类编程)详见 Using Protocol Buffers to Define Message Types。仓库中的 messages.proto 与 GettingStartedGrpc 示例 可作为对照参考。
小结与延伸阅读
本篇围绕 AutoGen Core for .NET 入口文档 覆盖了 .NET 版 AutoGen 的完整主线:
| 主题 | 关键 API / 包 | 源码位置 |
|---|---|---|
| Agent 定义 | BaseAgent + IHandle<T> + [TypeSubscription] |
dotnet/src/Microsoft.AutoGen/Core/BaseAgent.cs |
| 应用装配 | AgentsAppBuilder / AgentsApp |
dotnet/src/Microsoft.AutoGen/Core/AgentsApp.cs |
| 进程内运行时 | UseInProcessRuntime(deliverToSelf:) |
dotnet/src/Microsoft.AutoGen/Core/InProcessRuntime.cs |
| 分布式客户端 | Microsoft.AutoGen.Core.Grpc |
dotnet/src/Microsoft.AutoGen/Core.Grpc |
| 分布式后端 | Microsoft.AutoGen.RuntimeGateway + Microsoft.AutoGen.AgentHost |
dotnet/src/Microsoft.AutoGen/AgentHost |
| 示例 | Hello / GettingStarted / Aspire AppHost | dotnet/samples |
继续深入可阅读:Differences from Python、Installation、Tutorial、Using Protocol Buffers to Define Message Types,以及跨语言互通的 xlang Python Agent 示例。
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