记一次WPF集成SemanticKernel+OneAPI+讯飞星火认知大模型实践

开启OneAPI服务

OneAPI介绍

OpenAI 接口管理 & 分发系统,支持 Azure、Anthropic Claude、Google PaLM 2 & Gemini、智谱 ChatGLM、百度文心一言、讯飞星火认知、阿里通义千问、360 智脑以及腾讯混元,可用于二次分发管理 key,仅单可执行文件,已打包好 Docker 镜像,一键部署,开箱即用. OpenAI key management & redistribution system, using a single API for all LLMs, and features an English UI.

项目地址:github.com/songquanpen...

使用OneAPI

基于docker部署:

ini 复制代码
# 使用 SQLite 的部署命令:
docker run --name one-api -d --restart always -p 3000:3000 -e TZ=Asia/Shanghai -v /home/ubuntu/data/one-api:/data justsong/one-api
# 使用 MySQL 的部署命令,在上面的基础上添加 `-e SQL_DSN="root:123456@tcp(localhost:3306)/oneapi"`,请自行修改数据库连接参数,不清楚如何修改请参见下面环境变量一节。
# 例如:
docker run --name one-api -d --restart always -p 3000:3000 -e SQL_DSN="root:123456@tcp(localhost:3306)/oneapi" -e TZ=Asia/Shanghai -v /home/ubuntu/data/one-api:/data justsong/one-api

部署完成后,打开本地3000端口,如下所示:

初始账户为root,密码为123456。

登录之后,会提示修改密码。

点击渠道,创建新的渠道:

填入自己的大模型密钥。

添加令牌:

测试OneAPI服务是否可用

使用Postman查看接口是否可用:

注意事项

接口地址:http://<你的IP地址>:3000/v1/chat/completions

ip地址可通过cmd输入ipconfig查到。

在请求中加入令牌

在红框位置输入OneAPI中的令牌。

测试的json

json 复制代码
{
    "model":"SparkDesk",
    "messages":[
        {
            "role":"user",
            "content":"你是谁"
        }
    ],
      "temperature":0.7    
}

星火大模型的响应

json 复制代码
{
    "id": "",
    "object": "chat.completion",
    "created": 1709004732,
    "choices": [
        {
            "index": 0,
            "message": {
                "role": "assistant",
                "content": "您好,我是科大讯飞研发的认知智能大模型,我的名字叫讯飞星火认知大模型。我可以和人类进行自然交流,解答问题,高效完成各领域认知智能需求。"
            },
            "finish_reason": "stop"
        }
    ],
    "usage": {
        "prompt_tokens": 2,
        "completion_tokens": 40,
        "total_tokens": 42
    }
}

创建WPF项目

SemanticKernel简介

Semantic Kernel 是一个开源 SDK,可让您轻松构建可以调用现有代码的代理。作为高度可扩展的 SDK,可以将语义内核与 OpenAI、Azure OpenAI、Hugging Face 等模型一起使用!通过将现有的 C#、Python 和 Java 代码与这些模型相结合,可以生成用于回答问题和自动执行流程的代理。

安装SemanticKernel

在SemanticKernel中使用星火大模型

创建一个OpenAIHttpClientHandler类

OpenAIHttpClientHandler类代码:

ini 复制代码
 public class OpenAIHttpClientHandler : HttpClientHandler
 {
     protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
     {
         UriBuilder uriBuilder;
         switch (request.RequestUri?.LocalPath)
         {
             case "/v1/chat/completions":
                 uriBuilder = new UriBuilder(request.RequestUri)
                 {
                     // 这里是你要修改的 URL
                     Scheme = "http",
                     Host = "你的ip地址",
                     Port = 3000,
                     Path = "v1/chat/completions",
                 };
                 request.RequestUri = uriBuilder.Uri;
                 break;
         }
​
         // 接着,调用基类的 SendAsync 方法将你的修改后的请求发出去
         HttpResponseMessage response = await base.SendAsync(request, cancellationToken);
​
         int n = 0;
         while ((int)response.StatusCode == 500 && n < 10)
         {
             response = await base.SendAsync(request, cancellationToken);
             n++;
         }
​
         return response;
     }
 }

使用dotenv.net存储敏感数据

在dotenv.net.dll同一路径下,创建一个.env文件:

在.env文件中存储敏感数据:

模型ID要写SparkDesk,注意不要有空格,试过了有空格会报错。

APIKey就是写之前在OneAPI中复制的令牌。

测试能不能用

测试代码如下:

php 复制代码
 
 // 加载环境变量
 DotEnv.Load();
​
 // 读取环境变量
 var envVars = DotEnv.Read();
​
// Create kernel
 var builder = Kernel.CreateBuilder();
​
 var handler = new OpenAIHttpClientHandler();
​
 builder.AddOpenAIChatCompletion(
     modelId: envVars["ModeId"],
     apiKey: envVars["APIKey"],
     httpClient: new HttpClient(handler));
​
 var kernel = builder.Build();
​
 // Create chat history
 ChatHistory history = [];
​
 // Get chat completion service
 var chatCompletionService = kernel.GetRequiredService<IChatCompletionService>();
​
 // Start the conversation                                                  
     history.AddUserMessage("你是谁?");
​
 // Enable auto function calling
 OpenAIPromptExecutionSettings openAIPromptExecutionSettings = new()
  {
      ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions
   };
​
     // Get the response from the AI
     var result = await chatCompletionService.GetChatMessageContentAsync(
         history,
         executionSettings: openAIPromptExecutionSettings,
         kernel: kernel);
​
     // Print the results
     Console.WriteLine("Assistant > " + result);
​
     // Add the message from the agent to the chat history
     history.AddMessage(result.Role, result.Content);
 }

查看结果:

第一次请求失败,为了解决这个问题,我们加了下面这段代码:

ini 复制代码
  int n = 0;
  while ((int)response.StatusCode == 500 && n < 10)
  {
      response = await base.SendAsync(request, cancellationToken);
      n++;
  }

再请求一遍就成功了。

收到了星火认知大模型的回答。

使用HandyControl构建页面

xaml如下:

ini 复制代码
<Window x:Class="SK_Wpf.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"  
        xmlns:hc="https://handyorg.github.io/handycontrol"
        xmlns:local="clr-namespace:SK_Wpf"    
        mc:Ignorable="d"
        Title="SK_WPF" Height="450" Width="800"
        Loaded="Window_Loaded">
    <StackPanel Margin="32">
        <hc:Row Margin="0,20,0,0">
            <hc:Col Span="11">
                <StackPanel>
                    <Button Style="{StaticResource ButtonPrimary}" Content="问AI" Width="80"
                            Click="Button_Click_1"/>
                    <hc:TextBox x:Name="textBox1"
                                Margin="0,20,0,0"
                                Width="300" Height="200"
                                AcceptsReturn="True"/>
​
                </StackPanel>
            </hc:Col>
            <hc:Col Span="2">
                <Grid >
                    <hc:LoadingCircle x:Name="loading1" 
                                      HorizontalAlignment="Center" 
                                      VerticalAlignment="Center"
                                      Visibility="Hidden"/>
                </Grid>
            </hc:Col>
            <hc:Col Span="11">
                <StackPanel>
                    <hc:Tag ShowCloseButton="False" Content="AI回答"/>
                    <RichTextBox x:Name="richTextBox2"  
                                 VerticalAlignment="Center" 
                                 HorizontalAlignment="Center" 
                                 Margin="0,20,0,0"
                                 Width="300" Height="200">
                    </RichTextBox>
                </StackPanel>
            </hc:Col>
        </hc:Row>
    </StackPanel>
</Window>

实现效果如下:

在WPF中集成SK+OneAPI+星火认知大模型

cs如下:

ini 复制代码
using dotenv.net;
using HandyControl.Controls;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;
using Microsoft.SemanticKernel.Connectors.OpenAI;
using SK_Wpf.Plugins;
using System.Net.Http;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
​
namespace SK_Wpf
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : System.Windows.Window
    {
        IDictionary<string, string>? envVars;      
        Kernel? kernel;
        ChatHistory history = [];
        IChatCompletionService chatCompletionService;
​
        public MainWindow()
        {
            InitializeComponent();
        }
​
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            // 加载环境变量
            DotEnv.Load();
​
            // 读取环境变量
            envVars = DotEnv.Read();
​
​
​
            // Create kernel
            var builder = Kernel.CreateBuilder();
​
            var handler = new OpenAIHttpClientHandler();
​
            builder.AddOpenAIChatCompletion(
                modelId: envVars["ModeId"],
                apiKey: envVars["APIKey"],
                httpClient: new HttpClient(handler));
            builder.Plugins.AddFromType<HelloPlugin>("helloPlugin");
​
            var kernel = builder.Build();
​
            // Get chat completion service
            chatCompletionService = kernel.GetRequiredService<IChatCompletionService>();
​
​
        }
      
        private async void Button_Click_1(object sender, RoutedEventArgs e)
        {
            loading1.Visibility = Visibility.Visible;
​
            string question = textBox1.Text;
          
            // Get user input
            history.AddUserMessage(question);
​
            // Enable auto function calling
            OpenAIPromptExecutionSettings openAIPromptExecutionSettings = new()
            {
                ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions
            };
​
            // Get the response from the AI
            var result = await chatCompletionService.GetChatMessageContentAsync(
                history,
                executionSettings: openAIPromptExecutionSettings,
                kernel: kernel);
​
            // Print the results           
            richTextBox2.AppendText(result.ToString());
​
            // Add the message from the agent to the chat history
            history.AddMessage(result.Role, result.Content);
​
            loading1.Visibility = Visibility.Hidden;
         
        }
    }     
    }

实现效果如下所示:

总结

本文是一次在WPF使用SemanticKernel基于OneAPI集成讯飞星火认知大模型的实践,没有申请OpenAIAPIKey的可以使用讯飞星火认知大模型,现在个人身份认证有送200万token,个人使用可以用很久了。但是效果上肯定和OpenAI还有差别,经过测试,自动本地函数调用,用OpenAI可以用星火认知大模型不行。下期可以写一下两个模型回答的对比。

最后感谢大佬们的分享,见参考。

参考

1、想学Semantic Kernel,没有OpenAI接口该怎么办? (qq.com)

2、实战教学:用Semantic Kernel框架集成腾讯混元大模型应用 (qq.com)

3、Create AI agents with Semantic Kernel | Microsoft Learn

4、songquanpeng/one-api: OpenAI 接口管理 & 分发系统,支持 Azure、Anthropic Claude、Google PaLM 2 & Gemini、智谱 ChatGLM、百度文心一言、讯飞星火认知、阿里通义千问、360 智脑以及腾讯混元,可用于二次分发管理 key,仅单可执行文件,已打包好 Docker 镜像,一键部署,开箱即用. OpenAI key management & redistribution system, using a single API for all LLMs, and features an English UI. (github.com)

5、microsoft/semantic-kernel: Integrate cutting-edge LLM technology quickly and easily into your apps (github.com)

相关推荐
赛男丨木子丿小喵17 分钟前
Gridview配置数据源--信任服务器证书
c#
FL162386312920 分钟前
[C#]C# winform部署yolov11-pose姿态估计onnx模型
开发语言·yolo·c#
无情大菜刀3 小时前
C# 雷赛运动控制器 SMC304 新建工程
c#
IT良11 小时前
c#增删改查 (数据操作的基础)
开发语言·c#
yufei-coder11 小时前
掌握 C# 中的 LINQ(语言集成查询)
windows·vscode·c#·visual studio
59678515416 小时前
DotNetty ChannelRead接收数据为null
tcp/ip·c#
weixin_4640780717 小时前
C#串口温度读取
开发语言·c#
明耀19 小时前
WPF RadioButton 绑定boolean值
c#·wpf
Death20021 小时前
Qt 中的 QListWidget、QTreeWidget 和 QTableWidget:简化的数据展示控件
c语言·开发语言·c++·qt·c#
Death2001 天前
Qt 3D、QtQuick、QtQuick 3D 和 QML 的关系
c语言·c++·qt·3d·c#