Chains 链
Chains(链)是 LangChain 中的核心概念,它允许我们将多个组件串联起来,形成完整的工作流程。本章将详细介绍各种类型的 Chains 及其使用方法。
什么是 Chain?
Chain 是 LangChain 中的核心抽象,用于将多个组件组合成一条处理流水线。每个组件(如 LLM、Prompt、Tool 等)称为链的"链接(Link)",它们按顺序执行,数据在链接之间流动。
Chain 的工作原理
一个简单的 Chain 示例:
# 组成:PromptTemplate → LLM → OutputParser
用户输入 → 格式化 Prompt → 发送给 LLM → 解析输出
LCEL 语法
LangChain v1 引入了 LCEL(LangChain Expression Language),一种声明式的链式组合语法。
基础语法
from langchain.chat_models import init_chat_model
from langchain.prompts import ChatPromptTemplate
model = init_chat_model(model="gpt-4o-mini", model_provider="openai")
# 简单的管道组合
chain = (
ChatPromptTemplate.from_template("{question}") # 第一个链接
| model # 第二个链接
)
# 调用
response = chain.invoke({"question": "Python 是什么?"})
print(response.content)
为什么使用 LCEL?
- 声明式:更直观地表达数据流
- 可组合:易于组合和复用
- 流式输出:天然支持流式处理
- 异步支持:内置异步支持
LLMChain
最基本的链,用于将 Prompt 模板和 LLM 结合:
from langchain.chat_models import init_chat_model
from langchain.prompts import PromptTemplate
from langchain.chains import LLMChain
# 初始化模型
model = init_chat_model(model="gpt-4o-mini", model_provider="openai")
# 创建 Prompt 模板
prompt = PromptTemplate.from_template(
"请用一句话解释 {concept} 的核心概念"
)
# 创建 LLMChain
chain = LLMChain(llm=model, prompt=prompt)
# 调用
result = chain.invoke({"concept": "Python 装饰器"})
print(result["text"])
完整参数
from langchain.chains import LLMChain
chain = LLMChain(
llm=model, # LLM 实例
prompt=prompt, # Prompt 模板
output_key="answer", # 输出键名(默认 "text")
verbose=True, # 是否打印详细信息
)
转换链(Transformation Chain)
用于对输入进行预处理:
from langchain.chains import TransformChain
from langchain.schema import HumanMessage
# 定义转换函数
def transform_func(input_dict):
text = input_dict["text"]
# 简单的文本处理:转大写
return {"processed_text": text.upper()}
# 创建转换链
transform_chain = TransformChain(
input_variables=["text"],
output_variables=["processed_text"],
transform=transform_func
)
# 测试
result = transform_chain.invoke({"text": "hello world"})
print(result) # {'processed_text': 'HELLO WORLD'}
实际应用:清理用户输入
import re
def clean_input(inputs):
text = inputs["text"]
# 移除多余空白
text = re.sub(r'\s+', ' ', text).strip()
# 移除特殊字符
text = re.sub(r'[^\w\s\u4e00-\u9fff]', '', text)
return {"cleaned_text": text}
clean_chain = TransformChain(
input_variables=["text"],
output_variables=["cleaned_text"],
transform=clean_input
)
Sequential Chain
将多个链按顺序执行:
from langchain.chains import LLMChain, SimpleSequentialChain
from langchain.prompts import PromptTemplate
model = init_chat_model(model="gpt-4o-mini", model_provider="openai")
# Chain 1:提取关键词
chain1 = LLMChain(
llm=model,
prompt=PromptTemplate.from_template(
"从以下文本中提取3个关键词:{text}"
),
output_key="keywords"
)
# Chain 2:生成解释
chain2 = LLMChain(
llm=model,
prompt=PromptTemplate.from_template(
"用一句话解释以下关键词的含义:{keywords}"
),
output_key="explanation"
)
# 组合成顺序链
sequential_chain = SimpleSequentialChain(
chains=[chain1, chain2],
verbose=True
)
# 调用
result = sequential_chain.invoke("Python 装饰器是一种高级函数")
print(result["output"])
使用 LCEL 实现
# 使用 LCEL 实现相同功能
chain = (
{"text": lambda x: x["text"]}
| chain1
| {lambda x: x["keywords"]}
| chain2
)
Router Chain
根据输入动态选择不同的处理路径:
from langchain.chains import LLMRouterChain
from langchain.prompts import PromptTemplate
model = init_chat_model(model="gpt-4o-mini", model_provider="openai")
# 定义目的地
destinations = {
"python": "请解释Python相关问题...",
"java": "请解释Java相关问题...",
"go": "请解释Go相关问题..."
}
# 创建路由提示词
router_template = """
根据用户问题,选择最合适的处理方式。
问题:{input}
可用类别:python, java, go
请只返回类别名称,不要其他内容。
"""
router_chain = LLMRouterChain.from_llm(
model,
prompt=PromptTemplate.from_template(router_template),
destinations=destinations
)
RouterChain 完整示例
from langchain.chains import MultiRouteChain
# 定义多个处理链
python_chain = LLMChain(
llm=model,
prompt=PromptTemplate.from_template("你是一个Python专家。回答:{input}")
)
java_chain = LLMChain(
llm=model,
prompt=PromptTemplate.from_template("你是一个Java专家。回答:{input}")
)
# 路由配置
route_config = {
"python": python_chain,
"java": java_chain,
"default": python_chain # 默认链
}
# 创建多路由链
multi_chain = MultiRouteChain(
router_chain=router_chain,
destination_chains=route_config,
default_chain=python_chain
)
Map-Reduce Chain
对多个输入并行处理,然后合并结果:
from langchain.chains import MapReduceChain
from langchain.text_splitter import RecursiveCharacterTextSplitter
model = init_chat_model(model="gpt-4o-mini", model_provider="openai")
# 文本分割器
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=1000,
chunk_overlap=100
)
# Map 链:对每个chunk进行处理
map_template = "请总结以下内容:{chunk}"
map_chain = LLMChain(
llm=model,
prompt=PromptTemplate.from_template(map_template)
)
# Reduce 链:合并所有结果
reduce_template = "将以下摘要合并成一个完整的摘要:{summaries}"
reduce_chain = LLMChain(
llm=model,
prompt=PromptTemplate.from_template(reduce_template)
)
# Map-Reduce 链
map_reduce_chain = MapReduceChain(
text_splitter=text_splitter,
map_chain=map_chain,
reduce_chain=reduce_chain
)
# 使用
long_text = "..." # 长文本
result = map_reduce_chain.invoke(long_text)
Retrieval Chain
用于基于检索的问答:
from langchain.chains import RetrievalQA
from langchain.retrievers import WikipediaRetriever
model = init_chat_model(model="gpt-4o-mini", model_provider="openai")
# 创建检索器
retriever = WikipediaRetriever()
# 创建问答链
qa_chain = RetrievalQA.from_chain_type(
llm=model,
retriever=retriever,
chain_type="stuff"
)
# 提问
result = qa_chain.invoke("Python 装饰器是什么?")
print(result["result"])
不同的 Chain Type
| 类型 | 说明 | 适用场景 |
|---|---|---|
stuff | 将所有相关文档拼接后输入 | 文档数量少 |
map_reduce | 并行处理每个文档再合并 | 大量文档 |
refine | 逐个处理,结果逐步优化 | 需要逐步完善 |
map_rerank | 并行处理并选择最佳结果 | 需要精准答案 |
自定义 Chain
创建自定义 Chain
from langchain.chains import LLMChain
from langchain.schema import BaseRetriever
class MyCustomChain(LLMChain):
"""自定义 Chain 示例"""
@property
def input_keys(self):
return ["query", "context"]
@property
def output_keys(self):
return ["answer", "sources"]
def _call(self, inputs, run_manager):
# 自定义处理逻辑
context = inputs["context"]
query = inputs["query"]
# 调用 LLM
response = self.llm.invoke(f"基于以下内容回答:{context}\n问题:{query}")
return {
"answer": response.content,
"sources": context
}
使用自定义 Chain
custom_chain = MyCustomChain(
llm=model,
prompt=prompt
)
result = custom_chain.invoke({
"query": "Python 有什么优势?",
"context": "Python 是一种高级编程语言..."
})
实际应用示例
1. 多步骤问答
from langchain.chat_models import init_chat_model
from langchain.prompts import ChatPromptTemplate
model = init_chat_model(model="gpt-4o-mini", model_provider="openai")
# Step 1: 分析问题类型
analyze_template = ChatPromptTemplate.from_template("""
分析用户问题的类型:
问题:{question}
返回以下类型之一:fact, opinion, howto, other
""")
# Step 2: 生成回答
answer_template = ChatPromptTemplate.from_template("""
类型:{question_type}
问题:{question}
请给出恰当的回答
""")
# Step 3: 优化回答
refine_template = ChatPromptTemplate.from_template("""
原始回答:{answer}
请优化以上回答,使其更加完善
""")
# 组合链
chain = (
{"question": lambda x: x["question"]}
| {"question_type": (analyze_template | model | lambda x: x.content.strip())}
| {"question": lambda x: x["question"], "question_type": lambda x: x["question_type"]}
| answer_template
| model
| {"answer": lambda x: x.content}
| {"answer": lambda x: x["answer"]}
| refine_template
| model
)
result = chain.invoke({"question": "如何学习Python?"})
print(result.content)
2. 数据处理管道
# 场景:处理用户提交的数据,提取信息、验证、格式化
from langchain.chains import TransformChain, LLMChain
from langchain.prompts import PromptTemplate
# Step 1: 提取结构化数据
extract_chain = LLMChain(
llm=model,
prompt=PromptTemplate.from_template("""
从以下文本提取JSON格式的信息:
{text}
提取字段:姓名、年龄、职业
""")
)
# Step 2: 验证数据
def validate(inputs):
data = inputs["data"]
# 简单验证
if "年龄" in data and int(data["年龄"]) < 0:
return {"valid": False, "error": "年龄不能为负"}
return {"valid": True, "data": data}
validate_chain = TransformChain(
input_variables=["data"],
output_variables=["valid", "error", "data"],
transform=validate
)
# Step 3: 格式化输出
format_chain = LLMChain(
llm=model,
prompt=PromptTemplate.from_template("""
将以下JSON数据格式化输出为友好的文本:
{data}
""")
)
# 组合
pipeline = extract_chain | validate_chain | format_chain
result = pipeline.invoke({"text": "张三今年28岁,是一名软件工程师"})
Chain 调试
使用 verbose
chain = LLMChain(
llm=model,
prompt=prompt,
verbose=True # 打印详细执行信息
)
使用 LangSmith
# 开启 LangSmith 追踪
export LANGSMITH_TRACING=true
export LANGSMITH_API_KEY="ls-..."
from langsmith import traceable
@traceable
def my_chain(input_data):
return chain.invoke(input_data)
下一步
现在你已经掌握了 Chains 的核心概念,接下来学习: