【datawhale組隊學習】RAG技術 - TASK02

教程地址:https://github.com/datawhalechina/all-in-rag/
感謝datawhale的教程,以下筆記大部分內容來自該教程

文章目錄

  • 基于LangChain框架的RAG實現
    • 初始化設置
    • 數據準備
    • 索引構建
    • 查詢與檢索
    • 生成集成
  • 低代碼(基于LlamaIndex)

conda activate all-in-rag
# 假設當前在 all-in-rag 項目的根目錄下
cd code/C1
#運行代碼
python 01_langchain_example.py

在這里插入圖片描述
輸出的參數

  • content: 這是最核心的部分,即大型語言模型(LLM)根據你的問題和提供的上下文生成的具體回答。
  • additional_kwargs: 包含一些額外的參數,在這個例子中是 {‘refusal’: None},表示模型沒有拒絕回答。
  • response_metadata: 包含了關于LLM響應的元數據。
  • token_usage: 顯示了本次調用消耗的token數量,包括完成(completion_tokens)、提示(prompt_tokens)和總量(total_tokens)。
  • model_name: 使用的LLM模型名稱,當前是 deepseek-chat。
  • system_fingerprint, id, service_tier, finish_reason, logprobs: 這些是更詳細的API響應信息,例如 finish_reason: ‘stop’ 表示模型正常完成了生成。
  • id: 本次運行的唯一標識符。
  • usage_metadata: 與 response_metadata 中的 token_usage 類似,提供了輸入和輸出token的統計。

如果沒有魔法,且下載模型失敗
在shell中從huggingface下載模型

export HF_ENDPOINT=https://hf-mirror.com
hf download --local-dir ./bge-small-zh-v1.5  BAAI/bge-small-zh-v1.5 

在使用的時候顯示指定位置在哪個路徑。

基于LangChain框架的RAG實現

初始化設置

import os
# os.environ['HF_ENDPOINT'] = 'https://hf-mirror.com'
from dotenv import load_dotenv
from langchain_community.document_loaders import TextLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_huggingface import HuggingFaceEmbeddings
from langchain_core.vectorstores import InMemoryVectorStore
from langchain_core.prompts import ChatPromptTemplate
from langchain_deepseek import ChatDeepSeek# 加載環境變量
load_dotenv()

數據準備

  1. 加載原始文檔: 先定義Markdown文件的路徑,然后使用TextLoader加載該文件作為知識源
markdown_path = "../../data/C1/markdown/easy-rl-chapter1.md"
loader = TextLoader(markdown_path)
docs = loader.load()
  1. 文本分塊 (Chunking): 為了便于后續的嵌入和檢索,長文檔被分割成較小的、可管理的文本塊(chunks)。這里采用了遞歸字符分割策略,使用其默認參數進行分塊。當不指定參數初始化 RecursiveCharacterTextSplitter() 時,其默認行為旨在最大程度保留文本的語義結構:
  • 默認分隔符與語義保留: 按順序嘗試使用一系列預設的分隔符 [“\n\n” (段落), “\n” (行), " " (空格), “” (字符)] 來遞歸分割文本。這種策略的目的是盡可能保持段落、句子和單詞的完整性,因為它們通常是語義上最相關的文本單元,直到文本塊達到目標大小。
  • 保留分隔符: 默認情況下 (keep_separator=True),分隔符本身會被保留在分割后的文本塊中。
  • 默認塊大小與重疊: 使用其基類 TextSplitter 中定義的默認參數 chunk_size=4000(塊大小)和 chunk_overlap=200(塊重疊)。這些參數確保文本塊符合預定的大小限制,并通過重疊來減少上下文信息的丟失。
text_splitter = RecursiveCharacterTextSplitter()
texts = text_splitter.split_documents(docs)

索引構建

初始化中文嵌入模型+構建向量存儲
HugginfaceEmbeddings+InMemoeyVectorStore
初始化中文嵌入模型: 使用HuggingFaceEmbeddings加載之前在初始化設置中下載的中文嵌入模型。配置模型在CPU上運行,并啟用嵌入歸一化 (normalize_embeddings: True)。

embeddings = HuggingFaceEmbeddings(model_name="BAAI/bge-small-zh-v1.5",model_kwargs={'device': 'cpu'},#配置模型在CPU上運行encode_kwargs={'normalize_embeddings': True}#啟用嵌入歸一化
)

構建向量存儲: 將分割后的文本塊 (texts) 通過初始化好的嵌入模型轉換為向量表示,然后使用InMemoryVectorStore將這些向量及其對應的原始文本內容添加進去,從而在內存中構建出一個向量索引。

vectorstore = InMemoryVectorStore(embeddings)
vectorstore.add_documents(texts)

查詢與檢索

索引構建完畢后,便可以針對用戶問題進行查詢與檢索:
定義用戶查詢: 設置一個具體的用戶問題字符串。

question = "文中舉了哪些例子?"

在向量存儲中查詢相關文檔: 使用向量存儲的similarity_search方法,根據用戶問題在索引中查找最相關的 k (此處示例中 k=3) 個文本塊。

retrieved_docs = vectorstore.similarity_search(question, k=3)

準備上下文: 將檢索到的多個文本塊的頁面內容 (doc.page_content) 合并成一個單一的字符串,并使用雙換行符 (“\n\n”) 分隔各個塊,形成最終的上下文信息 (docs_content) 供大語言模型參考。

docs_content = "\n\n".join(doc.page_content for doc in retrieved_docs)

使用 “\n\n” (雙換行符) 而不是 “\n” (單換行符) 來連接不同的檢索文檔塊,主要是為了在傳遞給大型語言模型(LLM)時,能夠更清晰地在語義上區分這些獨立的文本片段。雙換行符通常代表段落的結束和新段落的開始,這種格式有助于LLM將每個塊視為一個獨立的上下文來源,從而更好地理解和利用這些信息來生成回答。

生成集成

最后一步是將檢索到的上下文與用戶問題結合,利用大語言模型(LLM)生成答案:

  • 構建提示詞模板: 使用ChatPromptTemplate.from_template創建一個結構化的提示模板。此模板指導LLM根據提供的上下文 (context) 回答用戶的問題 (question),并明確指出在信息不足時應如何回應。
prompt = ChatPromptTemplate.from_template("""請根據下面提供的上下文信息來回答問題。
請確保你的回答完全基于這些上下文。
如果上下文中沒有足夠的信息來回答問題,請直接告知:“抱歉,我無法根據提供的上下文找到相關信息來回答此問題。”上下文:
{context}問題: {question}回答:"""

配置大語言模型: 初始化ChatDeepSeek客戶端,配置所用模型 (deepseek-chat)、生成答案的溫度參數 (temperature=0.7)、最大Token數 (max_tokens=2048) 以及API密鑰 (從環境變量加載)。

llm = ChatDeepSeek(model="deepseek-chat",temperature=0.7,max_tokens=2048,api_key=os.getenv("DEEPSEEK_API_KEY")
)

調用LLM生成答案并輸出: 將用戶問題 (question) 和先前準備好的上下文 (docs_content) 格式化到提示模板中,然后調用ChatDeepSeek的invoke方法獲取生成的答案。

answer = llm.invoke(prompt.format(question=question, context=docs_content))
print(answer)
# 文本分塊
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000,      # 增大塊大小,每個塊約1000字符chunk_overlap=200,    # 增大重疊部分,保持上下文連貫性separators=["\n\n", "\n", " ", ""]  # 自定義分割符)

調整chunksize和chunk_overlap

在這里插入圖片描述

print(answer.content)#獲取回答

在這里插入圖片描述

參數調整對輸出的影響

  1. chunk_size 的影響:
  • 較小的chunk_size(如 500):文本塊更細碎,檢索到的信息可能更精準但不完整
  • 較大的chunk_size(如 2000):文本塊更完整,上下文信息更豐富,但可能包含冗余內容
  1. chunk_overlap 的影響:
  • 較小的chunk_overlap(如 50):文本塊獨立性強,可能丟失跨塊的上下文關聯
  • 較大的chunk_overlap(如 300):增強了塊之間的連貫性,適合處理有連續邏輯的文本,但會增加冗余

低代碼(基于LlamaIndex)

在RAG方面,LlamaIndex提供了更多封裝好的API接口,這無疑降低了上手門檻,下面是一個簡單實現:

import os
# os.environ['HF_ENDPOINT']='https://hf-mirror.com'
from dotenv import load_dotenv
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader, Settings 
from llama_index.llms.deepseek import DeepSeek
from llama_index.embeddings.huggingface import HuggingFaceEmbeddingload_dotenv()
#環境設置
#模型配置
Settings.llm = DeepSeek(model="deepseek-chat", api_key=os.getenv("DEEPSEEK_API_KEY"))
## 設置使用 DeepSeek 的聊天模型作為語言模型
Settings.embed_model = HuggingFaceEmbedding("BAAI/bge-small-zh-v1.5")
## 設置使用 BAAI 的中文小型嵌入模型進行文本向量化documents = SimpleDirectoryReader(input_files=["../../data/C1/markdown/easy-rl-chapter1.md"]).load_data()
## 從指定路徑加載 Markdown 文檔內容
index = VectorStoreIndex.from_documents(documents)
# 將文檔內容轉換為向量索引,便于后續的相似性搜索
query_engine = index.as_query_engine()
# 創建查詢引擎,用于處理自然語言查詢
print(query_engine.get_prompts()) # 打印使用的提示詞模板
print(query_engine.query("文中舉了哪些例子?")) # 執行查詢并打印結果

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

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

相關文章

Mitt 事件發射器完全指南:200字節的輕量級解決方案

簡介 Mitt 是一個輕量級的事件發射器庫,體積小巧(約 200 字節),無依賴,支持 TypeScript。它提供了簡單而強大的事件發布/訂閱機制,適用于組件間通信、狀態管理等場景。 特點 🚀 超輕量級&…

數據庫鎖與死鎖-筆記

一、概述 數據庫是一個共享資源,可以供給多個用戶使用。運行多個用戶同時使用一個數據庫的數據系統統稱多用戶數據庫系統。例如,飛機訂票數據庫系統。在這樣的一個系統中,在同一時刻并發運行的事務數可達數百上千個。 當多個用戶并發地存取數據庫時就會產生多個事務同時存…

滲透藝術系列之Laravel框架(二)

任何軟件,都會存在安全漏洞,我們應該將攻擊成本不斷提高!?**——服務容器與中間件的攻防博弈**?本文章僅提供學習,切勿將其用于不法手段!一、服務容器的"依賴注入陷阱"1.1 接口綁定的"影子服務"…

官網SSO登錄系統的企業架構設計全過程

第一階段:架構愿景與業務架構設計 (Architecture Vision & Business Architecture) 任何架構的起點都必須是業務目標和需求。 1.1 核心業務目標 (Business Goals) 提升用戶體驗:用戶一次登錄,即可無縫訪問集團下所有子公司的官網和應用&a…

2025世界機器人大會:中國制造“人形時代”爆發

2025世界機器人博覽會8月8日在北京亦莊開幕,主題為“讓機器人更智慧,讓具身體更智能”,匯聚全球200余家企業、1500余件展品,其中首發新品超100款,人形機器人整機企業參展數量創同類展會之最。 除了機器人本體外&#…

Oracle 庫定期備份表結構元數據信息至目標端備份腳本

一、背景描述當前 xxx 項目 Oracle 11g RAC 庫缺少 DG,并且日常沒有備份,存在服務器或存儲損壞,數據或表結構存在丟失風險,在和項目組同步后,項目組反饋可對該數據庫定期備份相關結構信息,如存在數據丟失&a…

wps安裝后win系統瀏覽窗口無法查看

前提需要有安裝office軟件,PDF一般默認是瀏覽器,如果設置瀏覽器不行,就安裝Adobe Acrobat DC軟件1、按winR鍵,輸入regedit,進入注冊表2、找到路徑:\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Current…

Qt 中最經典、最常用的多線程通信場景

實現步驟創建工作類 (Worker):在工作線程中處理數據的對象。創建線程對象 (QThread):用來托管工作對象。連接信號槽:主線程 -> 工作線程:連接一個主窗口發出的信號到工作對象的槽,用于傳遞數據。工作線程 -> 主線…

【CV 目標檢測】Fast RCNN模型①——與R-CNN區別

3.Fast RCNN模型 相比于R-CNN,Fast RCNN模型主要在以下三個方面進行了改進: 提高訓練和預測速度 R-CNN首先從測試圖中提取2000個候選區域,然后將這2000個候選區域分別輸入到預訓練好的CNN中提取特征。由于候選區域有大量的重疊,這…

Zookeeper學習

要精通 ZooKeeper,需要掌握其核心原理、數據模型、分布式協調機制、典型應用場景、運維管理與性能調優等方面的知識。以下是系統化的知識體系:? 一、ZooKeeper 基礎原理ZooKeeper 是什么 分布式協調服務,提供一致性、高可用的元數據管理核心…

用TestComplete打造高效CI/CD測試流程

傳統的UI測試往往受限于圖形界面渲染,導致執行速度慢、資源占用高,難以適應持續集成/持續交付(CI/CD)管道的需求。自動化UI測試平臺TestComplete的智能質量附加組件通過無頭測試技術,為開發團隊提供了一種更高效、更可…

C++ 淺拷貝 和深拷貝的知識點講解

好問題 👍,這個就是理解 delete 的關鍵前置知識。 我從 C語言基礎 出發,像教科書一樣,從零講給你聽。1. 什么是“拷貝”? 在 C 中,當你有一個對象 A,然后寫: Device_Info a; Device…

Arkts加載網頁url的pdf發票黑屏問題

使用模擬器會閃退,連接真機預覽正常import { HMRouter, HMRouterMgr, HMParamType, HMPageParam } from "hadss/hmrouter"; import { BaseTitle, RouterConstants } from "commonlib"; import { webview } from kit.ArkWeb; import { PDFView }…

使用 mongosh 設置 MongoDB 賬號密碼

可以使用 mongosh(MongoDB 6.0+ 的現代Shell)來設置賬號密碼。mongosh 是官方推薦的新一代MongoDB Shell工具,替代了傳統的 mongo 命令。 【本人博文提到的ip均為隨機生成的,不是實際的ip,僅供參考,如有雷同,純屬巧合】 使用 mongosh 設置 MongoDB 賬號密碼 1. 首先連…

HTML+CSS:浮動詳解

在HTMLCSS布局中,浮動(float) 是一種經典的布局技術,用于控制元素在頁面中的排列方式。它最初設計用于實現文字環繞圖片的效果,后來被廣泛用于復雜布局,但隨著Flexbox和Grid的興起,其使用場景有…

GPIO初始化及調用

下面把 HAL 庫 和 標準外設庫(SPL) 初始化 GPIO 點亮/熄滅 LED 的完整步驟、示例代碼和常用 API 逐一說清楚。用例默認 PC13 接 LED(藍板常見;低電平點亮,高電平熄滅——若板子相反,只把寫 1/0 對調即可&am…

【GPT入門】第48課 LlamaFacotory 合并原模型與LoRA模型

【GPT入門】第48課 LlamaFacotory 合并原模型與LoRA模型1.合并原模型與LoRA訓練的增量模型2. 測試模型1.合并原模型與LoRA訓練的增量模型 llamafactory-cli webui 執行合并 合并后模型大小 (base) rootautodl-container-b4b04ea4f2-b5ee47d1:~# du -sh /root/autodl-tmp/mod…

Python爬蟲實戰:研究tumblr,構建博客平臺數據采集分析系統

1. 引言 1.1 研究背景 在信息爆炸的時代,社交媒體平臺已成為人們獲取信息、表達觀點和進行社交互動的主要渠道。這些平臺上積累的海量數據包含了用戶偏好、社會趨勢、文化現象等豐富信息,對學術研究、市場分析、產品開發等領域具有重要價值。 Tumblr 作為一個綜合性的輕博客…

集成算法學習總結

一、集成學習基礎認知 核心思想:集成學習(ensemble learning)通過構建并結合多個個體學習器來完成學習任務,類似于 “多個專家共同決策”,通常比單個學習器的性能更優。其核心邏輯是利用多個學習器的優勢互補&#xff…

線程安全的產生以及解決方案

線程安全原子性(Atomicity)、可見性(Visibility)、有序性(Ordering) 是保證線程安全的三大核心要素 —— 線程安全問題的本質,幾乎都是這三個特性中的一個或多個被破壞導致的。操作不會被 “中途…