3. Chain
Chain是Langchain的关键组件,是实现复杂功能的必要元素。通过Chain,将Langchain的各个功能和组件彼此链接,将程序模块化。
按照类型,Chain可以分为LLMChain、SequentialChain、TransformChain、RouterChain等。
3.1. 链的类型
1) LLMChain
LLMChain是基本单元,一个LLMChain可以实现一套功能,单个链没有什么特色,多个相组合才能体现其优势。
from langchain.chains import LLMChain
llm_chain = LLMChain(llm=llm, prompt=prompt,output_key="output_text")
result = llm_chain("##输入内容##")
print(result["output_text"])
2)SequentialChain(顺序链)
线形组合,前一个链的输出作为后一个链的输入。
from langchain.chains import LLMChain, SequentialChain
from langchain.prompts import PromptTemplate
#创建LLMChain链1
prompt_template=PromptTemplate(input_variables=["variable1", "variable2"], template="##提示内容1##")
chain1=LLMChain(llm=llm, prompt=prompt_template, output_key="output_text1")
#创建LLMChain链2
prompt_template=PromptTemplate(input_variables=["output_text1"], template="##提示内容2##")
chain2=LLMChain(llm=llm, prompt=prompt_template, output_key="output_text2")
#将多个链按顺序组合
overall_chain=SequentialChain(
chains=[chain1, chain2],
input_variables=["variable1", "variable2"],
output_variables=["output_text1", "output_text2"],
verbose=True,
)
#自上而下按顺序逐个链输出结果
result=overall_chain.invoke("variable1":"##变量1##","variable2":"##变量2##")
3)RouterChain(路由链)
树形组合,从跟往叶一路往下,某个上游的链根据需要选择应该调用哪个下游的链。
- 构建信息提示,将各个链需要包含的信息放入其中。
prompt_infos = [
{
"feature1": "##特征1##",
"feature2": "##特征2##",
"template": "##提示内容1与输入{input}##",
},
{
"feature1": "##特征1##",
"feature2": "##特征2##",
"template": "提示内容2与输入{input}",
},
]
- 构建LLMChain,由于路由链涉及多个链,需要使用for循环等方法逐个构建,最后放到字典
chain_map里。 - 构建路由链,负责查看用户输入的问题,确定问题的类型。
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['feature1']}: {p['feature2']}" for p in prompt_infos]
router_template = RounterTemplate.format(destinations="\n".join(destinations))
router_prompt = PromptTemplate(
template=router_template,
input_variables=["input"],
output_parser=RouterOutputParser(),
)
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)
- 构建多提示链,把前几个链整合在一起,实现路由功能。其中有三个关键要素:router_chain,destination_chains,default_chain;router_chain决定该用哪个destination_chains;destination_chains是候选链的详细内容;default_chain是备选方案。
# 构建多提示链
from langchain.chains.router import MultiPromptChain
chain = MultiPromptChain(
router_chain=router_chain,
destination_chains=chain_map,
default_chain=default_chain,
verbose=True,
)
3.2. 链的调用
1)直接调用
实际上会调用该对象内部实现的__call__方法,跟run一样的效果。如果提示模板中包含多个变量,在调用链的时候,可以使用字典一次性输入。
response = llm_chain({"feature1": "##特征1##", "season": "##特征2##"})
print(response)
2)run
同上
llm_chain.run({"feature1": "##特征1##", "season": "##特征2##"})
3)predict
输入键被指定为关键字参数而不是 Python 字典
result = llm_chain.predict(flower="玫瑰", season="夏季")
print(result)
4)apply
input_list = [
{"flower": "玫瑰", "season": "夏季"},
{"flower": "百合", "season": "春季"},
{"flower": "郁金香", "season": "秋季"},
]
result = llm_chain.apply(input_list)
print(result)
5)generate
result = llm_chain.generate(input_list)
print(result)
4. Memory
4.1. ConversationChain
ConversationChain提供了包含AI 前缀和人类前缀的对话摘要格式,为实现记忆功能提供基础。
from langchain.chains import ConversationChain
conv_chain = ConversationChain(llm=llm)
4.2. Memory
1)ConversationBufferMemory
缓冲记忆,最基础的记忆,可以将之前的聊天内容都记录,存储在ConversationChain的提示模板中的 {history} 参数中,缺点是如果对话过长则Token数过大,成本过高,且Token有限制时无法记住太长的内容。
from langchain.chains.conversation.memory import ConversationBufferMemory
# 初始化对话链
conversation = ConversationChain(llm=llm, memory=ConversationBufferMemory())
查看记忆内容
# 第一轮的对话
# 回合1
conversation("##对话1##")
print("第一次对话后的记忆:", conversation.memory.buffer)
# 回合2
conversation("##对话2##")
print("第二次对话后的记忆:", conversation.memory.buffer)
# 回合3 (第二轮的对话)
conversation("##对话3##
print("/n第三次对话后时提示:/n", conversation.prompt.template)
print("/n第三次对话后的记忆:/n", conversation.memory.buffer)'
2)ConversationBufferWindowMemory
缓冲窗口记忆,只保存最新最近的几次人类和AI的互动。增加了一个窗口值 k,即保留的数量。
from langchain.chains.conversation.memory import ConversationBufferWindowMemory
# 初始化对话链
conversation = ConversationChain(llm=llm, memory=ConversationBufferWindowMemory(k=1
3)ConversationSummaryMemory
对话总结记忆,将对话历史进行汇总,然后再传递给 {history} 参数。通过Token数限制来决定总结的长度,可以避免过度使用 Token。
from langchain.chains.conversation.memory import ConversationSummaryBufferMemory
# 初始化对话链
conversation = ConversationChain(
llm=llm, memory=ConversationSummaryBufferMemory(llm=llm, max_token_limit=300)
4)ConversationSummaryBufferMemory
对话总结缓冲记忆,混合了缓冲记忆和总结记忆,效果最好。也设置了Token限制,长度在限制内的对话完全记录,超出长度则进行总结。