什么是Semantic Kernel?
Semantic Kernel是一个开源SDK,可以轻松地将OpenAI和Hugging Face等人工智能服务与C#和Python等编程语言相结合。通过这样做,可以创建将两个世界的优点结合在一起的人工智能应用程序。
在Kevin Scott的演讲《AI Copilot的时代》中,他展示了微软如何用模型和插件为其Copilot系统提供能量。这个堆栈的中心是一个人工智能编排层,人工智能模型和插件结合在一起,为用户创造全新的体验。
为了帮助开发人员在AI插件之上构建自己的Copilot体验,微软发布了Semantic Kernel,允许编排AI插件。使用Semantic Kernel,可以在应用程序中利用与Microsoft 365 Copilot和Bing相同的人工智能编排模式。
Semantic Kernel提供了一组连接器便于添加存储和模型,能够在你的应用程序中添加一个模拟的“大脑”。
Semantic Kernel可以通过AI插件轻松地将技能添加到应用程序中,与现实世界进行交互。这些插件由提示和本机函数组成,它们可以响应触发器并执行操作。通过这种方式,插件就像人工智能应用程序的“身体”。
基于连接器和插件的可扩展性,可以使用它在几乎任何模型的基础上协调OpenAI和Microsoft的AI插件。例如,可以使用在OpenAI的模型之上,为ChatGPT、Bing和Microsoft 365 Copilot构建插件。
Semantic kernel 的 基本原理
和Langchain类似, Semantic Kernel 同样使用流水线的形式提供AI 编排。
典型流程如下:
1 询问:从用户或开发人员发送到Semantic Kernel的目标开始。
2 内核:内核运行一个由开发人员定义的管道/链。当链运行时,内核提供了一个公共上下文,以便在函数之间共享数据。
2.1 记忆:通过一个专门的插件,开发人员可以在向量数据库中调用和存储上下文。
2.2 规划器:开发人员可以要求Semantic Kernel自动创建链,以满足用户的新需求。Planner通过混合和匹配插件来实现这一点,这些插件已经加载到内核中,以创建额外的步骤。
2.3连接器:为了获得额外的数据或执行自主操作,可以使用开箱即用的插件,或创建 自定义连接器,为自己的服务提供数据。
2.4自定义插件:可以创建在Semantic Kernel内部运行的自定义插件。这些插件可以由LLM的语义函数或本机C#或Python代码的原生函数组成,将您现有的应用程序和服务集成到Semantic Kernel中。
3 响应:内核流水线执行完成后,将响应发送回用户。
与操作系统内核类似,Semantic Kernel 负责管理在人工智能应用程序中运行“代码”所需的资源。这包括管理本地代码和AI服务一起运行所需的配置、服务和插件,一般的使用方式如下:
- 配置本地计算机以运行语义内核
- 从内核运行AI提示
- 使用变量使AI提示动态
- 创建一个简单的AI代理
- 与规划者自动组合功能
- 使用嵌入存储和检索内存
Semantic Kernel 的应用场景
虽然是Semantic Kernel 官方文档给出的应用场景, 但实际上这些也是大模型AI应用的一般用途:
- 聊天和会话创建:用户可以创建一个会话代理,该代理使用从可信文档(如公司内部文档或技术支持文档)中提取的响应进行响应;对话必须限于回答范围内的问题。
- 代码生成或转换场景:例如,将一种编程语言转换为另一种,为函数生成文档字符串,将自然语言转换为SQL。
- 新闻内容:用于创建新的新闻内容或重写用户提交的新闻内容,作为预定义主题的写作辅助。用户不能将该应用程序用作所有主题的常规内容创建工具。不得用于生成政治竞选内容。
- 问答:用户可以从可信的源文档(如公司内部文档)中提问并获得答案。该应用程序不会在受信任的源文档中生成未建立基础的答案。
- 结构化和非结构化数据的处理:用户可以使用分类、文本情感分析或实体提取来分析输入。例如分析产品反馈情绪,分析支持电话和记录,以及使用嵌入改进基于文本的搜索。
- 搜索:用户可以搜索可信的源文档,如公司内部文档。该应用程序不会生成在可信源文档中未建立基础的结果。
- 摘要:用户可以为应用程序中内置的预定义主题提交要摘要的内容,并且不能将应用程序用作开放式摘要程序。示例包括公司内部文档摘要、呼叫中心记录、技术报告和产品评论。
- 特定主题的写作辅助:用户可以创建新内容或重写用户提交的内容,作为业务内容或预定义主题的写作帮助。用户只能为特定业务目的或预定义主题重写或创建内容,不能将应用程序用作所有主题的通用内容创建工具。业务内容的示例包括提案和报告。
AI 插件(plug-in)
插件是一组可以暴露在人工智能应用程序和服务中的功能。AI应用程序可以将插件中的功能编排为用户请求。在 Semantic Kernel 中,可以手动调用这些插件的函数,也可以使用计划器自动调用。
然而,仅仅提供功能是不足以制作插件的。为了使用计划器实现自动编排,插件还需要提供语义描述其行为的详细信息。从功能的输入、输出到副作用,一切都需要以人工智能能够理解的方式进行描述,否则,规划器将提供意想不到的结果。
AI插件中的函数包括两种:语义函数和原生函数。原生函数完成传统的软件功能,例如
- 从外部数据源检索数据
- 知道现在的时间
- 执行复杂数学运算
- 在现实世界中完成任务
- 记忆和回忆信息
- ......
语义函数是 Semantic Kernel 的核心技术之一, 强调了对函数的语义化描述,例如:
代码语言:javascript复制{
"schema": 1,
"type": "completion",
"description": "Summarize given text or any text document",
"completion": {
"max_tokens": 512,
"temperature": 0.0,
"top_p": 0.0,
"presence_penalty": 0.0,
"frequency_penalty": 0.0
},
"input": {
"parameters": [
{
"name": "input",
"description": "Text to summarize",
"defaultValue": ""
}
]
} }
这些描述字段都是规划器的输入,因此提供详细而简洁的描述非常重要,这样计划器才可以在编排功能时做出最佳决策。
这些语义函数同样可以支持Prompt template ,在语义化描述中进行表达:
代码语言:javascript复制"input": {
"parameters": [
{
"name": "input",
"description": "The user's request.",
"defaultValue": ""
},
{
"name": "history",
"description": "The history of the conversation.",
"defaultValue": ""
},
{
"name": "options",
"description": "The options to choose from.",
"defaultValue": ""
}
]
}
模板语言设计为简单快速的呈现,允许使用简单的文本编辑器创建函数,使用自然语言,将特殊语法减少到最低限度,并最大限度地减少边缘情况。模板语言有意使用«$»符号,以明确区分检索执行某些代码的内容的函数调用和用本地临时内存中的数据替换的变量。
诸如“if”、“for”和代码块之类的分支功能不是SK模板语言的一部分。这反映了SK的设计原则,即尽可能使用自然语言,与传统编程代码有着明显的分离。通过使用简单的语言,内核还可以避免复杂的解析和外部依赖,从而实现快速高效的内存处理。
如果在语义函数中调用原生函数, 一般会使用语义函数装饰器来修饰原生函数以便Semantic kernel 可以识别。此外,原生函数可以路由方式访问Semantic kernel 。
Semantic kernel 中的plug-in 可以与openai 的plug-in 之间互相转换。以一个四则运算的plug-in为例,转换原理如下:
Semantic kernel 为其plug-in 的转换提供了模版和工具,例如semantic-functions-generator,转换步骤如下: 1.为每个原生函数创建HTTP端点。 2.创建一个描述插件的OpenAPI规范和插件清单文件。 3.在Semantic Kernel或ChatGPT中测试插件。
Semantic Kernel 还提供了一些工具类型的plug-in,可以在工程中直接使用。
AI 编排工具——规划器
规划器是一个接受用户请求并返回如何完成请求的规划功能。它通过使用AI混合匹配内核中注册的插件来实现这一点,这样它就可以将它们重新组合成一系列步骤来完成目标。这是一个强大的概念,因为它允许您创建原子函数,这些函数可以以开发人员可能没有想到的方式使用。
然而,功能越强,越要谨慎。因为规划器可以用你可能没有想到的方式组合函数,所以确保只公开自己想用这种方式使用的函数至关重要。同样,要确保目标应用于自己的功能,以便以公平、可靠、安全、私密和安全的方式使用它们。
Semantic Kernel 提供了四个内建的规划器:
- BasicPlanner:SequentialPlanner的简化版本,用字符串将一组函数组合在一起。
- ActionPlanner:通过单个步骤创建计划。
- SequentialPlanner:创建一个包含一系列步骤的计划与自定义生成的输入和输出变量。
- StepwisePlanner:逐步执行步骤并观察任何结果
如果有特定需求,还可以创建一个自定义规划器。
另外,在使用规划器时要考虑性能、成本和正确性的影响,最好使用预定义的规划器。也就是说,可以离线生成常见场景的规划,并将其作为XML存储在项目中。根据用户的意图,可以备份这些计划以便执行。这样就有机会创建额外的优化,以提高速度或降低成本。
语义化表达的可视化工具——prompt flow
Semantic Kernel 使用插件和规划器来构建自主的AI应用程序。然而,创建自主的AI应用程序很有挑战性,需要确保插件和规划器在广泛的输入中始终如一地产生所需的结果。这就是Prompt flow可以提供帮助的地方。
Prompt flow是一种开发工具,旨在简化LLM应用程序的创建。它提供的工具简化了LLM应用程序的原型设计、实验、迭代和部署过程。
值得注意的是,Prompt flow允许编写原生函数和语义函数链,并将它们可视化为图形。这使团队成员能够在本地使用VS code 轻松创建和测试人工智能的功能。
Prompt flow在定义和运行静态函数链方面非常出色。这适用于许多AI应用程序,但不适用于期望AI能够自动适应新输入和场景的场景。这就是Semantic Kernel 的一个动人之处。通过利用Prompt flow中的规划器和插件,我们可以编写流,根据用户的需求自动生成规划划,这样就可以避免自己手动定义每个可能的场景。
测试仍然是必须的,如果要使用多个输入测试流,可以使用批处理运行,即使用csv、tsv或JSON行文件中的输入列表来运行流。之后,所有输出都将保存到另一个JSON文件中。
再看 prompt engineering
虽然我们可以使用温度参数来控制模型输出的随机性,也可以使用其他参数如top-k、top-p、频率惩罚和存在惩罚也会影响模型的行为,但是,至少在目前而言,Prompt在交流和指导大模型AI的行为方面仍然发挥着至关重要的作用。它们是用户可以提供的输入或查询,以从模型中引出特定的响应。
提示工程,也称为提示设计,是一个新兴领域,需要创造力和对细节的关注。它包括选择正确的单词、短语、符号和格式,以指导模型生成高质量和相关的文本。成为一名熟练的prompt 工程师需要技术知识、创造力和实验的结合,提升Prompt能力的一些技巧:
- 了解LLM AI模型:深入了解LLM人工智能模型的工作方式,包括其架构、训练过程和行为。
- 领域知识:获取特定领域的知识,以设计与所需输出和任务一致的提示。
- 实验:探索不同的参数和设置,以微调提示并优化特定任务或域的模型行为。
- 反馈和迭代:持续分析模型生成的输出,并根据用户反馈对提示进行迭代,以提高其质量和相关性。
- 保持更新:及时了解工程技术、研究和最佳实践的最新进展,以提高自己的技能。