
Semantic Kernel 中的 OpenAI Assistants V2 迁移OpenAIAssistantAgent 架构、Run 处理与配置指南【免费下载链接】semantic-kernelIntegrate cutting-edge LLM technology quickly and easily into your apps项目地址: https://gitcode.com/GitHub_Trending/se/semantic-kernel本文基于 Semantic Kernel 官方架构决策记录ADR0049-agents-assistantsV2.md 编写系统讲解 OpenAI 发布Assistants V2API 后Semantic Kernel .NET 端如何通过OpenAIAssistantAgent完成迁移包括 Agent 实现形态、Definition属性重构、Run 轮询处理流程、Vector Store 支持以及 Assistant / Thread / Run 三个层级的配置类设计。读者读完本文后将能够理解 V2 迁移的破坏性变更来源掌握OpenAIAssistantAgent的公开 API 表面与调用链并能结合 OpenAIAssistant 示例 实际落地 file-search、code-interpreter 等功能。背景为什么 Assistants V2 是一次破坏性迁移OpenAI 发布的Assistants V2API 在 V1assistant概念之上演进但与此同时能力模型发生变化部分 V1 功能被废弃例如检索能力从retrieval迁移到file-search后者依赖Vector Store底层 SDK 不兼容支持Assistant V2特性的 .NET API 与当时正在使用的Azure.AI.OpenAI.AssistantsSDK 完全不同且新版OpenAI与Azure.AI.OpenAISDK 在版本上与 V1 互不兼容。因此从 V1 迁移到 Assistants V2 对既有 NuGet 包而言是破坏性变更breaking change而非简单的升级。Semantic Kernel 通过引入全新的 Agent Framework 实现位于 dotnet/src/Agents/OpenAI以OpenAIAssistantAgent为核心完成了对 V2 的适配。在 0049-agents-assistantsV2.md 中Streaming 被列为待处理的 Open Issue计划作为独立特性另行解决而在当前仓库中OpenAIAssistantAgent已提供InvokeStreamingAsync见 OpenAIAssistantAgent.cs通过AssistantThreadActions.InvokeStreamingAsync支持流式输出说明该议题后续已落地。OpenAIAssistantAgentV2 Agent 实现与 V1 的主要差异OpenAIAssistantAgent大致等价于其 V1 形态但有以下关键变化对应 ADR 的 Agent Implementation 章节在 assistant、thread、run 三个层级均支持配置选项每个衔接点都有专属的选项类Agent 定义收敛到Definition属性V1 时代通过FileIds、Metadata等直接属性暴露的 agent 定义现已整体迁移并扩充到Definition属性上提供便捷方法生产 OpenAI 客户端用于对接 OpenAI、Azure OpenAI 或代理proxy服务。从源码看OpenAIAssistantAgent.csOpenAIAssistantAgent的构造函数接收Assistant definition来自 OpenAI SDK 的OpenAI.Assistants.Assistant类型与AssistantClient并将Description、Id、Name、Instructions从定义同步到 Agent 实例还支持传入IPromptTemplateFactory与templateFormat从而把Instructions当作提示词模板渲染实现模板化的系统指令。方法一览ADR 给出了OpenAIAssistantAgent的核心方法职责Method NameDescriptionCreate创建新的 assistant agentListDefinitions列出已存在的 assistant 定义Retrieve获取已存在的 assistantCreateThread创建 assistant 线程DeleteThread删除 assistant 线程AddChatMessage向 assistant 线程添加消息GetThreadMessages获取 assistant 线程中的所有消息Delete删除 assistant agent 的定义使 agent 进入终止状态Invoke调用 assistant agent非 chat 场景GetChannelKeys继承自AgentCreateChannel继承自Agent其中GetChannelKeys与CreateChannel是Agent基类为多代理协作提供的通道能力。在实现中OpenAIAssistantAgent.csGetChannelKeys用通道类型全名 客户端实例的哈希码来区分不同通道确保同类型但不同客户端的 agent 不会被错误共享会话CreateChannelAsync调用AssistantClient.CreateThreadAsync创建底层 assistant 线程并包装成OpenAIAssistantChannel内部持有thread-id。Class Inventory公开类型清单ADR 列出的公开类型与职责如下它们全部位于 dotnet/src/Agents/OpenAI 命名空间Microsoft.SemanticKernel.Agents.OpenAIClass NameDescriptionOpenAIAssistantAgent基于 OpenAI Assistant API 的AgentOpenAIAssistantChannel与OpenAIAssistantAgent关联的AgentChannel绑定一个thread-idOpenAIAssistantDefinitionOpenAI Assistant 的全部元数据 / 定义由于 OpenAI API 模型的构造函数不是 public无法直接使用 API 模型因此单独建模OpenAIAssistantExecutionOptions影响run的选项在 agent / assistant 范围内全局定义OpenAIAssistantInvocationOptions绑定到单次 run 的选项用于直接非 chat调用OpenAIThreadCreationOptions创建线程的选项指定时优先于 assistant 定义OpenAIServiceConfiguration描述服务连接方式用于创建OpenAIClient通道与线程OpenAIAssistantChannel 与 OpenAIAssistantAgentThreadOpenAIAssistantChannelOpenAIAssistantChannel.cs内部持有一个AssistantClient与threadId职责包括ReceiveAsync把消息历史逐条写入线程通过AssistantThreadActions.CreateMessageAsync遇到服务端错误时包装为AgentThreadOperationExceptionInvokeAsync/InvokeStreamingAsync委托AssistantThreadActions.InvokeAsync/InvokeStreamingAsync完成 run 处理GetHistoryAsync读取线程消息ResetAsync删除底层线程Serialize将通道状态序列化为thread-id字符串支撑通道持久化与恢复RestoreChannelAsync依据该 ID 重建通道。线程对象OpenAIAssistantAgentThreadOpenAIAssistantAgentThread.cs封装了 OpenAI 的AssistantThread同时承载可选的VectorStoreId与 metadata是与 agent 交互的会话载体。类清单背后的三个衔接点Assistant / Thread / RunADR 反复强调一个设计思想assistant、thread、run 是三个独立的配置衔接点articulation points。V2 迁移为此引入了一系列专用配置类ClassPurposeOpenAIAssistantDefinitionassistant 的定义。用于创建新 assistant、检查 assistant-agent 实例或查询 assistant 定义OpenAIAssistantExecutionOptions影响 run 执行的选项定义在 assistant 作用域内OpenAIAssistantInvocationOptionsrun 级选项指定时优先于 assistant 定义OpenAIAssistantToolCallBehavior告知对应作用域assistant 或 run的 tool-call 行为OpenAIThreadCreationOptions线程级选项指定时优先于 assistant 定义OpenAIServiceConfiguration告知要连接哪个服务以及如何连接需要说明的是这些类当前均带有[Experimental(SKEXP0110)]特性部分还标注为[Obsolete]源码注释明确指引开发者直接使用 OpenAI SDK 的AssistantClient.CreateAssistantAsync()与RunCreationOptions来创建 assistant 定义与指定调用行为见 OpenAIAssistantDefinition.cs 与 OpenAIAssistantExecutionOptions.cs。因此本文既保留 ADR 的原始类型清单供理解演进脉络也如实说明当前代码库中的推荐用法。Assistant Definition从列表专用到创建/查询通用OpenAIAssistantDefinition最初只用于枚举已存储的 agent 列表V2 迁移后它同时被用作创建 agent 的输入OpenAIAssistantAgent实例上的独立属性。其能力继承自OpenAIAssistantCapabilities见 OpenAIAssistantCapabilities.cs包括属性说明ModelIdagent 定向的 AI 模型Idassistant 的唯一 ID创建时忽略EnableCodeInterpreter是否启用 code-interpreter 工具CodeInterpreterFileIds启用 code-interpreter 时可用的文件 IDEnableFileSearch是否启用 file-search 工具VectorStoreIdVector Store ID指定时要求启用 file-searchEnableJsonResponse是否启用 JSON 响应格式Temperature采样温度取值 0~2TopP核采样nucleus sampling概率质量建议与Temperature二选一Metadata最多 16 组键值对键 ≤64 字符值 ≤512 字符ExecutionOptions每次调用的默认执行选项见下ExecutionOptions承载的是OpenAIAssistantExecutionOptionsOpenAIAssistantExecutionOptions.cs可配置项包括AdditionalInstructions附加指令MaxCompletionTokens/MaxPromptTokensrun 全程可用的最大补全 / 提示 token 数ParallelToolCallsEnabled工具调用期间是否启用并行函数调用默认trueTruncationMessageCount线程截断后保留的最近消息条数。一个关键设计细节由于这些执行选项并不属于远程 assistant 定义的一部分为了在检索已有 agent时能还原行为它们会被持久化到 assistant 的 metadata 中。源码印证了这一约定OpenAIAssistantExecutionOptions.cs 的注释明确写道这些选项以键__run_options的单一条目持久化在 assistant 的 metadata 中同时 OpenAIAssistantAgent.cs 定义了OptionsMetadataKey __run_options与TemplateMetadataKey __template_format两个内部常量。OpenAIAssistantToolCallBehavior作为执行选项的一部分其建模与 AI Connectors 侧的ToolCallBehavior保持一致。ADR 特别注明OpenAIAssistantAgent与AgentChat目前不支持手动函数调用计划作为增强项待该能力引入后OpenAIAssistantToolCallBehavior将决定函数调用行为。关于tool_choice的决策ADR 记录了一个待定变更——计划把FunctionChoiceBehavior引入基类 / 抽象类PromptExecutionSettings届时可能让OpenAIAssistantExecutionOptions与OpenAIAssistantInvocationOptions继承PromptExecutionSettings以复用该模式。但在该能力落地之前官方DECISION 是暂不支持tool_choice。Assistant Invocation Options单次 run 级选项当直接非 chat调用OpenAIAssistantAgent时可以指定仅作用于单次 run 的定义即OpenAIAssistantInvocationOptionsOpenAIAssistantInvocationOptions.cs。它优先于任何对应的 assistant 或 thread 定义。可配置项在 Definition 级别能力的基础上进一步扩展ModelName本次 run 定向的模型AdditionalInstructions/AdditionalMessages附加指令与附加消息AdditionalMessages仅支持 role 为 User 或 Assistant 的消息EnableCodeInterpreter/EnableFileSearch/EnableJsonResponse按 run 开关工具MaxCompletionTokens/MaxPromptTokens/ParallelToolCallsEnabled/TruncationMessageCountTemperature/TopP采样参数Metadata附加元数据。ADR 提示这些选项同样受ToolCallBehavior/FunctionChoiceBehavior待定问题的影响。Thread Creation Options显式管理线程直接非 chat调用时线程必须被显式管理此时可传入OpenAIThreadCreationOptionsOpenAIThreadCreationOptions.cs且优先于 assistant 定义。其可配置项包括CodeInterpreterFileIds供 code-interpreter 使用的文件 IDVectorStoreId启用 file-search 的 Vector Store IDMessages初始化线程时的可选消息同样仅支持 User / Assistant 角色Metadata元数据键值对。Service Configuration统一服务连接OpenAIServiceConfiguration定义了如何连接远程服务OpenAI、Azure 或代理从而免去在每个调用点编写多个连接重载即创建 client的重复代码。ADR 特别注明该类此前命名为OpenAIAssistantConfiguration但因其并非 assistant 专属故更名。在当前仓库中与之一脉相承的底层设施是 OpenAIClientProvider.cs提供ForOpenAI、ForAzureOpenAI、FromClient等工厂方法用于基于 API Key、AzureTokenCredential或现成OpenAIClient生产客户端OpenAIAssistantAgent自身也通过部分类OpenAIAssistantAgent.ClientFactory.cs提供CreateOpenAIClient/CreateAzureOpenAIClient便捷工厂支持传入自定义HttpClient与 endpoint甚至为自定义 endpoint 且不带 API Key的场景准备了规避异常的处理。Run 处理支撑 assistant 的核心循环Run 是什么支持 assistant agent 的核心是创建并处理一次Run。Run本质上是某个Thread会话上一次离散的 assistant 交互。ADR 引用了 OpenAI 官方的 runs 与 run-steps API 文档作为参照。处理流程伪代码还原ADR 给出如下处理骨架输入包括agentOpenAIAssistantAgent、clientAssistantClient、threadidstring、optionsOpenAIAssistantInvocationOptions可选校验agent未被删除定义RunCreationOptions基于threadid与agent.Id创建run处理 rundo - 轮询 run 状态直到不再处于 queued / in-progress / cancelling - 若 run 状态为 expired / failed / cancelled则抛出异常 - 查询 run 的 steps - 若 run 状态为 requires-action - 处理函数型 steps - 提交函数执行结果 - foreach (step 已完成): - 若 step 是 tool-call生成并产出 tool 内容 - 否则若 step 是 message生成并产出消息内容 while (run 状态 ! completed)源码级印证上述流程在 Internal/AssistantThreadActions.cs 中有完整实现可逐条对应轮询状态集合s_pollingStatuses精确包含Queued、InProgress、Cancelling三个状态对应 ADR 中轮询直到非 queued/in-progress/cancelling终止态检查run.Status.IsTerminal run.Status ! RunStatus.Completed时抛出KernelException错误消息携带 run 状态、ID 与run.LastError信息对应expired/failed/cancelled 抛出工具合并调用前会把 Kernel 插件中的函数转换为FunctionToolDefinition并与 assistant 自带工具去重合并tools.AddRange(functionTools)随后client.CreateRunAsync(threadId, agent.Id, options, ...)创建 runrequires-action 处理当run.Status RunStatus.RequiresAction时解析函数型 step、并行执行 Kernel 函数FunctionCallsProcessor.InvokeFunctionCallsAsync当前配置AllowConcurrentInvocation true, AllowParallelCalls true再通过SubmitToolOutputsToRunAsync一次性回传工具输出completed step 产出遍历已完成 step——RunStepKind.ToolCall细分为 code-interpreter 内容可见与 function 结果内容RunStepKind.CreatedMessage则按CreatedMessageId拉取消息并产出可见循环出口while (RunStatus.Completed ! run.Status)与 ADR 的伪代码完全一致。轮询参数RunPollingOptions轮询行为的可调参数由 RunPollingOptions.cs 提供OpenAIAssistantAgent.PollingOptions属性默认持有其默认值参数默认值说明MaximumRetryCount3轮询 run 状态的最大重试次数仅影响可能瞬时失败的场景显式服务端错误会立即失败RunPollingInterval500ms监控 run 状态的轮询间隔RunPollingBackoff1s超过阈值后的退避间隔RunPollingBackoffThreshold2达到该轮询次数后切换为退避间隔MessageSynchronizationDelay500ms因同步延迟导致消息检索 404/NotFound 时的重试延迟其中GetPollingInterval(iterationCount)在轮询次数超过阈值后返回退避间隔避免高频空转。Vector Store 支持file-search 的底座启用file-search工具必须依赖Vector Store。ADR 指出与 V2 的FileClient流式能力对齐调用方也可以直接使用 OpenAI SDK 中的VectorStoreClient来管理 Vector Store。仓库中的 Step05_AssistantTool_FileSearch.cs 给出了完整落地流程创建 assistant 时启用 file-searchCreateAssistantAsync(model, enableFileSearch: true, ...)上传文件UploadAssistantFileAsync(stream, employees.pdf)得到fileId创建 Vector StoreCreateVectorStoreAsync([fileId], ...)得到vectorStoreId创建线程时绑定 Vector Storenew OpenAIAssistantAgentThread(assistantClient, vectorStoreId: vectorStoreId, ...)通过agent.InvokeAsync(message, thread)发起对话agent 即可基于文件内容回答示例中围绕虚构员工表回答最年轻的员工是谁等问题清理阶段依次删除线程、assistant、Vector Store 与文件。该示例同时验证了OpenAIThreadCreationOptions中VectorStoreId的用途——Vector Store 在线程级关联到会话。从示例看完整用法最小对话示例Step01模板化指令Step01_Assistant.cs 展示了模板化指令 参数化调用的完整链路// 1. 用 YAML 模板生成 assistant 定义 PromptTemplateConfig templateConfig KernelFunctionYaml.ToPromptTemplateConfig(GenerateStoryYaml); Assistant definition await this.AssistantClient.CreateAssistantFromTemplateAsync(this.Model, templateConfig, metadata: SampleMetadata); // 2. 构造 agent携带模板工厂Instructions 可被渲染 OpenAIAssistantAgent agent new( definition, this.AssistantClient, templateFactory: new KernelPromptTemplateFactory(), templateFormat: PromptTemplateConfig.SemanticKernelTemplateFormat) { Arguments new() { { topic, Dog }, { length, 3 } } }; // 3. 创建线程并发起调用可覆盖参数 AgentThread thread new OpenAIAssistantAgentThread(this.AssistantClient, metadata: SampleMetadata); await foreach (ChatMessageContent response in agent.InvokeAsync(thread, options: new() { KernelArguments arguments })) { WriteAgentChatMessage(response); }注意其中的OpenAIAssistantAgentThread携带 metadata 参数——这正是 ADR 所说执行选项持久化在 metadata的实践位置也是检索已有 agent 时还原行为的关键。工具开关示例Step04code-interpreterStep04_AssistantTool_CodeInterpreter.cs 演示了启用 code-interpreter 的最小路径Assistant assistant await this.AssistantClient.CreateAssistantAsync(this.Model, enableCodeInterpreter: true, metadata: SampleMetadata); OpenAIAssistantAgent agent new(assistant, this.AssistantClient); AgentThread thread new OpenAIAssistantAgentThread(this.AssistantClient, metadata: SampleMetadata); await agent.InvokeAsync(new ChatMessageContent(AuthorRole.User, Use code to determine the values in the Fibonacci sequence that are less than 101?), thread);当 run 进入RequiresAction且 step 为 code-interpreter 工具调用时内部逻辑会生成 code-interpreter 内容并作为可见消息产出对应源码中GenerateCodeInterpreterContent的isVisible true分支。多代理协作OpenAIAssistantAgent作为Agent的子类天然接入AgentChat/AgentGroupChat多代理编排其通道基于 thread-id 隔离会话GetChannelKeys按通道类型 客户端实例区分会话归属。相关编排能力可参考 Agents 相关文档与示例 及仓库中的 0032-agents.md 决策记录。迁移注意事项与边界综合 ADR 与当前源码进行 Assistants V2 迁移或集成时需重点确认以下几点破坏性变更不可避免底层能力差异如file-searchvsretrieval与 SDK 版本不兼容决定了无法原地升级需要迁移到Microsoft.SemanticKernel.Agents.OpenAI的新 API 面Definition是唯一入口创建、查询、检索 assistant 都围绕OpenAIAssistantDefinition/ OpenAI SDK 的Assistant展开旧的FileIds、Metadata直出属性不复存在三个衔接点的优先级run 级选项 thread 级选项 assistant 级默认invocation/thread 选项指定时优先于 assistant 定义执行选项的持久化ExecutionOptions以__run_options键写入 assistant metadata检索已有 agent 时据此恢复默认 run 行为tool_choice 暂不支持在FunctionChoiceBehavior落地前OpenAIAssistantToolCallBehavior只作为预留设计手动函数调用能力同样待增强实验性 API相关类型带[Experimental(SKEXP0110)]标记使用前需在项目中抑制对应诊断且 API 有变更或移除的可能源码注释同时指出创建 assistant 定义与线程的推荐路径已迁移到 OpenAI SDK 原生 APICreateAssistantAsync/CreateThreadAsync配置 run 行为推荐使用RunCreationOptions。总结0049-agents-assistantsV2.md这份 ADR 记录了 Semantic Kernel Agent Framework 从 Assistants V1 向 V2 迁移的关键架构决策以OpenAIAssistantAgent为统一入口将 agent 定义收敛到Definition属性在 assistant / thread / run 三个衔接点分别提供执行选项、调用选项与线程创建选项并以创建 run → 轮询状态 → 处理 requires-action → 产出消息的循环作为核心运行机制同时引入 Vector Store 支撑 file-search。结合 OpenAIAssistant 示例目录 与 Agents/OpenAI 源码开发者可以快速将这些设计落地为实际的智能体应用。【免费下载链接】semantic-kernelIntegrate cutting-edge LLM technology quickly and easily into your apps项目地址: https://gitcode.com/GitHub_Trending/se/semantic-kernel创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考