惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Y
Y Combinator Blog
D
Docker
有赞技术团队
有赞技术团队
D
DataBreaches.Net
The GitHub Blog
The GitHub Blog
爱范儿
爱范儿
H
Help Net Security
美团技术团队
MyScale Blog
MyScale Blog
B
Blog RSS Feed
C
Check Point Blog
Microsoft Security Blog
Microsoft Security Blog
阮一峰的网络日志
阮一峰的网络日志
A
About on SuperTechFans
小众软件
小众软件
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
GbyAI
GbyAI
G
Google Developers Blog
月光博客
月光博客
Google DeepMind News
Google DeepMind News
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Blog — PlanetScale
Blog — PlanetScale
MongoDB | Blog
MongoDB | Blog
F
Fortinet All Blogs

博客园 - 桂素伟

Semantic Kernel:开启MCP .NET10:解决json序列化时引用自己 .NET10:字符数字 Semantic Kernel:接入本地deepseek-r1:1.5b Semantic Kernel:接入azure中的deepseek-r1 C#中的Channel .NET9中基于策略角色验证的包冲突 .NET9中使用Options Semantic Kernel:OpenAPI的Plugin Semantic Kernel:Phi-4试用 AI应用开发的浅见 Semantic Kernel:Process Semantic Kernel:新Agent代理 UnitsNet 库简介 .NET9里WinForm更新了什么 SemanticKernel系列,AI系列,SmartFill介绍视频系列 更流畅的asp.net api的错误返回 用.srt字幕文件生成.wav语音 自制实时翻译小工具
Semantic Kernel:Phi-4 mini的tools
桂素伟 · 2025-03-17 · via 博客园 - 桂素伟

  Phi4-mini开始支持tools了,但在第一时间试用时不理想,kenfey最近发了一篇解决方案,详见https://techcommunity.microsoft.com/blog/educatordeveloperblog/building-ai-agents-on-edge-devices-using-ollama--phi-4-mini-function-calling/4391029。本篇文章想更详细地梳理一下,结合SK来给出一个完整的例子。

  首先安装olloma,然后安装phi4-mini,命令如下:

  ollama pull phi4-mini

  原生成phi4-mini对tools支持有有问题的,这里需在替换一下modelfile,可以先用下面命令查看一下原来的modelfile,以便获取FROM地的址信息:

  ollama show phi4-mini --modelfile

  找一个目录把下面修正后的Modefile存起来,Modefile文件没有扩展名。

FROM C:\Users\axzxs\.ollama\models\blobs\sha256-3c168af1dea0a414299c7d9077e100ac763370e5a98b3c53801a958a47f0a5db
TEMPLATE """{{- if or .System .Tools }}<|system|>{{ if .System }}{{ .System }}{{ end }}
{{- if .Tools }}
{{- if not .System }}You may call one or more functions to assist with the user query. You are provided with function signatures.
{{- end }}<|tool|>[{{- range .Tools }}{{ .Function }}{{ end }}]<|/tool|><|end|>
{{- end }}
{{- end }}
{{- range $i, $_ := .Messages }}
{{- $last := eq (len (slice $.Messages $i)) 1 -}}
{{- if ne .Role "system" }}<|{{ .Role }}|>{{ .Content }}
{{- if .ToolCalls }}<|tool_call|>[{{ range .ToolCalls }}{"name":"{{ .Function.Name }}","arguments":{{ .Function.Arguments }}}{{ end }}]<|/tool_call|>
{{- end }}
{{- if not $last }}<|end|>
{{- end }}
{{- if and (ne .Role "assistant") $last }}<|end|><|assistant|>{{ end }}
{{- end }}
{{- end }}"""

  然后用下面命令重写Modelfile:

  ollama create phi4-mini -f "你的Modelfile路径" 

  SK调用Phi4-mini tools的代码如下:

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;
using Microsoft.SemanticKernel.Connectors.Ollama;
using Microsoft.SemanticKernel.Connectors.OpenAI;
using OllamaSharp;
using OllamaSharp.Models;
using OpenAI.RealtimeConversation;
using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
#pragma warning disable

await Call();
Console.ReadLine();
async Task Call()
{
    var builder = Kernel.CreateBuilder();
    var modelId = "phi4-mini";
    var endpoint = new Uri("http://localhost:11434");
    builder.Services.AddOllamaChatCompletion(modelId, endpoint);
    builder.Plugins.AddFromType<OrderPlugin>();
    var kernel = builder.Build();
    var chatCompletionService = kernel.GetRequiredService<IChatCompletionService>();
    var settings = new OllamaPromptExecutionSettings { FunctionChoiceBehavior = FunctionChoiceBehavior.None() };
    Console.Write(">>> ");
    string? input = "获取订单编号为SN0000111的订单总额?";
    Console.WriteLine(input);
    try
    {
        ChatMessageContent chatResult = await chatCompletionService.GetChatMessageContentAsync(input, settings, kernel);
        Console.Write($"\n>>> Result: {chatResult}\n\n> ");
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Error: {ex.Message}\n\n> ");
    }
}
public class OrderPlugin
{
    [KernelFunction]
    [Description("获取订单总额")]
    public decimal GetOrderAmount([Description("订单编号")] string orderNo)
    {
        Console.WriteLine($"订单编号:{orderNo},订单:12345.67");
        return 12345.67m;
    }
}

  运行结果如下:

 从试用的结果来看,并不是每次都是理想的,调用tools成功率还不理想,期望官方能更新,进一步提升调成率。

  文章来源微信公众号

  想要更快更方便的了解相关知识,可以关注微信公众号 

****欢迎关注我的asp.net core系统课程****
《asp.net core精要讲解》 https://ke.qq.com/course/265696
《asp.net core 3.0》 https://ke.qq.com/course/437517
《asp.net core项目实战》 https://ke.qq.com/course/291868
《基于.net core微服务》 https://ke.qq.com/course/299524