Langchain实战:基于Chain实现Prompt的高级应用

2024-04-27 12:12

本文主要是介绍Langchain实战:基于Chain实现Prompt的高级应用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Langchain实战

    • 一. Langchain介绍
    • 二. 项目背景
    • 三. 代码实现
      • 3.1 导入必要的库并调用GPT大模型
      • 3.2 输出解析器(指定输出格式)
      • 3.3 定义Prompt模板
      • 3.4 构造LLMChain并推理
      • 3.5 解析推理结果
      • 3.6 异步调用
    • 四. 参考文献

一. Langchain介绍

LangChain 是一个用于开发由语言模型驱动的应用程序的框架。它使得应用程序能够:

  • 具有上下文感知能力:将语言模型连接到上下文来源(提示指令,少量的示例,需要回应的内容等)。
  • 具有推理能力:依赖语言模型进行推理(根据提供的上下文如何回答,采取什么行动等)。

LangChain 包的主要价值主张是:

  • 组件:用于处理语言模型的可组合工具和集成。无论你是否使用 LangChain 框架的其余部分,组件都是模块化的,易于使用
  • 现成的链:用于完成高级任务的组件的内置组合

现成的链使得开始变得容易。组件使得定制现有链和构建新链变得容易。

LangChain的安装与入门请参考:快速入门指南

二. 项目背景

假设有一串长文本,我们希望利用大模型提取出文本中与指定类型的商品品牌、型号等相关的信息,并通过JSON格式将商品信息输出,如下所示:

文本内容:"我今天买了一台Huawei Mate 60, 请你帮我送到华中科技大学南大门, 手机是蓝色的, 512G"
输出:
```json
{"品牌": "Huawei","品类": "手机","属性": {"型号": "Mate 60","颜色": "蓝色","存储容量": "512G"},"商品名称": "Huawei Mate 60 蓝色 512G"
}

三. 代码实现

3.1 导入必要的库并调用GPT大模型

# 导入Langchain相关的库
from langchain.llms import OpenAI
from langchain.prompts import PromptTemplate
from langchain.chains import LLMChain
from langchain.prompts import (ChatPromptTemplate,PromptTemplate,SystemMessagePromptTemplate,AIMessagePromptTemplate,HumanMessagePromptTemplate
)
from langchain.output_parsers import StructuredOutputParser, ResponseSchema
from langchain.chat_models import ChatOpenAI
from langchain.schema import (AIMessage,HumanMessage,SystemMessage
)

OPENAI_API_KEYOPENAI_API_BASE 是两个与 OpenAI API 交互时常用的环境变量,它们各自有不同的用途:

  • OPENAI_API_KEY
    用途:这是一个用于身份验证的密钥,允许你访问 OpenAI 的服务。当你通过 API 发送请求时,需要在请求头中包含这个 API 密钥,以便 OpenAI 能够验证请求者的身份。
    格式:通常是一个由数字和字母组成的字符串,长度固定。

  • OPENAI_API_BASE
    用途:这个环境变量用于指定 OpenAI API 的基础 URL。它决定了你的请求将被发送到哪个服务器。
    默认值:通常情况下,你不需要更改它,因为默认值已经指向了 OpenAI 的生产环境服务器。
    如何使用:如果你需要将请求发送到不同的服务器(如沙盒环境、自定义端点或其他地区特定的服务器),你可以设置这个环境变量。

import os
os.environ["OPENAI_API_KEY"] = "..."
os.environ["OPENAI_API_BASE"] = "..."
# 导入ChatModel
chat = ChatOpenAI(temperature=0)

3.2 输出解析器(指定输出格式)

在Langchain中封装了结构化输出的功能,通过Promt的输出解析器,可以直接将LLM的输出结果转化为指定格式:结构化输出解析器 structured

比如前面提到,我们希望输出为JSON格式,那么:

#定义输出格式
response_schemas = [ResponseSchema(name="品牌", description="商品的品牌"),ResponseSchema(name="品类", description="商品的品类"),ResponseSchema(name="属性", description="商品除品牌、品类外能够提炼的其他属性"),ResponseSchema(name="商品名称", description="根据提取的信息输出商品名称"),
]# 初始化解析器
output_parser = StructuredOutputParser.from_response_schemas(response_schemas)format_instructions = output_parser.get_format_instructions()

format_instructions将作为Prompt的一部分输入大模型中

3.3 定义Prompt模板

LangChain 提供了不同类型的 MessagePromptTemplate。最常用的是 AIMessagePromptTemplateSystemMessagePromptTemplateHumanMessagePromptTemplate,分别用于创建 AI 消息、系统消息和人工消息:与聊天相关的提示模板

# 创建SystemMessagePromptTemplate
SystemPrompt = PromptTemplate(template="你是一个 {industry} 行业的专家,你对行业内各个品牌的名称和型号了如指掌。",input_variables=["industry"]
)
SystemMessagePrompt = SystemMessagePromptTemplate(prompt=SystemPrompt)
# 创建HumanMessagePromptTemplate
HumanPrompt = PromptTemplate(template="""用户问题:给你一段输入文本,请从里面提炼与{goods}相关的以下信息:品牌:商品的品牌品类:商品的品类属性:商品除品牌、品类外能够提炼的其他属性,以json形式给出商品名称:根据提取的信息输出商品描述<context>{ocr_result}</context>根据<context>里的信息回答用户问题输出格式: {format_instructions}让我们一步一步分析,给出你分析的过程,并注意以下要点:1.只提取和{goods}相关的信息,如果无法提炼返回空json.只输出一个可能性最大的商品信息,输出的json只包含一种商品;2:参考{industry}行业内的常见品牌,并将文本中识别错误的品牌信息,根据字体之间的相似性与已有品牌进行对应;3.一般来说商品的品牌会在商品描述的前面,并且他们距离不会太远,如果提取到多个品牌信息,则考虑品牌和商品描述之间的距离;4.你需要判断提取到的品牌是否属于{industry}行业,若提取到的品牌明显不属于{industry}行业,则忽略该品牌信息;5.保证输出json的合法性,输出你分析的过程.""",input_variables=["goods","ocr_result","format_instructions","industry"]
)
HumanMessagePrompt = HumanMessagePromptTemplate(prompt=HumanPrompt)# 组合多个Prompt
chat_template = ChatPromptTemplate.from_messages([SystemMessagePrompt,HumanMessagePrompt])

在上面的Prompt中,我们需要外部导入四个参数,分别是:

  • goods:商品类别,比如手机,电脑等。
  • ocr_result:希望大模型提取信息的文本。
  • format_instructions:3.2中定义的输出解析器。
  • industry:该商品所处的行业,比如3C,家用电器等。

关于Prompt如何设计,请参考:Prompt之美:如何设计提示词让大模型变“聪明”

3.4 构造LLMChain并推理

链允许我们将多个组件组合在一起,创建一个单一的、一致的应用程序。例如,我们可以创建一个链,该链接接受用户输入,使用 PromptTemplate 对其进行格式化,然后将格式化后的响应传递给 LLM。我们可以通过将多个链组合在一起,或者通过将链与其他组件组合在一起,来构建更复杂的链:快速开始: 使用LLMChain

chain=LLMChain(llm=chat, prompt=chat_template)

接下来就可以推理了:

ocr = '我今天买了一台Huawei Mate 60, 请你帮我送到华中科技大学南大门, 手机是蓝色的, 512G'
res = chain.run(industry="电子产品",ocr_result=ocr,goods="手机",format_instructions=format_instructions)
print(res)
#输出:
1. 首先从文本中提取可能与手机相关的信息:- 品牌:Huawei- 商品名称:Mate 60- 属性:蓝色、512G2. 根据电子产品行业内的常见品牌,确认Huawei属于电子产品行业的品牌,无需修正。3. 根据文本中的描述,品牌信息在商品描述前面,且距离不远,因此可以确定Huawei是商品的品牌。4. 综合以上信息,得出提取的手机相关信息如下:```json
{"品牌": "Huawei","品类": "手机","属性": "蓝色, 512G","商品名称": "Huawei Mate 60"
}

3.5 解析推理结果

在得到输出结果后,我们希望解析输出的字符串中的JSON信息,从而提取我们想要的品牌、品类相关信息:

output = output_parser.parse(res)
print(output)
#输出
{'品牌': 'Huawei', '品类': '手机', '属性': '蓝色, 512G', '商品名称': 'Huawei Mate 60'}

解析出来的信息为字典格式,然后就可以从中提取我们想要的信息。

3.6 异步调用

上文展示了如何推理一条文本信息,当我们有大量的文本信息时,采用串行执行的方式将会非常耗时,因此考虑能不能采用并行执行的方式提高推理速度。Langchain支持通过利用asyncio库为代理提供异步支持:
如何使用异步API进行代理
Langchain(五)进阶之异步调用

import time,sys
import asyncio #异步调用#测试
async def async_function():print("Hello, async!")sys.stdout.flush()  # 刷新标准输出流await async_function()

假设我们有如下的五条文本信息:

ocr_results = [
'我今天买了一台Huawei Mate 60, 请你帮我送到华中科技大学南大门, 手机是蓝色的, 512G',
'这款红米Note 13 Pro手机现在在京东有优惠活动,原价1399元的商品,通过领取满1000元减100元、满99元减30元的优惠券后,实付价格低至1262.01元。如果购买京东PLUS会员,还可以享受立减6.99元的优惠。这款手机采用了6.67英寸超细四窄边直屏,搭载了Pro+同款金刚骨骼架构和第二代1.5K高光护眼屏。',
'2023 年 10 月 31 日,苹果发布了全新 M3 系列芯片(M3、M3 Pro、M3 Max),首次采用 3nm 工艺,同时发布了搭载 M3 系列芯片的全新 MacBook Pro 14/16 英寸,以及 24 英寸的 iMac。',
'据外媒 FujiFrmors 报道,富士 X-T50 相机有望于 5 月 16 日发布,这款相机将引入机身五轴防抖(IBIS)功能,同时还将搭载 X-T5 同款 X-Trans V CMOS 传感器,内置 1 个 SD 卡插槽。',
'联想旗下新款ThinkBook 16+笔记本电脑现已上架,其中集成显卡版本售价为7699元,配备RTX 4060独立显卡的版本售价为9999元。'
]

首先不采用异步调用串联推理:

result = []
s = time.perf_counter()
for ocr in ocr_results:res = chain1.run(industry="电子产品",ocr_result=ocr,goods="电子产品",format_instructions=format_instructions)output = output_parser.parse(res)result.append(output['商品名称'])
print(result)
elapsed = time.perf_counter() - s
print("\033[1m" + f"Serial executed in {elapsed:0.2f} seconds." + "\033[0m")

输出:

['Huawei Mate 60', 
'红米Note 13 Pro手机', 
'苹果 MacBook Pro 16 英寸(搭载 M3 系列芯片)', 
'富士 X-T50 相机', 
'联想ThinkBook 16+ 笔记本电脑']
Serial executed in 18.15 seconds.

采用异步调用并联推理:

async def async_generate(ocr_result):res = await chain.arun(industry='电子产品',ocr_result=ocr_result,goods='电子产品',format_instructions=format_instructions)output = output_parser.parse(res)return output['商品名称']async def generate_concurrently(data):tasks = [async_generate(ocr) for ocr in data]return await asyncio.gather(*tasks) ####异步调用s = time.perf_counter()
result=await generate_concurrently(ocr_results)
print(result)
elapsed = time.perf_counter() - s
print("\033[1m" + f"Concurrent executed in {elapsed:0.2f} seconds." + "\033[0m")

输出:

['Huawei Mate 60', 
'红米Note 13 Pro手机', 
'Apple MacBook Pro with M3 Series Chip, 14/16-inch', 
'富士 X-T50 相机', 
'ThinkBook 16+笔记本电脑']
Concurrent executed in 7.21 seconds.

可以看到二者输出的商品描述几乎一致,但是推理时间从18.15s减少到了7.21s,速度快了一倍还要多。

四. 参考文献

LangChain 中文网,500页码中文文档教程
LangChain 中文文档 v0.1.7

这篇关于Langchain实战:基于Chain实现Prompt的高级应用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

C++对象布局及多态实现探索之内存布局(整理的很多链接)

本文通过观察对象的内存布局,跟踪函数调用的汇编代码。分析了C++对象内存的布局情况,虚函数的执行方式,以及虚继承,等等 文章链接:http://dev.yesky.com/254/2191254.shtml      论C/C++函数间动态内存的传递 (2005-07-30)   当你涉及到C/C++的核心编程的时候,你会无止境地与内存管理打交道。 文章链接:http://dev.yesky

LangChain转换链:让数据处理更精准

1. 转换链的概念 在开发AI Agent(智能体)时,我们经常需要对输入数据进行预处理,这样可以更好地利用LLM。LangChain提供了一个强大的工具——转换链(TransformChain),它可以帮我们轻松实现这一任务。 转换链(TransformChain)主要是将 给定的数据 按照某个函数进行转换,再将 转换后的结果 输出给LLM。 所以转换链的核心是:根据业务逻辑编写合适的转换函

Javascript高级程序设计(第四版)--学习记录之变量、内存

原始值与引用值 原始值:简单的数据即基础数据类型,按值访问。 引用值:由多个值构成的对象即复杂数据类型,按引用访问。 动态属性 对于引用值而言,可以随时添加、修改和删除其属性和方法。 let person = new Object();person.name = 'Jason';person.age = 42;console.log(person.name,person.age);//'J

通过SSH隧道实现通过远程服务器上外网

搭建隧道 autossh -M 0 -f -D 1080 -C -N user1@remotehost##验证隧道是否生效,查看1080端口是否启动netstat -tuln | grep 1080## 测试ssh 隧道是否生效curl -x socks5h://127.0.0.1:1080 -I http://www.github.com 将autossh 设置为服务,隧道开机启动

时序预测 | MATLAB实现LSTM时间序列未来多步预测-递归预测

时序预测 | MATLAB实现LSTM时间序列未来多步预测-递归预测 目录 时序预测 | MATLAB实现LSTM时间序列未来多步预测-递归预测基本介绍程序设计参考资料 基本介绍 MATLAB实现LSTM时间序列未来多步预测-递归预测。LSTM是一种含有LSTM区块(blocks)或其他的一种类神经网络,文献或其他资料中LSTM区块可能被描述成智能网络单元,因为

亮相WOT全球技术创新大会,揭秘火山引擎边缘容器技术在泛CDN场景的应用与实践

2024年6月21日-22日,51CTO“WOT全球技术创新大会2024”在北京举办。火山引擎边缘计算架构师李志明受邀参与,以“边缘容器技术在泛CDN场景的应用和实践”为主题,与多位行业资深专家,共同探讨泛CDN行业技术架构以及云原生与边缘计算的发展和展望。 火山引擎边缘计算架构师李志明表示:为更好地解决传统泛CDN类业务运行中的问题,火山引擎边缘容器团队参考行业做法,结合实践经验,打造火山

vue项目集成CanvasEditor实现Word在线编辑器

CanvasEditor实现Word在线编辑器 官网文档:https://hufe.club/canvas-editor-docs/guide/schema.html 源码地址:https://github.com/Hufe921/canvas-editor 前提声明: 由于CanvasEditor目前不支持vue、react 等框架开箱即用版,所以需要我们去Git下载源码,拿到其中两个主

React+TS前台项目实战(十七)-- 全局常用组件Dropdown封装

文章目录 前言Dropdown组件1. 功能分析2. 代码+详细注释3. 使用方式4. 效果展示 总结 前言 今天这篇主要讲全局Dropdown组件封装,可根据UI设计师要求自定义修改。 Dropdown组件 1. 功能分析 (1)通过position属性,可以控制下拉选项的位置 (2)通过传入width属性, 可以自定义下拉选项的宽度 (3)通过传入classN

android一键分享功能部分实现

为什么叫做部分实现呢,其实是我只实现一部分的分享。如新浪微博,那还有没去实现的是微信分享。还有一部分奇怪的问题:我QQ分享跟QQ空间的分享功能,我都没配置key那些都是原本集成就有的key也可以实现分享,谁清楚的麻烦详解下。 实现分享功能我们可以去www.mob.com这个网站集成。免费的,而且还有短信验证功能。等这分享研究完后就研究下短信验证功能。 开始实现步骤(新浪分享,以下是本人自己实现

基于Springboot + vue 的抗疫物质管理系统的设计与实现

目录 📚 前言 📑摘要 📑系统流程 📚 系统架构设计 📚 数据库设计 📚 系统功能的具体实现    💬 系统登录注册 系统登录 登录界面   用户添加  💬 抗疫列表展示模块     区域信息管理 添加物资详情 抗疫物资列表展示 抗疫物资申请 抗疫物资审核 ✒️ 源码实现 💖 源码获取 😁 联系方式 📚 前言 📑博客主页: