课程介绍
- 启程篇:从 0 到 1
- 内容:LangChain的安装流程和快速入门操作
- 实践:构建基于“易速鲜花”本地知识库的智能问答系统
- 目标:直观感受LangChain的强大功能
- 基础篇:深入 6 大组件
- 模型(Models) :各大语言模型的接口、调用细节以及输出解析机制
- 提示模板(Prompts) :提示工程流线化,进一步激发大语言模型的潜力
- 数据检索(Indexes) :建立和操作文档,返回相关文档以搭建知识库
- 记忆(Memory) :通过短时和长时记忆存储和检索对话数据
- 链(Chains) :封装功能的核心机制,灵活完成常见用例
- 代理(Agents) :另一个LangChain中的核心机制,使大模型自主调用工具,形成智能自主Agent
- 应用篇:积累场景中的智慧
- 内容:LangChain组件在实际场景中的应用
- 实践:嵌入式存储、数据库连接、异步通信、智能代理的角色扮演等
- 目标:通过实际案例展示组件了解如何共同完成复杂任务,提升实战能力
- 实战篇:动手!
- 项目:部署鲜花网络电商的人脉工具,开发易速鲜花聊天客服机器人
- 实践:从模型调用到数据连接,再到记忆的存储与检索,掌握构建智能系统的每个环节
- 目标:能够独立利用LangChain构建智能问答系统,适用于企业或个人需求
Chain概述
Chain(链)是LangChain里的关键要素,它能把各个组件和功能,像不同模型以及模型与其他组件相互链接起来,其虽构思简单却功能强大,可简化复杂应用程序实现过程并使其模块化,利于调试、维护与改进应用程序;通过预设接口实现具体链功能,像LLMChain能处理用户输入等进行功能封装,而且链之间可组合或与其他组件组合构建更复杂链,它既是内部封装功能、外部可组合串联的基本功能单元,LangChain还提供多种预置链方便完成各类任务
LLMChain:最简单的链
以 LLMChain 为例,看其如何围绕语言模型推理增添功能,整合 PromptTemplate、语言模型及 Output Parser,将 Model I/O 置于一个链中整体操作,对比不使用链时 Model I/O 独立处理的代码示例,展现使用 LLMChain 后代码结构更简洁、能将提示模板构建与模型调用封装在一起的优势特点
#----第一步 创建提示
# 导入LangChain中的提示模板
from langchain import PromptTemplate
# 原始字符串模板
template = "{flower}的花语是?"
# 创建LangChain模板
prompt_temp = PromptTemplate.from_template(template)
# 根据模板创建提示
prompt = prompt_temp.format(flower='玫瑰')
# 打印提示的内容
print(prompt)
#----第二步 创建并调用模型
# 导入LangChain中的OpenAI模型接口
from langchain import OpenAI
# 创建模型实例
model = OpenAI(temperature=0)
# 传入提示,调用模型,返回结果
result = model(prompt)
print(result)
# 导入所需的库
from langchain import PromptTemplate, OpenAI, LLMChain
# 原始字符串模板
template = "{flower}的花语是?"
# 创建模型实例
llm = OpenAI(temperature=0)
# 创建LLMChain
llm_chain = LLMChain(
llm=llm,
prompt=PromptTemplate.from_template(template))
# 调用LLMChain,返回结果
result = llm_chain("玫瑰")
print(result)
链的调用方式
# 设置OpenAI API密钥
import os
# 导入所需库
from langchain import PromptTemplate, LLMChain
from langchain_openai import ChatOpenAI
# 设置提示模板
prompt = PromptTemplate(
input_variables=["flower", "season"], template="{flower}在{season}的花语是?"
)
# 初始化大模型
llm = ChatOpenAI(model=os.environ.get("LLM_MODELEND"), temperature=0)
# 初始化链
llm_chain = LLMChain(llm=llm, prompt=prompt)
# 调用链
response = llm_chain({"flower": "玫瑰", "season": "夏季"})
print(response)
# run方法
llm_chain.run({"flower": "玫瑰", "season": "夏季"})
# predict方法
result = llm_chain.predict(flower="玫瑰", season="夏季")
print(result)
# apply方法允许您针对输入列表运行链
input_list = [
{"flower": "玫瑰", "season": "夏季"},
{"flower": "百合", "season": "春季"},
{"flower": "郁金香", "season": "秋季"},
]
result = llm_chain.apply(input_list)
print(result)
# generate方法
result = llm_chain.generate(input_list)
print(result)
- 直接调用:像调用函数一样调用链对象(实际调用其__call__方法),以字典形式传入提示模板变量值获取回复
- run 方法:等价于直接调用__call__函数,同样传入字典形式的变量值来获取结果
- predict 方法:和 run 方法类似,但输入键以关键字参数形式传入而非字典形式
- apply 方法:可针对输入列表运行链,能一次处理多个输入情况,批量获取结果
- generate 方法:类似于 apply 方法,不过返回的是包含模型相关信息的 LLMResult 对象,而非简单字符串
Sequential Chain:顺序链
下面我们用Sequential Chain 把几个LLMChain串起来,形成一个顺序链
- 第一步,我们假设大模型是一个植物学家,让他给出某种特定鲜花的知识和介绍
- 第二步,我们假设大模型是一个鲜花评论者,让他参考上面植物学家的文字输出,对鲜花进行评论
- 第三步,我们假设大模型是易速鲜花的社交媒体运营经理,让他参考上面植物学家和鲜花评论者的文字输出,来写一篇鲜花运营文案
# 设置OpenAI API密钥
import os
# 导入所需要的库
from langchain.chains import LLMChain, SequentialChain
from langchain.prompts import PromptTemplate
from langchain_openai import ChatOpenAI
# 第一个LLMChain:生成鲜花的介绍
llm = ChatOpenAI(
temperature=0.7,
model=os.environ.get("LLM_MODELEND"),
)
template = """
你是一个植物学家。给定花的名称和类型,你需要为这种花写一个200字左右的介绍。
花名: {name}
颜色: {color}
植物学家: 这是关于上述花的介绍:"""
prompt_template = PromptTemplate(input_variables=["name", "color"], template=template)
introduction_chain = LLMChain(
llm=llm, prompt=prompt_template, output_key="introduction"
)
# 第二个LLMChain:根据鲜花的介绍写出鲜花的评论
template = """
你是一位鲜花评论家。给定一种花的介绍,你需要为这种花写一篇200字左右的评论。
鲜花介绍:
{introduction}
花评人对上述花的评论:"""
prompt_template = PromptTemplate(input_variables=["introduction"], template=template)
review_chain = LLMChain(llm=llm, prompt=prompt_template, output_key="review")
# 第三个LLMChain:根据鲜花的介绍和评论写出一篇自媒体的文案
template = """
你是一家花店的社交媒体经理。给定一种花的介绍和评论,你需要为这种花写一篇社交媒体的帖子,300字左右。
鲜花介绍:
{introduction}
花评人对上述花的评论:
{review}
社交媒体帖子:
"""
prompt_template = PromptTemplate(
input_variables=["introduction", "review"], template=template
)
social_post_chain = LLMChain(
llm=llm, prompt=prompt_template, output_key="social_post_text"
)
# 总的链:按顺序运行三个链
overall_chain = SequentialChain(
chains=[introduction_chain, review_chain, social_post_chain],
input_variables=["name", "color"],
output_variables=["introduction", "review", "social_post_text"],
verbose=True,
)
# 运行链并打印结果
result = overall_chain({"name": "玫瑰", "color": "黑色"})
print(result)
- 第一个链:初始化 ChatOpenAI 模型,设置相关参数。创建提示模板,按花名和颜色生成花的介绍内容,构建
introduction_chain用于输出对应鲜花介绍,指定输出键 - 第二个链:定义新提示模板,基于鲜花介绍写评论,以此构建
review_chain输出鲜花评论,设输出键 - 第三个链:再定义提示模板,结合鲜花介绍与评论写自媒体文案,构建
social_post_chain输出文案,设输出键 - 用
SequentialChain将前面三个链按顺序组合,设置输入变量为花名和颜色,输出变量对应各链的输出内容,开启详细输出模式
Router Chain:路由链
RouterChain(路由链)可动态选择给定输入对应的下一个链,能依据预设规则或分析输入内容来智能判断,使处理流程更灵活高效,适配不同情况的处理路径,满足多样化任务需求,在复杂业务与多链路框架中有重要作用
import warnings
import os # 添加
warnings.filterwarnings("ignore")
# 设置OpenAI API密钥
# 构建两个场景的模板
flower_care_template = """
你是一个经验丰富的园丁,擅长解答关于养花育花的问题。
下面是需要你来回答的问题:
{input}
"""
flower_deco_template = """
你是一位网红插花大师,擅长解答关于鲜花装饰的问题。
下面是需要你来回答的问题:
{input}
"""
# 构建提示信息
prompt_infos = [
{
"key": "flower_care",
"description": "适合回答关于鲜花护理的问题",
"template": flower_care_template,
},
{
"key": "flower_decoration",
"description": "适合回答关于鲜花装饰的问题",
"template": flower_deco_template,
},
]
# 初始化语言模型
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
model=os.environ.get("LLM_MODELEND"),
)
# 构建目标链
from langchain.chains.llm import LLMChain
from langchain.prompts import PromptTemplate
chain_map = {}
for info in prompt_infos:
prompt = PromptTemplate(template=info["template"], input_variables=["input"])
print("目标提示:\n", prompt)
chain = LLMChain(llm=llm, prompt=prompt, verbose=True)
chain_map[info["key"]] = chain
# 构建路由链
from langchain.chains.router.llm_router import LLMRouterChain, RouterOutputParser
from langchain.chains.router.multi_prompt_prompt import (
MULTI_PROMPT_ROUTER_TEMPLATE as RounterTemplate,
)
destinations = [f"{p['key']}: {p['description']}" for p in prompt_infos]
router_template = RounterTemplate.format(destinations="\n".join(destinations))
print("路由模板:\n", router_template)
router_prompt = PromptTemplate(
template=router_template,
input_variables=["input"],
output_parser=RouterOutputParser(),
)
print("路由提示:\n", router_prompt)
router_chain = LLMRouterChain.from_llm(llm, router_prompt, verbose=True)
# 构建默认链
from langchain.chains import ConversationChain
default_chain = ConversationChain(llm=llm, output_key="text", verbose=True)
# 构建多提示链
from langchain.chains.router import MultiPromptChain
chain = MultiPromptChain(
router_chain=router_chain,
destination_chains=chain_map,
default_chain=default_chain,
verbose=True,
)
# 测试1
print(chain.run("如何为玫瑰浇水?"))
# 测试2
print(chain.run("如何为婚礼场地装饰花朵?"))
# 测试3
print(chain.run("如何区分阿豆和罗豆?"))
- 构建提示模板:创建两个不同场景下的文本模板,分别是
flower_care_template(针对养花育花问题,以园丁角度)和flower_deco_template(针对鲜花装饰问题,以网红插花大师角度),用于后续生成不同用途的提示信息 - 构建提示信息列表:将上述两个模板相关信息整理成
prompt_infos列表,每个元素包含key(用于标识不同场景链)、description(对应场景描述)以及template(具体模板内容),明确不同提示的用途及对应模板情况 - 初始化语言模型:从
langchain_openai库中导入ChatOpenAI并初始化语言模型llm,模型名称尝试从环境变量LLM_MODELEND中获取(可能存在变量名准确性问题),用于后续链构建中的语言处理环节 - 构建目标链:从相关库导入必要的类,通过循环
prompt_infos列表,针对每个提示信息创建对应的PromptTemplate,再用其和已初始化的llm构建LLMChain,将这些链存储在chain_map字典中,以key作为字典的键,方便后续按场景调用不同的链 - 构建路由链:从相应路由相关库中导入类,先是基于
prompt_infos整理出destinations信息,然后结合特定模板格式生成router_template,并创建对应的PromptTemplate即router_prompt,最后利用语言模型llm和router_prompt构建出LLMRouterChain(路由链),且设置为详细输出模式,用于根据输入动态选择后续链 - 构建默认链:从
langchain.chains库导入ConversationChain并构建default_chain,用于在路由链无法匹配合适场景时作为默认的处理链,同样设置为详细输出模式 - 构建多提示链:从
langchain.chains.router库导入相关类构建MultiPromptChain,整合了前面构建的router_chain(路由链)、destination_chains(目标链集合)以及default_chain(默认链),使其可以根据输入决定使用目标链或默认链来处理,并开启详细输出模式
写在最后
LangChain 提供了实用的 “链” 来连接多个组件,链代表着组件的调用顺序,且可包含其他链。我们能用多种方法调用链,并按需选择不同类型的链。这些链帮助我们按不同需求灵活构建和处理语言相关任务,让整个开发流程更有条理、更具针对性……无论如何,有一点毋庸置疑。我们正站在一个崭新的历史节点上。