| 大家好,我是工藤学编程 🦉 | 一个正在努力学习的小博主,期待你的关注 |
|---|---|
| 实战代码系列最新文章😉 | C++实现图书管理系统(Qt C++ GUI界面版) |
| SpringBoot实战系列🐷 | 【SpringBoot实战系列】SpringBoot3.X 整合 MinIO 存储原生方案 |
| 分库分表 | 分库分表之实战-sharding-JDBC分库分表执行流程原理剖析 |
| 消息队列 | 深入浅出 RabbitMQ-RabbitMQ消息确认机制(ACK) |
| AI大模型 | 零基础学AI大模型之LangChain核心:Runnable接口底层实现 |
前情摘要
1、零基础学AI大模型之读懂AI大模型
2、零基础学AI大模型之从0到1调用大模型API
3、零基础学AI大模型之SpringAI
4、零基础学AI大模型之AI大模型常见概念
5、零基础学AI大模型之大模型私有化部署全指南
6、零基础学AI大模型之AI大模型可视化界面
7、零基础学AI大模型之LangChain
8、零基础学AI大模型之LangChain六大核心模块与大模型IO交互链路
9、零基础学AI大模型之Prompt提示词工程
10、零基础学AI大模型之LangChain-PromptTemplate
11、零基础学AI大模型之ChatModel聊天模型与ChatPromptTemplate实战
12、零基础学AI大模型之LangChain链
13、零基础学AI大模型之Stream流式输出实战
14、零基础学AI大模型之LangChain Output Parser
15、零基础学AI大模型之解析器PydanticOutputParser
16、零基础学AI大模型之大模型的"幻觉"
17、零基础学AI大模型之RAG技术
18、零基础学AI大模型之RAG系统链路解析与Document Loaders多案例实战
19、零基础学AI大模型之LangChain PyPDFLoader实战与PDF图片提取全解析
20、零基础学AI大模型之LangChain WebBaseLoader与Docx2txtLoader实战
21、零基础学AI大模型之RAG系统链路构建:文档切割转换全解析
22、零基础学AI大模型之LangChain 文本分割器实战:CharacterTextSplitter 与 RecursiveCharacterTextSplitter 全解析
23、零基础学AI大模型之Embedding与LLM大模型对比全解析
24、零基础学AI大模型之LangChain Embedding框架全解析
25、零基础学AI大模型之嵌入模型性能优化
26、零基础学AI大模型之向量数据库介绍与技术选型思考
27、零基础学AI大模型之Milvus向量数据库全解析
28、零基础学AI大模型之Milvus核心:分区-分片-段结构全解+最佳实践
29、零基础学AI大模型之Milvus部署架构选型+Linux实战:Docker一键部署+WebUI使用
30、零基础学AI大模型之Milvus实战:Attu可视化安装+Python整合全案例
31、零基础学AI大模型之Milvus索引实战
32、零基础学AI大模型之Milvus DML实战
33、零基础学AI大模型之Milvus向量Search查询综合案例实战
33、零基础学AI大模型之新版LangChain向量数据库VectorStore设计全解析
34、零基础学AI大模型之相似度Search与MMR最大边界相关搜索实战
35、零基础学AI大模型之LangChain整合Milvus:新增与删除数据实战
36、零基础学AI大模型之LangChain+Milvus实战:相似性搜索与MMR多样化检索全解析
37、零基础学AI大模型之LangChain Retriever
38、零基础学AI大模型之MultiQueryRetriever多查询检索全解析
39、零基础学AI大模型之LangChain核心:Runnable接口底层实现
本文章目录
- 零基础学AI大模型之RunnablePassthrough
-
- 一、RunnablePassthrough:链中的"数据搬运工"
- 二、基础用法:从纯透传到扩展字段
-
- [1. 纯透传:直接传递原始输入](#1. 纯透传:直接传递原始输入)
- [2. 扩展字段:用`.assign()`新增上下文](#2. 扩展字段:用
.assign()新增上下文)
- 三、核心实战:本地模型+Milvus+透传参数
-
- [1. 实战目标](#1. 实战目标)
- [2. 环境准备](#2. 环境准备)
- [3. 完整代码](#3. 完整代码)
- 四、实战关键解析:透传参数的核心价值
- 五、总结:RunnablePassthrough的"轻量但强大"
零基础学AI大模型之RunnablePassthrough
一、RunnablePassthrough:链中的"数据搬运工"

核心功能:保留与扩展输入数据
RunnablePassthrough的核心作用有两个,既简单又实用:
- 纯透传:不修改原始输入,直接传递给下一个组件(比如保留用户问题供后续使用)。
- 扩展上下文 :通过
.assign()方法给输入新增字段,丰富上下文(比如给用户问题附加检索到的文档)。
它就像链中的"数据搬运工",既不破坏原始数据,又能按需补充新数据,解决了"多步骤数据共享"的核心痛点。
关键应用场景
- 链中需要保留用户原始问题,供后续步骤(如输出对比)使用。
- 结合Retriever时,需将"用户问题+检索结果"一起传给Prompt。
- 动态添加固定参数(如请求ID、时间戳)到上下文,便于日志追踪。
二、基础用法:从纯透传到扩展字段
1. 纯透传:直接传递原始输入
当我们需要让原始输入完整进入下一个组件时,直接实例化RunnablePassthrough即可,适合简单的"数据直通"场景。
python
from langchain_core.runnables import RunnablePassthrough
# 初始化本地模型(按你的配置)
from langchain_openai import ChatOpenAI
local_model = ChatOpenAI(
model_name="deepseek-r1:7b",
base_url="http://127.0.0.1:11434/v1",
api_key="none", # 本地模型无需API密钥
temperature=0.7
)
# 构建纯透传链:输入→透传→本地模型
passthrough_chain = RunnablePassthrough() | local_model
# 执行:用户输入直接传给模型
result = passthrough_chain.invoke("什么是RunnablePassthrough?")
print(result.content)
2. 扩展字段:用.assign()新增上下文
更常用的场景是"透传原始数据+新增字段",通过.assign(key=处理函数)实现,处理函数的输入是原始上下文,返回值作为新字段的值。
python
from langchain_core.runnables import RunnablePassthrough
# 构建扩展链:透传原始输入+新增processed_num字段
extend_chain = RunnablePassthrough.assign(
# 新字段processed_num:原始num的2倍
processed_num=lambda x: x["num"] * 2,
# 新字段num_desc:对原始num的描述
num_desc=lambda x: f"原始数字是{x['num']}"
)
# 执行:输入包含num,输出会新增两个字段
input_data = {"num": 5}
result = extend_chain.invoke(input_data)
print(result)
# 输出:{"num":5, "processed_num":10, "num_desc":"原始数字是5"}
三、核心实战:本地模型+Milvus+透传参数
用RunnablePassthrough透传用户问题,同时结合Milvus(检索相关文档,最终让本地模型基于"问题+文档"生成答案。
1. 实战目标
- 透传用户原始问题(
question)到Prompt。 - 用用户问题检索Milvus中的"你的博客相关文档",得到
context。 - 本地模型结合
question和context生成精准回答。
2. 环境准备
先安装依赖(若未安装):
bash
pip install langchain_core langchain_openai langchain_milvus sentence-transformers
3. 完整代码
步骤1:初始化组件(嵌入模型+Milvus+Retriever)
python
from langchain_core.runnables import RunnablePassthrough
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
from langchain_milvus import Milvus
from langchain_core.documents import Document
# 本地嵌入模型(无需API)
from langchain_community.embeddings import SentenceTransformerEmbeddings
# 1. 初始化本地嵌入模型
local_embeddings = SentenceTransformerEmbeddings(model_name="all-MiniLM-L6-v2")
# 2. 准备与你相关的文档(你的博客主题数据)
your_blog_docs = [
Document(
page_content="我的博客《LangChain链》中提到,Chain是组件的串联工具,基于Runnable接口实现。",
metadata={"source": "你的博客-LangChain链"}
),
Document(
page_content="我的博客《RAG技术》中说明,RAG需结合向量库(如Milvus)和大模型,提升回答准确性。",
metadata={"source": "你的博客-RAG技术"}
),
Document(
page_content="我的博客《本地模型部署》中提到,deepseek-r1:7b本地部署后,可通过127.0.0.1:11434调用。",
metadata={"source": "你的博客-本地模型部署"}
)
]
# 3. 初始化Milvus向量库
milvus_vector_store = Milvus.from_documents(
documents=your_blog_docs,
embedding=local_embeddings,
collection_name="your_blog_collection", #
connection_args={"uri": "http://192.168.229.128:19530"} # 你的Milvus地址
)
# 4. 构建Retriever(检索你的博客文档)
blog_retriever = milvus_vector_store.as_retriever(search_kwargs={"k": 2}) # 取Top2相关文档
步骤2:构建带透传参数的完整链
核心逻辑:用字典结构分配context(检索结果)和question(透传用户输入),一起传给Prompt和本地模型。
python
# 1. 初始化你的本地模型
local_model = ChatOpenAI(
model_name="deepseek-r1:7b",
base_url="http://127.0.0.1:11434/v1",
api_key="none",
temperature=0.7
)
# 2. 定义Prompt:结合context和question
prompt = ChatPromptTemplate.from_template("""
基于以下我的博客文档内容,回答用户问题:
{context}
用户问题:{question}
注意:回答要贴合我的博客内容,语言简洁。
""")
# 3. 构建完整链:Retriever+透传→Prompt→本地模型
# 字典中:context来自Retriever,question来自RunnablePassthrough透传
full_chain = (
{
"context": blog_retriever, # 用用户问题检索你的博客文档
"question": RunnablePassthrough() # 透传用户原始问题
}
| prompt # 接收context和question,生成最终提示
| local_model # 本地模型基于提示生成答案
)
步骤3:执行与结果
python
# 执行:输入用户问题,链会自动检索+透传+生成答案
user_question = "我的博客中提到LangChain Chain基于什么实现?"
result = full_chain.invoke(user_question)
# 输出结果
print("本地模型回答:")
print(result.content)
print("\n检索到的博客文档:")
retrieved_docs = blog_retriever.invoke(user_question)
for doc in retrieved_docs:
print(f"- {doc.metadata['source']}:{doc.page_content[:50]}...")
预期输出
本地模型回答:
你的博客《LangChain链》中提到,Chain是组件的串联工具,基于Runnable接口实现。
检索到的博客文档:
- 你的博客-LangChain链:我的博客《LangChain链》中提到,Chain是组件的串联工具,基于Runnable...
- 你的博客-RAG技术:我的博客《RAG技术》中说明,RAG需结合向量库(如Milvus)和大模型,提升回答准...
四、实战关键解析:透传参数的核心价值
在上面的案例中,RunnablePassthrough解决了两个关键问题:
- 数据不丢失 :用户原始问题
question没有被Retriever"消耗",而是完整传递到Prompt,确保模型知道"要回答什么"。 - 上下文扩展 :无需手动拼接
question和context,链会自动将两者整合为Prompt输入,简化代码逻辑。
如果没有RunnablePassthrough,我们需要手动保存原始问题、处理检索结果,代码会增加至少3-5行,且易出错。
五、总结:RunnablePassthrough的"轻量但强大"
RunnablePassthrough看似简单,却是LangChain链中"数据管理"的关键工具,核心优势在于:
- 轻量无侵入:不修改原始数据,仅做传递或扩展,避免数据污染。
- 灵活适配:无论是纯透传、新增字段,还是结合Retriever/本地模型,都能无缝集成。
- 降低复杂度:无需手动处理上下文拼接,让链的逻辑更清晰。
对于使用本地模型和私有Milvus的场景,RunnablePassthrough更是必备工具,能帮你高效管理"用户输入-检索结果-模型输出"的全链路数据。
如果这篇文章对你有帮助,别忘了点赞关注哦!😊