• 记一次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 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();
    
     // 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如下:

    
        
            
                
                    
                        

    实现效果如下:

    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
    {
        /// 
        /// Interaction logic for MainWindow.xaml
        /// 
        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");
    
                var kernel = builder.Build();
    
                // Get chat completion service
                chatCompletionService = kernel.GetRequiredService();
    
    
            }
          
            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可以用星火认知大模型不行。下期可以写一下两个模型回答的对比。

    image-20240228122947902

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

    参考

    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)

  • 相关阅读:
    【分类网络】GoogLeNet
    【LeetCode】2511.最多可以摧毁的敌人城堡数目
    npm 常用的命令
    浅析数据采集工具Flume
    Git基础命令+Gitee代码托管平台学习
    Django的模板系统(一)
    [python 刷题] 19 Remove Nth Node From End of List
    Java面试时,该如何准备亮点?
    Maven 聚合工程的创建
    使用github创建个人页面,以及git的两种使用方式
  • 原文地址:https://www.cnblogs.com/mingupupu/p/18040008