Semantic Kernel:架起大型语言模型与代码的桥梁
译者 | 布加迪
审校 | 重楼
51CTO读者成长计划社群招募,咨询小助手(微信号:CTOjishuzhan)
微软的Semantic Kernel SDK让用户更容易管理复杂的提示,并从GPT之类的大型语言模型获得精准的结果。
乍一看,把GPT-4之类的大型语言模型(LLM)做入到代码中似乎很简单。API是单一的REST调用,获取文本后基于输入返回响应,但实际情况比这要复杂得多。将API视为域边界(domain boundary)可能更好,您在其中交付的提示定义了模型用于生成输出的格式。但这里有一个关键点:LLM可以很简单或很复杂,取决于您想让它多简单或多复杂。
当我们将AI模型做入到代码中时,其实跨越了两种不同计算方式之间的界限,就像为量子计算机编程酷似设计硬件一样。在这里,我们描述了模型应该有怎样的行为,期望它的输出采用由提示定义的格式。在量子计算中,像Q#语言这样的构件提供了一座架起传统计算和量子计算的机梁,我们需要工具来包装LLM API,并提供管理输入和输出的方法,以确保模型始终专注于我们已定义的提示,并确保输出依然准确。
这是需要强调的重要一点:我们与LLM的互动方式与传统编程大不相同。我们需要的是Q#对等体,即在不同域之间转换的高级抽象,从而帮助我们获取数据后用数据来设计提示,同时提供一种方法来管理调用之间的必要上下文,以免耗尽会话中的可用token,同时仍保持输出基于源数据。
1、Semantic Kernel介绍
几周前,我研究了微软的第一个LLM包装器:开源的Prompt Engine。此后,微软发布了一个更庞大更强大的C#工具:Semantic Kernel,用于处理Azure OpenAI(以及处理OpenAI自己的API)。它也是开源的,可以在GitHub上获得,还有一些示例应用程序可以帮助您入手。Python版本的Semantic Kernel也在开发中。
这个名字的选择饶有意思,因为它表明对LLM的用途有一番更好的理解。Prompt Engine侧重于管理API的输入,而Semantic Kernel的范围更广,专注于自然语言的输入和输出。微软将其方法描述为“面向目标”,使用来自用户的初始请求(“ask”)来指导模型,协调与模型相关的资源的传递以实现请求,并返回请求响应(“get”)。
所以称Semantic Kernel为内核有其道理。它就像LLM API的操作系统,接受输入,通过使用模型来处理输入,然后返回输出。内核充当协调器的角色是这里的关键,因为它不仅能够处理当前提示及其关联的token,还能够处理记忆(键值对、本地存储以及矢量或“语义”搜索)、通向其他信息服务的连接器以及混合提示和传统代码的预定义技能(想想LLM函数)。
Semantic Kernel工具提供了更有效的方法来构建和使用包装Prompt Engine所需的构件类型,从而简化了可能变得相当复杂的编程任务,尤其是在处理上下文、支持含有LLM API多个调用的操作时。
2、矢量和语义记忆
处理用户请求的一个关键要素是记忆这个概念。这是Semantic Kernel管理上下文的方式,处理熟悉的文件和键值存储。然而,还有第三种选择:语义记忆(semantic memory)。这种方法接近于LLM处理数据的方式,将内容视为矢量或嵌入,它们是LLM用来表示文本含义的数字数组。相似的文本在与您的模型及其内容相关的整体空间中会有相似的矢量,就像搜索引擎生成排序结果的方式一样。
像GPT这样的LLM使用这些嵌入的矢量来提取提示的上下文,帮助底层模型保持相关性和一致性。嵌入越好,模型生成纯随机输出的可能性就越小。通过将大型提示分解为可由LLM总结的文本块,我们就可以为每个摘要生成嵌入矢量,然后使用这些矢量创建复杂的提示,而不用耗尽请求的可用token(比如GPT-4对每个输入的token限制为8192个)。
这些数据可以存储在矢量数据库中,以便快速检索。可以为专业知识创建特定的矢量数据库,使用总结的内容来帮助LLM处于正轨。因此比如说,使用GPT-4进行病例笔记摘要的应用程序可以使用矢量数据库(其嵌入来自医学论文、适当的匿名笔记及其他相关文本),以确保输出具有连贯性、符合上下文。这种方法在某种程度上解释了为什么微软的第一个基于GPT的大型应用程序是Bing搜索引擎,因为它已经拥有适当的可供使用的矢量数据库。
3、连接到外部数据源
连接器是Semantic Kernel的一个有意思的特性,因为它们可以将现有API与LLM集成起来。比如说,您可以使用微软Graph连接器在电子邮件中自动发送请求的输出,或者在贵组织结构图中构建关系描述。Semantic Kernel应用程序中没有设置点来进行调用,它可能是输入的一部分,也可能是输出的一部分,甚至是LLM调用序列的一部分。您可以利用API调用来构建提示,这些提示本身构建进一步的API调用,可能是通过使用基于Codex代码的模型将结果输出注入到运行时环境中。
连接器的一个更有趣的特性是,它对LLM运用某种基于角色的访问控制。如果您使用微软Graph查询来构建提示,那么这些查询将在运行该应用程序的用户上下文中,使用凭据来提供数据。将凭据传递给连接器可以确保基于用户自己的数据为用户量身定制输出。
4、构建混合提示模板和代码的技能
Semantic Kernel的第三个主要组件是技能(skills),它们是混合LLM提示和常规代码的函数容器。这些函数在概念和操作上类似Azure Functions,可用于将专门的提示串联起来。应用程序可以有一组使用GPT生成文本的函数,然后使用该文本作为Codex和DALL-E的提示,以便由描述变成原型Web应用程序(类似自然语言编程工具在微软的低代码和无代码Power Platform中的工作方式)。
一旦技能、记忆和连接器落实到位,您就可以开始构建基于LLM的应用程序了,使用技能将请求转换成提供给底层模型的提示。这种方法让您可以构建灵活的技能,代码可以根据需要选择和使用这些技能。Semantic Kernel区分语义函数、模板提示和原生函数,即处理用于LLM语义函数中的数据的原生计算机代码。一个函数的输出可以链接到另一个函数,允许您构建一条混合原生处理和LLM操作的函数管道。
通过对Semantic Kernel的这番简单介绍,我们可以清楚地看到这是一个强大的工具,但是需要认真考虑和规划。您可以使用Semantic Kernel来构建和管理复杂的提示以及处理输入和输出链的管道,以便提供有趣又有用的结果。很自然,当您适当地使用每个要素时,将获得最好的结果,原生代码负责处理计算,而模型专注于引导的目标(或者微软文档中所称的“the asks”)。
使用Semantic Kernel之类的工具来编排和协调输入和函数,肯定会比仅仅向输入传递提示更有效地使用LLM。它将允许您净化输入,引导LLM生成有用的输出。为了帮助您入门,微软提供了一份最佳实践指南列表(《语义AI的Shillace定律》),这些最佳实践是从构建跨微软业务的LLM应用程序中汇总而来的。它们可帮助您了解如何围绕GPT之类的LLM构建代码,这样可以帮助您从这些新工具和技术中获得尽可能多的价值,同时避免不切实际的期望。
原文链接:https://www.infoworld.com/article/3693310/semantic-kernel-a-bridge-between-large-language-models-and-your-code.html