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

Langchain实战

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

一. Langchain介绍

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

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

LangChain 包的主要价值主张是:

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

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

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

二. 项目背景

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

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

三. 代码实现

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

python 复制代码
# 导入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 的生产环境服务器。

    如何使用:如果你需要将请求发送到不同的服务器(如沙盒环境、自定义端点或其他地区特定的服务器),你可以设置这个环境变量。

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

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

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

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

python 复制代码
#定义输出格式
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 消息、系统消息和人工消息:与聊天相关的提示模板

python 复制代码
# 创建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

python 复制代码
chain=LLMChain(llm=chat, prompt=chat_template)

接下来就可以推理了:

python 复制代码
ocr = '我今天买了一台Huawei Mate 60, 请你帮我送到华中科技大学南大门, 手机是蓝色的, 512G'
res = chain.run(industry="电子产品",ocr_result=ocr,goods="手机",format_instructions=format_instructions)
print(res)
python 复制代码
#输出:
1. 首先从文本中提取可能与手机相关的信息:
   - 品牌:Huawei
   - 商品名称:Mate 60
   - 属性:蓝色、512G

2. 根据电子产品行业内的常见品牌,确认Huawei属于电子产品行业的品牌,无需修正。

3. 根据文本中的描述,品牌信息在商品描述前面,且距离不远,因此可以确定Huawei是商品的品牌。

4. 综合以上信息,得出提取的手机相关信息如下:

```json
{
	"品牌": "Huawei",
	"品类": "手机",
	"属性": "蓝色, 512G",
	"商品名称": "Huawei Mate 60"
}

3.5 解析推理结果

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

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

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

3.6 异步调用

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

python 复制代码
import time,sys
import asyncio #异步调用

#测试
async def async_function():
    print("Hello, async!")
    sys.stdout.flush()  # 刷新标准输出流

await async_function()

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

python 复制代码
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元。'
]

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

python 复制代码
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")

输出:

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

采用异步调用并联推理:

python 复制代码
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")

输出:

python 复制代码
['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

相关推荐
一切尽在,你来12 分钟前
1.4 LangChain 1.2.7 核心架构概览
人工智能·langchain·ai编程
一切尽在,你来34 分钟前
1.3 环境搭建
人工智能·ai·langchain·ai编程
蛇皮划水怪7 小时前
深入浅出LangChain4J
java·langchain·llm
、BeYourself9 小时前
LangChain4j 流式响应
langchain
、BeYourself9 小时前
LangChain4j之Chat and Language
langchain
AI绘画哇哒哒9 小时前
【干货收藏】深度解析AI Agent框架:设计原理+主流选型+项目实操,一站式学习指南
人工智能·学习·ai·程序员·大模型·产品经理·转行
算法备案代理11 小时前
大模型备案与算法备案,企业该如何选择?
人工智能·算法·大模型·算法备案
qfljg11 小时前
langchain usage
langchain
lili-felicity11 小时前
#CANN AIGC文生图轻量推理:Prompt优化算子插件开发
prompt·aigc
猫头虎13 小时前
2026年AI产业13大趋势预测:Vibe Coding创作者经济元年到来,占冰强专家解读AIGC未来图景
人工智能·开源·prompt·aigc·ai编程·远程工作·agi