AI全栈大模型工程师(二十)SKvs.LangChain

文章目录

    • SK vs. LangChain
      • 概念对照
      • 功能对照
    • 环境搭建
    • Plugins
      • Semantic Functions
        • skprompt.txt
        • config.json
      • Semantic Kernel Tools
      • Native Functions
      • 内置 Plugins
    • Memory
    • Planner
    • 后记

SK vs. LangChain

#%% md

概念对照

LangChainSemantic Kernel
ModelConnector
ToolsConnector
VectorstoreConnector
MemoryMemory
Prompt TemplatesPlugins
ChainPipeline / Chain
AgentPlanner
TextSplittertext.*
OutputParser

功能对照

LangChainSemantic Kernel
大模型60+5+
向量数据库40+11
Agent10+4

#%% md

环境搭建

#%% md

  1. 安装 Python 3.x:https://www.python.org/downloads/
  2. 安装 SK 包:pip install semantic-kernel
  3. 在项目目录创建 .env 文件,添加以下内容:
# .env
OPENAI_API_KEY=""
OPENAI_API_BASE=""
AZURE_OPENAI_DEPLOYMENT_NAME=""
AZURE_OPENAI_ENDPOINT=""
AZURE_OPENAI_API_KEY=""

OpenAI 和 Azure,配置好一个就行。

#%% md

## Hello, World!#%% md
这是一个简单示例。第一段代码是初始化。后面所有代码都要在执行过这段代码后,才能执行。#%%
import semantic_kernel as sk
from semantic_kernel.connectors.ai.open_ai import OpenAIChatCompletion
import os# 加载 .env 到环境变量from dotenv import load_dotenv, find_dotenv
_ = load_dotenv(find_dotenv())# 创建 semantic kernelkernel = sk.Kernel()# 配置 OpenAI 服务api_key = os.getenv('OPENAI_API_KEY')
endpoint = os.getenv('OPENAI_API_BASE')
model = OpenAIChatCompletion("gpt-3.5-turbo", api_key, endpoint=endpoint)# 把 LLM 服务加入 kernel# 可以加多个。第一个加入的会被默认使用,非默认的要被指定使用kernel.add_text_completion_service("my-gpt3", model)
#%% md
执行讲笑话的 prompt。#%%# 定义 semantic functiontell_joke_about = kernel.create_semantic_function("给我讲个关于{{$input}}的笑话吧")# 看结果print(tell_joke_about("Hello world"))

#%% md

划重点: 用我们熟悉的操作系统来类比,可以更好地理解 SK。
  1. 启动操作系统:kernel = sk.Kernel()
  2. 安装驱动程序:kernel.add_xxx_service()
  3. 安装应用程序:func = kernel.create_semantic_function()
  4. 运行应用程序:func()

基于 SK 开发的主要工作是写「应用程序」,也就是 Plugins

#%% md

Plugins

#%% md
简单说,plugin 就是一组函数的集合。它可以包含两种函数:

  • Semantic Functions - 语义函数,本质是 Prompt Engineering
  • Native Functions - 原生函数,类似 OpenAI 的 Function Calling

值得一提的是,SK 的 plugin 会和 ChatGPT、Bing、Microsoft 365 通用。「很快」你用 SK 写的 plugin 就可以在这些平台上无缝使用了。这些平台上的 plugin 也可以通过 SK 被你调用。

注意:Plugins 最初命名为 Skills,后来改为 Plugins。但是无论文档还是代码,都还有大量的「Skill」遗留。见到后,就知道两者是一回事就好

#%% md

Semantic Functions

#%% md
Semantic Functions 是纯用数据(prompt + 描述)定义的,不需要编写任何代码。所以它与编程语言无关,可以被任何编程语言调用。

一个典型的 semantic function 包含两个文件:

  • skprompt.txt: 存放 prompt,可以包含参数,还可以调用其它函数
  • config.json: 存放描述,包括函数功能,参数的数据类型,以及调用大模型时的参数

举例:把 LangChain 「生成 Linux 命令」的例子用 SK 实现。

#%% md

skprompt.txt

#%% raw
将用户的指令转换成 Linux 命令

The output should be formatted as a JSON instance that conforms to the JSON schema below.

As an example, for the schema {“properties”: {“foo”: {“title”: “Foo”, “description”: “a list of strings”, “type”: “array”, “items”: {“type”: “string”}}}, “required”: [“foo”]}}
the object {“foo”: [“bar”, “baz”]} is a well-formatted instance of the schema. The object {“properties”: {“foo”: [“bar”, “baz”]}} is not well-formatted.

Here is the output schema:

{"properties": {"command": {"title": "Command", "description": "linux shell命令名", "type": "string"}, "arguments": {"title": "Arguments", "description": "命令的参数 (name:value)", "type": "object", "additionalProperties": {"type": "string"}}}, "required": ["command", "arguments"]}

{{$input}}
#%% md

config.json

#%%
{
“schema”: 1,
“type”: “completion”,
“description”: “将用户的指令转换成 Linux 命令”,
“completion”: {
“max_tokens”: 256,
“temperature”: 0,
“top_p”: 0,
“presence_penalty”: 0,
“frequency_penalty”: 0
},
“input”: {
“parameters”: [
{
“name”: “input”,
“description”: “用户的指令”,
“defaultValue”: “”
}
]
}
}
#%% md
上面两个文件都在 sk_samples/SamplePlugin/GenerateCommand 目录下。

#%% md

#### 调用 Semantic Functions#%%# 加载 semantic function。注意目录结构functions = kernel.import_semantic_skill_from_directory("./sk_samples/", "SamplePlugin")
cli = functions["GenerateCommand"]# 看结果print(cli("将系统日期设为2023-04-01"))

#%% md
官方提供了大量的 Semantic Functions 可以参考:https://github.com/microsoft/semantic-kernel/tree/main/samples/skills

#%% md

Semantic Kernel Tools

#%% md
这是个 VS Code 的插件,在 VS Code 里可以直接创建和调试 Semantic Function。

安装地址:https://marketplace.visualstudio.com/items?itemName=ms-semantic-kernel.semantic-kernel

#%% md

Native Functions

#%% md
用编程语言写的函数,如果用 SK 的 Native Function 方式定义,就能纳入到 SK 的编排体系,可以被 Planner、其它 plugin 调用。

下面,写一个过滤有害 Linux 命令的函数,和 GenerateCommand 组合使用。

这个函数名是 harmful_command。如果输入的命令是有害的,就返回 true,否则返回 false

它也要放到目录结构中,在 sk_samples/SamplePlugin/SamplePlugin.py 里加入。

#%%# 因为是代码,不是数据,所以必须 importfrom sk_samples.SamplePlugin.SamplePlugin import SamplePlugin# 加载 semantic functionfunctions = kernel.import_semantic_skill_from_directory("./sk_samples/", "SamplePlugin")
cli = functions["GenerateCommand"]# 加载 native functionfunctions = kernel.import_skill(SamplePlugin(), "SamplePlugin")
harmful_command = functions["harmful_command"]# 看结果command = cli("删除根目录下所有文件")
print(command)  # 这个 command 其实是 SKContext 类型
print(harmful_command(context=command))  # 所以要传参给 context
#%% md### 用 SKContext 实现多参数 Functions#%% md
如果 Function 都只有一个参数,那么只要把参数定义为 `{{$input}}`,就可以按前面的例子来使用,比较直观。`{{$input}}`会默认被赋值。多参数时,就不能用默认机制了,需要定义 `SKContext` 类型的变量。#%%# 因为是代码,不是数据,所以必须 importfrom sk_samples.SamplePlugin.SamplePlugin import SamplePlugin# 加载 native functionfunctions = kernel.import_skill(SamplePlugin(), "SamplePlugin")
add = functions["add"]# 看结果context = kernel.create_new_context()
context["number1"] = 1024
context["number2"] = 65536
total = add(context=context)
print(total)
#%% md

内置 Plugins

#%% md
SK 内置了若干好用的 plugin,但因为历史原因,它们叫 skill……

加载方法:

from semantic_kernel.core_skills import SkillName

它们是:

  • ConversationSummarySkill - 生成对话的摘要
  • FileIOSkill - 读写文件
  • HttpSkill - 发出 HTTP 请求,支持 GET、POST、PUT 和 DELETE
  • MathSkill - 加法和减法计算
  • TextMemorySkill - 保存文本到 memory 中,可以对其做向量检索
  • TextSkill - 把文本全部转为大写或小写,去掉头尾的空格(trim)
  • TimeSkill - 获取当前时间及用多种格式获取时间参数
  • WaitSkill - 等待指定的时间
  • WebSearchEngineSkill - 在互联网上搜索给定的文本

#%% md

Memory

#%% md
SK 的 memory 使用非常简单:

  1. kernel.add_text_embedding_generation_service() 添加一个文本向量生成服务
  2. kernel.register_memory_store() 注册一个 memory store,可以是内存、文件、向量数据库等
  3. kernel.memory.save_information_async() 保存信息到 memory store
  4. kernel.memory.search_async() 搜索信息

使用 ChatALL 的 README.md 做数据,使用内存作为 memory store,我们演示下基于文档对话。

#%% md### 初始化 Embedding#%%
import semantic_kernel as sk
from semantic_kernel.connectors.ai.open_ai import OpenAIChatCompletion, OpenAITextEmbedding
import os# 加载 .env 到环境变量from dotenv import load_dotenv, find_dotenv
_ = load_dotenv(find_dotenv())# 创建 semantic kernelkernel = sk.Kernel()# 配置 OpenAI 服务api_key = os.getenv('OPENAI_API_KEY')
endpoint = os.getenv('OPENAI_API_BASE')
model = OpenAIChatCompletion("gpt-3.5-turbo", api_key, endpoint=endpoint)# 把 LLM 服务加入 kernel# 可以加多个。第一个加入的会被默认使用,非默认的要被指定使用kernel.add_text_completion_service("my-gpt3", model)# 添加 embedding 服务kernel.add_text_embedding_generation_service("ada", OpenAITextEmbedding("text-embedding-ada-002", api_key, endpoint=endpoint))
#%% md### 文本向量化#%%# 使用内存做 memory storekernel.register_memory_store(memory_store=sk.memory.VolatileMemoryStore())# 读取文件内容with open('../05-langchain/ChatALL.md', 'r') as f:# with open('sk_samples/SamplePlugin/SamplePlugin.py', 'r') as f:content = f.read()# 将文件内容分片,单片最大 100 token(注意:SK 的 text split 功能目前对中文支持不如对英文支持得好)lines = sk.text.split_markdown_lines(content, 100)# 将分片后的内容,存入内存for index, line in enumerate(lines):await kernel.memory.save_information_async("chatall", id=index, text=line)
#%% md### 向量搜索#%%
result = await kernel.memory.search_async("chatall", "ChatALL怎么下载?")
print(result[0].text)
#%% md## Pipeline / Chain#%% md
SK 更想用 pipeline 来描述 LangChain 中 chain 的概念,大概因为 pipeline 这个词更操作系统吧。但 chain 这个名词影响力太大,所以 SK 时不时也会用它。但是,SK 没有在代码里定义什么是 pipeline,它并不是一个类,或者函数什么的。它是贯彻整个 kernel 的一个概念。当一个 kernel 添加了 LLM、memory、functions,我们写下的 functions 之间的组合调用,就是个 pipeline 了。如果需要多条 pipeline,就定义多个 kernel。<div class="alert alert-block alert-info">
<b>思考:</b>LangChain 定义了好几种 Chain;SK 只是用 kernel 把抽象功能组合起来,pipeline 的过程完全交给开发者自己定义。你觉得哪种设计更好?
</div>#%% md
现在用 pipeline 思想把对话式搜索 ChatALL 的 README.md 功能做完整。要用到内置的 `TextMemorySkill`。#%%# 导入内置的 `TextMemorySkill`。主要使用它的 `recall()`kernel.import_skill(sk.core_skills.TextMemorySkill())# 直接在代码里创建 semantic function。里面调用了 `recall()`sk_prompt = """
基于下面的背景信息回答问题。如果背景信息为空,或者和问题不相关,请回答"我不知道"。[背景信息开始]
{{recall $input}}
[背景信息结束]问题:{{$input}}
回答:
"""
ask = kernel.create_semantic_function(sk_prompt)# 提问context = kernel.create_new_context()
context[sk.core_skills.TextMemorySkill.COLLECTION_PARAM] = "chatall"
context[sk.core_skills.TextMemorySkill.RELEVANCE_PARAM] = 0.8
context["input"] = "ChatALL 怎么下载?"
result = ask(context=context)
print(result)
#%% md

Planner

#%% md
SK 的 planner 概念上对标 LangChain 的 agent,但目前实现得还比较简单(C# 版丰富些)。SK Python 提供了三种 planner:1. `BasicPlanner` - 把任务拆解,自动调用各个函数,完成任务。它只是个用于基础验证的功能,最终会被 `SequentialPlanner` 替代。[Prompt 地址](https://github.com/microsoft/semantic-kernel/blob/main/python/semantic_kernel/planning/basic_planner.py#L27-L123)
2. `SequentialPlanner` - 开发中,未发布。比 `BasicPlanner` 更高级,但目标一致。[Prompt 地址](https://github.com/microsoft/semantic-kernel/blob/main/python/semantic_kernel/planning/sequential_planner/Skills/SequentialPlanning/skprompt.txt)、[官方例程](https://github.com/microsoft/semantic-kernel/blob/main/python/samples/kernel-syntax-examples/sequential_planner.py)
3. `ActionPlanner` - 已发布。只输出 action,不执行。[Prompt 地址](https://github.com/microsoft/semantic-kernel/blob/main/python/semantic_kernel/planning/action_planner/skprompt.txt)、[官方例程](https://github.com/microsoft/semantic-kernel/blob/main/python/samples/kernel-syntax-examples/action_planner.py)来,把查周杰伦的生日是星期几,用 SK 的 `BasicPlanner` 再做一遍(版本 > 0.3.7dev 才能工作)。#%%
from semantic_kernel.core_skills import WebSearchEngineSkill, TimeSkill, MathSkill
from semantic_kernel.connectors.search_engine import BingConnector
from semantic_kernel.planning import BasicPlanner
import semantic_kernel as sk
from semantic_kernel.connectors.ai.open_ai import OpenAIChatCompletion, OpenAITextEmbedding
import os# 加载 .env 到环境变量from dotenv import load_dotenv, find_dotenv
_ = load_dotenv(find_dotenv())# 创建 semantic kernelkernel = sk.Kernel()# 配置 OpenAI 服务api_key = os.getenv('OPENAI_API_KEY')
endpoint = os.getenv('OPENAI_API_BASE')
model = OpenAIChatCompletion("gpt-4", api_key, endpoint=endpoint)    # GPT-4 才能完成此任务。不信改成 gpt-3.5-turbo 试试# 把 LLM 服务加入 kernel# 可以加多个。第一个加入的会被默认使用,非默认的要被指定使用kernel.add_text_completion_service("my-gpt4", model)# 导入搜索 pluginconnector = BingConnector(api_key=os.getenv("BING_API_KEY"))
kernel.import_skill(WebSearchEngineSkill(connector), "WebSearch")# 导入其它 plugin。所有被导入的 plugin,都是可以被 planner 调用的kernel.import_skill(MathSkill(), "math")
kernel.import_skill(TimeSkill(), "time")# 创建 plannerplanner = BasicPlanner()# 开始ask = "周杰伦的生日是星期几?"
plan = await planner.create_plan_async(ask, kernel)
print(plan.generated_plan)
result = await planner.execute_plan_async(plan, kernel)
print(result)

后记

📢博客主页:https://manor.blog.csdn.net

📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!
📢本文由 Maynor 原创,首发于 CSDN博客🙉
📢不能老盯着手机屏幕,要不时地抬起头,看看老板的位置⭐
📢专栏持续更新,欢迎订阅:https://blog.csdn.net/xianyu120/category_12471942.html

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

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

相关文章

elementui-plus el-tree组件数据不显示问题解决

当前情况: 显示: 注意看右侧的树是没有文字的,数据已经渲染,个数是对的,但就是没有文字, 解决: 对比以后发现是template中的#default{data}没有写大括号导致的 所以写上大括号后: 正常显示

Docker入门指南:什么是Docker?

Docker入门指南&#xff1a;什么是Docker&#xff1f; Docker已经成为现代应用程序开发和部署的重要工具&#xff0c;但对于初学者来说&#xff0c;理解Docker的核心概念可能有些令人困惑。在本文中&#xff0c;我们将深入介绍Docker的基本知识&#xff0c;包括容器化技术、容…

如何安装mmcv

问题&#xff1a; modulenotfounderror: no module named mmcv 解决措施&#xff1a; 这里无法使用常规的pip安装思路解决这个问题&#xff0c;我们可以使用mmcv的官方文档解决这个问题&#xff0c;官方文档地址如下&#xff1a; https://mmcv.readthedocs.io/en/latest/ge…

理解MySQL的日志 Redo、Undo

理解MySQL的Redo日志和Undo日志 1、MySQL 日志文件解决的问题2、redo 日志2.1、redo log 的组成2.2、redo log 刷盘策略2.3、MySQL 的 redo log解决了哪些问题 3、undo 日志3.1、undo 日志作用3.2、undo log 的类型3.3、undo log 的生命周期3.4、事务回滚相关的几个隐藏字段 1、…

垂直领域大模型落地思考

相比能做很多事&#xff0c;但每件事都马马虎虎的通用大模型&#xff1b;只能做一两件事&#xff0c;但这一两件事都能做好&#xff0c;可被信赖的垂直大模型会更有价值。这样的垂直大模型能帮助我们真正解决问题&#xff0c;提高生产效率。 本文将系统介绍如何做一个垂直领域…

【Linux精讲系列】——vim详解

​作者主页 &#x1f4da;lovewold少个r博客主页 ⚠️本文重点&#xff1a;c入门第一个程序和基本知识讲解 &#x1f449;【C-C入门系列专栏】&#xff1a;博客文章专栏传送门 &#x1f604;每日一言&#xff1a;宁静是一片强大而治愈的神奇海洋&#xff01; 目录 目录 ​作者…

Django(二、静态文件的配置、链接数据库MySQL)

文章目录 一、静态文件及相关配置1.以登录功能为例2.静态文件3.资源访问4.静态文件资源访问如何解决&#xff1f; 二、静态文件相关配置1. 如何配置静态文件配置&#xff1f;2.接口前缀3. 接口前缀动态匹配4. form表单请求方法补充form表单要注意的点 三、request对象方法reque…

11、云服务器的宝塔面板安装、在宝塔安装MySQL、Redis、NGINX、JAVA

1►云服务器的宝塔面板安装 如果购买云服务器的时候&#xff0c;选择系统为宝塔面板&#xff0c;那么就不需要麻烦了。宝塔已经装好了。 但是如果没有选择宝塔面板&#xff0c;就需要手动安装。 第一步&#xff1a;点击重装系统 第二步&#xff1a;选择宝塔面板 宝塔面板官方…

Python标准库有哪些

概述 可用性注释 内置函数 内置常量 由 site 模块添加的常量 # Author : 小红牛 # 微信公众号&#xff1a;wdPython内置类型 逻辑值检测 布尔运算 — and, or, not 比较运算 数字类型 — int, float, complex 布尔类型 - bool 迭代器类型 序列类型 — list, tuple, range 文本…

如何写一篇吊炸天的竞品分析

这段时间&#xff0c;除了撩妹之外&#xff0c;最多的就是竞品分析了。最近很多临近毕业的同学也在四处应聘产品岗&#xff0c;而一份不错的竞品分析一定能为你的求职加分不少。于是&#xff0c;有着菩萨心肠天使面孔魔鬼身材的我&#xff0c;就来教大家怎么做一份完整的竞品分…

MySQL的表格去重,史上最简便的算法,一看就会

首先&#xff0c;表格my_tab02存在很多重复的数据&#xff1a; #表格的去重 方法一&#xff1a; 详细内容传送门&#xff1a;表格的去重 -- 思路&#xff1a; -- 1.先创建一张临时表 my_tmp,该表的结构和my_tab02一样 -- 2.把my_tmp的记录通过distinct关键字 处理后 把记录复…

『 MySQL数据库 』数据库基础之库的基本操作

文章目录 库的操作创建数据库字符集与校验集那么该如何查看当前数据库默认的字符集与校验规则?查看数据库所支持的字符集与校验集不同字符集(校验集)之间的区别 基本操作查看数据库显式数据库创建语句数据库的修改数据库的删除数据库的备份检查连接 库的操作 创建数据库 CRE…

APISpace IP归属地查询接口案例代码

1.IP归属地查询API 1.1 API接口简介 IP归属地查询API&#xff1a;根据IP地址查询归属地信息&#xff0c;包含国家、省、市、区县和运营商等信息。APISpace 提供了IPv4 和 IPv6 的IP归属地查询接口&#xff0c;并且包含了各种归属地精度查询的接口。 1.2 IPv4 IPv4归属地查询…

51单片机+SIM800C(GSM模块)实现短信发送功能

一、前言 本项目利用51单片机和SIM800C GSM模块实现短信发送功能。短信作为一种广泛应用的通信方式&#xff0c;在许多领域具有重要的作用&#xff0c;如物联网、安防系统、远程监控等。通过将51单片机与SIM800C GSM模块相结合&#xff0c;可以实现在各种应用场景下的短信通信…

【数据库技术】金管局计算机岗位——数据仓库(⭐⭐⭐⭐)

数据库技术 数据仓库数据仓库的定义数据仓库的作用数据仓库的特点(⭐⭐⭐⭐)数据仓库的主要功能(⭐⭐⭐⭐)OLTP&#xff1a;联机事务处理(⭐⭐⭐⭐⭐)OLAP&#xff1a;联机分析处理(⭐⭐⭐⭐⭐)OLAP的基本多维分析操作(⭐⭐⭐⭐⭐) 数据仓库与数据库的区别(⭐⭐⭐)数据仓库的三…

微服务的发展历程的详细说明及每个阶段主流的架构和组件

微服务的发展历程的详细说明及每个阶段主流的架构和组件如下&#xff1a; 一、微服务的发展历程&#xff1a; 起始阶段&#xff1a;这个阶段主要是面向服务的架构&#xff08;SOA&#xff09;的兴起。此时&#xff0c;企业开始尝试将单体应用拆分为多个服务&#xff0c;但此时…

IDEA 设置 Git 在左侧展示

File->settings->Version Control->commit 勾选 Use non-model commit interface

Java用fastjson转换JSON对象和字符串

Fastjson是阿里巴巴的一个开源项目&#xff0c;它是一个高性能的Java语言实现的JSON库。下面是如何使用Fastjson将Java对象转换为JSON对象的示例。 下载安装 需要将Fastjson库添加到项目的依赖中。如果您使用的是Maven&#xff0c;可以在pom.xml文件中添加以下依赖&#xff1…

5G创新突破 | 紫光展锐5G芯片全球首发R17 NR广播端到端业务演示

近日&#xff0c;在中国广电集团的统一指导下&#xff0c;紫光展锐联合中兴通讯等行业伙伴&#xff0c;全面实现了基于3GPP R17标准的5G NR广播&#xff0c;这意味着未来搭载紫光展锐5G芯片的手机将具备接收5G广播的能力&#xff0c;进一步助力5G NR广播产业链生态成熟和商用部…

vue.js实现科室无限层选中和回显

一、效果展示&#xff1a; 展示可选层级 查看选中的值 二、实现&#xff1a; <el-form-item label"相关科室:" prop"orgId"><el-cascaderpopper-class"cascader-my":options"orgOptions":show-all-levels"false"…