资讯详情

Semantic Kernel 中的 OpenAI Function Calling 支持:从 ADR 决策到源码实现的完整指南

📅 2026/9/11 1:31:08 | 华诺云谱 👁 阅读
Semantic Kernel 中的 OpenAI Function Calling 支持:从 ADR 决策到源码实现的完整指南
Semantic Kernel 中的 OpenAI Function Calling 支持从 ADR 决策到源码实现的完整指南【免费下载链接】semantic-kernelIntegrate cutting-edge LLM technology quickly and easily into your apps项目地址: https://gitcode.com/GitHub_Trending/se/semantic-kernel导读本篇文章围绕 docs/decisions/0017-openai-function-calling.md 这份架构决策记录ADR深入剖析 Semantic Kernel 项目如何支持 OpenAI Chat Completions API 的 Function Calling 能力。你将理解该能力的 API 背景、当时的三大候选方案与最终决策理由以及这一决策在当前仓库代码中的具体落地形态——包括请求设置对象、FunctionChoiceBehavior与ToolCallBehavior的用法、自动调用机制与安全护栏。读完本文你既能掌握在 SK 应用中启用函数调用的完整实操方法也能从源码层面理解其设计边界。背景OpenAI 的 Function Calling 能力是什么2023 年 OpenAI 为 Chat Completions 的/v1/chat/completions端点引入了 Function Calling 能力允许开发者在请求中描述函数由模型自行判断是否需要调用某个函数并在回答中输出一个包含函数名与参数的 JSON 对象。这项能力由两个新的 API 参数启用参数取值作用function_callauto默认、none、或指定某个函数名控制模型是否调用函数、调用哪个函数functions一组 JSON 描述描述模型可用的函数函数名、参数 schema 等文档中还明确了一个重要的成本特征提供给模型的函数描述会被注入到 system message 中并按输入 token 计费。这意味着函数列表越长单次请求的输入成本越高——这一事实直接影响了后文 ADR 的决策驱动力。从 Semantic Kernel 的角度看社区多次提出希望在使用 SK 调用支持该能力的 OpenAI 聊天模型时能够利用这一特性。这正是本 ADR 的起源。架构决策三个候选方案与最终选择决策驱动力ADR 记录了三个关键决策驱动力Decision Drivers最小化对核心 Kernel 的改动OpenAI 专属的功能不应污染核心抽象成本顾虑请求中携带一长串函数描述会产生显著的 token 开销安全与成本顾虑自动执行模型返回的函数存在风险需要谨慎对待。三个候选方案方案一修改接口以支持函数收发修改IChatCompletion与IChatResult接口显式暴露函数信息相关的参数与方法。优点为使用函数调用提供了清晰路径应用可控制暴露给模型的函数包括非 SK 函数。缺点对核心 Kernel 抽象产生破坏性变更breaking changeOpenAI 专属功能会进入核心抽象其他模型提供商必须忽略这些成员。方案二不修改接口通过现有请求设置对象收发函数最终选择复用现有的 request settings 对象将函数描述随请求发给模型。应用开发者自行控制包含哪些函数并负责校验与执行模型返回的函数结果。优点避免了对核心 Kernel 的破坏性变更OpenAI 专属逻辑被限制在 OpenAI connector 包内应用可完全控制暴露给模型的函数包括非 SK 函数为未来与 Planner 集成保留了可能性。中性要求应用开发者自行校验并执行返回的函数。缺点使用方式不如接口方案直观函数结果的访问路径不够明显。方案三围绕函数调用实现一个 Planner把编排外部函数调用纳入 SK 的规划Planning概念实现一个类似 ActionPlanner 的 Planner将函数调用结果转换为可由开发者执行的计划。优点以计划plan形式返回结果便于开发者执行所选函数。缺点函数必须先注册到 Kernel 才能被执行会造成该用哪个 Planner的混淆。决策结果最终选择方案二不修改接口利用现有请求设置对象发送函数到模型。ADR 同时记录了后续演进的重要注记关于模型返回的函数若已注册到 Kernel 是否自动执行存在大量讨论由于仍有诸多悬而未决的问题初版实现不包含自动调用能力留待未来版本探索。决策在源码中的落地从 ToolCallBehavior 到 FunctionChoiceBehavior随着项目演进这一 ADR 的决策在仓库中形成了两代实现正好对应先不自动调用、后支持自动调用的演进脉络。初代实现ToolCallBehaviorOpenAI Connector 内在 ToolCallBehavior.cs 中抽象类ToolCallBehavior定义了 OpenAI connector 内的工具调用行为提供四个静态工厂工厂方法行为EnableKernelFunctions向模型提供 Kernel 中所有插件函数的信息但不自动执行函数调用请求回传给调用方AutoInvokeKernelFunctions向模型提供所有插件函数信息并自动执行模型请求的函数把结果回传给模型EnableFunctions(functions, autoInvoke)向模型提供指定的函数列表可选择性开启自动执行RequireFunction(function, autoInvoke)强制模型使用指定的某个函数关键安全护栏在类内常量中体现private const int DefaultMaximumAutoInvokeAttempts 128;即单次用户请求内的自动调用轮次上限为 128 次。注释中说明这是防止模型反复请求同一函数导致失控执行runaway execution的保险机制达到上限后AutoInvokeKernelFunctions会退化为EnableKernelFunctions的行为只提供函数信息不再自动执行。该行为对象被挂载到 OpenAIPromptExecutionSettings.cs 的ToolCallBehavior属性上。其文档注释清晰地给出了四种配置方式的语义置null默认完全禁用工具调用ToolCallBehavior.RequireFunction(...) 要求模型使用指定函数ToolCallBehavior.EnableFunctions(...) 允许模型从给定列表中选择函数ToolCallBehavior.EnableKernelFunctions/AutoInvokeKernelFunctions 允许模型请求 Kernel 中的任意函数后者附带自动执行能力。演进后的实现FunctionChoiceBehavior核心抽象层后续版本将函数选择能力提升到了核心抽象层位于 dotnet/src/SemanticKernel.Abstractions/AI/FunctionChoiceBehaviors/。FunctionChoiceBehavior是抽象基类通过 JSON 多态反序列化支持三种派生类型type discriminator 分别为auto/required/none并提供了三个静态工厂方法工厂方法Choice 语义说明FunctionChoiceBehavior.Auto()FunctionChoice.Auto由模型自行决定是否调用、调用哪些函数对应 OpenAI 的function_call: autoFunctionChoiceBehavior.Required()FunctionChoice.Required强制模型调用一个或多个函数FunctionChoiceBehavior.None()FunctionChoice.None向模型提供函数描述但指示其不要调用可用于让模型先描述将要执行的函数供人工校验三个工厂方法均接受三个参数functions为null时提供 Kernel 中全部插件函数为空集合时等价于禁用函数调用、autoInvoke是否由 AI connector 自动执行函数、options行为选项。从源码看函数解析的核心逻辑在基类的 GetFunctions 方法 中值得注意的推断结论自动调用必须依赖 Kernel当autoInvoke true而 Kernel 为null时直接抛出KernelExceptionAuto-invocation is not supported when no kernel is provided.。其意图在注释中写明绝不能向模型承诺我能处理这些函数却在执行时失败因此宁可提前失败。显式指定的函数必须能被解析指定了函数全名FQN如PluginName.FunctionName却找不到时自动调用模式下会提前抛错非自动调用模式下才会回退到传入的KernelFunction实例列表。functions为 null 时展开全部插件遍历kernel.Plugins将所有函数加入候选列表。Required行为还有一个值得注意的实现细节在 RequiredFunctionChoiceBehavior.GetConfiguration 中当RequestSequenceIndex 1即多轮自动调用中的后续请求时会停止向模型继续广告函数防止模型反复调用同一个函数——代码注释明确标注这是临时方案未来将改为动态控制函数广告列表。行为选项由 FunctionChoiceBehaviorOptions.cs 定义属性JSON 字段默认值作用AllowParallelCallsallow_parallel_callsnull采用模型默认是否让模型优先并行调用多个函数AllowConcurrentInvocationallow_concurrent_invocationfalse模型并行请求的多个函数是否允许并发执行若函数不修改共享状态可设为trueAllowStrictSchemaAdherenceallow_strict_schema_adherencefalse是否要求模型严格遵循函数 schemaRetainArgumentTypes非序列化字段实验特性SKEXP0001false函数参数是否保留类型信息默认 SK 将参数反序列化为字符串为true时以JsonElement保留类型实践在应用中启用函数调用使用FunctionChoiceBehavior.Auto()的典型用法仓库示例 FunctionCalling.cs 展示了最典型的用法——在OpenAIPromptExecutionSettings中配置行为并传入 Kernel因为自动调用需要 Kernel 来解析与执行函数OpenAIPromptExecutionSettings settings new() { FunctionChoiceBehavior FunctionChoiceBehavior.Auto() }; Kernel kernel new(); var result await kernel.GetRequiredServiceIChatCompletionService() .GetChatMessageContentAsync(chatHistory, settings, kernel);其中FunctionChoiceBehavior.Auto()等价于FunctionChoiceBehavior.Auto(functions: null, autoInvoke: true)即把 Kernel 中全部插件函数广告给模型并在模型请求调用时自动执行。如果只想把函数信息暴露给模型、由应用自行校验与执行对应 ADR 决策中的应用开发者负责校验和执行函数结果则显式关闭自动调用OpenAIPromptExecutionSettings settings new() { FunctionChoiceBehavior Microsoft.SemanticKernel.FunctionChoiceBehavior.Auto(autoInvoke: false) };同目录下的 AzureAIInference_FunctionCalling.cs 表明该行为不仅是 OpenAI 专属——兼容 OpenAI 协议的 Azure AI Inference 服务同样通过FunctionChoiceBehavior.Auto()配置印证了 ADR 中OpenAI 专属功能收敛在 connector 包内、核心抽象保持通用的设计意图。函数描述的成本与数量控制回到 ADR 记录的事实函数描述按输入 token 计费。因此实践中的关键建议是不要无条件地把 Kernel 中所有函数广告给模型应根据场景用FunctionChoiceBehavior.Auto(functions: 指定函数集合, ...)或Required/None收敛候选列表多轮对话中模型可能反复请求同一函数Required行为在第二轮起停止广告函数ToolCallBehavior的 128 次自动调用上限都是防止 token 失控与循环调用的内置护栏在需要人工审批的场景如敏感操作前可先用FunctionChoiceBehavior.None()让模型描述将要执行的函数由人确认后再真正执行。执行入口与验证测试自动调用的完整链路模型返回函数调用 → connector 解析 → 调用 Kernel 函数 → 回传结果给模型由 ClientCore.ChatCompletion.cs 承载。仓库中的集成测试提供了可直接参考的验证场景OpenAIChatCompletion_FunctionCallingTests.csAzureOpenAIChatCompletionFunctionCallingTests.csAutoFunctionInvocationFilterTests.cs自动调用与过滤器协同的单元测试此外该能力同样覆盖其他兼容 Function Calling 的 provider如 Google Gemini 的 GeminiToolCallBehavior.cs、Mistral 的 MistralAIToolCallBehavior.cs可见函数选择行为抽象化已成为 SK 多模型 connector 的通用模式。演进脉络总结阶段代表产物自动调用位置ADR 决策2023-090017-openai-function-calling.md明确暂不包含架构决策记录初代实现ToolCallBehavior.csEnableKernelFunctions不自动AutoInvokeKernelFunctions自动OpenAI connector 包内通用抽象FunctionChoiceBehaviorAuto/Required默认自动None不自动核心抽象层这条演进路径清晰印证了 ADR 的决策智慧先以最小侵入方式不改接口、不自动执行在 connector 内落地能力待自动调用行为的安全性讨论成熟后再以通用抽象的形式沉淀到核心层——既避免了破坏性变更又保留了未来的扩展空间。参考与延伸阅读决策原文0017-openai-function-calling.md关联 ADR0017-openai-function-calling.md 后续的 0061-function-call-behavior.md 与 0063-function-calling-reliability.md 记录了该能力后续的行为演进与可靠性设计行为实现FunctionChoiceBehavior.cs、FunctionChoiceBehaviorOptions.csConnector 实现ToolCallBehavior.cs、OpenAIPromptExecutionSettings.cs可运行示例FunctionCalling.cs验证测试OpenAIChatCompletion_FunctionCallingTests.cs【免费下载链接】semantic-kernelIntegrate cutting-edge LLM technology quickly and easily into your apps项目地址: https://gitcode.com/GitHub_Trending/se/semantic-kernel创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。