摘要
本文基于源码分析与官方文档梳理,系统解析 LangChain 框架中的核心组件 Chain 链,旨在帮助开发者深入理解其设计原理、功能分类及实践应用场景。
作为 LangChain 的核心机制,Chain 链采用管道-过滤器(Pipe-Filter)架构,通过面向对象函数调用的方式或更高级的LCEL(LangChain Expression Language),以声明式语法将多个功能组件(如模型、检索器、记忆模块等)串联为可复用的工作流。其核心运行逻辑为:以串行化数据流方式传递处理结果,前一环节的输出自动作为下一环节的输入,最终完成复杂任务的端到端执行。
Chain 父类
Chain
是 LangChain 框架中所有链的抽象基类,定义了链式组件的统一接口与核心生命周期逻辑。它是构建复杂应用(如 RAG、多步推理)的底层基础,支持通过继承实现自定义链或组合内置链。
核心功能
-
工作流编排
-
结构化调用序列:通过
_call()
方法编码对模型、检索器、其他链等组件的调用顺序,形成可复用流水线。 -
LCEL 兼容:支持通过
|
运算符与其他组件(如Runnable
)组合,例如chain = prompt | model | output_parser
。
-
-
状态管理
-
Memory 集成:通过添加
Memory
对象,Chain
类可以实现状态管理。Memory
类在每次链调用的开始和结束时被调用,在开始时通过memory.load_memory_variables()
在调用前加载变量并将其传递给链,在结束时通过memory.save_context()
保存返回的变量。使用方式如: -
chain = ConversationChain(llm=llm, memory=ConversationBufferMemory())
-
-
可观测性
-
Callbacks 回调:通过传递
Callbacks
对象,Chain
类可以执行额外的功能,如支持日志、监控等扩展功能,通过callbacks
属性注入处理器,触发on_chain_start
、on_chain_end
、on_chain_error
等事件。
-
-
可组合性
-
Chain
类的 API 非常灵活,使得它可以轻松地与其他组件(包括其他链)组合在一起,形成更复杂的应用程序。例如: -
parent_chain = ChainA() | ChainB()
-
关键属性
属性 | 作用 |
---|---|
| 状态存储器(如 |
| 回调机制,支持日志记录、监控追踪等扩展功能(如StdOutCallbackHandler )。 |
| 调试模式开关,输出详细执行日志。 |
| 链调用的分类标签,这些标签将与每次链调用关联用于回调过滤 |
| 元数据(如环境标识),这些元数据将与每次链调用关联,并作为参数传递给 |
核心方法
-
执行入口
-
同步调用
-
invoke(inputs)
:基础执行方法,返回完整输出字典。
-
-
异步调用
-
ainvoke(inputs)
:异步执行,需子类实现_acall()
。
-
-
-
生命周期钩子
-
_call(inputs)
:抽象方法,子类必须实现核心逻辑(如调用模型、处理文档)。 -
_acall(inputs)
:异步逻辑入口,默认同步转异步(可覆盖实现)。
-
-
输入输出处理
-
prep_inputs(inputs)
:预处理输入(合并memory
中的变量)。 -
prep_outputs(outputs)
:后处理输出(验证结构并更新memory
)。
-
-
序列化与调试
-
save(file_path)
:导出链配置为 JSON/YAML 文件(保留组件参数,不保存运行时状态)。 -
dict()
:返回链的配置字典(可用于重建对象)。
-
Chain 链分类
文档处理与组合
类型 | 说明 |
---|---|
基础组合 | |
StuffDocumentsChain | 文档拼接器:将所有文档内容直接拼接为单一上下文字符串,适合短文本场景(需注意 Token 限制)。常用于直接注入完整上下文到 Prompt 中。 |
MapReduceDocumentsChain | 分治处理器:先对每个文档独立执行映射操作(如提取关键词),再将结果合并后统一处理(如生成摘要)。适用于大规模文档的并行处理。 |
RefineDocumentsChain | 迭代优化器:通过多次迭代逐步完善输出,每次处理部分文档并结合前次结果优化最终内容。适合长文档生成或需渐进式改进的场景。 |
MapRerankDocumentsChain | 重排序器:先对每个文档映射处理(如打分),再根据得分排序并筛选高权重文档。常用于优先处理相关性高的内容。 |
ReduceDocumentsChain | 文档压缩器:通过截断、摘要或聚类减少文档数量,解决上下文过长问题。例如,将 100 篇文档压缩为 10 篇关键摘要。 |
create_stuff_documents_chain | 动态文档拼接链:基于 StuffDocumentsChain 的工厂函数,允许动态生成提示模板并直接拼接所有文档内容。支持自定义文档分隔符、头部/尾部提示词注入,适用于需要灵活控制上下文格式的场景(如生成报告、批量问答)。 |
摘要与生成 | |
load_summarize_chain | 摘要流水线:内置预配置链,支持多种摘要模式(Map-Reduce、Refine 等),自动加载文档并生成结构化摘要。 |
QAGenerationChain | 问答对生成器:从文档中提取关键信息,自动生成“问题-答案”对,用于构建训练数据或增强检索效果。 |
AnalyzeDocumentChain | 文档解析器:分析文档结构(如表格、章节)、提取元数据或识别关键实体(如人名、日期),常用于预处理阶段。 |
检索与问答
类型 | 说明 |
---|---|
基础检索 | |
RetrievalQA | 检索增强问答:结合检索器(如向量数据库)与 LLM,先检索相关文档,再生成答案。支持多种检索后端(FAISS、Chroma 等)。 |
VectorDBQA | 向量数据库问答:RetrievalQA 的别名,专为向量数据库设计,支持相似度检索与混合搜索(关键词+向量)。 |
create_retrieval_chain | 动态检索链:根据输入动态选择检索策略(如切换不同数据库或调整检索参数),实现灵活适配。 |
带来源的问答 | |
create_qa_with_sources_chain | 带来源的问答生成器:生成答案的同时自动关联来源片段(如文档段落),输出结构化结果。 |
QAWithSourcesChain | 溯源问答:在答案中标注引用来源(如文档 ID 或段落),适用于需验证可信度的场景(如学术研究)。 |
RetrievalQAWithSourcesChain | 检索溯源问答:在 RetrievalQA 基础上追加来源追踪,输出格式为 {"answer": "...", "sources": [...]} 。 |
VectorDBQAWithSourcesChain | 向量数据库溯源问答:针对向量数据库的扩展,记录检索到的向量片段及其元数据。 |
对话式检索 | |
ConversationalRetrievalChain | 历史感知检索:结合聊天历史优化检索结果(如根据对话上下文调整查询语句),支持连续多轮问答。 |
ChatVectorDBChain | 向量库对话链:旧版对话检索链,已整合至 ConversationalRetrievalChain ,专用于向量数据库历史管理。 |
API 与结构化数据
类型 | 说明 |
---|---|
API 调用 | |
APIChain | 通用 API 调用器:根据自然语言描述生成 API 请求参数(如 URL、Headers),执行调用并解析响应。支持 RESTful 和 GraphQL。(已弃用)被LangGraph 的实现代替。 |
OpenAPIEndpointChain | 规范驱动调用器:基于 OpenAPI 规范自动构建 API 请求,确保参数合法性,适用于标准化接口(如 GitHub API)。 |
LLMRequestsChain | 请求生成器:利用 LLM 解析用户指令生成 HTTP 请求(如构造查询参数),常用于爬虫或自动化工具。 |
SimpleRequestChain | 简易HTTP请求链:执行基础HTTP请求(GET/POST),返回原始响应文本。适用于无需复杂解析的API调用。 |
数据库与图数据 | |
| 用于 将自然语言转换为 SQL 查询并执行 的链。它允许用户通过自然语言与数据库交互,无需手动编写 SQL 语句。 |
create_sql_query_chain | SQL 生成器:将自然语言转换为 SQL 查询语句,执行后返回结果(需配合 SQLDatabase 组件)。 |
GraphQAChain | 图数据库问答:支持多种图数据库(Neo4j、ArangoDB)的通用问答链,自动生成查询语言(如 Cypher)。 |
GraphCypherQAChain | Cypher 查询链:专为 Neo4j 设计,生成并执行 Cypher 查询,处理图结构数据(如社交网络分析)。 |
NeptuneSparqlQAChain | SPARQL 查询链:针对 Amazon Neptune 图数据库,支持 RDF 数据查询与语义推理。 |
ArangoGraphQAChain | ArangoDB 问答链:专为 ArangoDB(多模型数据库)设计,支持 AQL 查询语言,处理文档、图和键值数据。 |
FalkorDBQAChain | FalkorDB 问答链:针对 FalkorDB(高性能图数据库)优化,兼容 Redis 生态,执行高效图遍历查询。 |
HugeGraphQAChain | HugeGraph 问答链:适配百度 HugeGraph 的问答链,支持 Gremlin 查询,适用于大规模图分析场景。 |
KuzuQAChain | Kuzu 问答链:为 KuzuDB(嵌入式图数据库)设计的轻量级链,适合边缘计算或本地化部署。 |
NebulaGraphQAChain | NebulaGraph 问答链:支持 NebulaGraph 的 nGQL 查询语言,擅长分布式图数据的高并发查询。 |
NeptuneOpenCypherQAChain | Neptune OpenCypher 链:兼容 Amazon Neptune 的 OpenCypher 方言,提供与 Neo4j 相似的语法支持。 |
OntotextGraphDBQAChain | Ontotext GraphDB 链:专为语义图数据库 GraphDB 设计,支持 SPARQL 和 RDF 推理,适用于知识图谱场景。 |
GraphSparqlQAChain | 通用 SPARQL 链:跨图数据库的 SPARQL 查询链,兼容任何支持 SPARQL 协议的存储(如 Virtuoso)。 |
逻辑与计算
类型 | 说明 |
---|---|
数学与验证 | |
LLMMathChain | 数学计算器:解析数学问题(如方程、单位换算),调用 Python 计算库(如 SymPy)确保结果精确性。 |
LLMCheckerChain | 逻辑验证器:检查生成内容的逻辑一致性(如事实矛盾、循环论证),支持多轮修正。 |
LLMSummarizationCheckerChain | 摘要校验器:对比原文与摘要的关键信息完整性,防止遗漏或曲解。 |
路由与多链组合 | |
RouterChain | 路由选择器:根据输入内容(如意图识别)动态选择子链执行(如区分“客服问答”和“订单查询”)。 |
MultiPromptChain | 多提示路由:为不同任务分配专用提示词(Prompt),自动匹配最优提示生成回答。 |
LLMRouterChain | LLM 驱动路由器:利用 LLM 分析输入内容(如意图识别),动态选择最优子链执行。 |
MultiRetrievalQAChain | 多检索器路由链:根据问题类型选择不同检索器(如全文检索 vs 向量检索),合并结果生成答案。 |
MultiRouteChain | 通用多路由链:支持自定义路由规则(如正则匹配、关键词检测),扩展性更强。 |
SimpleSequentialChain | 简易顺序链:SequentialChain 的轻量版,仅传递最终结果(不保留中间输出)。 |
SequentialChain | 顺序执行器:严格按顺序执行多个链,前链的输出作为后链的输入,支持中间结果传递。 |
内容生成与增强
类型 | 说明 |
---|---|
生成与扩展 | |
HypotheticalDocumentEmbedder (HyDE) | 假设文档生成器:根据问题生成虚拟文档,提升检索相关性(如“什么是量子计算?”→ 生成假想解释段落用于检索)。 |
FlareChain | 不确定性标记器:在生成内容中标记低置信度部分(如 “[可能需要验证]”),提示用户人工审核。 |
generate_example | 示例生成工具:根据 Schema 生成结构化示例数据,用于测试或引导模型输出格式。 |
结构化输出 | |
create_extraction_chain | 信息抽取器:从文本中提取结构化字段(如 JSON),支持实体、关系、事件抽取(需定义输出 Schema)。 |
create_tagging_chain | 分类打标器:为文本添加多标签分类(如情感极性、主题类别),支持开放式或预定义标签集。 |
create_structured_output_runnable | 格式强制器:确保输出符合预定义格式(如 Pydantic 模型),防止 LLM 自由发挥导致解析失败。 |
create_citation_fuzzy_match_chain | 模糊引文匹配器:从文本中模糊匹配并标准化引文(如论文标题→DOI),支持容错查询。 |
create_citation_fuzzy_match_runnable | 可运行版引文匹配:功能同 create_citation_fuzzy_match_chain ,但返回 LCEL Runnable 对象,便于流式处理。 |
create_extraction_chain_pydantic | Pydantic 抽取器:基于 Pydantic 模型定义输出结构,强制生成符合类型约束的数据(如日期格式校验)。 |
create_tagging_chain_pydantic | Pydantic 打标器:使用 Pydantic 模型定义标签枚举,确保分类结果严格匹配预定义选项。 |
create_qa_with_structure_chain | 结构化问答生成器:强制问答输出为指定 JSON Schema 格式,适合 API 集成场景。 |
对话与历史
类型 | 说明 |
---|---|
ConversationChain | 基础对话链:管理多轮对话历史,支持记忆窗口控制(如仅保留最近 5 轮),内置模板处理对话上下文。(已弃用)使用 RunnableWithMessageHistory函数代替。 |
create_history_aware_retriever | 历史感知检索器:将对话历史融入检索查询(如重写查询语句),提升长对话场景的连贯性。 |
安全与审核
类型 | 说明 |
---|---|
OpenAIModerationChain | 内容审核器:调用 OpenAI Moderation API 检测有害内容(如暴力、仇恨言论),自动拦截违规输出。 |
ConstitutionalChain | 原则审核器:基于预设伦理原则(如“避免偏见”)修正模型输出,实现 Constitutional AI 的自我修正机制。 |
问答评估与生成
Chain | 说明 |
---|---|
QAGenerateChain | 问答对生成链:从文档生成“问题-答案”对,用于构建评估数据集或增强检索。 |
QAEvalChain | 问答评估链:对比模型生成的答案与参考答案,输出准确性评分(如BLEU、ROUGE)。 |
ContextQAEvalChain | 上下文问答评估链:评估答案在给定上下文中的相关性(是否基于文档内容)。 |
CotQAEvalChain | 思维链评估链:评估模型推理过程(Chain-of-Thought)的逻辑一致性,而不仅是最终答案。 |
其他工具链
类型 | 说明 |
---|---|
TransformChain | 自定义转换器:允许注入任意函数处理数据(如清洗文本、计算特征),作为链式流程的中间节点。 |
NatBotChain | 浏览器自动化器:控制浏览器执行点击、表单填写等操作,常用于网页爬取或自动化测试。 |
load_chain | 动态加载器:从配置文件(JSON/YAML)加载链定义,支持热更新与模块化部署。 |
Chain 链的组装方式
函数调用
核心特点
-
面向过程编程:通过实例化 Chain 对象并调用方法逐步执行。
-
手动管理流程:需要开发者显式传递输入/输出,适合简单链或调试场景。
语法示例
from langchain.chains import LLMChain
from langchain.prompts import PromptTemplate
# 定义组件
prompt = PromptTemplate.from_template("翻译成{language}:{text}")
llm = ChatOpenAI(model="gpt-3.5")
# 组装链
chain = LLMChain(llm=llm, prompt=prompt)
# 执行链(显式传递参数)
result = chain.run(language="法语", text="你好!") # 输出:"Bonjour !"
适用场景
-
单链快速测试(如简单问答、翻译)。
-
需要逐步调试中间结果(如查看生成的 Prompt 内容)。
优缺点
优点 | 缺点 |
---|---|
简单直观,学习成本低 | 代码冗余,复杂流程难维护 |
直接控制每一步输入输出 | 不支持流式、异步等高级特性 |
LCEL (LangChain Expression Language)
核心特点
-
声明式编程:用管道符
|
连接组件,类似函数式编程。 -
自动流程管理:输入/输出自动传递,支持异步、流式、并行等高级模式。
语法示例
from langchain_core.runnables import RunnablePassthrough, RunnableParallel
# 定义组件
prompt = PromptTemplate.from_template("翻译成{language}:{text}")
llm = ChatOpenAI(model="gpt-3.5")
output_parser = StrOutputParser()
# 组装链(声明式管道)
chain = (
RunnableParallel({ # 并行提取参数
"language": lambda x: x["lang"],
"text": RunnablePassthrough()
})
| prompt # 生成 Prompt
| llm # 调用模型
| output_parser # 解析输出
)
# 执行链(输入自动路由)
result = chain.invoke({"lang": "法语", "text": "你好!"}) # 输出:"Bonjour !"
适用场景
-
复杂多步骤流程(如 RAG:检索 → 过滤 → 生成 → 审核)。
-
需要高性能、流式响应或并发的生产环境。
-
与其他 LangChain 组件(Agents、Tools)深度集成。
优缺点
优点 | 缺点 |
---|---|
代码简洁,流程可视化 | 学习曲线较陡峭 |
内置异步/流式/批处理 | 调试中间结果需额外配置 |
无缝组合任意组件 | 对简单任务可能显得过度设计 |
两种方式对比
维度 | 函数调用 | LCEL |
---|---|---|
语法复杂度 | 简单,适合少量步骤 | 灵活,适合多组件编排 |
调试便利性 | 易于逐步调试 | 需结合 RunnableLambda 插入调试点 |
性能优化 | 手动实现异步 / 缓存 | 内置异步、缓存、批处理 |
组件兼容性 | 仅支持 Chain 类 | 支持所有 Runnable 对象 |
代码可读性 | 面向过程,逻辑分散 | 声明式,流程清晰 |
参考文献
使用指南 | LangChain中文网