AutoGen.NET:通过 SemanticKernelChatMessageContentConnector 让 SemanticKernelAgent 支持更多内置消息类型
AutoGen.NET通过 SemanticKernelChatMessageContentConnector 让 SemanticKernelAgent 支持更多内置消息类型【免费下载链接】autogenA programming framework for agentic AI项目地址: https://gitcode.com/GitHub_Trending/au/autogen在 AutoGen.NET.NET 版 AutoGen中SemanticKernelAgent 原生的消息通道只认一种类型来自 Semantic Kernel 的ChatMessageContent即IMessageChatMessageContent。当你的对话系统中同时存在 AutoGen 内置消息如TextMessage、ImageMessage、MultiModalMessage时如何让它们与 Semantic Kernel Agent 无缝互通本文基于官方文档 SemanticKernelAgent-support-more-messages 并结合仓库源码完整讲解如何通过注册SemanticKernelChatMessageContentConnector中间件扩展 Agent 的消息兼容性包括支持的消息类型清单、完整可运行代码、双向转换的底层实现细节以及当前版本尚不支持的消息类型与验证方式。一、SemanticKernelAgent 的默认消息限制SemanticKernelAgent是基于Microsoft.SemanticKernel的Kernel对象构建的流式 Agent实现IStreamingAgent接口。它接收IEnumerableIMessage作为输入内部通过BuildChatHistory将消息列表拼装为 Semantic Kernel 的ChatHistory。关键限制体现在它的消息处理逻辑中。从 SemanticKernelAgent.cs 的ProcessMessage方法可以看到private IEnumerableChatMessageContent ProcessMessage(IEnumerableIMessage messages) { return messages.Select(m m switch { IMessageChatMessageContent cmc cmc.Content, _ throw new ArgumentException(Invalid message type) }); }也就是说只有IMessageChatMessageContent能通过类型匹配任何 AutoGen 内置消息类型TextMessage、ImageMessage等传入都会直接抛出ArgumentException: Invalid message type。Agent 类注释SemanticKernelAgent.cs也明确说明入站/回复消息均为IMessageChatMessageContent流式回复为IMessageStreamingChatMessageContent要支持更多 AutoGen 内置IMessage请注册SemanticKernelChatMessageContentConnector。默认用法下你需要用MessageEnvelope.Create把ChatMessageContent包装成IMessageChatMessageContent再发送回复同样以MessageEnvelopeChatMessageContent形式返回。这是 AutoGen 与 Semantic Kernel 之间的窄通道。二、SemanticKernelChatMessageContentConnector双向消息转换器SemanticKernelChatMessageContentConnector是解决上述限制的核心组件位于 Middleware/SemanticKernelChatMessageContentConnector.cs。它的职责是双向转换入站Inbound把调用方发来的 AutoGen 内置消息转换为ChatMessageContent再包上MessageEnvelopeChatMessageContent传给底层 Agent出站Outbound把 Agent 返回的ChatMessageContent流式场景为StreamingChatMessageContent转换回 AutoGen 内置消息类型返回给调用方。从类型声明看它同时实现了IMiddleware与IStreamingMiddleware两个接口SemanticKernelChatMessageContentConnector.cs因此同步SendAsync与流式GenerateStreamingReplyAsync两条链路都能走转换逻辑——这是它与普通单一中间件的重要区别。支持的消息类型清单根据文档与中间件源码当前阶段转换器的支持范围如下方向支持的消息类型说明入站TextMessage按Role映射为 System/User/Assistant入站ImageMessage需带 URL 或可构造 Data URI 的二进制数据入站MultiModalMessage内部元素仅支持TextMessage与ImageMessage出站非流式TextMessage/ImageMessage/MultiModalMessage单内容项返回单条消息多内容项打包为MultiModalMessage出站流式TextMessageUpdate流式增量文本更新不支持ToolCallMessage/ToolCallResultMessage函数调用类消息当前版本尚未支持此外IMessageChatMessageContent本身会被直接透传原样解包因此注册连接器后原有 Semantic Kernel 风格的用法依然兼容。三、注册方式与完整可运行示例注册操作通过扩展方法RegisterMessageConnector()完成定义在 Extension/SemanticKernelAgentExtension.cspublic static MiddlewareStreamingAgentSemanticKernelAgent RegisterMessageConnector( this SemanticKernelAgent agent, SemanticKernelChatMessageContentConnector? connector null) { if (connector null) { connector new SemanticKernelChatMessageContentConnector(); } return agent.RegisterStreamingMiddleware(connector); }该扩展方法有两个重载分别接收SemanticKernelAgent与MiddlewareStreamingAgentSemanticKernelAgent连接器实例可以缺省——不传时自动new一个默认实例返回值是注册了流式中间件的新 Agent 实例AutoGen 的中间件机制采用注册即返回新 Agent的不可变风格。下面是官方示例工程 SemanticKernelCodeSnippet.cs 中的完整代码对应文档引用的register_semantic_kernel_chat_message_content_connector代码块var openAIKey Environment.GetEnvironmentVariable(OPENAI_API_KEY) ?? throw new Exception(Please set OPENAI_API_KEY environment variable.); var modelId gpt-3.5-turbo; var builder Kernel.CreateBuilder() .AddOpenAIChatCompletion(modelId: modelId, apiKey: openAIKey); var kernel builder.Build(); // create a semantic kernel agent var semanticKernelAgent new SemanticKernelAgent( kernel: kernel, name: assistant, systemMessage: You are an assistant that help user to do some tasks.); // Register the connector middleware to the kernel agent var semanticKernelAgentWithConnector semanticKernelAgent .RegisterMessageConnector(); // now semanticKernelAgentWithConnector supports more message types IMessage[] messages [ MessageEnvelope.Create(new ChatMessageContent(AuthorRole.User, Hello)), new TextMessage(Role.Assistant, Hello, from: user), new MultiModalMessage(Role.Assistant, [ new TextMessage(Role.Assistant, Hello, from: user), ], from: user), ]; foreach (var message in messages) { var reply await semanticKernelAgentWithConnector.SendAsync(message); // SemanticKernelChatMessageContentConnector will convert the reply message to TextMessage reply.Should().BeOfTypeTextMessage(); }运行前提需要设置OPENAI_API_KEY环境变量项目需引用AutoGen.SemanticKernel、Microsoft.SemanticKernel等 NuGet 包仓库 Directory.Packages.props 中当前锁定的 Semantic Kernel 稳定版为 1.45.0。这段代码展示了三种入站消息混用ChatMessageContent信封消息透传、AutoGenTextMessage、AutoGenMultiModalMessage且回复统一被转换器还原为 AutoGen 的TextMessage。对比未注册连接器时的基线用法同一示例文件中的CreateSemanticKernelAgentAsyncSemanticKernelCodeSnippet.cs演示了不注册连接器时的用法只能发送IMessageChatMessageContent回复需用reply.AsMessageEnvelopeChatMessageContent().Content解包流式则通过GenerateStreamingReplyAsync拿到MessageEnvelopeStreamingChatMessageContent。两段示例放在一起可以直观看到连接器带来的能力差异。四、转换逻辑源码剖析4.1 入站转换区分自己发的与别人发的中间件的ProcessMessageSemanticKernelChatMessageContentConnector.cs按m.From agent.Name把消息分为两类分别处理这决定了 AutoGen 的Role到 Semantic KernelAuthorRole的映射规则来自 Agent 自身ProcessMessageForSelf即消息在对话历史中是 Agent 自己之前的回复Role.System→AuthorRole.System其余一律 →AuthorRole.Assistant来自其他参与者ProcessMessageForOthers即用户或第三方 AgentRole.System→AuthorRole.System其余一律 →AuthorRole.UserImageMessage他人优先使用message.Url构造ImageContent(new Uri(...))若无 URL 但持有二进制Data则调用BuildDataUri()生成 base64 Data URI 再包装为ImageContent两者皆无时抛出InvalidOperationException: ImageMessage must have Url or DataUri。ImageMessage的 Data URI 构造与 MIME 类型推断逻辑见 ImageMessage.cs支持 png/jpg/jpeg/gif/bmp/webp/svg 等扩展名自动推断MultiModalMessage他人遍历内部Content逐项转换为TextContent或ImageContent后装入ChatMessageContentItemCollection打包为单条AuthorRole.User消息MultiModalMessage自己明确抛出InvalidOperationException(MultiModalMessage is not supported in the semantic kernel if its from self.)——即 Agent 自己历史中的多模态消息暂不支持回放旧版Message类型已标记[Obsolete]仍有兼容分支但其中携带函数调用字段FunctionName/FunctionArguments的消息会抛出 Function call is not supported 异常。不支持的类型一律抛InvalidOperationException(unsupported message type, only support TextMessage, ImageMessage, MultiModalMessage and Message.)错误信息直接给出了支持清单排错成本很低。4.2 出站转换按内容项数量选择消息类型回复方向由PostProcessMessage(IMessageChatMessageContent)SemanticKernelChatMessageContentConnector.cs完成TextContent→TextMessage(Role.Assistant, ...)ImageContent带Uri或ReadOnlyMemorybyte二进制→ImageMessage转换后的内容项若只有 1 个直接返回该单条消息否则打包为MultiModalMessage(Role.Assistant, items, ...)——这解释了为何多模态回复会自动升级类型遇到其他KernelContent子类型抛Unsupported content type。流式回复走PostProcessMessage(IMessageStreamingChatMessageContent)校验ChoiceIndex必须为 0多 choice 抛异常然后把每个增量块包装为TextMessageUpdate(Role.Assistant, content, from)。TextMessageUpdate的定义见 TextMessage.cs它与TextMessage的区别在于Content可为空且用于增量累积。4.3 为什么这样设计AutoGen 的消息模型以IMessage接口为统一抽象各后端OpenAI、Ollama、Gemini、Semantic Kernel 等有自己的原生消息类型。连接器中间件本质上是适配器让上层编排代码如 GroupChat只操作 AutoGen 原生消息而由中间件屏蔽后端的类型差异。这一注册中间件即扩展能力的模式在 AutoGen.NET 的中间件体系中是通用设计SemanticKernelChatMessageContentConnector只是 Semantic Kernel 后端的具体实现。五、测试用例中的行为验证SemanticKernelAgentTest.cs 提供了对上述能力的端到端验证基于 Azure OpenAI需AZURE_OPENAI_API_KEY、AZURE_OPENAI_ENDPOINT、AZURE_OPENAI_DEPLOY_NAME环境变量SemanticKernelChatMessageContentConnectorTestAsync测试代码注册连接器后对ChatMessageContent信封、TextMessage、MultiModalMessage三种入站消息逐一SendAsync断言回复均为TextMessage且From assistant随后用同样的消息列表验证流式路径断言每个增量块都是TextMessageUpdate。这与本文第三节的示例完全对应SemanticKernelPluginTestAsync还验证了注册连接器后 Kernel 插件函数仍可正常工作向 Kernel 注入GetWeatherAsync插件函数并发送What is the weather in Seattle?断言回复包含 seattle 与 sunny——说明连接器只转换消息通道不影响 Kernel 自身通过ToolCallBehavior.AutoInvokeKernelFunctions见 SemanticKernelAgent.cs 的默认设置完成的函数调用闭环SkChatCompletionAgentChatMessageContentConnectorTestAsync则展示了同一连接器也可用于SemanticKernelChatCompletionAgent包装 Semantic KernelChatCompletionAgent的 另一种封装通过.RegisterMiddleware(new SemanticKernelChatMessageContentConnector())注册行为一致。需要说明这些测试标注了[ApiKeyFact(...)]属于依赖密钥的集成测试仓库只读环境下你主要参考其断言逻辑即可。六、限制与注意事项函数调用消息暂不支持ToolCallMessage与ToolCallResultMessage无法通过该连接器传递携带函数调用信息的旧式Message也会抛出 Function call is not supported 异常。如果你需要在 Semantic Kernel Agent 上使用 AutoGen 侧的函数调用编排当前应从源码结构看只能依赖 Kernel 原生插件机制ToolCallBehavior.AutoInvokeKernelFunctions而非 AutoGen 的ToolCallMessage通道多模态消息不能来自 Agent 自身对话历史中 Agent 自己产生的MultiModalMessage会直接抛异常回放多轮多模态历史时需注意这一点仅支持单一 choice非流式场景ResultsPerPrompt 1与流式场景ChoiceIndex 0均会抛异常这与 Semantic Kernel 后端配置相关注册返回新实例RegisterMessageConnector()基于 AutoGen 的中间件机制返回新的MiddlewareStreamingAgentSemanticKernelAgent原 Agent 实例的消息行为不变请在后续代码中使用返回的新实例。七、小结当 Semantic Kernel Agent 需要融入 AutoGen 的多 Agent 编排体系时注册SemanticKernelChatMessageContentConnector是打通消息模型的唯一推荐路径一行RegisterMessageConnector()即可让TextMessage、ImageMessage、MultiModalMessage等 AutoGen 内置消息在入站时转为ChatMessageContent、出站时还原为 AutoGen 消息流式场景还原为TextMessageUpdate且同步/流式两条链路同时生效。实现细节可在 SemanticKernelChatMessageContentConnector.cs 中逐方法核对行为验证可参考 SemanticKernelAgentTest.cs完整可运行示例见 SemanticKernelCodeSnippet.cs。【免费下载链接】autogenA programming framework for agentic AI项目地址: https://gitcode.com/GitHub_Trending/au/autogen创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考