RAG 中的語義分塊:實現更優的上下文檢索
檢索增強生成(RAG)技術異軍突起,席卷了整個大語言模型領域。通過將大語言模型(LLMs)的強大能力與外部知識檢索相結合,RAG使得模型能夠生成準確且有依據的回復,即便在專業領域也不例外。在每一個表現卓越的RAG流程背后,都有一個默默發揮關鍵作用的 “英雄”:分塊技術,尤其是語義分塊。
RAG生態系統與分塊的作用
RAG代表了人工智能系統獲取和利用知識方式的重大變革。傳統的大語言模型僅依賴于其預先訓練的知識,這可能存在局限性或時效性問題。RAG通過在生成過程中從外部資源(如數據庫、文檔或互聯網)檢索相關信息,很好地解決了這一局限性。這些外部知識就像補充彈藥,極大地擴展了模型的知識邊界,使其能夠應對各種復雜問題。
在RAG流程中,分塊是至關重要的一環。分塊指的是在對文檔進行嵌入和索引之前,將其分割成較小單元的過程。這些分塊在查詢時被檢索出來,并輸入到大語言模型中用于生成回復。然而,分塊并非簡單的切割操作,其方式直接影響著RAG系統的性能。如果分塊過大,它們可能無法適配模型的上下文窗口,導致信息丟失;而如果分塊過小或分割不當,語義信息會被破壞,使模型難以理解和處理,進而影響最終回復的質量。
分塊面臨的挑戰
以一段醫學文章為例,假設內容如下:“蝙蝠俠主要在哥譚市活動,這是一個犯罪猖獗、腐敗橫行的大都市。他的宿敵小丑在混亂和不可預測中如魚得水。盡管布魯斯·韋恩資助了哥譚市的許多社會項目,但他仍在為自己作為億萬富翁和義警的雙重身份而苦苦掙扎。” 如果使用簡單的分塊方法,可能會將其分割為:
- 分塊1:“蝙蝠俠主要在哥譚市活動,這是一個犯罪猖獗的”
- 分塊2:“大都市,腐敗橫行。他的宿敵小丑,”
- 分塊3:“在混亂和不可預測中如魚得水。盡管布魯斯·韋恩”
- 分塊4:“資助了哥譚市的許多社會項目,但他仍在為......”
此時,若用戶提問:“是什么讓蝙蝠俠的生活如此矛盾?” 檢索器可能會隨機獲取到句子中間的某個分塊,或者遺漏關于他雙重身份的關鍵信息,進而導致給出的答案籠統或錯誤。這清晰地展現了不恰當分塊帶來的問題,突出了語義分塊的重要性和必要性。
語義分塊詳解
語義分塊旨在以一種保留每個單元有意義、自包含上下文的方式分割文檔。它尊重自然的邊界,比如段落、句子或主題,確保每個分塊都能獨立回答相關的查詢。實現語義分塊通常涉及以下幾個關鍵步驟:
- 句子邊界檢測
準確識別句子的起止位置,這是保留語義完整性的基礎。因為句子是表達完整思想的基本語言單位,正確劃分句子邊界有助于將相關信息歸為一組。
- 主題建模或基于嵌入的分割
主題建模可以分析文檔內容,將具有相似主題的部分劃分為一個分塊。基于嵌入的分割則利用詞或句子的嵌入向量,通過計算向量之間的相似度來確定分割點,在語義發生變化的地方進行分割,使每個分塊內的語義更加連貫。
- 使用重疊窗口保留上下文
為了避免在分割過程中丟失上下文信息,通常會采用重疊窗口的方法。即相鄰分塊之間有一定比例的重疊內容,這樣可以確保在檢索和處理分塊時,前后信息能夠相互關聯,增強模型對上下文的理解。
分塊策略對比
常見的分塊策略有多種,從簡單到語義化程度高依次介紹如下:
- 固定大小分塊(簡單方法)
在Python的LangChain庫中,可以使用 CharacterTextSplitter
進行固定大小分塊。示例代碼如下:
from langchain.text_splitter import CharacterTextSplitter
splitter = CharacterTextSplitter(chunk_size=500, chunk_overlap=50)
chunks = splitter.split_text(document)
這種方法的優點是簡單直接,易于實現。但它存在明顯的缺陷,可能會在句子中間進行分割,破壞句子的完整性和上下文連貫性,影響語義的表達。
- 基于句子的分塊
借助 NLTKTextSplitter
可以實現基于句子的分塊,示例代碼為:
from langchain.text_splitter import NLTKTextSplitter
splitter = NLTKTextSplitter(chunk_size=3, chunk_overlap=1)
chunks = splitter.split_text(document)
- 該方法能夠保留句子邊界,一定程度上保證了語義的完整性。然而,它可能仍然會在分塊過程中分割主題,導致一個主題被分散到多個分塊中,不利于模型對完整主題的理解和處理。
- 遞歸分塊
RecursiveCharacterTextSplitter
提供了遞歸分塊的功能,代碼如下:
from langchain.text_splitter import RecursiveCharacterTextSplitter
splitter = RecursiveCharacterTextSplitter(
separators=["\n\n", "\n", ".", " ", ""],
chunk_size=500,
chunk_overlap=100
)
chunks = splitter.split_text(document)
遞歸分塊嘗試在較大的邊界(如段落、句子、單詞)上進行分割,能夠在分塊長度和語義保持之間取得較好的平衡。不過,它可能仍然需要根據具體應用場景進行微調,以達到最佳效果。
- 基于嵌入的語義分塊(高級方法)
這種技術利用句子嵌入來在語義發生變化的地方分割文本。示例代碼如下:
from sentence_transformers import SentenceTransformer, util
import nltk
model = SentenceTransformer('all-MiniLM-L6-v2')
sentences = nltk.sent_tokenize(document)
embeddings = model.encode(sentences)
similarities = [util.cos_sim(embeddings[i], embeddings[i+1]) for i in range(len(embeddings)-1)]
chunks = []
chunk = [sentences[0]]
for i, score in enumerate(similarities):
if score < 0.6: # 可根據需要調整閾值
chunks.append(" ".join(chunk))
chunk = []
chunk.append(sentences[i+1])
if chunk:
chunks.append(" ".join(chunk))
基于嵌入的語義分塊能夠真正實現語義層面的分割,對于包含豐富主題的文檔效果顯著。但它的計算復雜度較高,處理速度相對較慢,實現過程也更為復雜。
評估分塊質量
分塊策略的優劣直接影響RAG系統下游的各個環節,因此評估分塊質量至關重要。可以從以下幾個方面進行評估:
指標
- 與真實情況的分塊重疊度(如使用Recall@k指標)通過計算分塊與理想分塊(真實情況)的重疊比例,衡量分塊的準確性。重疊度越高,說明分塊結果越接近理想狀態,能夠更好地保留相關信息。
- 嵌入一致性(分塊內相似度應較高)評估分塊內文本的嵌入向量之間的相似度。如果分塊內的文本相似度高,意味著分塊內的語義連貫性好,模型更容易理解和處理。
- 模型回答準確率(端到端RAG評估)通過實際輸入查詢,觀察模型基于分塊生成的回答的準確率。這是最直接評估分塊策略對RAG系統整體性能影響的指標。
工具
- LangChain RAG評估器LangChain庫提供的評估器可以方便地對RAG系統進行評估,包括對分塊效果的評估。
- Ragas這是一個專門用于評估RAG系統的工具包,能夠從多個維度對分塊質量進行分析。
- 帶有真實相關性標簽的自定義問答對通過創建自定義的問答對,并標注問題與答案之間的相關性,可以針對性地評估分塊策略在特定任務上的表現。
最佳實踐
為了實現有效的語義分塊,需要遵循以下最佳實踐:
- 優先選擇基于句子或語義感知的分塊方式
這種方式能夠更好地保留語義信息,提高模型對上下文的理解能力。
- 合理使用分塊重疊
通常,50 - 100個標記的重疊是比較合適的。分塊重疊可以確保相鄰分塊之間的信息連貫性,避免因分割導致的上下文丟失。
- 根據具體應用場景調整分塊大小
不同類型的文檔(如法律文檔和推文)對分塊大小的要求不同。法律文檔通常內容復雜、信息量大,可能需要較大的分塊;而推文內容簡短,分塊大小應相應減小。
- 利用元數據(如標題、副標題)進行層次感知分塊
元數據可以提供文檔的結構信息,幫助在分塊時更好地考慮文檔的層次結構,使分塊結果更符合邏輯。
- 持續評估、迭代和重新訓練檢索器
隨著數據的變化和應用場景的調整,分塊策略可能需要不斷優化。通過持續評估分塊質量,對檢索器進行迭代和重新訓練,可以確保RAG系統始終保持良好的性能。
語義分塊在現實中的巨大影響
語義分塊對于實際的RAG系統來說至關重要,甚至可以決定系統的成敗。以一個企業應用案例(法律合同問答機器人)為例,從簡單分塊切換到遞歸 + 語義分塊后,取得了顯著的效果:
- 答案準確率提高23%
語義分塊使得機器人能夠更準確地理解問題的上下文,從合同文檔中檢索到更相關的信息,從而生成更準確的答案。
- 幻覺現象減少41%
在生成式模型中,幻覺是一個常見問題,即模型生成看似合理但實際上錯誤的信息。語義分塊通過提供更準確的上下文,有效減少了這種現象的發生。
- 檢索器命中率從62% 提升到87%
語義分塊優化了分塊的內容和結構,使檢索器能夠更精準地匹配用戶的查詢,大大提高了命中率。
語義分塊是RAG技術中不可或缺的關鍵環節。它通過優化文檔的分割方式,提升了上下文檢索的效果,進而顯著提高了RAG系統的性能。隨著人工智能技術的不斷發展,語義分塊技術也將不斷演進和完善,為更多領域的應用提供有力支持。無論是開發內部知識機器人,還是構建特定領域的智能助手,深入理解和應用語義分塊技術都將帶來巨大的優勢,推動人工智能應用向更加智能、高效的方向發展。