初步体验通过 Semantic Kernel 与自己部署的通义千问开源大模型进行对话
春节之前被 Semantic Kernel 所吸引,开始了解它,学习它。
在写这篇博文之前读了一些英文博文,顺便在这里分享一下:
- Intro to Semantic Kernel – Part One
- Intro to Semantic Kernel – Part Two
- Build a custom Copilot experience with your private data using and Kernel Memory
- Semantic Kernel: The New Way to Create Artificial Intelligence Applications
- Semantic Kernel: A bridge between large language models and your code
为了方便学习与体验以及写代码实践 Semantic Kernel,打算自己部署一个对中文友好的开源大模型,于是选择了通义千问
根据通义千问开源仓库中的 README,经过一番折腾,终于部署成功,详见博文 以容器方式部署通义千问 Qwen
紧接着就是尝试通过 Semantic Kernel 与自己部署的通义千问进行对话,在昨天晚上睡觉前初步尝试成功,通过这篇博文记录一下。
主要面临的问题是 Semantic Kernel 与通义千问之间互不支持(内置支持),Semantic Kernel 目前只内置支持 OpenAI 与 Azure OpenAI。幸运的是,通义千问实现了一个四两拔千斤的巧妙能力——提供了兼容 OpenAI api 的 api,于是这个大问题迎刃而解为一个小问题——如何欺骗 Semantic Kernel 让它在请求 OpenAI api 时改道请求自己部署的通义千问模型服务?
在 Semantic Kernel github issue 的一个评论中发现了一个移花接木的巧妙方法——通过 DelegatingHandler 修改 HttpClient 请求的 url。
对应到这里的场景就是修改所请求的 OpenAI api url 中的 scheme 与 host,也就是将 https://api.openai.com 替换为 http://localhost:8901,实现代码如下
class QwenRedirectingHandler() : DelegatingHandler(new HttpClientHandler())
{
protected override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
request.RequestUri = new UriBuilder(request.RequestUri!) { Scheme = "http", Host = "localhost", Port = 8901 }.Uri;
return base.SendAsync(request, cancellationToken);
}
}
移花接木之后本以为初步体验小功告成,却遇到一个小挫折,在用下面的代码发送 prompt 时报错
var prompt = @"博客园是什么网站";
var result = await kernel.InvokePromptAsync(prompt);
Console.WriteLine(result);
错误来自通义千问的响应
{"detail":"Invalid request: Expecting at least one user message."}
后来参考公众号文章利用阿里通义千问和Semantic Kernel,10分钟搭建知识助手中的代码解决了
var prompt = @"<message role=""user"">博客园是什么网站</message>";
var summarize = kernel.CreateFunctionFromPrompt(prompt);
var result = kernel.InvokeStreamingAsync(summarize);
await foreach (var item in result)
{
Console.Write(item.ToString());
}
解决这个问题后,控制台就能看到来自通义千问慢吞吞的吐字回答:
博客园(CNG.cn)是中国最大的IT社区,也是一个专业的程序员学习交流的平台。它提供了一个可以让程序员交流思想、分享经验的环境,并且有多重功能支持用户创建个人博客和参与讨论。
注:这里使用的通义千问模型版本是 Qwen-7B-Chat
到此,初步体验 Semantic Kernel 就小功告成了,下面是完整代码。
using Microsoft.Extensions.DependencyInjection;
using Microsoft.SemanticKernel;
var builder = Kernel.CreateBuilder();
builder.AddOpenAIChatCompletion("gpt-3.5-turbo", "***");
builder.Services.ConfigureHttpClientDefaults(b =>
b.ConfigurePrimaryHttpMessageHandler(() => new QwenRedirectingHandler()));
var kernel = builder.Build();
var prompt = @"<message role=""user"">博客园是什么网站</message>";
var summarize = kernel.CreateFunctionFromPrompt(prompt);
var result = kernel.InvokeStreamingAsync(summarize);
await foreach (var item in result)
{
Console.Write(item.ToString());
}
class QwenRedirectingHandler() : DelegatingHandler(new HttpClientHandler())
{
protected override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
request.RequestUri = new UriBuilder(request.RequestUri!) { Scheme = "http", Host = "localhost", Port = 8901 }.Uri;
return base.SendAsync(request, cancellationToken);
}
}
初步体验通过 Semantic Kernel 与自己部署的通义千问开源大模型进行对话的更多相关文章
- MongoDB3.6之Replica Set初步体验
Replica Set在国内叫做副本集,简单来说就是一份数据在多个地方存储. 1.为什么要用副本集,什么时候使用副本集? 有人说一份数据在多个地方存储占用了大量的额外空间,是一种浪 ...
- Semantic Kernel 知多少 | 开启面向AI编程新篇章
引言 在ChatGPT 火热的当下, 即使没有上手亲自体验,想必也对ChatGPT的强大略有耳闻.当一些人在对ChatGPT犹犹豫豫之时,一些敏锐的企业主和开发者们已经急不可耐的开展基于ChatGPT ...
- mysql connector c++ 1.1 API初步体验
mysql connector c++ 1.1 API初步体验 1,常用的头文件 #include <mysql_connection.h> #include <mysql_driv ...
- Semantic Kernel 入门系列:🛸LLM降临的时代
不论你是否关心,不可否认,AGI的时代即将到来了. 在这个突如其来的时代中,OpenAI的ChatGPT无疑处于浪潮之巅.而在ChatGPT背后,我们不能忽视的是LLM(Large Language ...
- Semantic Kernel 入门系列:🪄LLM的魔法
ChatGPT 只是LLM 的小试牛刀,让人类能够看到的是机器智能对于语言系统的理解和掌握. 如果只是用来闲聊,而且只不过是将OpenAI的接口封装一下,那么市面上所有的ChatGPT的换皮应用都差不 ...
- Semantic Kernel 入门系列:🔥Kernel 内核和🧂Skills 技能
理解了LLM的作用之后,如何才能构造出与LLM相结合的应用程序呢? 首先我们需要把LLM AI的能力和原生代码的能力区分开来,在Semantic Kernel(以下简称SK),LLM的能力称为 sem ...
- Semantic Kernel 入门系列:💬Semantic Function
如果把提示词也算作一种代码的话,那么语义技能所带来的将会是全新编程方式,自然语言编程. 通常情况下一段prompt就可以构成一个Semantic Function,如此这般简单,如果我们提前可以组织好 ...
- Semantic Kernel 入门系列:💾Native Function
语义的归语义,语法的归语法. 基础定义 最基本的Native Function定义只需要在方法上添加 SKFunction 的特性即可. using Microsoft.SemanticKernel. ...
- Semantic Kernel 入门系列:🥑突破提示词的限制
无尽的上下文 LLM的语言理解和掌握能力在知识内容的解读和总结方面提供了强大的能力. 但是由于训练数据本身来自于公共领域,也就注定了无法在一些小众或者私有的领域能够足够的好的应答. 因此如何给LLM ...
- Semantic Kernel 入门系列:🥑Memory内存
了解的运作原理之后,就可以开始使用Semantic Kernel来制作应用了. Semantic Kernel将embedding的功能封装到了Memory中,用来存储上下文信息,就好像电脑的内存一样 ...
随机推荐
- Liunx快捷命令(别名)与快捷方式(软/硬链接)
一.快捷命令(别名)-临时生效1.命令:alias 别名='原命令' 2.举例:给检查防火墙的命令设置别名 [root@localhost ~]# alias fhq='firewall-cmd -- ...
- AMBA总线介绍-02
AMBA总线介绍 1 HSIZE AHB总线的地址位宽和数据位宽一般都是32bit,一个字节8bit,一个字节占用一个地址空间,但当一个32bit的数据写入一个存储器中或者从一个存储器中读取,32bi ...
- Go-值传递&引用传递
值类型和引用类型 值类型关注其值 引用类型关注其指针 值类型和引用类型区别在于传递值的时候拷贝的对象不同,值传递拷贝是变量的值,引用传递拷贝的是变量的指针 拷贝 -- 传递值 赋值 函数调用 初始化 ...
- [转帖]一文深度讲解JVM 内存分析工具 MAT及实践(建议收藏)
https://juejin.cn/post/6911624328472133646 1. 前言 熟练掌握 MAT 是 Java 高手的必备能力,但实践时大家往往需面对众多功能,眼花缭乱不知如何下手, ...
- JVM内存参数的学习之三
JVM内存参数的学习之三 背景 研究启动性能时, 顺便看到了jmap -heap 1 的部分信息 看到: MinHeapFreeRatio.MaxHeapFreeRatio 自己突然以为是 Perce ...
- 【转帖】【漏洞提示】MySQL8.0.29因重大bug官网已下架
前阵子,MySQL官网已经将 MySQL 8.0.29版本下架.据悉下架原因是由于MySQL 8.0.29 存在关于InnoDB解释器的重大Bug.而最新版本 8.0.30及以上的版本已修复此漏洞.各 ...
- [转帖]Python模块winRM
https://www.jianshu.com/p/ac095497bad4 一.介绍 winRM服务是windows server下PowerShell的远程管理服务.Python脚本通过连接win ...
- 批量删除一个月为tag的镜像的办法
第一步获取镜像列表 这是一个最简单的列转行. docker images |grep 20220401 |awk 'BEGIN{ORS=","}{print $1}' 第二步执行双 ...
- pycharm提交代码到gitee
1.在pycharm中下载gitee插件,打开pycharm进入settings页面,查看当前页面version control下是否 有gitee,要是没有点击plugins,在搜索框中搜索gite ...
- node+express+ multer 实现文件上传入门
文件上传 文件上传需要借助一个中间件 multer 因此我们需要安装 cnpm install multer --save 前端界面 在express创建的项目下的 public/upload目录下创 ...