首页
/ AutoGen .NET 双世代包体系与快速上手:从 ConversableAgent 对话到事件驱动新 API

AutoGen .NET 双世代包体系与快速上手:从 ConversableAgent 对话到事件驱动新 API

2026-09-05 13:35:32作者:蔡丛锟

本文基于 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.CoreAutoGen.OpenAIAutoGen.LMStudioAutoGen.SemanticKernelAutoGen.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 的构造参数完全一致。查看 AssistantAgentUserProxyAgent 的源码,二者均继承自 ConversableAgent,构造参数为 namesystemMessagellmConfigisTermination(终止判定回调)、humanInputModefunctionMap(工具映射)与 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.csExample03_Agent_FunctionCall.csExample04_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 处理方法;
  • 消息类型(NewMessageReceivedConversationClosedShutdown)由 gRPC protobuf 规范生成 C# 类,仓库根目录的 protos/ 目录存放了 agent_worker.protocloudevent.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 并保证签名同步。使用步骤:

  1. .csproj 中设置 GenerateDocumentationFiletrue(启用 XML 文档,特性参数的描述会取自 XML doc 注释),并引用 AutoGen.SourceGenerator 包;
  2. 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/ 目录还提供了分层递进的实践路径:

小结

AutoGen 的 .NET 生态正处于从“ConversableAgent 对话模型”(AutoGen.*)向“事件驱动消息模型”(Microsoft.AutoGen.*)迁移的阶段。旧包提供了即装即用的助手对话、函数调用、群聊与基于 dotnet-interactive 的代码执行,配合 AutoGen.SourceGenerator 的类型安全函数定义,能快速搭建 LLM 应用原型;新包则以 Topic 订阅、protobuf 消息契约、进程内/gRPC 双运行时为核心,通过 Hello、GettingStartedGrpc、dev-team 等样本展示了可分布式、可跨语言(.NET 与 Python)的 Agent 编排能力。由于新包 API 尚未稳定,实践中建议以旧包做功能验证、以新包做架构演进跟踪,并关注 Nightly feed 获取最新构建。

登录后查看全文
热门项目推荐
相关项目推荐