尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Semantic Kernel 实战:使用 Ollama Connector 驱动小型语言模型实现 Function Calling

Semantic Kernel 实战:使用 Ollama Connector 驱动小型语言模型实现 Function Calling Semantic Kernel 实战使用 Ollama Connector 驱动小型语言模型实现 Function Calling【免费下载链接】semantic-kernelIntegrate cutting-edge LLM technology quickly and easily into your apps项目地址: https://gitcode.com/GitHub_Trending/se/semantic-kernel导读本文围绕 Semantic Kernel 仓库中的 OllamaFunctionCalling 示例展开讲解如何通过Microsoft.SemanticKernel.Connectors.Ollama连接器让本地部署的支持 Function Calling 的小型语言模型SLM如 llama3.1 及更高版本自主调用 C# 插件函数。读完本文你将掌握 Ollama 连接器的注册方式、FunctionChoiceBehavior.Auto()的启用方法、插件函数的标注约定以及如何基于本地 Ollama 服务搭建一个能控制闹钟、电灯等真实对象的最小对话式 Copilot。示例概览Ollama Function Calling该示例演示了 Semantic Kernel 的 Ollama 连接器与启用 Function Calling 的小型语言模型的完整集成。核心结论如下推荐使用llama3.1 或更高版本的模型以获得最佳的 Function Calling 效果README 明确指出Best results with llama3.1 or higher示例默认配置modelId为llama3.2端点指向本地默认端口http://localhost:11434需要配置模型 ID 为你想要使用的模型当前主要支持 llama3.1 及相关模型。示例通过三个自定义插件展示了函数调用的真实落地场景时间查询MyTimePlugin、电灯控制MyLightPlugin与闹钟管理MyAlarmPlugin。环境准备与工程结构前置条件本地安装并启动 Ollama 服务默认监听11434端口使用ollama pull llama3.2或llama3.1等支持 Function Calling 的模型预先拉取模型.NET SDK示例工程目标框架为net10.0见 OllamaFunctionCalling.csproj。工程组成示例位于 dotnet/samples/Demos/OllamaFunctionCalling包含文件职责Program.cs内核构建、服务注册与交互式对话主循环Plugins/MyTimePlugin.cs返回当前时间Plugins/MyLightPlugin.cs电灯开关状态查询与控制Plugins/MyAlarmPlugin.cs闹钟时间设置与查询README.md使用说明工程通过ProjectReference直接引用 Connectors.Ollama.csproj 与SemanticKernel.Abstractions源码无需额外安装 NuGet 包即可运行。若在自有项目中使用则需添加Microsoft.SemanticKernel.Connectors.Ollama包该连接器底层依赖 OllamaSharp 客户端库目标框架为net8/netstandard2.0。连接器实现原理从端点注册到 IChatCompletionService在深入示例代码之前先了解其底层实现有助于理解为何仅需几行代码就能打通本地模型。服务的三种注册形态OllamaChatCompletionService 实现了IChatCompletionService接口支持三种构造方式端点方式传入modelId与Uri endpoint本示例采用此方式HttpClient 方式传入modelId与已配置BaseAddress的HttpClientOllamaApiClient 方式直接传入 OllamaSharp 客户端实例。无论哪种方式最终都会通过this._client.AsChatCompletionService()将 OllamaSharp 客户端适配为 Semantic Kernel 的IChatCompletionService对外暴露GetChatMessageContentsAsync与GetStreamingChatMessageContentsAsync两个异步方法。值得注意的是源码中该类已标注[Obsolete]提示使用OllamaApiClient.AsChatCompletionService()替代但示例仍使用AddOllamaChatCompletion扩展方法完成注册这也说明 Kernel Builder 扩展方法层对底层 API 变化做了屏蔽普通用户无需感知。Kernel Builder 扩展方法OllamaKernelBuilderExtensions 提供了AddOllamaChatCompletion的多个重载AddOllamaChatCompletion(string modelId, Uri endpoint, string? serviceId null)AddOllamaChatCompletion(string modelId, HttpClient? httpClient null, string? serviceId null)AddOllamaChatCompletion(OllamaApiClient? ollamaClient null, string? serviceId null)serviceId参数用于在多个 AI 服务并存时进行路由选择。此外该连接器还提供AddOllamaTextGeneration、AddOllamaChatClient、AddOllamaEmbeddingGenerator等扩展方法旧的AddOllamaTextEmbeddingGeneration已标记为过时覆盖文本生成、聊天补全与嵌入生成三类能力。构建内核与注册插件完整可运行代码Program.cs 的核心逻辑非常简洁using System; using Microsoft.SemanticKernel; using Microsoft.SemanticKernel.ChatCompletion; using Microsoft.SemanticKernel.Connectors.Ollama; using OllamaFunctionCalling; var builder Kernel.CreateBuilder(); var modelId llama3.2; var endpoint new Uri(http://localhost:11434); builder.Services.AddOllamaChatCompletion(modelId, endpoint); builder.Plugins .AddFromTypeMyTimePlugin() .AddFromObject(new MyLightPlugin(turnedOn: true)) .AddFromObject(new MyAlarmPlugin(11)); var kernel builder.Build(); var chatCompletionService kernel.GetRequiredServiceIChatCompletionService(); var settings new OllamaPromptExecutionSettings { FunctionChoiceBehavior FunctionChoiceBehavior.Auto() };关键点逐条拆解1. 注册 Ollama 聊天补全服务builder.Services.AddOllamaChatCompletion(modelId, endpoint)将IChatCompletionService注入内核modelId对应本地已拉取的模型名如llama3.2endpoint指向 Ollama 服务地址。2. 三种插件注册方式AddFromTypeMyTimePlugin()按类型自动发现公共方法并注册为内核函数AddFromObject(new MyLightPlugin(turnedOn: true))从带初始状态的对象实例注册AddFromObject(new MyAlarmPlugin(11))同上通过构造函数传入初始闹钟时间为 11。这展示了builder.Plugins对类型注册与实例注册的统一支持。3. 启用自动函数调用var settings new OllamaPromptExecutionSettings { FunctionChoiceBehavior FunctionChoiceBehavior.Auto() };FunctionChoiceBehavior.Auto()是 Function Calling 的开关启用后模型会在需要时自动决定是否调用插件函数Semantic Kernel 负责把函数签名发给模型、解析模型返回的工具调用请求、执行对应插件函数并把结果回填给模型形成思考 → 调用 → 观察 → 再回答的完整循环。4. 交互式对话循环Console.Write( ); string? input null; while ((input Console.ReadLine()) is not null) { ChatMessageContent chatResult await chatCompletionService.GetChatMessageContentAsync(input, settings, kernel); Console.Write($\n Result: {chatResult}\n\n ); }每次用户输入都会被送入GetChatMessageContentAsync同时传入settings与kernel——kernel参数至关重要它让内核能够查找到前面注册的插件并代表模型执行函数调用。循环内还包裹了 try/catch任一环节出错都会打印Error: ...并继续下一轮输入。插件定义规范如何让模型看懂你的函数Function Calling 的可用性完全取决于函数对模型的可见性。三个插件都遵循 Semantic Kernel 的[KernelFunction][Description]约定。MyTimePlugin最简单的只读函数MyTimePlugin.cspublic class MyTimePlugin { [KernelFunction, Description(Get the current time)] public DateTimeOffset Time() DateTimeOffset.Now; }[KernelFunction]标记使方法暴露为内核函数[Description]提供给模型自然语言描述这是模型判断何时该调用此函数的依据。MyLightPlugin带对象状态的控制函数MyLightPlugin.cs 使用 C# 主构造函数注入初始状态并在类级别标注[Description(Represents a light bulb)][Description(Represents a light bulb)] public class MyLightPlugin(bool turnedOn false) { private bool _turnedOn turnedOn; [KernelFunction, Description(Returns whether this light is on)] public bool IsTurnedOn() _turnedOn; [KernelFunction, Description(Turn on this light)] public void TurnOn() _turnedOn true; [KernelFunction, Description(Turn off this light)] public void TurnOff() _turnedOn false; }TurnOn/TurnOff返回void、IsTurnedOn返回bool展示了函数调用中命令式操作与查询式操作并存时的写法。MyAlarmPlugin带参数与状态回读的复杂函数MyAlarmPlugin.cs 演示了带输入参数的函数如何与状态联动public class MyAlarmPlugin { private string _hour; public MyAlarmPlugin(string providedHour) this._hour providedHour; [KernelFunction, Description(Sets an alarm at the provided time)] public string SetAlarm(string time) { this._hour time; return GetCurrentAlarm(); } [KernelFunction, Description(Get current alarm set)] public string GetCurrentAlarm() $Alarm set for {_hour}; }SetAlarm(string time)的参数time会作为 JSON Schema 描述发送给模型模型需要从用户指令如 Change the alarm to 8中抽取参数值并填充到函数调用中——这正是 Function Calling 的核心价值让模型完成自然语言 → 结构化参数的转换。运行与交互效果构建并运行示例后控制台会提示可尝试的指令Change the alarm to 8修改闹钟What is the current alarm set?查询闹钟Is the light on?查询电灯状态Turn the light off please.关闭电灯Set an alarm for 6:00 am.设置闹钟这些指令的共同特点是必须依赖插件函数才能正确回答。例如 What is the current alarm set? 需要模型调用MyAlarmPlugin.GetCurrentAlarm()Turn the light off please. 需要模型调用MyLightPlugin.TurnOff()。模型会根据函数描述自主决策调用哪个函数、传入什么参数最终把函数返回值组织成自然语言回复。运行结果形如 What is the current alarm set? Result: The alarm is currently set for 11 oclock. Turn the light off please. Result: The light has been turned off.执行参数详解OllamaPromptExecutionSettings示例中使用的OllamaPromptExecutionSettings位于 Settings/OllamaPromptExecutionSettings.cs除FunctionChoiceBehavior继承自基类外还支持以下常用参数均对应 Ollama 原生 API 字段属性JSON 字段说明默认值Temperaturetemperature采样温度越高回答越有创造性0.8TopPtop_p与 top-k 配合越高文本越多样0.9TopKtop_k降低生成无意义内容的概率越高答案越多样40NumPredictnum_predict最大输出 token 数-1 表示无限生成-1Stopstop停止序列命中即停止生成nullThinkthink控制推理模型如 deepseek-r1、qwen3、phi4-reasoning的思考开关null跟随模型默认Think参数说明设置为false可禁用推理模型的思考过程使输出全部出现在标准响应字段为true则显式开启。当思考激活时推理内容会进入独立的 thinking 流而非主响应内容。此外该类还实现了FromExecutionSettings静态转换方法支持从通用PromptExecutionSettings反序列化转换并恢复序列化过程中丢失的FunctionChoiceBehavior内部函数实例状态以及Clone()/Freeze()方法。所有数值属性都标注了[JsonNumberHandling(JsonNumberHandling.AllowReadingFromString)]允许从字符串形式解析数值兼容更宽松的 API 响应。在自有项目中集成参照本示例将 Ollama Function Calling 引入自有项目的步骤可归纳为安装连接器包引用Microsoft.SemanticKernel.Connectors.Ollama示例工程直接引用源码路径dotnet/src/Connectors/Connectors.Ollama/Connectors.Ollama.csproj启动 Ollama 并拉取模型确保ollama serve运行且llama3.1及以上版本模型已就绪创建内核并注册服务AddOllamaChatCompletion(modelId, endpoint)注册插件用AddFromTypeT()或AddFromObject(instance)暴露业务函数函数须标注[KernelFunction]与清晰的[Description]启用自动函数调用构造OllamaPromptExecutionSettings { FunctionChoiceBehavior FunctionChoiceBehavior.Auto() }调用对话服务将settings与kernel一并传入GetChatMessageContentAsync。注意事项模型选择是成败关键README 明确提示使用 llama3.1 或更高版本较低版本模型可能无法稳定输出符合工具调用格式的响应参数抽取质量函数参数应使用语义明确的命名与描述[Description]越精确模型抽取参数越准确本地资源模型推理在本地完成无云端费用但受限于机器显存/内存需按硬件条件选择模型尺寸。小结OllamaFunctionCalling 示例展示了 Semantic Kernel 与本地模型的组合范式以 Connectors.Ollama 为桥梁、以FunctionChoiceBehavior.Auto()为开关、以[KernelFunction]插件为载体即可让 llama3.1 这类支持函数调用的小型语言模型胜任对话式控制真实对象的任务。这一模式可进一步推广到智能家居控制、本地知识库工具调用、无需联网的私密助手等场景是探索 SLM 落地应用的高性价比起点。若想了解更深入的函数调用机制可继续阅读仓库内相关文档0061-function-call-behavior.md、0063-function-calling-reliability.md 以及 0017-openai-function-calling.md。【免费下载链接】semantic-kernelIntegrate cutting-edge LLM technology quickly and easily into your apps项目地址: https://gitcode.com/GitHub_Trending/se/semantic-kernel创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表