记一次WPF集成SemanticKernel+OneAPI+讯飞星火认知大模型实践_semantickernel oneapi-程序员宅基地

技术标签: c#  gpt  wpf  

记一次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.

项目地址:https://github.com/songquanpeng/one-api

image-20240227105438373

使用OneAPI

基于docker部署:

# 使用 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端口,如下所示:

image-20240227110126395

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

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

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

image-20240227112714344

填入自己的大模型密钥。

添加令牌:

image-20240227112824812

测试OneAPI服务是否可用

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

image-20240227113413504

注意事项

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

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

在请求中加入令牌

image-20240227113639334

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

测试的json

{
    
    "model":"SparkDesk",
    "messages":[
        {
    
            "role":"user",
            "content":"你是谁"
        }
    ],
      "temperature":0.7    
}

星火大模型的响应

{
    
    "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 代码与这些模型相结合,可以生成用于回答问题和自动执行流程的代理。

image-20240227141312234

安装SemanticKernel

image-20240227141440713

在SemanticKernel中使用星火大模型

创建一个OpenAIHttpClientHandler类

OpenAIHttpClientHandler类代码:

 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文件:

image-20240227153748317

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

image-20240227154101538

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

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

测试能不能用

测试代码如下:

 
 // 加载环境变量
 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);
 }

查看结果:

image-20240227154656502

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

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

image-20240227154922453

再请求一遍就成功了。

image-20240227155010554

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

使用HandyControl构建页面

xaml如下:

<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>

实现效果如下:

image-20240227181715497

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

cs如下:

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可以用星火认知大模型不行。下期可以写一下两个模型回答的对比。

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

推荐阅读

gpt-3.5-turbo与星火认知大模型v3.5回答对比 (qq.com)

参考

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

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

3、Create AI agents with Semantic Kernel | Microsoft Learn

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

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/mingupup/article/details/136370168

智能推荐

c# 调用c++ lib静态库_c#调用lib-程序员宅基地

文章浏览阅读2w次,点赞7次,收藏51次。四个步骤1.创建C++ Win32项目动态库dll 2.在Win32项目动态库中添加 外部依赖项 lib头文件和lib库3.导出C接口4.c#调用c++动态库开始你的表演...①创建一个空白的解决方案,在解决方案中添加 Visual C++ , Win32 项目空白解决方案的创建:添加Visual C++ , Win32 项目这......_c#调用lib

deepin/ubuntu安装苹方字体-程序员宅基地

文章浏览阅读4.6k次。苹方字体是苹果系统上的黑体,挺好看的。注重颜值的网站都会使用,例如知乎:font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, PingFang SC, Microsoft YaHei, Source Han Sans SC, Noto Sans CJK SC, W..._ubuntu pingfang

html表单常见操作汇总_html表单的处理程序有那些-程序员宅基地

文章浏览阅读159次。表单表单概述表单标签表单域按钮控件demo表单标签表单标签基本语法结构<form action="处理数据程序的url地址“ method=”get|post“ name="表单名称”></form><!--action,当提交表单时,向何处发送表单中的数据,地址可以是相对地址也可以是绝对地址--><!--method将表单中的数据传送给服务器处理,get方式直接显示在url地址中,数据可以被缓存,且长度有限制;而post方式数据隐藏传输,_html表单的处理程序有那些

PHP设置谷歌验证器(Google Authenticator)实现操作二步验证_php otp 验证器-程序员宅基地

文章浏览阅读1.2k次。使用说明:开启Google的登陆二步验证(即Google Authenticator服务)后用户登陆时需要输入额外由手机客户端生成的一次性密码。实现Google Authenticator功能需要服务器端和客户端的支持。服务器端负责密钥的生成、验证一次性密码是否正确。客户端记录密钥后生成一次性密码。下载谷歌验证类库文件放到项目合适位置(我这边放在项目Vender下面)https://github.com/PHPGangsta/GoogleAuthenticatorPHP代码示例://引入谷_php otp 验证器

【Python】matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距-程序员宅基地

文章浏览阅读4.3k次,点赞5次,收藏11次。matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距

docker — 容器存储_docker 保存容器-程序员宅基地

文章浏览阅读2.2k次。①Storage driver 处理各镜像层及容器层的处理细节,实现了多层数据的堆叠,为用户 提供了多层数据合并后的统一视图②所有 Storage driver 都使用可堆叠图像层和写时复制(CoW)策略③docker info 命令可查看当系统上的 storage driver主要用于测试目的,不建议用于生成环境。_docker 保存容器

随便推点

网络拓扑结构_网络拓扑csdn-程序员宅基地

文章浏览阅读834次,点赞27次,收藏13次。网络拓扑结构是指计算机网络中各组件(如计算机、服务器、打印机、路由器、交换机等设备)及其连接线路在物理布局或逻辑构型上的排列形式。这种布局不仅描述了设备间的实际物理连接方式,也决定了数据在网络中流动的路径和方式。不同的网络拓扑结构影响着网络的性能、可靠性、可扩展性及管理维护的难易程度。_网络拓扑csdn

JS重写Date函数,兼容IOS系统_date.prototype 将所有 ios-程序员宅基地

文章浏览阅读1.8k次,点赞5次,收藏8次。IOS系统Date的坑要创建一个指定时间的new Date对象时,通常的做法是:new Date("2020-09-21 11:11:00")这行代码在 PC 端和安卓端都是正常的,而在 iOS 端则会提示 Invalid Date 无效日期。在IOS年月日中间的横岗许换成斜杠,也就是new Date("2020/09/21 11:11:00")通常为了兼容IOS的这个坑,需要做一些额外的特殊处理,笔者在开发的时候经常会忘了兼容IOS系统。所以就想试着重写Date函数,一劳永逸,避免每次ne_date.prototype 将所有 ios

如何将EXCEL表导入plsql数据库中-程序员宅基地

文章浏览阅读5.3k次。方法一:用PLSQL Developer工具。 1 在PLSQL Developer的sql window里输入select * from test for update; 2 按F8执行 3 打开锁, 再按一下加号. 鼠标点到第一列的列头,使全列成选中状态,然后粘贴,最后commit提交即可。(前提..._excel导入pl/sql

Git常用命令速查手册-程序员宅基地

文章浏览阅读83次。Git常用命令速查手册1、初始化仓库git init2、将文件添加到仓库git add 文件名 # 将工作区的某个文件添加到暂存区 git add -u # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,不处理untracked的文件git add -A # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,包括untracked的文件...

分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120-程序员宅基地

文章浏览阅读202次。分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120

【C++缺省函数】 空类默认产生的6个类成员函数_空类默认产生哪些类成员函数-程序员宅基地

文章浏览阅读1.8k次。版权声明:转载请注明出处 http://blog.csdn.net/irean_lau。目录(?)[+]1、缺省构造函数。2、缺省拷贝构造函数。3、 缺省析构函数。4、缺省赋值运算符。5、缺省取址运算符。6、 缺省取址运算符 const。[cpp] view plain copy_空类默认产生哪些类成员函数

推荐文章

热门文章

相关标签