Semantic Kernel Agents 语法实战指南:从 OpenAI Assistant 到多 Agent 混合编排
2026/9/12 8:14:15 网站建设 项目流程

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系列包的安装引入、示例分类、测试运行方式与密钥配置流程,并结合仓库源码深入剖析OpenAIAssistantAgentChatCompletionAgentAgentGroupChat等核心类型的使用语法与底层机制。读完本文,你将能够独立配置环境、运行并改造 Agent 示例,掌握流式调用、函数调用、群聊编排、序列化恢复等实战技能。

一、Agent 语法示例集概览

dotnet/samples/Concepts/Agents/README.md 对应的示例项目位于dotnet/samples/Concepts/Agents/目录,是 Semantic Kernel .NET 体系中"概念示例(Concepts)"的一部分。与 GettingStarted 系列强调循序渐进不同,这里的示例按语法主题组织,覆盖了 Agent 框架的各类高级用法。

从仓库目录可以看到 26 个 C# 示例文件,其核心命名空间包括:

  • Microsoft.SemanticKernel.Agents(Agent 基类、线程、群聊)
  • Microsoft.SemanticKernel.Agents.OpenAI(OpenAI Assistant 支持)
  • Microsoft.SemanticKernel.Agents.AzureAI(Azure AI Agent 支持)
  • Microsoft.SemanticKernel.Agents.ChatAgentGroupChat群聊编排)
  • Microsoft.SemanticKernel.ChatCompletion(聊天消息模型)

1.1 所需 NuGet 包

示例依赖以下三个 NuGet 包:

包名用途
Microsoft.SemanticKernel.Agents.AbstractionsAgent 抽象层:AgentAgentThreadAgentChat等接口与基类
Microsoft.SemanticKernel.Agents.CoreAgent 核心实现:ChatCompletionAgentAggregatorAgentAgentGroupChatTerminationStrategy
Microsoft.SemanticKernel.Agents.OpenAIOpenAI Assistant API 支持:OpenAIAssistantAgentOpenAIAssistantAgentThread

此外,如果使用 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.csOpenAIAssistant_ChartMaker.csOpenAIAssistant_Streaming.csOpenAIAssistant_FunctionFilters.csOpenAIAssistant_Templating.cs
MixedChat如何组合不同类型的 AgentMixedChat_Agents.csMixedChat_Files.csMixedChat_Images.csMixedChat_Reset.csMixedChat_Serialization.csMixedChat_Streaming.cs
ComplexChat如何开发复杂的 Agent 群聊解决方案ComplexChat_NestedShopper.cs
Legacy如何使用旧的 Experimental Agent APIMicrosoft.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 优先级规则与强制 OpenAI

README 特别标注了一个容易踩坑的细节:

NOTE: 如果同时定义了 OpenAI 和 Azure OpenAI 的机密,Azure 机密将优先(take precedence),除非设置了ForceOpenAI

protected 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.CreateFromType<MenuPlugin>(); 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 Task<bool> ShouldAgentTerminateAsync(Agent agent, IReadOnlyList<ChatMessageContent> 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(函数式终止策略)的组合:

  • 内部群聊:由InternalLeaderInternalGiftIdeasInternalGiftReviewer三个ChatCompletionAgent组成,通过提示词模板驱动KernelFunctionSelectionStrategy决定下一轮由谁发言(模板通过KernelFunctionSelectionStrategy.DefaultHistoryVariableName注入对话历史变量);
  • 外部聚合AggregatorAgentAggregatorMode.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.Translate<OuterTerminationResult>(result.GetValue<string>())?.isAnswered ?? false, MaximumIterations = 5, } } };

ResultParser将 LLM 返回的 JSON 解析为结构化结果(OuterTerminationResult(bool isAnswered, string reason)),展示了用提示词函数驱动编排逻辑的高级模式。

七、Azure AI Agent:同一套语法的云原生变体

仓库中还有 AzureAIAgent_Streaming.cs,它与 OpenAI 版本保持几乎一致的语法结构:通过Azure.AI.Agents.PersistentPersistentAgent定义 +AzureAIAgent包装,线程使用AzureAIAgentThread。差异点在于:

  • Agent 定义通过this.Client.Administration.CreateAgentAsync(model, name, null, instructions, tools)创建;
  • 插件直接加入agent.Kernel.Plugins
  • 清理资源时需显式删除线程(Threads.DeleteThreadAsync)与 Agent(Administration.DeleteAgentAsync)。

从源码结构看,OpenAIAssistantAgentAzureAIAgent均实现统一的Agent抽象(参见 dotnet/src/Agents/Abstractions),因此可以无缝混入同一个AgentGroupChat,这正是"OpenAIAssistant / MixedChat / ComplexChat"分组想要传达的核心:语法统一、类型可混编

八、快速上手指南

8.1 最小可运行步骤

  1. 创建一个 .NET 控制台/测试项目,引入Microsoft.SemanticKernel.Agents.CoreMicrosoft.SemanticKernel.Agents.OpenAI
  2. 按第四节配置OpenAI:ApiKeyOpenAI:ChatModelId机密(或 Azure 四件套);
  3. 从任一示例复制代码(如OpenAIAssistant_Streaming的 Parrot 场景),将this.AssistantClient/this.Model替换为显式构建的AssistantClient与模型 ID;
  4. 直接运行或dotnet test --filter <前缀>执行。

8.2 排错提示

  • 同时配置了两套密钥但行为异常:Azure 优先,检查是否需要protected override bool ForceOpenAI => true;
  • 函数不被调用:确认插件已通过构造器参数[plugin]agent.Kernel.Plugins.Add(plugin)注入;
  • 群聊不结束或轮数失控:检查TerminationStrategy.AgentsMaximumIterations配置;
  • Code Interpreter 无输出文件:确认enableCodeInterpreter: true且正确使用DownloadResponseContentAsync/DownloadResponseImageAsync下载产物。

九、总结

Semantic Kernel 的 Agents 语法示例集以"前缀分组 + 测试即示例"的方式,完整覆盖了从单个OpenAIAssistantAgent基础调用、插件与 Code Interpreter 增强、流式与过滤器进阶,到AgentGroupChat异构混编、序列化恢复、嵌套聚合编排的完整能力图谱。配合 README 给出的 NuGet 依赖、运行方式与密钥配置规范,开发者可以快速将这套语法迁移到自己的应用:统一的Agent抽象让 OpenAI、Azure AI 与本地 Kernel 驱动的 Agent 能够在同一群聊中协作,而TerminationStrategySelectionStrategyAgentChatSerializer则为构建可靠、可恢复的多 Agent 应用提供了原生支撑。

【免费下载链接】semantic-kernelIntegrate cutting-edge LLM technology quickly and easily into your apps项目地址: https://gitcode.com/GitHub_Trending/se/semantic-kernel

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询