赞
踩
LangChain 是一个用于开发由语言模型驱动的应用程序的框架。它使得应用程序能够:
LangChain 包的主要价值主张是:
现成的链使得开始变得容易。组件使得定制现有链和构建新链变得容易。
LangChain的安装与入门请参考:快速入门指南
假设有一串长文本,我们希望利用大模型提取出文本中与指定类型的商品品牌、型号等相关的信息,并通过JSON格式将商品信息输出,如下所示:
文本内容:"我今天买了一台Huawei Mate 60, 请你帮我送到华中科技大学南大门, 手机是蓝色的, 512G"
输出:
```json
{
"品牌": "Huawei",
"品类": "手机",
"属性": {
"型号": "Mate 60",
"颜色": "蓝色",
"存储容量": "512G"
},
"商品名称": "Huawei Mate 60 蓝色 512G"
}
# 导入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_KEY
和 OPENAI_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)
在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的一部分输入大模型中。
LangChain 提供了不同类型的 MessagePromptTemplate
。最常用的是 AIMessagePromptTemplate
、SystemMessagePromptTemplate
和 HumanMessagePromptTemplate
,分别用于创建 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中,我们需要外部导入四个参数,分别是:
关于Prompt如何设计,请参考:Prompt之美:如何设计提示词让大模型变“聪明”
链允许我们将多个组件组合在一起,创建一个单一的、一致的应用程序。例如,我们可以创建一个链,该链接接受用户输入,使用 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
- 属性:蓝色、512G
2. 根据电子产品行业内的常见品牌,确认Huawei属于电子产品行业的品牌,无需修正。
3. 根据文本中的描述,品牌信息在商品描述前面,且距离不远,因此可以确定Huawei是商品的品牌。
4. 综合以上信息,得出提取的手机相关信息如下:
```json
{
"品牌": "Huawei",
"品类": "手机",
"属性": "蓝色, 512G",
"商品名称": "Huawei Mate 60"
}
在得到输出结果后,我们希望解析输出的字符串中的JSON信息,从而提取我们想要的品牌、品类相关信息:
output = output_parser.parse(res)
print(output)
#输出
{'品牌': 'Huawei', '品类': '手机', '属性': '蓝色, 512G', '商品名称': 'Huawei Mate 60'}
解析出来的信息为字典格式,然后就可以从中提取我们想要的信息。
上文展示了如何推理一条文本信息,当我们有大量的文本信息时,采用串行执行的方式将会非常耗时,因此考虑能不能采用并行执行的方式提高推理速度。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,速度快了一倍还要多。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。