7.LCEL 五大核心Runnable组件
LCEL 五大核心Runnable组件
前置统一依赖与环境配置
1. 安装依赖
pip install langchain langchain-core langchain-openai loguru python-dotenv
2. .env 文件配置(项目根目录新建)
aliQwen-api=你的阿里云通义千问API Key
3. 公共基础封装(每个文件开头引入)
from langchain_core.output_parsers import StrOutputParser, JsonOutputParser
from langchain_core.prompts import ChatPromptTemplate
import os
from langchain.chat_models import init_chat_model
from loguru import logger
# 统一初始化通义千问兼容接口模型
model = init_chat_model(
model="qwen3.5:9b",
model_provider="openai",
base_url="http://localhost:11434/v1"
)
parser = StrOutputParser()
一、LCEL基础顺序链 RunnableSequence
核心概念
| 管道符底层是 RunnableSequence,串行执行,上游输出作为下游输入;标准链路:Prompt | Model | Parser。
代码
import os
from dotenv import load_dotenv
from loguru import logger
from langchain.chat_models import init_chat_model
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
# 1. 定义带占位符提示词
chat_prompt = ChatPromptTemplate.from_messages([
("system", "你是专业AI助手,回答控制在100字以内"),
("human", "{question}")
])
# 方式1:分步手动执行(调试用)
def run_step_by_step():
prompt_msg = chat_prompt.invoke({"question": "什么是LCEL?"})
logger.info("【分步-完整提示词】", prompt_msg)
ai_msg = model.invoke(prompt_msg)
text = parser.invoke(ai_msg)
logger.info("【分步-最终文本结果】", text)
# 方式2:管道链一键执行(业务标准写法)
chain = chat_prompt | model | parser
def run_pipeline():
res = chain.invoke({"question": "什么是LCEL?"})
logger.info("【管道链执行结果】", res)
if __name__ == "__main__":
run_step_by_step()
print("-" * 50)
run_pipeline()
- 分步执行:拆分模板填充、模型调用、文本解析三步,适合排查每一层原始数据;
- 管道链
|:自动封装顺序执行器,仅传入原始参数字典即可完成全流程; StrOutputParser:剥离模型返回的AIMessage对象,提取纯字符串文本。
二、多步串行复合链(多轮模型调用)
核心概念
连续调用2次及以上大模型,上游输出是纯文本,下游模板需要指定key入参,用 lambda 做字典格式转换。
代码
from langchain_core.output_parsers import StrOutputParser, JsonOutputParser
from langchain_core.prompts import ChatPromptTemplate
import os
from langchain.chat_models import init_chat_model
from loguru import logger
model = init_chat_model(
model="qwen3.5:9b",
model_provider="openai",
base_url="http://localhost:11434/v1"
)
parser = StrOutputParser()
# 子链1:根据topic生成中文简介
prompt_cn = ChatPromptTemplate.from_messages([
("system", "简短中文介绍,50字内"),
("human", "介绍:{topic}")
])
chain_cn = prompt_cn | model | parser
# 子链2:将中文文本翻译英文
prompt_en = ChatPromptTemplate.from_messages([
("system", "直译英文,简洁"),
("human", "{input_text}")
])
chain_en = prompt_en | model | parser
# 组合链路:中文生成 → lambda包装字段 → 英文翻译
full_chain = chain_cn | (lambda text: {"input_text": text}) | chain_en
if __name__ == "__main__":
result = full_chain.invoke({"topic": "LangChain LCEL"})
logger.info("多轮串行最终翻译结果:", result)
- 两条独立子链入参key不同,无法直接串联;
- lambda接收上游纯文本,封装为下游需要的
{"input_text": xxx}; - 执行链路:
{"topic":xxx}→ chain_cn输出文本 → lambda转换字典 → chain_en翻译。
三、自定义函数节点 RunnableLambda
核心概念
RunnableLambda 将任意Python普通函数包装为可接入管道的执行单元,用于日志打印、数据清洗、参数转换。
代码
from langchain_core.output_parsers import StrOutputParser, JsonOutputParser
from langchain_core.prompts import ChatPromptTemplate
import os
from langchain.chat_models import init_chat_model
from langchain_core.runnables import RunnableLambda
model = init_chat_model(
model="qwen3.5:9b",
model_provider="openai",
base_url="http://localhost:11434/v1"
)
parser = StrOutputParser()
# 自定义中间处理函数:打印中间数据并转换格式
def debug_handle(x):
print(f"【Lambda中间节点原始数据】{x}")
return {"content": x}
# 包装为Runnable节点
debug_node = RunnableLambda(debug_handle)
# 子链
prompt_ask = ChatPromptTemplate.from_messages([("human", "简单解释{subject}")])
chain_ask = prompt_ask | model | parser
prompt_trans = ChatPromptTemplate.from_messages([("human", "把下面内容转英文:{content}")])
chain_trans = prompt_trans | model | parser
# 插入自定义节点的完整链路
full_chain = chain_ask | debug_node | chain_trans
if __name__ == "__main__":
res = full_chain.invoke({"subject": "RunnableLambda"})
logger.info("最终输出:", res)
RunnableLambda(func)把普通函数转为管道可识别组件;- 函数入参=上游链路输出,返回值=下游链路输入;
- 适用场景:调试打印、文本过滤、字段映射、自定义校验。
四、并行多任务 RunnableParallel
核心概念
多条子链共用同一输入,并发执行,全部完成后以字典聚合结果,互不阻塞,适合同一输入多风格/多语言生成。
完整可运行代码
from langchain_core.output_parsers import StrOutputParser, JsonOutputParser
from langchain_core.prompts import ChatPromptTemplate
import os
from langchain.chat_models import init_chat_model
from langchain_core.runnables import RunnableLambda, RunnableParallel
model = init_chat_model(
model="qwen3.5:9b",
model_provider="openai",
base_url="http://localhost:11434/v1"
)
parser = StrOutputParser()
# 子链1:中文简介
prompt_cn = ChatPromptTemplate.from_messages([("human", "中文简短介绍{topic}")])
chain_cn = prompt_cn | model | parser
# 子链2:英文简介
prompt_en = ChatPromptTemplate.from_messages([("human", "English brief intro {topic}")])
chain_en = prompt_en | model | parser
# 构建并行链,key为结果标识
parallel_chain = RunnableParallel({
"zh_content": chain_cn,
"en_content": chain_en
})
if __name__ == "__main__":
output = parallel_chain.invoke({"topic": "RunnableParallel"})
logger.info("并行聚合结果:", output)
# 打印链路可视化图
parallel_chain.get_graph().print_ascii()
- 并行链内所有子链共享输入参数
{"topic": xxx}; - 返回字典结构
{"zh_content": "中文结果", "en_content": "英文结果"}; get_graph().print_ascii()打印链路拓扑,用于复杂流程可视化调试。
五、条件路由分支 RunnableBranch
核心概念
类似if-elif-else路由,根据输入自定义判断逻辑,匹配对应子链执行,兜底分支处理未匹配场景。
代码
from langchain_core.output_parsers import StrOutputParser, JsonOutputParser
from langchain_core.prompts import ChatPromptTemplate
import os
from langchain.chat_models import init_chat_model
from langchain_core.runnables import RunnableLambda, RunnableParallel, RunnableBranch
model = init_chat_model(
model="qwen3.5:9b",
model_provider="openai",
base_url="http://localhost:11434/v1"
)
parser = StrOutputParser()
# 三套翻译提示词
prompt_jp = ChatPromptTemplate.from_messages([("system", "日语翻译专家"), ("human", "{query}")])
prompt_kr = ChatPromptTemplate.from_messages([("system", "韩语翻译专家"), ("human", "{query}")])
prompt_en = ChatPromptTemplate.from_messages([("system", "英语翻译专家"), ("human", "{query}")])
# 自定义路由判断函数
def detect_language(inputs):
q = inputs["query"]
if "日语" in q:
return "jp"
elif "韩语" in q:
return "kr"
else:
return "en"
# 构建分支路由链
branch_chain = RunnableBranch(
# 条件1:匹配日语分支
(lambda x: detect_language(x) == "jp", prompt_jp | model | parser),
# 条件2:匹配韩语分支
(lambda x: detect_language(x) == "kr", prompt_kr | model | parser),
# 默认兜底英语分支
prompt_en | model | parser
)
# 批量测试
test_list = [
{"query": "用日语翻译:你好"},
{"query": "用韩语翻译:你好"},
{"query": "翻译:你好"}
]
if __name__ == "__main__":
for item in test_list:
lang_tag = detect_language(item)
logger.info(f"检测语种标识:{lang_tag},输入:{item}")
res = branch_chain.invoke(item)
logger.info(f"分支输出:{res}\n")
RunnableBranch入参格式:(判断lambda, 对应子链), (判断lambda, 子链), 默认子链;- 判断lambda接收完整输入字典,调用自定义函数识别关键词;
- 业务场景:意图分流、多语种路由、客服问答分类。
五大Runnable核心对比总结
| 组件实现方式 | 核心类 | 执行逻辑 | 典型业务场景 |
|---|---|---|---|
| 基础管道 | 自动生成RunnableSequence | 顺序串行,单流程 | 简单问答、单次翻译 |
| 多轮串行 | 管道+lambda转换 | 多次模型串行,格式转换 | 生成内容→润色→翻译 |
| 自定义函数 | RunnableLambda | 插入自定义Python逻辑 | 中间调试、数据清洗 |
| 并发多任务 | RunnableParallel | 多子链并行,结果聚合 | 多语言输出、多风格文案 |
| 条件路由 | RunnableBranch | 输入匹配分支,动态路由 | 语种分流、用户意图分发 |

浙公网安备 33010602011771号