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

本文主要是介绍实战教学:用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」公众号后台回复「大模型」,即可下载本文完整的源代码~

这篇关于实战教学:用Semantic Kernel框架集成腾讯混元大模型应用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/658111

相关文章

SpringBoot中四种AOP实战应用场景及代码实现

《SpringBoot中四种AOP实战应用场景及代码实现》面向切面编程(AOP)是Spring框架的核心功能之一,它通过预编译和运行期动态代理实现程序功能的统一维护,在SpringBoot应用中,AO... 目录引言场景一:日志记录与性能监控业务需求实现方案使用示例扩展:MDC实现请求跟踪场景二:权限控制与

C语言中位操作的实际应用举例

《C语言中位操作的实际应用举例》:本文主要介绍C语言中位操作的实际应用,总结了位操作的使用场景,并指出了需要注意的问题,如可读性、平台依赖性和溢出风险,文中通过代码介绍的非常详细,需要的朋友可以参... 目录1. 嵌入式系统与硬件寄存器操作2. 网络协议解析3. 图像处理与颜色编码4. 高效处理布尔标志集合

Java中的Lambda表达式及其应用小结

《Java中的Lambda表达式及其应用小结》Java中的Lambda表达式是一项极具创新性的特性,它使得Java代码更加简洁和高效,尤其是在集合操作和并行处理方面,:本文主要介绍Java中的La... 目录前言1. 什么是Lambda表达式?2. Lambda表达式的基本语法例子1:最简单的Lambda表

Spring Boot 集成 Quartz并使用Cron 表达式实现定时任务

《SpringBoot集成Quartz并使用Cron表达式实现定时任务》本篇文章介绍了如何在SpringBoot中集成Quartz进行定时任务调度,并通过Cron表达式控制任务... 目录前言1. 添加 Quartz 依赖2. 创建 Quartz 任务3. 配置 Quartz 任务调度4. 启动 Sprin

Python结合PyWebView库打造跨平台桌面应用

《Python结合PyWebView库打造跨平台桌面应用》随着Web技术的发展,将HTML/CSS/JavaScript与Python结合构建桌面应用成为可能,本文将系统讲解如何使用PyWebView... 目录一、技术原理与优势分析1.1 架构原理1.2 核心优势二、开发环境搭建2.1 安装依赖2.2 验

Java字符串操作技巧之语法、示例与应用场景分析

《Java字符串操作技巧之语法、示例与应用场景分析》在Java算法题和日常开发中,字符串处理是必备的核心技能,本文全面梳理Java中字符串的常用操作语法,结合代码示例、应用场景和避坑指南,可快速掌握字... 目录引言1. 基础操作1.1 创建字符串1.2 获取长度1.3 访问字符2. 字符串处理2.1 子字

Python列表去重的4种核心方法与实战指南详解

《Python列表去重的4种核心方法与实战指南详解》在Python开发中,处理列表数据时经常需要去除重复元素,本文将详细介绍4种最实用的列表去重方法,有需要的小伙伴可以根据自己的需要进行选择... 目录方法1:集合(set)去重法(最快速)方法2:顺序遍历法(保持顺序)方法3:副本删除法(原地修改)方法4:

在Spring Boot中浅尝内存泄漏的实战记录

《在SpringBoot中浅尝内存泄漏的实战记录》本文给大家分享在SpringBoot中浅尝内存泄漏的实战记录,结合实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 目录使用静态集合持有对象引用,阻止GC回收关键点:可执行代码:验证:1,运行程序(启动时添加JVM参数限制堆大小):2,访问 htt

SpringBoot集成Milvus实现数据增删改查功能

《SpringBoot集成Milvus实现数据增删改查功能》milvus支持的语言比较多,支持python,Java,Go,node等开发语言,本文主要介绍如何使用Java语言,采用springboo... 目录1、Milvus基本概念2、添加maven依赖3、配置yml文件4、创建MilvusClient

SpringShell命令行之交互式Shell应用开发方式

《SpringShell命令行之交互式Shell应用开发方式》本文将深入探讨SpringShell的核心特性、实现方式及应用场景,帮助开发者掌握这一强大工具,具有很好的参考价值,希望对大家有所帮助,如... 目录引言一、Spring Shell概述二、创建命令类三、命令参数处理四、命令分组与帮助系统五、自定