Langchain構建RAG對話應用

本文:關注 檢索器與上下文的子鏈、父鏈;即檢索器也需要上下文內容。

RAG是一種增強LLM知識的方法,通過引入額外的數據來實現。

實現思路:加載—》分割—》存儲—》檢索—》生成。

初始化

import os
import bs4
from langchain.chains.combine_documents import create_stuff_documents_chain
from langchain.chains.history_aware_retriever import create_history_aware_retriever
from langchain.chains.retrieval import create_retrieval_chain
from langchain_chroma import Chroma
from langchain_community.document_loaders import WebBaseLoader
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.runnables import RunnableWithMessageHistory
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_community.chat_message_histories import ChatMessageHistory
from langchain_openai import ChatOpenAI, OpenAIEmbeddingsos.environ['http_proxy'] = '127.0.0.1:7890'
os.environ['https_proxy'] = '127.0.0.1:7890'os.environ["LANGCHAIN_TRACING_V2"] = "true"
os.environ["LANGCHAIN_PROJECT"] = "LangchainDemo"
os.environ["LANGCHAIN_API_KEY"] = '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'
# os.environ["TAVILY_API_KEY"] = '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'# 聊天機器人案例
# 創建模型
model = ChatOpenAI(model='gpt-4-turbo')

加載數據

通過angchain_community..document_loaders import WebBaseLoader加載博客內容數據

返回一個Document列表,每個Document包含web元數據(metadata)、內容(page_content);

##?angchain_community.包含大量工具。

#WebBaseLoader 相當于一個爬蟲,可以爬取多個網頁

# Beautiful Soup的SoupStrainer用于解析HTML文檔時僅提取特定(class_)的部分

# 1、加載數據: 一篇博客內容數據
loader = WebBaseLoader(web_paths=['https://lilianweng.github.io/posts/2023-06-23-agent/'],bs_kwargs=dict(parse_only=bs4.SoupStrainer(class_=('post-header', 'post-title', 'post-content')))
)docs = loader.load()# print(len(docs))
# print(docs)

切割

可以看到,上述Document的內容非常大;因此要進行切割。

# from langchain_text_splitters import RecursiveCharacterTextSplitter

##?chunk_size:分割塊大小;chunk_overlap:允許重復字符(保證語句完整性)

# splitter包含多種切割,還有split_text:切割string、bytes

# 2、大文本的切割
# text = "hello world, how about you? thanks, I am fine.  the machine learning class. So what I wanna do today is just spend a little time going over the logistics of the class, and then we'll start to talk a bit about machine learning"
splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)splits = splitter.split_documents(docs)

test示例

#可以看到第一塊,和第二塊末尾都有how。第一塊 how因補充chunk_size;第二塊how因語序完整性及chunk_overlap而存在。

存儲與檢索

# 根據切割結果,創建向量數據庫

# 2、存儲
vectorstore = Chroma.from_documents(documents=splits, embedding=OpenAIEmbeddings())

# 檢索器

# 3、檢索器
retriever = vectorstore.as_retriever()

創建Prompt和chain

# 創PromptTemplate:系統定位、聊天歷史、用戶輸入。

# 創 chain:create_stuff_documents_chain(model, prompt) :創建多文本的chain

# 創建一個問題的模板
system_prompt = """You are an assistant for question-answering tasks. 
Use the following pieces of retrieved context to answer 
the question. If you don't know the answer, say that you 
don't know. Use three sentences maximum and keep the answer concise.\n{context}
"""
prompt = ChatPromptTemplate.from_messages(  # 提問和回答的 歷史記錄  模板[("system", system_prompt),MessagesPlaceholder("chat_history"),  #("human", "{input}"),]
)chain1 = create_stuff_documents_chain(model, prompt)# 下述測試,因為沒有 chat_history,因此會報錯。
### 將檢索器和已有chain鏈接
# chain2 = create_retrieval_chain(retriever, chain1)# resp = chain2.invoke({'input': "What is Task Decomposition?"})
### resp包含多個key,只取answer。
# print(resp['answer'])

子鏈-歷史記錄

'''注意:
一般情況下,我們構建的鏈(chain)直接使用輸入問答記錄來關聯上下文。

但在此案例中查詢檢索器也需要 對話上下文 才能被理解

#解決辦法
添加一個子鏈(chain),它采用最新用戶問題和聊天歷史,并在它引用歷史信息中的任何信息時重新表述問題。這可以被簡單地認為是構建一個新的“歷史感知”檢索器。
這個子鏈的目的:讓檢索過程融入了對話的上下文

#eg:HumanMessage:它的方法有哪些;這里的‘?它?’即需要結合上下文,才能理解。”

# 子鏈提示詞模板:重新定義子鏈AI的定位(根據用戶新問題和上下文,分析并返回最新真實問題)。

##create_history_aware_retriever(模型、檢索器、子鏈Prompt):用于創建一種??能夠感知對話歷史??的檢索器(Retriever)。它的核心作用是讓檢索過程動態結合之前的對話上下文,從而使當前查詢的檢索結果更精準、更相關。

##create_retrieval_chain(history_chain, chain1):整合倆個鏈。

# 創建一個子鏈
# 子鏈的提示模板
contextualize_q_system_prompt = """Given a chat history and the latest user question 
which might reference context in the chat history, 
formulate a standalone question which can be understood 
without the chat history. Do NOT answer the question, 
just reformulate it if needed and otherwise return it as is."""retriever_history_temp = ChatPromptTemplate.from_messages([('system', contextualize_q_system_prompt),MessagesPlaceholder('chat_history'),("human", "{input}"),]
)# 創建一個子鏈
history_chain = create_history_aware_retriever(model, retriever, retriever_history_temp)# 保持問答的歷史記錄
store = {}def get_session_history(session_id: str):if session_id not in store:store[session_id] = ChatMessageHistory()return store[session_id]# 創建父鏈chain: 把前兩個鏈整合
chain = create_retrieval_chain(history_chain, chain1)# 創建攜帶history的Runnable對象
result_chain = RunnableWithMessageHistory(chain,get_session_history,input_messages_key='input',history_messages_key='chat_history',output_messages_key='answer'
)

1

多輪會話

# 第一輪對話
resp1 = result_chain.invoke({'input': 'What is Task Decomposition?'},config={'configurable': {'session_id': 'zs123456'}}
)print(resp1['answer'])# 第二輪對話
resp2 = result_chain.invoke({'input': 'What are common ways of doing it?'},config={'configurable': {'session_id': 'ls123456'}}
)print(resp2['answer'])

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/76236.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/76236.shtml
英文地址,請注明出處:http://en.pswp.cn/web/76236.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

關于模擬噪聲分析的11個誤區

目錄 1. 降低電路中的電阻值總是能改善噪聲性能 2. 所有噪聲源的噪聲頻譜密度可以相加,帶寬可以在最后計算時加以考慮 3. 手工計算時必須包括每一個噪聲源 4. 應挑選噪聲為ADC 1/10的ADC驅動器 5. 直流耦合電路中必須始終考慮1/f噪聲 6. 因為1/f噪聲隨著頻率降…

vue,uniapp解決h5跨域問題

如果有這樣的跨域問題,解決辦法: ? 第一步:在項目根目錄下創建 vue.config.js 和 package.json 同級目錄。 // vue.config.js module.exports {devServer: {proxy: {/api: {target: https://app.yycjkb.cn, // 你的后端接口地址changeOrig…

SQL通用語法和注釋,SQL語句分類(DDL,DML,DQL,DCL)及案例

目錄 SQL通用語法和注釋 SQL語句分類(DDL,DML,DQL,DCL,TPL,CCL) DDL(數據定義語言) 數據庫操作 查詢(SHOW、SELECT) 創建(CREAT…

Linux:線程概念與控制

??所屬專欄:Linux?? ??作者主頁:嶔某?? Linux:線程概念于控制 var code “d7e241ae-ed4d-475f-aa3d-8d78f873fdca” 概念 在一個程序里的一個執行路線就叫做線程thread。更準確一點:線程是“一個進程內部的控制序列” …

人臉識別聯合行為檢測的辦公管理新模式

基于人臉識別與行為檢測的辦公智能化解決方案 一、背景 在傳統辦公場景中,員工考勤管理、工位使用情況統計、安全監控等環節存在諸多痛點。例如,傳統考勤方式如指紋打卡、刷卡等存在代打卡現象,考勤數據不準確;對于員工是否在工…

ceph weight 和 reweight 的區別

ceph osd df ID CLASS WEIGHT REWEIGHT SIZE RAW USE DATA OMAP META AVAIL %USE VAR PGS STATUS0 nvme 6.98630 0.95508 7.0 TiB 5.0 TiB 4.9 TiB 13 GiB 33 GiB 2.0 TiB 71.10 0.96 83 up1 nvme 6.98630

WInform當今技術特性分析

Windows Forms (WinForms) 技術特性分析 引言 Windows Forms (WinForms) 作為微軟最早推出的基于.NET的圖形用戶界面開發框架,已經存在了20多年。在如今充滿了各種現代UI框架的軟件開發生態系統中,WinForms仍然保持著其獨特的地位。本文將深入分析WinF…

Spark rdd算子解析與實踐

一、RDD基礎回顧 RDD(Resilient Distributed Dataset) 是Spark的核心抽象,代表一個不可變、分區的分布式數據集合。其核心特性包括: 容錯性:通過血緣(Lineage)記錄數據生成過程,支…

sqlite3的API以及命令行

sqlite是目前最流行的嵌入式數據庫。 所謂嵌入式,就是足夠簡單,可以嵌入到我們自己開發的應用程序之中。 在Linux系統中,sqlite的使用只需要使用它的API,連接它的動態連接庫,甚至都不用連接,sqlite的實現…

Allure測試報告按測試終端和測試類型智能分類查看

以下是實現Allure測試報告按測試終端和測試類型智能分類的完整方案: 一、測試框架分層設計 # 項目結構 project/ ├── api_tests/ # API測試 │ └── test_order.py ├── app_tests/ # 移動端測試 │ ├── android/ │ └── ios/ ├── pc_te…

Spine-Leaf 與 傳統三層架構:全面對比與解析

本文將詳細介紹Spine-Leaf架構,深入對比傳統三層架構(Core、Aggre、Access),并探討其與Full-mesh網絡和軟件定義網絡(SDN)的關聯。通過通俗易懂的示例和數據中心網絡分析,我將幫助您理解Spine-L…

圖像預處理-圖像噪點消除

一.基本介紹 噪聲:指圖像中的一些干擾因素,也可以理解為有那么一些點的像素值與周圍的像素值格格不入。常見的噪聲類型包括高斯噪聲和椒鹽噪聲。 濾波器:也可以叫做卷積核 - 低通濾波器是模糊,高通濾波器是銳化 - 低通濾波器就…

安卓手機如何改ip地址教程

對于安卓手機用戶而言,ip修改用在電商、跨境電商、游戲搬磚、社交軟件這些需要開多個賬號的項目。因為多個設備或賬號又不能在同一ip網絡下,所以修改手機的IP地址防檢測成為一個必要的操作。以下是在安卓手機上更改IP地址的多種方法及詳細步驟&#xff0…

對象池模式在uniapp鴻蒙APP中的深度應用

文章目錄 對象池模式在uniapp鴻蒙APP中的深度應用指南一、對象池模式核心概念1.1 什么是對象池模式?1.2 為什么在鴻蒙APP中需要對象池?1.3 性能對比數據 二、uniapp中的對象池完整實現2.1 基礎對象池實現2.1.1 核心代碼結構2.1.2 在Vue組件中的應用 2.2 …

本地部署大模型實現掃描版PDF文件OCR識別!

在使用大模型處理書籍 PDF 時,有時你會遇到掃描版 PDF,也就是說每一頁其實是圖像形式。這時,大模型需要先從圖片中提取文本,而這就需要借助 OCR(光學字符識別)技術。 像 Gemini 2.5 這樣的強大模型&#x…

《Operating System Concepts》閱讀筆記:p700-p732

《Operating System Concepts》學習第 60 天,p700-p732 總結,總計 33 頁。 一、技術總結 1.Virtual machine manager (VMM) The computer function that manages the virtual machine; also called a hypervisor. VMM 也稱為 hypervisor。 2.types …

軟件項目驗收報告模板

軟件項目驗收報告 一、項目基本信息 項目名稱XX智能倉儲管理系統開發單位XX科技有限公司驗收單位XX物流集團合同簽訂日期2023年3月15日項目啟動日期2023年4月1日驗收日期2024年1月20日 二、驗收范圍 入庫管理模塊(包含RFID識別、庫存預警)出庫調度模…

深度學習筆記39_Pytorch文本分類入門

🍨 本文為🔗365天深度學習訓練營 中的學習記錄博客🍖 原作者:K同學啊 | 接輔導、項目定制 一、我的環境 1.語言環境:Python 3.8 2.編譯器:Pycharm 3.深度學習環境: torch1.12.1cu113torchvision…

二分查找-LeetCode

題目 給定一個 n 個元素有序的(升序)整型數組 nums 和一個目標值 target,寫一個函數搜索 nums 中的 target,如果目標值存在返回下標,否則返回 -1。 示例 1: 輸入: nums [-1,0,3,5,9,12], target 9 輸出: 4 解釋: …

從 Ext 到 F2FS,Linux 文件系統與存儲技術全面解析

與 Windows 和 macOS 操作系統不同,Linux 是由愛好者社區開發的大型開源項目。它的代碼始終可供那些想要做出貢獻的人使用,任何人都可以根據個人需求自由調整它,或在其基礎上創建自己的發行版本。這就是為什么 Linux 存在如此多的變體&#x…