You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Semantic Kernel对接本地LLM无法调用插件的问题及临时解法

本地LLM对接Semantic Kernel的函数调用问题排查与临时解决方法

问题背景

我正在开发首个AI演示项目,目标是用Semantic Kernel对接本地部署的LLM实现函数调用。目前能正常获取LLM的响应,但插件调用失败——虽然插件已作为工具包含在发送给LLM的JSON请求中:

"tools": [
    {
      "type": "function",
      "function": {
        "description": "获取灯光列表及其当前状态",
        "name": "Lights-get_lights",
        "parameters": {
          "type": "object",
          "required": [],
          "properties": {}
        }
      }
    }
]

但LLM始终无法通过Kernel调用插件函数获取数据。我试过Llama-3.2-3B-Instruct、Phi-3-mini-4k-instruct等模型,用LM Studio托管本地服务器,作为LLM新手,不清楚遗漏了哪些关键步骤。

原方案代码

Program.cs

var messageAPIPlatform = "LocalAI";
var url = "http://localhost:1234/v1";
var modelId = "llama-3.2-3b-instruct";

Console.WriteLine($"使用本地{messageAPIPlatform}的示例");

#pragma warning disable SKEXP0010
var kernel = Kernel.CreateBuilder()
    .AddOpenAIChatCompletion(
        modelId: modelId,
        apiKey: null,
        endpoint: new Uri(url))
    .Build();


var chatCompletionService = kernel.GetRequiredService<IChatCompletionService>();

kernel.Plugins.AddFromType<LightsPlugin>("Lights");

// 启用规划
#pragma warning disable SKEXP0001
OpenAIPromptExecutionSettings settings = new OpenAIPromptExecutionSettings()
{
    ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions,
    Temperature = .1,
    ChatSystemPrompt = """
                       你是一个大语言模型助手,会通过插件与软件交互。
                       """
};

// 创建对话历史存储
var history = new ChatHistory();

// 启动交互式对话
string? userInput;
do
{
    // 收集用户输入
    Console.Write("用户 > ");
    userInput = Console.ReadLine();

    // 添加用户消息到历史
    history.AddUserMessage(userInput);

    // 获取AI响应
    var result = await chatCompletionService.GetChatMessageContentAsync(
        history,
        executionSettings: settings,
        kernel: kernel);

    // 打印结果
    Console.WriteLine("助手 > " + result);

    // 将助手消息添加到对话历史
    history.AddMessage(result.Role, result.Content ?? string.Empty);
} while (userInput is not null);

LightsPlugin.cs

public class LightsPlugin
{
    // 灯光模拟数据
    private readonly List<LightModel> lights = new()
    {
        new LightModel { Id = 1, Name = "台灯", IsOn = false },
        new LightModel { Id = 2, Name = " porch灯", IsOn = false },
        new LightModel { Id = 3, Name = "吊灯", IsOn = true }
    };

    [KernelFunction("get_lights")]
    [Description("获取灯光列表及其当前状态")]
    [return: Description("灯光数组")]
    public async Task<List<LightModel>> GetLightsAsync()
    {
        return lights;
    }

    [KernelFunction("change_state")]
    [Description("修改灯光状态")]
    [return: Description("更新后的灯光状态;如果灯光不存在则返回null")]
    public async Task<LightModel?> ChangeStateAsync(int id, bool isOn)
    {
        var light = lights.FirstOrDefault(light => light.Id == id);

        if (light == null)
        {
            return null;
        }

        // 更新灯光状态
        light.IsOn = isOn;

        return light;
    }
}

当询问灯光状态时,LLM只会回复无法回答该问题,不会调用GetLightsAsync()方法。

尝试过的其他方案

OllamaConnector

试过Ollama函数调用的官方示例,但未成功,使用的是最新版Semantic Kernel和Ollama。

临时解决方法(基于旧版Semantic Kernel)

最终通过Ollama实现了函数调用,核心修改点如下:

  • 用ChatCompletionAgent替代ChatCompletionService发送请求
  • 将Semantic Kernel对象绑定到ChatCompletionAgent
  • 使用KernelPluginFactory创建插件,而非KernelBuilder.AddFromType
  • 仍使用OpenAiChatCompletion(原本以为应该用OllamaConnector)
  • 必须降级Semantic Kernel到1.18.2版本才能使用ChatCompletionAgent

该方案并不完美,依赖旧版本库且不符合官方最新指南,但这是目前唯一能让LLM调用函数的方式。

临时解决代码

var modelId = "llama3.2";
var baseUrl = "http://localhost:11434";

var httpClient = new HttpClient
{
    Timeout = TimeSpan.FromMinutes(2)
};

var builder = Kernel.CreateBuilder().AddOpenAIChatCompletion(modelId: modelId!, apiKey: null, endpoint: new Uri(baseUrl!), httpClient: httpClient);
var kernel = builder.Build();

var hostName = "AI助手";
var hostInstructions =
    @"你是一个友好的助手";


var settings = new OpenAIPromptExecutionSettings()
{
    Temperature = 0.1,
    ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions,
};

ChatCompletionAgent agent =
           new()
           {
               Instructions = hostInstructions,
               Name = hostName,
               Kernel = kernel,
               Arguments = new(settings),
           };

KernelPlugin lightsPlugin = KernelPluginFactory.CreateFromType<LightsPlugin>();
agent.Kernel.Plugins.Add(lightsPlugin);

Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("助手: 你好,我是你的AI助手,有什么可以帮你的?");

AgentGroupChat chat = new();

while (true)
{
    Console.ForegroundColor = ConsoleColor.White;
    Console.Write("用户: ");
    await InvokeAgentAsync(Console.ReadLine()!);
}

async Task InvokeAgentAsync(string question)
{
    chat.AddChatMessage(new ChatMessageContent(AuthorRole.User, question));

    Console.ForegroundColor = ConsoleColor.Green;

    await foreach (ChatMessageContent content in chat.InvokeAsync(agent))
    {
        Console.WriteLine(content.Content);
    }
}

#pragma warning restore SKEXP0010
#pragma warning restore SKEXP0110

待解答疑问

仍想了解原方案失效的具体原因。


内容的提问来源于stack exchange,提问作者Oreth

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 22:14:56