什么是 Chain?
在 LangChain 框架中,Chain 是一个核心概念,用于将多个组件或功能模块有序地链接在一起。通过 Chain,可以将模型、提示模板、输出解析器等功能模块组合成一个完整的流程,从而实现复杂任务。Chain 的设计理念在于模块化和简化复杂性,使开发者能够专注于核心业务逻辑,同时更方便地调试和维护应用程序。
为什么需要 Chain?
简化复杂流程
当开发一个简单的应用程序时,单独调用语言模型(LLM)可能已经足够。然而,面对更复杂的场景时,需要多个模型或组件协同工作,而 Chain 可以帮助我们:
- 封装复杂逻辑:将整个流程抽象成链条中的一个步骤。
- 模块化开发:通过组合不同的链条,实现高度定制化的功能。
- 提高维护性:便于调试、扩展和优化。
示例:LLMChain
LLMChain 是最基础的链之一。它将提示模板(PromptTemplate)、语言模型(LLM 或聊天模型)、输出解析器(Output Parser)整合到一个链中。如下是使用与不使用 Chain 的对比:
不使用 Chain:
from langchain import PromptTemplate, OpenAI
# 创建提示模板
template = "{flower}的花语是?"
prompt_temp = PromptTemplate.from_template(template)
prompt = prompt_temp.format(flower='玫瑰')
# 调用模型
llm = OpenAI(temperature=0)
result = llm(prompt)
print(result)
使用 Chain:
from langchain import PromptTemplate, OpenAI, LLMChain
# 定义提示模板
template = "{flower}的花语是?"
prompt_template = PromptTemplate.from_template(template)
# 创建 LLMChain
llm = OpenAI(temperature=0)
llm_chain = LLMChain(llm=llm, prompt=prompt_template)
# 调用链
result = llm_chain({"flower": "玫瑰"})
print(result)
输出:
{'flower': '玫瑰', 'text': '爱情、浪漫、美丽、永恒、誓言、坚贞不渝。'}
通过 LLMChain,我们将提示模板构建和模型调用的逻辑封装在一起,显著简化了代码。
Chain 的调用方式
链的调用方式非常灵活,可以根据场景选择适合的方法。
直接调用
直接调用链对象,实际上是调用其内部实现的 __call__
方法。例如:
result = llm_chain({"flower": "玫瑰"})
使用 run
方法
run
是 __call__
的等价方法,适用于单输入场景:
result = llm_chain.run("玫瑰")
使用 predict
方法
predict
方法适合传入命名参数:
result = llm_chain.predict(flower="玫瑰")
使用 apply
方法
apply
方法可以一次处理多个输入:
input_list = [{"flower": "玫瑰"}, {"flower": "百合"}]
result = llm_chain.apply(input_list)
使用 generate
方法
generate
返回 LLMResult
对象,包含模型的更多信息:
result = llm_chain.generate(input_list)
print(result.generations)
复杂链:Sequential Chain
Sequential Chain 是一种顺序链,通过将多个链串联,依次执行每个链的任务。例如:
目标:
- 生成鲜花的知识性说明。
- 根据说明生成评论。
- 根据说明和评论生成社交媒体文案。
实现:
from langchain.chains import SequentialChain
from langchain.prompts import PromptTemplate
from langchain.llms import OpenAI
from langchain.chains import LLMChain
llm = OpenAI(temperature=0.7)
# 第一个链:生成说明
template_intro = "描述{color}的{flower}的特性。"
prompt_intro = PromptTemplate(input_variables=["flower", "color"], template=template_intro)
intro_chain = LLMChain(llm=llm, prompt=prompt_intro, output_key="introduction")
# 第二个链:生成评论
template_review = "根据以下介绍,写一段评论:\n{introduction}"
prompt_review = PromptTemplate(input_variables=["introduction"], template=template_review)
review_chain = LLMChain(llm=llm, prompt=prompt_review, output_key="review")
# 第三个链:生成文案
template_social = "根据以下介绍和评论,生成一段社交媒体文案:\n介绍:{introduction}\n评论:{review}"
prompt_social = PromptTemplate(input_variables=["introduction", "review"], template=template_social)
social_chain = LLMChain(llm=llm, prompt=prompt_social, output_key="social_post")
# 顺序链
overall_chain = SequentialChain(
chains=[intro_chain, review_chain, social_chain],
input_variables=["flower", "color"],
output_variables=["introduction", "review", "social_post"],
verbose=True,
)
result = overall_chain({"flower": "玫瑰", "color": "黑色"})
print(result)
总结
LangChain 中的 Chain 是实现复杂应用程序的基础工具:
- 通过封装简化了代码。
- 提供了多种类型的链(如 LLMChain 和 Sequential Chain)。
- 支持灵活调用和动态组合。
随着任务的复杂性增加,Chain 提供了模块化、高效和可扩展的解决方案,使开发者能够更快速地构建强大的语言模型应用。下一节,我们将探索更高级的链类型,如 RouterChain 和 Memory,以解决动态路由和记忆上下文的问题。