為了讓向量檢索加入鏈,可以使用RunnablePassthrough來實(shí)現(xiàn)
# 導(dǎo)入必要的庫
from langchain_community.chat_models import ChatTongyi # 通義千問聊天模型
from langchain_core.vectorstores import InMemoryVectorStore # 內(nèi)存向量存儲
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 # 可運(yùn)行的通配符,用于傳遞輸入
from langchain_core.documents import Document # 文檔對象
# 初始化聊天模型
# 使用通義千問的 qwen3-max 模型
model = ChatTongyi(model="qwen3-max")
# 創(chuàng)建提示詞模板,包含系統(tǒng)提示和用戶提示
# 系統(tǒng)提示:要求模型以提供的參考資料為主,簡潔專業(yè)地回答問題
# 用戶提示:包含用戶的具體問題
prompt = ChatPromptTemplate.from_messages([
("system", "以我提供的參考資料為主,簡潔和專業(yè)的回答用戶問題。參考資料:{context}。"),
("user", "用戶提問:{input}"),
])
# 初始化內(nèi)存向量存儲,使用 DashScope 嵌入模型
# 嵌入模型用于將文本轉(zhuǎn)換為向量表示,以便進(jìn)行相似度搜索
vector_store = InMemoryVectorStore(embedding=DashScopeEmbeddings(model="text-embedding-v4"))
# 向向量庫中添加文本數(shù)據(jù)
# 這里添加了三條與減肥相關(guān)的文本作為知識儲備
vector_store.add_texts(["減肥就是要少吃多練","在減脂期間吃東西很重要,清淡少油控制卡路里攝入并運(yùn)動起來","跑步是很好的運(yùn)動哦"])
# 用戶輸入的問題
input_text = "如何減肥?"
# 定義一個函數(shù),用于打印提示詞內(nèi)容
# 這樣可以在鏈執(zhí)行過程中看到完整的提示詞
# 同時該函數(shù)會返回原始提示詞,不影響鏈的執(zhí)行
def print_prompt(prompt):
print(prompt.to_string())
print("="*20)
return prompt
# langchain中向量存儲對象,有一個方法:as_retriever,可以返回一個Runnable接口的子類實(shí)例對象
# search_type="similarity" 表示使用相似度搜索
# search_kwargs={"k": 2} 表示返回最相似的2個結(jié)果
retriever = vector_store.as_retriever(search_type="similarity", search_kwargs={"k": 2})
# 定義一個函數(shù),用于格式化檢索到的文檔
# 將文檔列表轉(zhuǎn)換為字符串格式,方便在提示詞中使用
def format_func(docs: list[Document]):
if not docs:
return "無相關(guān)參考資料"
formatted_str = "["
for doc in docs:
formatted_str += f"{doc.page_content}"
formatted_str += "]"
return formatted_str
'''
retriever:
輸入:用戶的提問 str
輸出:向量庫的檢索結(jié)果 list[Document]
prompt:
輸入:用戶的提問+向量庫的檢索結(jié)果 dict
輸出:完整的提示詞 PromptValue
'''
# 構(gòu)建鏈?zhǔn)教幚砹鞒?# 1. 使用字典將輸入分配給不同的鍵:
# - "input": 使用 RunnablePassthrough() 直接傳遞用戶輸入
# - "context": 使用 retriever 檢索相關(guān)文檔,然后通過 format_func 格式化
# 2. 將結(jié)果傳遞給 prompt 模板
# 3. 通過 print_prompt 函數(shù)打印完整提示詞
# 4. 將提示詞傳遞給模型生成回答
# 5. 使用 StrOutputParser 解析模型輸出為字符串
chain = {"input": RunnablePassthrough(), "context": retriever | format_func} | prompt | print_prompt | model | StrOutputParser()
# 執(zhí)行鏈并獲取回答
answer = chain.invoke(input_text)
# 打印回答
print(answer)
System: 以我提供的參考資料為主,簡潔和專業(yè)的回答用戶問題。參考資料:[減肥就是要少吃多練在減脂期間吃東西很重要,清淡少油控制卡路里攝入并運(yùn)動起來]。
Human: 用戶提問:如何減肥?
====================
減肥的關(guān)鍵在于“少吃多練”:
- **飲食方面**:選擇清淡、少油的食物,嚴(yán)格控制每日卡路里攝入;
- **運(yùn)動方面**:堅(jiān)持規(guī)律運(yùn)動,增加熱量消耗。
通過合理飲食與科學(xué)鍛煉相結(jié)合,才能有效減脂并保持健康。