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

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

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

相关文章

新兴游戏引擎Godot vs. 主流游戏引擎Unity和虚幻引擎,以及版本控制工具Perforce Helix Core如何与其高效集成

游戏行业出现一个新生事物——Godot&#xff0c;一个免费且开源的2D和3D游戏引擎。曾经由Unity和虚幻引擎&#xff08;Unreal Engine&#xff09;等巨头主导的领域如今迎来了竞争对手。随着最近“独特”定价模式的变化&#xff0c;越来越多的独立开发者和小型开发团队倾向于选择…

Vitis HLS 学习笔记--Syn Report解读(1)

目录 1. 介绍 2. 示例一 2.1 HLS 代码 2.2 Report 解读 2.2.1 General Information 2.2.2 Timing Estimate 2.2.3 Performance & Resource Estimates 2.2.4 HW interfaces 2.2.4.1 硬件接口报告 2.2.4.2 导出至 Vivado 中的 IP 2.2.4.3 Port-Level Protocols 端…

图形化编程要怎么做

0. 简介 Scratch其实应该算得上最早做图形化编程的工程了。Scratch 是麻省理工学院的“终身幼儿园团队”在 2007 年 [5]发布的一种图形化编程工具&#xff0c;主要面对全球青少年开放&#xff0c;是图形化编程工具当中最广为人知的一种&#xff0c;所有人都可以在软件中创作自…

排序算法-计数排序

一、计数排序 这种排序算法 是利用数组下标来确定元素的正确位置的。 如果数组中有20个随机整数&#xff0c;取值范围为0~10&#xff0c;要求用最快的速度把这20个整数从小到大进行排序。 很大的情况下&#xff0c;它的性能甚至快过那些时间复杂度为O(nlogn&#xff09;的排序。…

【React】Sigma.js框架网络图-入门篇(2)

通过《【React】Sigma.js框架网络图-入门篇》有了基本认识 由于上一篇直接给出了基本代码示例&#xff0c;可能看着比较复杂也不知道是啥意思&#xff1b; 今天从理论入手重新认识下&#xff01; 一、基本认识 首先&#xff0c;我们先了解下基础术语&#xff1a; 图(Graph)&…

如何实现直播声卡反向给手机充电功能呢?

在数字化时代的浪潮中&#xff0c;声卡作为多媒体系统的核心组件&#xff0c;扮演着声波与数字信号相互转换的关键角色。它不仅能够将来自各类音源的原始声音信号转换为数字信号&#xff0c;进而输出到各类声响设备&#xff0c;更能够通过音乐设备数字接口(MIDI)发出合成乐器的…

Eudic欧路词典for Mac:专业英语学习工具

Eudic欧路词典for Mac&#xff0c;作为专为Mac用户设计的英语学习工具&#xff0c;凭借其简捷高效的特点&#xff0c;成为众多英语学习者不可或缺的助手。 Eudic欧路词典for Mac v4.6.4激活版下载 这款词典整合了多个权威词典资源&#xff0c;如牛津、柯林斯、朗文等&#xff0…

​「Python大数据」词频数据渲染词云图导出HTML

前言 本文主要介绍通过python实现数据聚类、脚本开发、办公自动化。词频数据渲染词云图导出HTML。 一、业务逻辑 读取voc数据采集的数据批处理,使用jieba进行分词,去除停用词词频数据渲染词云图将可视化结果保存到HTML文件中二、具体产出 三、执行脚本 python wordCloud.p…

mysql中日期函数now()和sysdate()的区别

说明&#xff1a; 在mysql数据库中&#xff0c;now()、sysdate() 都是获取系统当前日期时间 区别&#xff1a; 示例脚本&#xff1a; select sleep(2),now(),sysdate() from dual; 输出&#xff1a; 小结&#xff1a; 1、 now()和sysdate()都可以获取系统当前日期时间 2、区别…

将游戏界面与注册/登录界面连接到一起

一、 导包 在注册页面中导入一个import subprocess包 二、 使用代码将其连接到一起 在循环中加入下面这一行代码&#xff0c;用来实现效果 subprocess.run(["python", "game代码.py"]

Faust勒索病毒:了解变种faust,以及如何保护您的数据

导言&#xff1a; 近年来&#xff0c;网络安全问题日益严峻&#xff0c;其中勒索病毒成为了一种日益猖獗的威胁。在众多勒索病毒中&#xff0c;.faust勒索病毒以其高度的隐秘性和破坏性引起了广泛关注。本文91数据恢复将深入剖析.faust勒索病毒的威胁特点&#xff0c;并提出相…

实现SpringMVC底层机制(一)

文章目录 1.环境配置1.创建maven项目2.创建文件目录3.导入jar包 2.开发核心控制器文件目录1.流程图2.编写核心控制器SunDispatcherServlet.java3.类路径下编写spring配置文件sunspringmvc.xml4.配置中央控制器web.xml5.配置tomcat&#xff0c;完成测试1.配置发布方式2.配置热加…

【stomp 实战】Spring websocket使用详解和基本原理

spring框架对websocket有很好的支持&#xff0c;stomp协议作为websocket的子协议&#xff0c;Spring也做了很多封装&#xff0c;让我们在开发中易于使用。 学习使用Spring的Websocket模块&#xff0c;当然最好的办法就是看官网说明了。本篇文章对官网做一些简述和个人的理解。 …

采集 Kubernetes 容器日志最佳实践

前言 指标、日志、链路是可观测的三大支柱&#xff0c;日志主要用于记录代码执行的痕迹&#xff0c;方便定位和排查问题。当前主流的应用都是以容器的方式运行在 Kubernetes 集群&#xff0c;由于容器的动态性&#xff0c;容器可能会频繁地创建和销毁。日志的采集和持久化变得…

用例整体执行及pytest.ini文件

在我们写代码的过程中&#xff0c;一般都是右键或者命令行去执行一个用例 但是当我们写完后&#xff0c;需要整体执行一遍。那应该怎么搞呢&#xff1f; 我们可以在根目录下新建一个main.py或者run.py之类的文件&#xff0c;文件内容如下&#xff1a; if __name__ "__ma…

JAVA实现easyExcel批量导入

注解类型描述ExcelProperty导入指定当前字段对应excel中的那一列。可以根据名字或者Index去匹配。当然也可以不写&#xff0c;默认第一个字段就是index0&#xff0c;以此类推。千万注意&#xff0c;要么全部不写&#xff0c;要么全部用index&#xff0c;要么全部用名字去匹配。…

个人电脑本地部署LLM

普通电脑配置即可本地运行大模型&#xff0c;本地部署LLM最简单的方法 OLLAMA Ollama是一个开源框架&#xff0c;专门设计用于在本地运行大型语言模型&#xff08;LLM&#xff09;。它的主要功能是在Docker容器中部署和管理LLM&#xff0c;使得在本地运行大模型的过程变得非常…

python之List列表

1. 高级数据类型 Python中的数据类型可以分为&#xff1a;数字型&#xff08;基本数据类型&#xff09;和非数字型&#xff08;高级数据类型&#xff09; 数字型包含&#xff1a;整型int、浮点型float、布尔型bool、复数型complex 非数字型包含&#xff1a;字符串str、列表l…

CPPTest实例分析(C++ Test)

1 概述 CppTest是一个可移植、功能强大但简单的单元测试框架&#xff0c;用于处理C中的自动化测试。重点在于可用性和可扩展性。支持多种输出格式&#xff0c;并且可以轻松添加新的输出格式。 CppTest下载地址&#xff1a;下载地址1  下载地址2 下面结合实例分析下CppTest如…

Vue3+ts(day03:ref和reactive)

学习源码可以看我的个人前端学习笔记 (github.com):qdxzw/frontlearningNotes 觉得有帮助的同学&#xff0c;可以点心心支持一下哈&#xff08;笔记是根据b站上学习的尚硅谷的前端视频【张天禹老师】&#xff0c;记录一下学习笔记&#xff0c;用于自己复盘&#xff0c;有需要学…