Semantic Kernel Agents 语法实战指南:从 OpenAI Assistant 到多 Agent 混合编排 📅 发布时间:2026/9/12 8:14:19 👁 浏览次数: Semantic Kernel Agents 语法实战指南从 OpenAI Assistant 到多 Agent 混合编排【免费下载链接】semantic-kernelIntegrate cutting-edge LLM technology quickly and easily into your apps项目地址: https://gitcode.com/GitHub_Trending/se/semantic-kernel本篇技术指南以 .NET 版 Semantic Kernel 仓库中的 Agents 概念示例集为核心系统讲解Microsoft.SemanticKernel.Agents系列包的安装引入、示例分类、测试运行方式与密钥配置流程并结合仓库源码深入剖析OpenAIAssistantAgent、ChatCompletionAgent、AgentGroupChat等核心类型的使用语法与底层机制。读完本文你将能够独立配置环境、运行并改造 Agent 示例掌握流式调用、函数调用、群聊编排、序列化恢复等实战技能。一、Agent 语法示例集概览dotnet/samples/Concepts/Agents/README.md 对应的示例项目位于dotnet/samples/Concepts/Agents/目录是 Semantic Kernel .NET 体系中概念示例Concepts的一部分。与 GettingStarted 系列强调循序渐进不同这里的示例按语法主题组织覆盖了 Agent 框架的各类高级用法。从仓库目录可以看到 26 个 C# 示例文件其核心命名空间包括Microsoft.SemanticKernel.AgentsAgent 基类、线程、群聊Microsoft.SemanticKernel.Agents.OpenAIOpenAI Assistant 支持Microsoft.SemanticKernel.Agents.AzureAIAzure AI Agent 支持Microsoft.SemanticKernel.Agents.ChatAgentGroupChat群聊编排Microsoft.SemanticKernel.ChatCompletion聊天消息模型1.1 所需 NuGet 包示例依赖以下三个 NuGet 包包名用途Microsoft.SemanticKernel.Agents.AbstractionsAgent 抽象层Agent、AgentThread、AgentChat等接口与基类Microsoft.SemanticKernel.Agents.CoreAgent 核心实现ChatCompletionAgent、AggregatorAgent、AgentGroupChat、TerminationStrategy等Microsoft.SemanticKernel.Agents.OpenAIOpenAI Assistant API 支持OpenAIAssistantAgent、OpenAIAssistantAgentThread此外如果使用 Azure AI Foundry Agent还需引入Microsoft.SemanticKernel.Agents.AzureAI对应源码目录 dotnet/src/Agents/AzureAI。1.2 示例的两种运行形态README 特别强调这些示例既可以作为集成测试integration tests运行其代码也可以复制到独立程序中直接使用。这正是 Concepts 示例的标准组织方式——每个示例类继承自测试基类如BaseAssistantTest用[Fact]或[Theory]标记测试方法同时方法体内的代码又是完整的、可移植的 Agent 使用范例。二、示例分组按前缀组织的语法地图README 给出了清晰的示例分组规则示例文件按前缀组织便于按主题检索前缀说明仓库中的代表文件OpenAIAssistant基于 OpenAI Assistant API 的 Agent 用法OpenAIAssistant_FileManipulation.cs、OpenAIAssistant_ChartMaker.cs、OpenAIAssistant_Streaming.cs、OpenAIAssistant_FunctionFilters.cs、OpenAIAssistant_Templating.csMixedChat如何组合不同类型的 AgentMixedChat_Agents.cs、MixedChat_Files.cs、MixedChat_Images.cs、MixedChat_Reset.cs、MixedChat_Serialization.cs、MixedChat_Streaming.csComplexChat如何开发复杂的 Agent 群聊解决方案ComplexChat_NestedShopper.csLegacy如何使用旧的 Experimental Agent API由Microsoft.SemanticKernel.Experimental.Agents包提供2.1 Legacy Agent API 的演进说明README 明确指出一个重要的历史背景OpenAI Assistant API 的支持最初发布在Microsoft.SemanticKernel.Experimental.Agents包中但该包已被正式的 Semantic Kernel Agents 取代后者现已原生包含 OpenAI Assistant Agent 支持。因此新项目应直接使用Microsoft.SemanticKernel.Agents.*系列包而不是 Experimental 版本。这也是为什么示例集中没有任何Legacy前缀文件——旧 API 已被移除或不再推荐使用。三、运行示例Visual Studio 与命令行两种方式3.1 在 Visual Studio 中通过测试资源管理器运行由于示例以 xUnit 测试形式编写可以直接在 Visual Studio 的 Test Explorer测试资源管理器中发现并运行它们。每个[Fact]/[Theory]方法对应一个可独立运行的 Agent 场景。3.2 命令行筛选运行也可以使用dotnet test --filter按名称筛选运行指定示例例如dotnet test --filter OpenAIAssistant_CodeInterpreter更多筛选语法可查看dotnet test --help的输出。--filter支持通配符、逻辑运算等例如dotnet test --filter FullyQualifiedName~OpenAIAssistant可以运行所有 OpenAI Assistant 相关示例。四、配置密钥OpenAI 与 Azure OpenAI 双通道每个示例都需要访问 OpenAI 或 Azure OpenAI 的凭据。README 推荐使用.NET Secret Manager用户机密来避免密钥泄漏到仓库、分支和 Pull Request 中也可以使用环境变量。4.1 完整配置步骤第 1 步将控制台导航到示例项目目录cd dotnet/samples/GettingStartedWithAgents注意README 中给出的示例路径为dotnet/samples/GettingStartedWithAgents该目录下的示例同样使用这套密钥体系。Concepts/Agents 示例的密钥读取逻辑BaseAssistantTest与之一致若直接运行 Concepts 项目请以实际项目目录为准。第 2 步查看已有的机密定义dotnet user-secrets list第 3 步如需首次初始化dotnet user-secrets init第 4 步为 OpenAI 配置机密dotnet user-secrets set OpenAI:ChatModelId ... dotnet user-secrets set OpenAI:ApiKey ...第 5 步或为 Azure OpenAI 配置机密dotnet user-secrets set AzureOpenAI:DeploymentName ... dotnet user-secrets set AzureOpenAI:ChatDeploymentName ... dotnet user-secrets set AzureOpenAI:Endpoint https://... .openai.azure.com/ dotnet user-secrets set AzureOpenAI:ApiKey ...4.2 优先级规则与强制 OpenAIREADME 特别标注了一个容易踩坑的细节NOTE: 如果同时定义了 OpenAI 和 Azure OpenAI 的机密Azure 机密将优先take precedence除非设置了ForceOpenAIprotected override bool ForceOpenAI true;也就是说测试基类默认优先使用 Azure OpenAI 配置如果你希望强制走 OpenAI只需在测试类中重写ForceOpenAI属性返回true。从仓库的测试基类BaseAssistantTest/BaseAgentsTest位于 dotnet/samples/Concepts 共享代码中可以推断密钥的读取、模型的选择均通过这一开关统一控制。五、源码级深入OpenAIAssistant 系列示例解析下面结合仓库源码逐一剖析 README 提到的前缀分组背后的典型实现。5.1 基础调用链创建 Assistant → 包装 Agent → 流式/非流式调用以 OpenAIAssistant_Streaming.cs 为例其调用链清晰地展示了OpenAIAssistantAgent的标准用法// 1. 在 OpenAI 侧定义 Assistant设置名称、指令、可选工具 Assistant assistant await this.AssistantClient.CreateAssistantAsync( this.Model, name: Parrot, instructions: Repeat the user message in the voice of a pirate and then end with a parrot sound., metadata: SampleMetadata); // 2. 将 Assistant 包装为 Semantic Kernel Agent OpenAIAssistantAgent agent new(assistant, this.AssistantClient); // 3. 创建线程承载对话 OpenAIAssistantAgentThread agentThread new(this.AssistantClient, metadata: SampleMetadata); // 4. 流式调用 await foreach (StreamingChatMessageContent response in agent.InvokeStreamingAsync(message, agentThread)) { // 处理流式内容 }该示例还演示了流式响应中函数调用与内容消息的区分当response.Content为空时从response.Items中查找StreamingFunctionCallUpdateContent来识别函数调用同时借助OpenAIAssistantAgent.CodeInterpreterMetadataKey元数据区分 Assistant 消息与 Code Interpreter 工具消息。5.2 插件Plugin注入让 Agent 具备工具能力同一文件中的第二个测试展示了如何为OpenAIAssistantAgent附加插件KernelPlugin plugin KernelPluginFactory.CreateFromTypeMenuPlugin(); OpenAIAssistantAgent agent new(assistant, this.AssistantClient, [plugin]);MenuPlugin是一个用[KernelFunction]标注的普通 C# 类[KernelFunction, Description(Provides a list of specials from the menu.)] public string GetSpecials() { ... } [KernelFunction, Description(Provides the price of the requested menu item.)] public string GetItemPrice([Description(The name of the menu item.)] string menuItem) { ... }由此可以看出Agent 与普通 Kernel 使用同一套插件体系KernelPluginFactory.CreateFromType可以将任意 POCO 类转换为可被 LLM 调用的工具集。5.3 Code Interpreter让 Agent 写代码、做计算、生成图表OpenAIAssistant_ChartMaker.cs 演示了如何开启 Code Interpreter 能力Assistant assistant await this.AssistantClient.CreateAssistantAsync( this.Model, ChartMaker, instructions: Create charts as requested without explanation., enableCodeInterpreter: true, metadata: SampleMetadata);调用时Agent 会生成图表图片示例通过DownloadResponseImageAsync(response)下载并展示图片内容。OpenAIAssistant_FileManipulation.cs 则进一步演示了文件操作先上传sales.csv获得fileId再通过codeInterpreterFileIds参数把文件交给 Assistant随后 Agent 可以执行哪个细分市场销量最高列出利润 Top 5 国家生成按月利润的制表符分隔报告等数据分析任务。5.4 函数过滤器在 Agent 层拦截函数调用OpenAIAssistant_FunctionFilters.cs 演示了 Agent 场景下的两类过滤器IFunctionInvocationFilter函数执行前后拦截示例中通过将context.Result覆盖为BLOCKED来屏蔽 MenuPlugin 的调用结果IAutoFunctionInvocationFilter自动函数调用过滤器可设置context.Terminate来控制是否在调用指定插件后终止 Agent 循环。关键点在于过滤器通过 DI 注册进 Kernel然后作为Kernel属性传给OpenAIAssistantAgent即可在 Agent 的函数调用流程中生效——这说明Agent 的过滤机制与普通 Kernel 过滤机制完全打通。六、源码级深入MixedChat 与 ComplexChat 多 Agent 编排6.1 MixedChat_Agents异构 Agent 同群聊MixedChat_Agents.cs 演示了两种不同类型 Agent 参与同一对话ChatCompletionAgent本地 Kernel 驱动的评审者 ArtDirector与OpenAIAssistantAgent云端 Assistant 驱动的文案 CopyWriter。// 定义 ChatCompletionAgent ChatCompletionAgent agentReviewer new() { Instructions ReviewerInstructions, Name ReviewerName, Kernel this.CreateKernelWithChatCompletion(...), }; // 定义 OpenAIAssistantAgent Assistant assistant await this.AssistantClient.CreateAssistantAsync(this.Model, name: CopyWriterName, instructions: CopyWriterInstructions); OpenAIAssistantAgent agentWriter new(assistant, this.AssistantClient); // 组合成群聊 AgentGroupChat chat new(agentWriter, agentReviewer) { ExecutionSettings new() { TerminationStrategy new ApprovalTerminationStrategy() { Agents [agentReviewer], // 只有 art-director 可以批准 MaximumIterations 10, // 限制总轮数 } } }; chat.AddChatMessage(new(AuthorRole.User, concept: maps made out of egg cartons.)); await foreach (ChatMessageContent response in chat.InvokeAsync()) { // 输出各 Agent 响应 }其中ApprovalTerminationStrategy继承自TerminationStrategy通过重写ShouldAgentTerminateAsync实现自定义终止逻辑protected override Taskbool ShouldAgentTerminateAsync(Agent agent, IReadOnlyListChatMessageContent history, CancellationToken ct) Task.FromResult(history[^1].Content?.Contains(approve, StringComparison.OrdinalIgnoreCase) ?? false);该示例展示的核心语法要点AgentGroupChat构造器接受任意数量的 Agent不要求类型一致TerminationStrategy.Agents限定只有特定 Agent 的输出才能触发终止MaximumIterations作为安全上限防止死循环chat.IsComplete用于判断群聊是否已结束。6.2 MixedChat_Serialization群聊状态序列化与恢复MixedChat_Serialization.cs 演示了AgentChatSerializer的用法——将AgentGroupChat完整序列化到流再反序列化到新实例继续对话await using MemoryStream stream new(); await AgentChatSerializer.SerializeAsync(source, stream); stream.Position 0; AgentChatSerializer serializer await AgentChatSerializer.DeserializeAsync(stream); await serializer.DeserializeAsync(clone);序列化内容包含参与 Agent、消息历史、执行状态如计数型终止策略的进度因此反序列化后可以无缝继续之前的对话。这对于多轮对话持久化、进程重启恢复、分布式状态传递等场景非常关键。6.3 ComplexChat_NestedShopper嵌套聚合编排ComplexChat_NestedShopper.cs 是仓库中编排最复杂的示例演示了AggregatorAgent聚合器KernelFunctionSelectionStrategy函数式选择策略KernelFunctionTerminationStrategy函数式终止策略的组合内部群聊由InternalLeader、InternalGiftIdeas、InternalGiftReviewer三个ChatCompletionAgent组成通过提示词模板驱动KernelFunctionSelectionStrategy决定下一轮由谁发言模板通过KernelFunctionSelectionStrategy.DefaultHistoryVariableName注入对话历史变量外部聚合AggregatorAgent以AggregatorMode.Nested模式运行将内部多 Agent 协作的结论聚合后呈现给用户双层终止外层用KernelFunctionTerminationStrategy判断用户请求是否已被完整回答解析 JSON 中的isAnswered字段内层用自定义AgentTerminationStrategy限制内部轮次并支持AutomaticReset。AggregatorAgent personalShopperAgent new(CreateChat) { Name PersonalShopper, Mode AggregatorMode.Nested, }; AgentGroupChat chat new(personalShopperAgent) { ExecutionSettings new() { TerminationStrategy new KernelFunctionTerminationStrategy(outerTerminationFunction, kernel) { ResultParser (result) JsonResultTranslator.TranslateOuterTerminationResult(result.GetValuestring())?.isAnswered ?? false, MaximumIterations 5, } } };ResultParser将 LLM 返回的 JSON 解析为结构化结果OuterTerminationResult(bool isAnswered, string reason)展示了用提示词函数驱动编排逻辑的高级模式。七、Azure AI Agent同一套语法的云原生变体仓库中还有 AzureAIAgent_Streaming.cs它与 OpenAI 版本保持几乎一致的语法结构通过Azure.AI.Agents.Persistent的PersistentAgent定义 AzureAIAgent包装线程使用AzureAIAgentThread。差异点在于Agent 定义通过this.Client.Administration.CreateAgentAsync(model, name, null, instructions, tools)创建插件直接加入agent.Kernel.Plugins清理资源时需显式删除线程Threads.DeleteThreadAsync与 AgentAdministration.DeleteAgentAsync。从源码结构看OpenAIAssistantAgent与AzureAIAgent均实现统一的Agent抽象参见 dotnet/src/Agents/Abstractions因此可以无缝混入同一个AgentGroupChat这正是OpenAIAssistant / MixedChat / ComplexChat分组想要传达的核心语法统一、类型可混编。八、快速上手指南8.1 最小可运行步骤创建一个 .NET 控制台/测试项目引入Microsoft.SemanticKernel.Agents.Core与Microsoft.SemanticKernel.Agents.OpenAI按第四节配置OpenAI:ApiKey与OpenAI:ChatModelId机密或 Azure 四件套从任一示例复制代码如OpenAIAssistant_Streaming的 Parrot 场景将this.AssistantClient/this.Model替换为显式构建的AssistantClient与模型 ID直接运行或dotnet test --filter 前缀执行。8.2 排错提示同时配置了两套密钥但行为异常Azure 优先检查是否需要protected override bool ForceOpenAI true;函数不被调用确认插件已通过构造器参数[plugin]或agent.Kernel.Plugins.Add(plugin)注入群聊不结束或轮数失控检查TerminationStrategy.Agents与MaximumIterations配置Code Interpreter 无输出文件确认enableCodeInterpreter: true且正确使用DownloadResponseContentAsync/DownloadResponseImageAsync下载产物。九、总结Semantic Kernel 的 Agents 语法示例集以前缀分组 测试即示例的方式完整覆盖了从单个OpenAIAssistantAgent基础调用、插件与 Code Interpreter 增强、流式与过滤器进阶到AgentGroupChat异构混编、序列化恢复、嵌套聚合编排的完整能力图谱。配合 README 给出的 NuGet 依赖、运行方式与密钥配置规范开发者可以快速将这套语法迁移到自己的应用统一的Agent抽象让 OpenAI、Azure AI 与本地 Kernel 驱动的 Agent 能够在同一群聊中协作而TerminationStrategy、SelectionStrategy与AgentChatSerializer则为构建可靠、可恢复的多 Agent 应用提供了原生支撑。【免费下载链接】semantic-kernelIntegrate cutting-edge LLM technology quickly and easily into your apps项目地址: https://gitcode.com/GitHub_Trending/se/semantic-kernel创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考