AutoGen .NET 双世代包体系与快速上手:从 ConversableAgent 对话到事件驱动新 API
本文基于 AutoGen 仓库的 dotnet/README.md 展开,系统讲解 .NET 版本 AutoGen 的两套包体系(AutoGen.* 旧包与 Microsoft.AutoGen.* 新包)、NuGet 安装与 Nightly 源配置、ConversableAgent 最小对话示例,以及事件驱动 Hello 样本的完整运行机制。读完本文,你将能够在 .NET 8 环境中安装并运行 AutoGen,理解旧版对话式 API 与新版事件驱动 API 的差异,并掌握 .NET 独有的源码生成器与代码执行能力。
两代 .NET 包体系:AutoGen.* 与 Microsoft.AutoGen.*
dotnet/README.md 开篇即说明,仓库中的 .NET 包分为两套:
| 包前缀 | 定位 | 状态 |
|---|---|---|
AutoGen.* |
派生自 AutoGen 0.2 for .NET 的旧包(ConversableAgent 对话模型) | 将逐步废弃,并逐步移植进新包 |
Microsoft.AutoGen.* |
基于事件驱动模型(event-driven model)的新包 | API 尚不稳定,可能随时变化 |
这个“双轨并行”的现状意味着:如果你要快速跑通一个 LLM 对话原型,仍应使用 AutoGen.* 系列;如果你要构建可长期演进、可分布式部署的 Agent 应用,则应以 Microsoft.AutoGen.* 的 Hello 样本为起点,并关注其 API 变更。
安装 AutoGen .NET 包
官方安装指引位于 dotnet/website/articles/Installation.md,其中列出了完整的包清单,可按需选择一个或多个安装:
AutoGen:一键全家桶,依赖AutoGen.Core、AutoGen.OpenAI、AutoGen.LMStudio、AutoGen.SemanticKernel和AutoGen.SourceGenerator;AutoGen.Core:核心包,提供消息类型、Agent 与群聊的抽象,不引入Azure.AI.OpenAI或 Semantic Kernel 等外部依赖,适合只想使用 AutoGen 抽象(群聊、内置消息类型、workflow、middleware)并自行实现 Agent 的场景;AutoGen.OpenAI/AutoGen.Mistral/AutoGen.Ollama/AutoGen.Anthropic/AutoGen.LMStudio/AutoGen.Gemini/AutoGen.AzureAIInference:各自提供对应 LLM 后端的集成 Agent;AutoGen.SemanticKernel:基于 Semantic Kernel 的集成 Agent;AutoGen.SourceGenerator:源码生成器,支持类型安全的函数定义生成;AutoGen.DotnetInteractive:基于 dotnet interactive 的代码执行支持,当前支持 C#、F#、PowerShell 与 Python。
官方给出的选型建议是:只想装一个包享受核心功能,就选 AutoGen;只要抽象、不要额外依赖,就选 AutoGen.Core;只想要类型安全的函数调用源码生成能力、连 AutoGen 抽象都不要,就只装 AutoGen.SourceGenerator。
安装命令:
dotnet add package AutoGen
使用 Nightly 构建
dotnet/README.md 指出 Nightly 构建托管在 Azure DevOps 的 AutoGen-Nightly feed 上。要消费 Nightly 包,需要把 feed 加入 NuGet.config 或全局 NuGet 配置。在项目根目录创建本地 NuGet.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<clear />
<add key="AutoGen" value="$(FEED_URL)" /> <!-- replace $(FEED_URL) with the feed url -->
<!-- other feeds -->
</packageSources>
<disabledPackageSources />
</configuration>
或全局添加源(注意:dotnet-tools 源提供 Microsoft.DotNet.Interactive.VisualStudio 包,是 AutoGen.DotnetInteractive 运行所依赖的):
dotnet nuget add source FEED_URL --name AutoGen
dotnet nuget add source https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json --name dotnet-tools
添加源后即可指定版本号安装 Nightly 包:
dotnet add package AutoGen <VERSION>
快速上手:用 ConversableAgent 与助手聊天
以下是 dotnet/README.md 给出的最小可运行片段(使用 AutoGen.* 旧包):
using AutoGen;
using AutoGen.OpenAI;
var openAIKey = Environment.GetEnvironmentVariable("OPENAI_API_KEY") ?? throw new Exception("Please set OPENAI_API_KEY environment variable.");
var gpt35Config = new OpenAIConfig(openAIKey, "gpt-3.5-turbo");
var assistantAgent = new AssistantAgent(
name: "assistant",
systemMessage: "You are an assistant that help user to do some tasks.",
llmConfig: new ConversableAgentConfig
{
Temperature = 0,
ConfigList = [gpt35Config],
})
.RegisterPrintMessage(); // register a hook to print message nicely to console
// set human input mode to ALWAYS so that user always provide input
var userProxyAgent = new UserProxyAgent(
name: "user",
humanInputMode: HumanInputMode.ALWAYS)
.RegisterPrintMessage();
// start the conversation
await userProxyAgent.InitiateChatAsync(
receiver: assistantAgent,
message: "Hey assistant, please do me a favor.",
maxRound: 10);
这段代码的关键点可以结合源码进一步确认:
- 两个内置 Agent 的构造参数完全一致。查看 AssistantAgent 与 UserProxyAgent 的源码,二者均继承自
ConversableAgent,构造参数为name、systemMessage、llmConfig、isTermination(终止判定回调)、humanInputMode、functionMap(工具映射)与defaultReply。二者的唯一区别是humanInputMode的默认值:AssistantAgent默认HumanInputMode.NEVER(从不向人类要输入),UserProxyAgent默认HumanInputMode.ALWAYS(始终向人类要输入)。示例中显式传入ALWAYS,即让对话循环在每一轮都等待终端用户输入。 llmConfig中的ConfigList支持多模型回退:OpenAIConfig(openAIKey, "gpt-3.5-turbo")描述了模型与凭据,Temperature = 0表示关闭随机性以获得确定性输出。.RegisterPrintMessage()注册一个 middleware 钩子,将消息格式化打印到控制台,属于 AutoGen.Core 的 middleware 机制,方便调试对话内容。InitiateChatAsync(receiver, message, maxRound)由 UserProxy 发起与助手的对话,maxRound: 10限制最大对话轮数,防止循环不终止。
更完整的对话示例可参考仓库内 AutoGen.Basic.Sample 样本项目,其中包含两 Agent 数学对话、函数调用、动态群聊、Dalle + GPT4V 图像生成、UserProxy、LM Studio、ReAct Agent 等十多个示例(如 Example01_AssistantAgent.cs、Example03_Agent_FunctionCall.cs、Example04_Dynamic_GroupChat_Coding_Task.cs)。
新包入门:事件驱动的 Hello 样本
README 指出:要开始使用 Microsoft.AutoGen.* 新包,请查看 samples 目录,尤其是 Hello 样本。该样本是一个 .NET Aspire 多项目工程,包含以下子项目:
- Hello.AppHost:Aspire App Host,负责编排启动 .NET 后端、.NET Agent 与 Python Agent(跨语言 xlang 演示),并可打开 Aspire Dashboard 查看遥测与日志;
- HelloAgent:最小事件驱动 Agent,仅监听事件并回复;
- HelloAIAgents:在 HelloAgent 基础上注入
IChatClient,用 LLM 生成打油诗式问候,演示如何扩展 Agent; - HelloAgentState:演示带状态的 Agent;
- protos/agent_events.proto:自定义消息的 protobuf 定义。
运行前提为 .NET 8.0 及以上,命令为:
cd dotnet/samples/Hello
dotnet run
HelloAgent 的事件处理机制
HelloAgent.cs 展示了新包的核心编程模型——订阅 Topic、处理消息、发布新消息:
[TypeSubscription("HelloTopic")]
public class HelloAgent(
IHostApplicationLifetime hostApplicationLifetime,
AgentId id,
IAgentRuntime runtime,
Logger<BaseAgent>? logger = null) : BaseAgent(id, runtime, "Hello Agent", logger),
IHandle<NewMessageReceived>,
IHandle<ConversationClosed>,
IHandle<Shutdown>
{
// 接收 Program.cs 中发布的新消息
public async ValueTask HandleAsync(NewMessageReceived item, MessageContext messageContext)
{
Console.Out.WriteLine(item.Message);
ConversationClosed goodbye = new ConversationClosed
{
UserId = this.Id.Type,
UserMessage = "Goodbye"
};
// 发布 ConversationClosed,触发自身的对应 handler
await this.PublishMessageAsync(goodbye, new TopicId("HelloTopic"));
}
public async ValueTask HandleAsync(ConversationClosed item, MessageContext messageContext)
{
Console.Out.WriteLine($"{item.UserId} said {item.UserMessage}");
if (Environment.GetEnvironmentVariable("STAY_ALIVE_ON_GOODBYE") != "true")
{
await this.PublishMessageAsync(new Shutdown(), new TopicId("HelloTopic"));
}
}
public async ValueTask HandleAsync(Shutdown item, MessageContext messageContext)
{
Console.WriteLine("Shutting down...");
hostApplicationLifetime.StopApplication(); // 关闭应用
}
}
从源码结构看,这里体现了新 API 的几个关键概念:
[TypeSubscription("HelloTopic")]特性声明 Agent 订阅的主题;IHandle<T>接口把 protobuf 消息类型映射到HandleAsync处理方法;- 消息类型(
NewMessageReceived、ConversationClosed、Shutdown)由 gRPC protobuf 规范生成 C# 类,仓库根目录的 protos/ 目录存放了agent_worker.proto与cloudevent.proto等基础定义,开发者也可以在项目中新增.proto文件定义自定义消息; PublishMessageAsync(message, new TopicId("HelloTopic"))把新消息发回事件总线,形成“收消息 → 处理 → 发新消息 → 触发下一个 handler”的链式编排。
App Builder 与进程内 / 分布式两种运行时
HelloAgent/Program.cs 演示了 AgentsAppBuilder 的两种启动方式:
var appBuilder = new AgentsAppBuilder();
bool usingGrpc = false;
if (hostAddress is string agentHost) // 设置了 --host 或 AGENT_HOST 环境变量
{
usingGrpc = true;
appBuilder.AddGrpcAgentWorker(agentHost).AddAgent<HelloAgent>("HelloAgent");
}
else
{
// 进程内运行时,允许消息投递给自身,并注册 Hello Agent
appBuilder.UseInProcessRuntime(deliverToSelf: true).AddAgent<HelloAgent>("HelloAgent");
}
var app = await appBuilder.BuildAsync();
await app.StartAsync();
var message = new NewMessageReceived { Message = "Hello World!" };
await app.PublishMessageAsync(message, new TopicId("HelloTopic"));
await app.WaitForShutdownAsync();
命令行参数说明(来自同文件内 PrintHelp()):
--host <hostAddress>:通过 gRPC 网关连接分布式运行时,也可用环境变量AGENT_HOST指定;--nosend:不发送启动消息,等待其他 Agent 先发消息(注意在 InProcessRuntime 下无效);- 环境变量
STAY_ALIVE_ON_GOODBYE=true时,Agent 收到 Goodbye 后不自我关闭,便于 Aspire 多 Agent 场景中保持存活。
HelloAppHost 的 Program.cs 则演示了 .NET Aspire 的编排:启动 AgentHost 后端(WithExternalHttpEndpoints()),为 .NET Agent 与 Python Agent 分别注入 AGENT_HOST 端点,实现同一事件总线上 C# 与 Python Agent 互通的 xlang 场景。更多新包概念可继续阅读 HelloAgent 的 README,其中包含事件流程图、事件处理器写法、继承与组合、自定义 protobuf 消息(含 .csproj 中引入 Grpc.Tools 的配置片段)等细节。
功能支持矩阵与 .NET 独有能力
dotnet/README.md 的 Functionality 一节明确了当前 .NET 版的功能边界:
| 能力 | 状态 | 说明 |
|---|---|---|
| ConversableAgent 函数调用 | 已支持 | 通过 functionMap 或 [Function] 特性绑定工具 |
| 代码执行 | 已支持(仅 .NET 版) | 由 dotnet-interactive 驱动,见 AutoGen.DotnetInteractive 包 |
| 双 Agent 对话 | 已支持 | 参见 TwoAgentTest 等测试 |
| 群聊(Group chat) | 已支持 | 实现位于 AutoGen.Core/GroupChat |
| 增强型 LLM 推理 | 计划中 | README 中仍为未完成项 |
| 类型安全函数定义源码生成 | 已支持(.NET 独有) | AutoGen.SourceGenerator 包 |
值得强调的是 .NET 独有的源码生成器:AutoGen.SourceGenerator 让你在方法上标注 [Function] 特性,编译期即自动生成 FunctionDefinition 与 JSON 参数反序列化包装器,免去手写函数 schema 并保证签名同步。使用步骤:
- 在
.csproj中设置GenerateDocumentationFile为true(启用 XML 文档,特性参数的描述会取自 XML doc 注释),并引用AutoGen.SourceGenerator包; - 在
public partial class中为方法标注[Function],方法需为public,参数与返回值尽量使用基础类型以获得最佳性能:
using AutoGen;
public partial class MyFunctions
{
/// <summary>
/// Add two numbers.
/// </summary>
/// <param name="a">The first number.</param>
/// <param name="b">The second number.</param>
[Function]
public Task<string> AddAsync(int a, int b)
{
return Task.FromResult($"{a} + {b} = {a + b}");
}
}
生成结果包含三部分:一个与参数对应的私有 schema 类(AddAsyncSchema)、一个 AddAsyncWrapper(把 LLM 返回的 JSON 字符串反序列化为强类型参数并调用原方法)、一个 AddAsyncFunction 属性(把方法名、XML 文档与参数类型映射为 FunctionDefinition,供 Agent 注册为工具)。生成的 JSON schema 使用 CamelCase 命名策略,int 参数映射为 number 类型。更多示例见 AutoGen.SourceGenerator.Tests。
样本索引与延伸路径
除了本文重点剖析的 Hello 样本,dotnet/samples/ 目录还提供了分层递进的实践路径:
- AgentChat/AutoGen.Basic.Sample:旧包对话式 API 的完整示例集(数学对话、函数调用、群聊、Dalle/GPT4V、UserProxy、LM Studio、Semantic Kernel、JSON 模式等);
- AgentChat/AutoGen.OpenAI.Sample:连接 Azure OpenAI、Ollama、o1-preview、结构化输出、JSON 模式;
- AgentChat/AutoGen.Gemini.Sample 与 AutoGen.Ollama.Sample:Google Gemini / Vertex 与 Ollama(LLaMA、LLaVA)集成;
- AgentChat/AutoGen.SemanticKernel.Sample:Semantic Kernel 集成与内核函数跨 Agent 复用;
- GettingStarted 与 GettingStartedGrpc:新包最小示例及其 gRPC 分布式版本(含
message.proto自定义消息定义); - dev-team:基于新包构建的多 Agent 开发团队协作系统,含完整的服务端(Agents/Options/Services)、protobuf 契约(Protos/messages.proto、states.proto)与 Aspire 编排,是理解事件驱动模型如何落地为真实应用的最佳范本。
小结
AutoGen 的 .NET 生态正处于从“ConversableAgent 对话模型”(AutoGen.*)向“事件驱动消息模型”(Microsoft.AutoGen.*)迁移的阶段。旧包提供了即装即用的助手对话、函数调用、群聊与基于 dotnet-interactive 的代码执行,配合 AutoGen.SourceGenerator 的类型安全函数定义,能快速搭建 LLM 应用原型;新包则以 Topic 订阅、protobuf 消息契约、进程内/gRPC 双运行时为核心,通过 Hello、GettingStartedGrpc、dev-team 等样本展示了可分布式、可跨语言(.NET 与 Python)的 Agent 编排能力。由于新包 API 尚未稳定,实践中建议以旧包做功能验证、以新包做架构演进跟踪,并关注 Nightly feed 获取最新构建。
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