42.RAG开发-29-RunnablePassthrough的使用

为了让向量检索加入链,可以使用RunnablePassthrough来实现


# 导入必要的库
from langchain_community.chat_models import ChatTongyi  # 通义千问聊天模型
from langchain_core.vectorstores import InMemoryVectorStore  # 内存向量存储
from langchain_community.embeddings import DashScopeEmbeddings  #  DashScope 嵌入模型
from langchain_core.prompts import ChatPromptTemplate  # 聊天提示词模板
from langchain_core.output_parsers import StrOutputParser  # 字符串输出解析器
from langchain_core.runnables import RunnablePassthrough  # 可运行的通配符,用于传递输入
from langchain_core.documents import Document  # 文档对象

# 初始化聊天模型
# 使用通义千问的 qwen3-max 模型
model = ChatTongyi(model="qwen3-max")

# 创建提示词模板,包含系统提示和用户提示
# 系统提示:要求模型以提供的参考资料为主,简洁专业地回答问题
# 用户提示:包含用户的具体问题
prompt = ChatPromptTemplate.from_messages([
    ("system", "以我提供的参考资料为主,简洁和专业的回答用户问题。参考资料:{context}。"),
    ("user", "用户提问:{input}"),
])

# 初始化内存向量存储,使用 DashScope 嵌入模型
# 嵌入模型用于将文本转换为向量表示,以便进行相似度搜索
vector_store = InMemoryVectorStore(embedding=DashScopeEmbeddings(model="text-embedding-v4"))

# 向向量库中添加文本数据
# 这里添加了三条与减肥相关的文本作为知识储备
vector_store.add_texts(["减肥就是要少吃多练","在减脂期间吃东西很重要,清淡少油控制卡路里摄入并运动起来","跑步是很好的运动哦"])

# 用户输入的问题
input_text = "如何减肥?"

# 定义一个函数,用于打印提示词内容
# 这样可以在链执行过程中看到完整的提示词
# 同时该函数会返回原始提示词,不影响链的执行
def print_prompt(prompt):
    print(prompt.to_string())
    print("="*20)
    return prompt

# langchain中向量存储对象,有一个方法:as_retriever,可以返回一个Runnable接口的子类实例对象
# search_type="similarity" 表示使用相似度搜索
# search_kwargs={"k": 2} 表示返回最相似的2个结果
retriever = vector_store.as_retriever(search_type="similarity", search_kwargs={"k": 2})

# 定义一个函数,用于格式化检索到的文档
# 将文档列表转换为字符串格式,方便在提示词中使用
def format_func(docs: list[Document]):
    if not docs:
        return "无相关参考资料"
    formatted_str = "["
    for doc in docs:
        formatted_str += f"{doc.page_content}"
    formatted_str += "]"
    return formatted_str

'''

retriever:
    输入:用户的提问         str
    输出:向量库的检索结果    list[Document]

prompt:
    输入:用户的提问+向量库的检索结果    dict
    输出:完整的提示词                  PromptValue

'''

# 构建链式处理流程
# 1. 使用字典将输入分配给不同的键:
#    - "input": 使用 RunnablePassthrough() 直接传递用户输入
#    - "context": 使用 retriever 检索相关文档,然后通过 format_func 格式化
# 2. 将结果传递给 prompt 模板
# 3. 通过 print_prompt 函数打印完整提示词
# 4. 将提示词传递给模型生成回答
# 5. 使用 StrOutputParser 解析模型输出为字符串
chain = {"input": RunnablePassthrough(), "context": retriever | format_func} | prompt | print_prompt | model | StrOutputParser()

# 执行链并获取回答
answer = chain.invoke(input_text)

# 打印回答
print(answer)

System: 以我提供的参考资料为主,简洁和专业的回答用户问题。参考资料:[减肥就是要少吃多练在减脂期间吃东西很重要,清淡少油控制卡路里摄入并运动起来]。
Human: 用户提问:如何减肥?
====================
减肥的关键在于“少吃多练”:  
- **饮食方面**:选择清淡、少油的食物,严格控制每日卡路里摄入;  
- **运动方面**:坚持规律运动,增加热量消耗。  

通过合理饮食与科学锻炼相结合,才能有效减脂并保持健康。
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容