实战教学:用Semantic Kernel框架集成腾讯混元大模型应用

导语 | 众所周知,Semantic Kernel 主要支持国外的两款大模型,但这对于开发者而言,显然是不够的,尤其是当我们希望对接国内的大模型时,我们应该怎么做呢?如何用 Semantic Kernel 通过 oneapi 来集成腾讯混元大模型应用?今天,我们特邀智用人工智能应用研究院 CTO 张善友老师,他将为我们带来手把手实战教学。

作者简介

张善友,智用人工智能应用研究院 CTO,毕业于兰州大学数学系,专注于云原生开发,推崇开源文化, 使用开源软件构建云原生软件系统,运营微信公众号“dotNet 跨平台”和 "新一代智能应用",推广和普及云原生技术在企业业务开发的应用。 从事 .NET 平台开发 20 年,业余爱好写作,在个人技术博客上撰写了大量的系列技术文章,并在腾讯云开发者社区开设专栏。

引言

腾讯混元大模型(Tencent Hunyuan)是由腾讯研发的大语言模型,具备强大的中文创作能力,复杂语境下的逻辑推理能力,以及可靠的任务执行能力。具体参见:腾讯混元大模型-腾讯云 (http://tencent.com)。

一、Semantic Kernel的功能特性

Semantic Kernel(简称SK)是一个轻量级的 SDK(软件开发工具包),旨在实现人工智能大型语言模型(LLM)与传统编程语言的集成。

这个工具包允许开发者将传统的编程语言与最新的大型语言模型相结合,以创建更智能、更强大的应用程序, SK 目前支持三种主流的编程语言 C#、Python 和 Java,其中 C# 的核心 API 已经发布了 1.0 版本,详见

https://github.com/microsoft/semantic-kernel

Semantic Kernel 提供了以下功能和特性:

● 模板和链接:它提供开箱即用的模板和链接,使开发者能够轻松地将大型语言模型的"提示"(suggestion)整合到其应用程序中。

● 深度集成:Semantic Kernel允许开发者在应用程序中充分利用与 Microsoft 365 Copilot 和 Bing 相同的人工智能协调模式,从而提高应用程序的智能程度。

● 应用程序集成:开发者可以将 Semantic Kernel 用于将语言模型与应用程序的开发技能和积累进行集成,从而增强应用程序的功能。

● 在使用语义内核开发解决方案时,我们可以使用一系列组件来为我们的应用程序提供更好的体验。并非所有这些都是强制性的,但建议熟悉它们。下面列出了符合语义内核的组件:

○ 内核(kernel): 在内核中,我们将注册所有连接器和插件,此外还要配置运行程序所需的内容。此外,我们还可以添加对日志和遥测的支持,以检查程序的状态和性能,并在必要时协助调试。

○ 记忆(memory): 我们来到允许我们为用户问题提供上下文的组件。这意味着我们的插件可以回忆过去与用户的对话,为他们提出的问题提供背景信息。

○ 计划器(planner): 计划器是一个函数,它接受用户的提示并返回执行计划来执行请求。计划器是SK 扩展性最强的一个组件,也是实现 Agent 的关键组件。

○ 连接(connector):连接器在 SK 中起着非常重要的作用,因为它们充当不同组件之间的桥梁,使它们之间能够交换信息。这些连接器可以被开发为与外部系统交互,例如与腾讯混元模型交互或使用 SQLite 数据库作为我们开发的内存。

○ 插件(plugin):插件可以被描述为一组函数,无论是原生的还是语义的,都暴露给 AI 服务和应用程序。

二、手把手配置One-API系统

Semantic kernel 可以支持各种大模型,今天我们就来看一看如何把 SK 和腾讯混元大模型集成起来。我们使用 MIT 协议的开源项目“one-api”:以 OpenAI 接口管理&分发系统,支持现有大模型场景,可用于二次分发管理 key,仅单可执行文件,已打包好 Docker 镜像,一键部署,开箱即用,

https://github.com/songquanpeng/one-api

简单而言,我们使用 Semantic kernel 的 OpenAI connector 连接到 oneapi,这样就可以使用 OpenAI 的接口访问腾讯混元大模型。

OneAPI 支持使用 docker 部署,操作简单,fork one-api 仓库,使用仓库里提供的 docker-compose.yml 搭建就很简单。具体命令如下:docker-compose up -d

等待应用启动完成后,在浏览器中输入 IP+端口,例如:

http://192.168.10.12:3000

,系统本身是开箱即用,直接使用默认的 root 用户登录系统即可。初始账号用户名为 root,密码为 123456。在登录系统后,我们需要立刻到用户管理中将密码修改成其它的。

而渠道则可以简单理解为各个大模型厂商,可以是原始厂商,也支持代理厂商,每家厂商又可以支持多种模型,点击渠道,然后点击添加新的渠道。

类型:选择 腾讯混元,会自动带出下面的模型:hunyuan

名称:自己自拟名字即可,一个代号

分组:模型分组使用,支持多选。目前仅支持内置的 3 种分组,分别是:default、vip、svip

模型:选完类型后会自动弹出来,支持多选,也支持自己填写

模型重定向:假如用户传入的模型是 A,系统可以自动改成 B

密钥:从大模型厂商获得的 API Key,每家厂商的填写格式可能都不一样,选完类型以后会有提示,按照提示填写,填写密钥为腾讯云的密钥管理— API 密钥管理里获取 APPID、SecretId 和 Secretkey

接着,我们创建令牌,供客户端或调用方使用,其作用跟大模型厂商的令牌或密钥的概念和作用是一样的。点击令牌,然后点击添加新的令牌,如图添加即可,过期时间可以选择永不过期。

如图,然后点击复制即可:

这个令牌相当于 OpenAI 的 apikey:

sk-1Ib4X0HmR4HzXXZ644D1DdCa96934f0199Dc2b0e162b524d

日志展示用户充值和额度消耗记录,普通用户与管理员用户查看的范围不一样,普通用户只能看到自己的。

以上我们便已经安装并配置好了 One API 系统,那么如何给终端使用呢?其实很简单,使用客户端或编程的方式调用 One API 的 API 接口就行了,使用方式与OpenAI API 一致。相当于只需要将 OpenAI 的网址改成你部署的 One API 系统的网址、将 OpenAI 的 API Key 改成你的令牌即可。One API 将代理用户向实际的大模型发出请求并接收响应,如下图所示:

另外需要特殊说明下,前面我们提到每个用户分组是可以支持多个渠道的(即多个模型负载均衡),如果你在客户端想指定使用某个渠道,可以通过在令牌后面添加渠道 ID 的方式指定使用哪一个渠道处理本次请求,例如:Authorization: Bearer ONE_API_KEY-CHANNEL_ID。 注意,需要是管理员用户创建的令牌才能指定渠道ID。

三、SK+one-api+openai connector集成腾讯混元大模型

通过 oneapi 我们将腾讯混元大模型转换为 OpenAI 的格式,通过 SK 的 OpenAI 的 Connector 访问,这里需要做的是把 openai 的 Endpoint 指向 oneapi,这个我们可以通过一个自定义的 HttpClient 来完成这项工作,例如下面的这个示例:

internal class OpenAIHttpclientHandler : HttpClientHandler
{private  KernelSettings _kernelSettings;public OpenAIHttpclientHandler(KernelSettings settings){this._kernelSettings = settings;}protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken){if (request.RequestUri.LocalPath == "/v1/chat/completions"){UriBuilder uriBuilder = new UriBuilder(request.RequestUri){Scheme = this._kernelSettings.Scheme,Host = this._kernelSettings.Host,Port = this._kernelSettings.Port};request.RequestUri = uriBuilder.Uri;}return await base.SendAsync(request, cancellationToken);}
}

上面我们做好了所有的准备工作,接下来就是要把所有的组件组装起来,让它们协同工作。因此打开 Visual studio code 创建一个 c# 项目 sk-csharp-hello-world,其中 Program.cs 内容如下:

using System.Reflection;
using config;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;
using Microsoft.SemanticKernel.Connectors.OpenAI;
using Microsoft.SemanticKernel.PromptTemplates.Handlebars;
using Plugins;var kernelSettings = KernelSettings.LoadSettings();
var handler = new OpenAIHttpclientHandler(kernelSettings);
IKernelBuilder builder = Kernel.CreateBuilder();
builder.Services.AddLogging(c => c.SetMinimumLevel(LogLevel.Information).AddDebug());
builder.AddChatCompletionService(kernelSettings,handler);
builder.Plugins.AddFromType<LightPlugin>();Kernel kernel = builder.Build();// Load prompt from resource
using StreamReader reader = new(Assembly.GetExecutingAssembly().GetManifestResourceStream("prompts.Chat.yaml")!);
KernelFunction prompt = kernel.CreateFunctionFromPromptYaml(reader.ReadToEnd(),promptTemplateFactory: new HandlebarsPromptTemplateFactory()
);// Create the chat history
ChatHistory chatMessages = [];// Loop till we are cancelled
while (true)
{// Get user inputSystem.Console.Write("User > ");chatMessages.AddUserMessage(Console.ReadLine()!);// Get the chat completionsOpenAIPromptExecutionSettings openAIPromptExecutionSettings = new(){};var result = kernel.InvokeStreamingAsync<StreamingChatMessageContent>(prompt,arguments: new KernelArguments(openAIPromptExecutionSettings) {{ "messages", chatMessages }});// Print the chat completionsChatMessageContent? chatMessageContent = null;await foreach (var content in result){System.Console.Write(content);if (chatMessageContent == null){System.Console.Write("Assistant > ");chatMessageContent = new ChatMessageContent(content.Role ?? AuthorRole.Assistant,content.ModelId!,content.Content!,content.InnerContent,content.Encoding,content.Metadata);}else{chatMessageContent.Content += content;}}System.Console.WriteLine();chatMessages.Add(chatMessageContent!);
}

首先,我们做的第一件事是导入一堆必要的命名空间,使一切正常(第 1 行到第 9 行)。

然后,我们创建一个内核构建器的实例(通过模式,而不是因为它是构造函数),这将有助于塑造我们的内核。

IKernelBuilder builder = Kernel.CreateBuilder();

你需要知道每时每刻都在发生什么吗?答案是肯定的!让我们在内核中添加一个日志。我们在第 14 行添加了日志的支持。

我们想使用 Azure,OpenAI 中使用 Microsoft 的 AI 模型,以及我们腾讯混元的 AI 模型,我们可以将它们包含在我们的内核中。正如我们在 15 行看到的那样:

   /// <summary>/// Adds a chat completion service to the list. It can be either an OpenAI、 Azure OpenAI or tencent hunyuan backend service ./// </summary>/// <param name="kernelBuilder"></param>/// <param name="kernelSettings"></param>/// <exception cref="ArgumentException"></exception>internal static IKernelBuilder AddChatCompletionService(this IKernelBuilder kernelBuilder, KernelSettings kernelSettings, HttpClientHandler handler){switch (kernelSettings.ServiceType.ToUpperInvariant()){case ServiceTypes.AzureOpenAI:kernelBuilder = kernelBuilder.AddAzureOpenAIChatCompletion(kernelSettings.DeploymentId,  endpoint: kernelSettings.Endpoint, apiKey: kernelSettings.ApiKey, serviceId: kernelSettings.ServiceId, kernelSettings.ModelId);break;case ServiceTypes.OpenAI:kernelBuilder = kernelBuilder.AddOpenAIChatCompletion(modelId: kernelSettings.ModelId, apiKey: kernelSettings.ApiKey, orgId: kernelSettings.OrgId, serviceId: kernelSettings.ServiceId);break;case ServiceTypes.HunyuanAI:                kernelBuilder = kernelBuilder.AddOpenAIChatCompletion(modelId: kernelSettings.ModelId, apiKey: kernelSettings.ApiKey, httpClient: new HttpClient(handler));break;default:throw new ArgumentException($"Invalid service type value: {kernelSettings.ServiceType}");}return kernelBuilder;}
}

我们可以为内核中导入在不同模型后端使用的插件,如第 16 行所示。为此,我们导入第 21 行到第 25 行中的语义函数。我们所做的是传递 yaml 文件编写的语义提示词。之后我们的内核和我们的插件就可以使用了。

接下来开启一个聊天循环,使用 SK 的流式传输 InvokeStreamingAsync,如第 42 行到 46 行代码所示,运行起来就可以体验下列的效果:

结语

有了 Semantic kernel 这个新框架,无论我们是在桌面上使用 AvaloniaUI 构建应用,还是在服务器上使用 http://ASP.NET Core 构建后端服务,都为未来将人工智能集成到我们的开发中奠定了基础。也许最重要的是,我们更应该关注使用其公司数据将新的人工智能服务集成到其应用程序中,并始终确保该数据的隐私合规性。

在「腾讯云TVP」公众号后台回复「大模型」,即可下载本文完整的源代码~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/437828.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何对Microsoft 365中Loop文档进行权限划分

Microsoft 365中Loop文档的权限划分为两种&#xff1a;第一种是共享创意页面。第二种是共享特定的Loop组件。 共享创意页面。 进入创意页面后&#xff0c;点击右上角的“共享”-“页面链接”。 如上图所示&#xff0c;页面共享分三种类型。以“你选择的人”为例。添加要共享的…

iOS 文件分割保存加密

demo只是验证想法&#xff0c;没有做很多异常处理 默认文件是大于1KB的&#xff0c;对于小于1KB的没有做异常处理demo中文件只能分割成2个&#xff0c;可以做成可配置的N个文件分割拼接还可以使用固定的二进制数据&#xff0c;拼接文件开头或结尾 不论哪种拼法&#xff0c;目的…

防御保护--NAT策略

目录 NAT策略 NAT类型 server-map表 P2P --- peer to peer 网络类型 ​编辑 目标NAT--服务器映射 双向NAT ​编辑 多出口NAT NAT策略 静态NAT --- 一对一 动态NAT --- 多对多 NAPT --- 一对多的NAPT --- easy ip --- 多对多NAPT 服务器映射 源NAT--基于源IP地址进行转…

GIS应用水平考试一级—2009 年度第二次

全国信息化工程师——GIS应用水平考试 2009 年度第二次全国统一考试一级 试卷说明: 1、本试卷共9页,6个大题,满分150 分,150 分钟完卷。 2、考试方式为闭卷考试。 3、将第一、二、三題的答案用铅笔涂写到(NCIE-GIS)答题卡上。 4、将第四、五、六题的答案填写到主观题答题卡上…

《HTML 简易速速上手小册》第1章:HTML 入门(2024 最新版)

文章目录 1.1 HTML 简介与历史&#xff08;&#x1f609;&#x1f310;&#x1f47d;踏上神奇的网页编程之旅&#xff09;1.1.1 从过去到现在的华丽蜕变1.1.2 市场需求 —— HTML的黄金时代1.1.3 企业中的实际应用 —— 不只是个网页1.1.4 职业前景 —— 未来属于你 1.2 基本 H…

千川投流怎么涨粉的?巨量千川粉丝是怎么投流的呢?

在当今数字时代&#xff0c;流量已经成为了一个品牌或产品成功与否的关键因素。因此&#xff0c;千川投流作为一种有效的涨粉引流推广方法&#xff0c;已经成为了许多品牌和产品的首选。本文将向您详细介绍千川投流涨粉引流推广方法&#xff0c;帮助您实现粉丝数量的暴涨目标。…

数据可视化工具JSON Crack结合内网穿透实现公网访问

文章目录 1. 在Linux上使用Docker安装JSONCrack2. 安装Cpolar内网穿透工具3. 配置JSON Crack界面公网地址4. 远程访问 JSONCrack 界面5. 固定 JSONCrack公网地址 JSON Crack 是一款免费的开源数据可视化应用程序&#xff0c;能够将 JSON、YAML、XML、CSV 等数据格式可视化为交互…

Zerosync:构建基于STARK的Bitcoin证明系统

1. 引言 前序博客&#xff1a; BitcoinSTARK: ZeroSync & Khepri Robin Linus、Tino Steffens、Lukas George 等人成立了一个名为 ZeroSync 协会&#xff08;ZeroSync Association&#xff09;的瑞士非营利组织&#xff0c;该组织将牵头开发比特币证明系统。ZeroSync 于…

智慧文旅:重塑旅游业的商业模式与未来

随着科技的飞速发展和消费者需求的不断演变&#xff0c;旅游业正经历着前所未有的变革。智慧文旅&#xff0c;作为这场变革的核心驱动力&#xff0c;正在逐步重塑旅游业的商业模式和未来。本文将深入探讨智慧文旅如何改变传统旅游业的格局&#xff0c;并展望其未来的发展趋势。…

pytest的内置插件盘点7:python

本文系《pytest源码剖析》系列内容 正在连载&#xff0c;欢迎关注 7. 内置插件 python 插件路径&#xff1a;_pytest.python 实现的 hook hooktryfirsttrylastoptionalhookhookwrapperwrapperpytest_addoptionFalseFalseFalseFalseFalsepytest_cmdline_mainFalseFalseFalseFal…

SQL注入:二次注入

SQL注入系列文章&#xff1a; 初识SQL注入-CSDN博客 SQL注入&#xff1a;联合查询的三个绕过技巧-CSDN博客 SQL注入&#xff1a;报错注入-CSDN博客 SQL注入&#xff1a;盲注-CSDN博客 目录 什么是二次注入&#xff1f; 二次注入演示 1、可以注册新用户 2、可以登录->…

【算法与数据结构】139、LeetCode单词拆分

文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析&#xff1a;本题可以看做一个动态规划问题。其中&#xff0c;字符串s是背包&#xff0c;而字典中的单词就是物品。…