偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

總結(jié)了 13 個 頂級 RAG 技術(shù)

人工智能
改進(jìn) RAG 系統(tǒng)的檢索和生成能力對于打造更優(yōu)秀的 AI 應(yīng)用至關(guān)重要。本文討論的技術(shù)涵蓋從低投入、高效率的方法(查詢重寫、重新排序)到更復(fù)雜的流程(嵌入和 LLM 微調(diào))。最佳技術(shù)取決于你應(yīng)用的具體需求和限制。

AI 能否大規(guī)模生成真正相關(guān)的答案?我們?nèi)绾未_保它理解復(fù)雜的多輪對話?我們?nèi)绾畏乐顾p率地吐出錯誤的事實?這些都是現(xiàn)代 AI 系統(tǒng)面臨的挑戰(zhàn),尤其是使用 RAG 構(gòu)建的系統(tǒng)。RAG 將文檔檢索的強(qiáng)大功能與語言生成的流暢性相結(jié)合,使系統(tǒng)能夠基于上下文感知、基于事實的響應(yīng)來回答問題。雖然基本的 RAG 系統(tǒng)在處理簡單任務(wù)時表現(xiàn)良好,但在處理復(fù)雜查詢、幻聽以及長時間交互中的上下文記憶時,它們往往會遇到問題。這時,高級 RAG 技術(shù)就派上用場了。

在本篇博文中,我們將探討如何升級你的 RAG 流水線,從而增強(qiáng)堆棧的每個階段:索引、檢索和生成。我們將逐步介紹一些強(qiáng)大的方法(并附上實際代碼),這些方法可以幫助你提升相關(guān)性、降低噪音并擴(kuò)展系統(tǒng)性能——無論你是構(gòu)建醫(yī)療助理、教育導(dǎo)師還是企業(yè)知識機(jī)器人。

基本 RAG 的不足之處是什么?

讓我們看一下基本 RAG 框架:

圖片圖片

這個 RAG 系統(tǒng)架構(gòu)展示了向量存儲中塊嵌入的基本存儲方式。第一步是加載文檔,然后使用各種分塊技術(shù)對其進(jìn)行拆分或分塊,最后使用嵌入模型進(jìn)行嵌入,以便 LLM 能夠輕松理解。

這張圖描繪了RA G的檢索和生成步驟:用戶提出一個問題,然后我們的系統(tǒng)通過搜索 Vector 庫,根據(jù)該問題提取結(jié)果。檢索到的內(nèi)容連同問題一起傳遞給 LLM,LLM 提供結(jié)構(gòu)化的輸出。

基本的 RAG 系統(tǒng)有明顯的局限性,尤其是在苛刻的情況下。

  • 幻覺:幻覺是一個主要問題。該模型創(chuàng)建的內(nèi)容在事實上是錯誤的,或者沒有源文檔的支持。這會損害可靠性,尤其是在醫(yī)學(xué)或法律等精確性至關(guān)重要的領(lǐng)域。
  • 缺乏領(lǐng)域特異性:標(biāo)準(zhǔn) RAG 模型難以處理專業(yè)主題。如果不根據(jù)領(lǐng)域的具體細(xì)節(jié)調(diào)整檢索和生成過程,系統(tǒng)可能會發(fā)現(xiàn)不相關(guān)或不準(zhǔn)確的信息。
  • 復(fù)雜對話:基本的 RAG 系統(tǒng)難以處理復(fù)雜的查詢或多輪對話。它們經(jīng)常在交互過程中丟失上下文信息,導(dǎo)致答案不連貫或不完整。RAG 系統(tǒng)必須能夠處理日益復(fù)雜的查詢。

因此,我們將逐一介紹 RAG 堆棧的高級 RAG 技術(shù),即索引、檢索和生成。我們將討論如何使用開源庫和資源進(jìn)行改進(jìn)。無論你構(gòu)建的是醫(yī)療聊天機(jī)器人、教育機(jī)器人還是其他應(yīng)用程序,這些高級 RAG 技術(shù)都具有普遍適用性。它們將改進(jìn)大多數(shù) RAG 系統(tǒng)。

讓我們從高級 RAG 技術(shù)開始吧!

索引和分塊:構(gòu)建堅實的基礎(chǔ)

良好的索引對于任何 RAG 系統(tǒng)都至關(guān)重要。第一步涉及如何導(dǎo)入、拆分和存儲數(shù)據(jù)。讓我們探索索引數(shù)據(jù)的方法,重點介紹如何索引和分塊文本以及使用元數(shù)據(jù)。

1. HNSW

Hierarchical Navigable Small Worlds (HNSW)是一種在大型數(shù)據(jù)集中查找相似項的有效算法。它使用基于圖的結(jié)構(gòu)化方法,幫助快速定位近似最近鄰 (ANN) 。

  • 鄰近圖:HNSW 構(gòu)建了一個圖,其中每個點都連接到附近的點。這種結(jié)構(gòu)可以實現(xiàn)高效的搜索。
  • 層次結(jié)構(gòu):該算法將點組織成多層。頂層連接較遠(yuǎn)的點,而較低層連接較近的點。這種設(shè)置加快了搜索過程。
  • 貪婪路由:HNSW 使用貪婪算法來尋找鄰居。它從高階點開始,然后移動到最近的鄰居,直到達(dá)到局部最小值。這種方法減少了查找相似項目所需的時間。

HNSW如何運作?

HNSW 的工作包括幾個關(guān)鍵部分:

  1. 輸入層:每個數(shù)據(jù)點表示為高維空間中的向量。
  2. 圖形構(gòu)造:
  • 每次將一個節(jié)點添加到圖中。
  • 每個節(jié)點根據(jù)概率函數(shù)被分配到某一層。該函數(shù)決定了節(jié)點被放置在更高層的可能性。
  • 該算法平衡了連接數(shù)和搜索速度。
  1. 搜索過程:
  • 搜索從頂層的特定入口點開始。
  • 該算法每一步都會移動到最近的鄰居。
  • 一旦達(dá)到局部最小值,它就會轉(zhuǎn)移到下一個較低層并繼續(xù)搜索,直到找到底層的最近點。
  1. 參數(shù):
  • M:連接到每個節(jié)點的鄰居數(shù)量。
  • efConstruction:此參數(shù)影響算法在構(gòu)建圖形時考慮的鄰居數(shù)量。
  • efSearch:此參數(shù)影響搜索過程,確定要評估多少個鄰居。

HNSW 的設(shè)計使其能夠快速準(zhǔn)確地找到相似的項目。這使得它成為需要在大型數(shù)據(jù)集中高效搜索的任務(wù)的理想選擇。

圖片圖片

該圖描繪了一個簡化的 HNSW 搜索:算法從“入口點”(藍(lán)色)開始,將圖導(dǎo)航至“查詢向量”(黃色)?!白罱彙保l紋)是通過基于鄰近度的邊遍歷來識別的。這說明了高效近似最近鄰搜索的圖導(dǎo)航核心概念。

體驗 HNSW

請按照以下步驟使用 FAISS 實現(xiàn)分層可導(dǎo)航小世界 (HNSW) 算法。本指南包含示例輸出,用于說明該過程。

步驟 1:設(shè)置 HNSW 參數(shù)

首先,定義 HNSW 索引的參數(shù)。需要指定向量的大小以及每個節(jié)點的鄰居數(shù)量。

import faiss
import numpy as np
# Set up HNSW parameters
d = 128  # Size of the vectors
M = 32   # Number of neighbors for each nodel

步驟 2:初始化 HNSW 索引

使用上面定義的參數(shù)創(chuàng)建 HNSW 索引。

# Initialize the HNSW index
index = faiss.IndexHNSWFlat(d, M)

步驟 3:設(shè)置 efConstruction

在將數(shù)據(jù)添加到索引之前,請設(shè)置 efConstruction 參數(shù)。此參數(shù)控制算法在構(gòu)建索引時考慮的鄰居數(shù)量。

efConstruction = 200  # Example value for efConstruction
index.hnsw.efConstruction = efConstruction

步驟4:生成示例數(shù)據(jù)

在此示例中,生成要索引的隨機(jī)數(shù)據(jù)。其中,“xb”表示要索引的數(shù)據(jù)集。

# Generate random dataset of vectors
n = 10000  # Number of vectors to index
xb = np.random.random((n, d)).astype('float32')
# Add data to the index
index.add(xb)  # Build the index

步驟 5:設(shè)置 efSearch

建立索引后,設(shè)置 efSearch 參數(shù)。此參數(shù)影響搜索過程。

efSearch = 100  # Example value for efSearch
index.hnsw.efSearch = efSearch

步驟 6:執(zhí)行搜索

現(xiàn)在,你可以搜索查詢向量的最近鄰。這里,“xq”表示查詢向量。

# Generate random query vectors
nq = 5  # Number of query vectors
xq = np.random.random((nq, d)).astype('float32')
# Perform a search for the top k nearest neighbors
k = 5  # Number of nearest neighbors to retrieve
distances, indices = index.search(xq, k)
# Output the results
print("Query Vectors:\n", xq)
print("\nNearest Neighbors Indices:\n", indices)
print("\nNearest Neighbors Distances:\n", distances)

輸出

查詢向量:

 [[0.12345678 0.23456789 ... 0.98765432] 
 [0.23456789 0.34567890 ... 0.87654321] 
 [0.34567890 0.45678901 ... 0.76543210] 
 [0.45678901 0.56789012 ... 0.65432109] 
 [0.56789012 0.67890123 ... 0.54321098]]

最近鄰索引:

 [[123 456 789 101 112] 
 [234 567 890 123 134] 
 [345 678 901 234 245] 
 [ 456 789 012 345 356] 
 [ 567 890 123 456 467]]

最近鄰距離:

 [[0.123 0.234 0.345 0.456 0.567] 
 [0.234 0.345 0.456 0.567 0.678] 
 [0.345 0.456 0.567 0.678 0.789] 
 [0.456 0.567 0.678 0.789 0.890] 
 [0.567 0.678 0.789 0.890 0.901]]

2. 語義分塊

這種方法根據(jù)含義而非固定大小劃分文本。每個塊代表一段連貫的信息。我們計算句子嵌入之間的余弦距離。如果兩個句子語義相似(低于閾值),則將它們歸入同一塊。這會根據(jù)內(nèi)容的含義創(chuàng)建不同長度的塊。

  • 優(yōu)點:創(chuàng)建更連貫、更有意義的塊,改善檢索。
  • 缺點:需要更多計算(使用基于 BERT 的編碼器)。

動手語義分塊

from langchain_experimental.text_splitter import SemanticChunker
from langchain_openai.embeddings import OpenAIEmbeddings
text_splitter = SemanticChunker(OpenAIEmbeddings())
docs = text_splitter.create_documents([document])
print(docs[0].page_content)

這段代碼使用了 LangChain 的 SemanticChunker,它使用 OpenAI 嵌入將文檔拆分為語義相關(guān)的塊。它創(chuàng)建的文檔塊旨在捕獲連貫的語義單元,而不是任意的文本片段。

3.基于語言模型的分塊

這種先進(jìn)的方法使用語言模型從文本中創(chuàng)建完整的語句。每個塊在語義上都是完整的。語言模型(例如,一個擁有 70 億個參數(shù)的模型)負(fù)責(zé)處理文本。它將文本分解成各自有意義的語句。然后,該模型將這些語句組合成塊,在完整性和上下文之間取得平衡。這種方法計算量很大,但準(zhǔn)確率很高。

  • 優(yōu)點:適應(yīng)文本的細(xì)微差別并創(chuàng)建高質(zhì)量的塊。
  • 缺點:計算成本高;可能需要針對特定用途進(jìn)行微調(diào)。

基于語言模型的分塊實踐

async def generate_contexts(document, chunks):
   asyncdef process_chunk(chunk):
       response = await client.chat.completions.create(
           model="gpt-4o",
           messages=[
               {"role": "system", "content": "Generate a brief context explaining how this chunk relates to the full document."},
               {"role": "user", "content": f"<document> \n{document} \n</document> \nHere is the chunk we want to situate within the whole document \n<chunk> \n{chunk} \n</chunk> \nPlease give a short succinct context to situate this chunk within the overall document for the purposes of improving search retrieval of the chunk. Answer only with the succinct context and nothing else."}
           ],
           temperature=0.3,
           max_tokens=100
       )
       context = response.choices[0].message.content
       returnf"{context} {chunk}"
   # Process all chunks concurrently
   contextual_chunks = await asyncio.gather(
       *[process_chunk(chunk) for chunk in chunks]
   )
   return contextual_chunks

此代碼片段利用 LLM(可能是 OpenAI 的 deepseek,通過 client.chat.completions.create 調(diào)用)為文檔的每個塊生成上下文信息。它異步處理每個塊,促使 LLM 解釋該塊與完整文檔的關(guān)系。最后,它返回一個原始塊列表,并在列表前面添加了生成的上下文,從而有效地豐富了這些塊,從而改進(jìn)了搜索檢索。

4. 利用元數(shù)據(jù):添加上下文

添加和過濾元數(shù)據(jù)

元數(shù)據(jù)提供額外的上下文信息,從而提高檢索的準(zhǔn)確性。通過添加日期、患者年齡和既往病史等元數(shù)據(jù),你可以在搜索過程中過濾掉不相關(guān)的信息。過濾功能可以縮小搜索范圍,提高檢索效率和相關(guān)性。索引時,請將元數(shù)據(jù)與文本一起存儲。

例如,醫(yī)療保健數(shù)據(jù)包括患者記錄中的年齡、就診日期和具體病情。使用這些元數(shù)據(jù)來篩選搜索結(jié)果,確保系統(tǒng)只檢索相關(guān)信息。例如,如果查詢與兒童相關(guān),則過濾掉 18 歲以上患者的記錄。這可以減少噪音并提高相關(guān)性。

例子

塊 #1

Source Metadata:  {'id': 'doc:1c6f3e3f7ee14027bc856822871572dc:26e9aac7d5494208a56ff0c6cbbfda20', 'source': 'https://plato.stanford.edu/entries/goedel/'}

源文本:

2.2.1 The First Incompleteness Theorem
In his Logical Journey (Wang 1996) Hao Wang published the
full text of material G?del had written (at Wang’s request)
about his discovery of the incompleteness theorems. This material had
formed the basis of Wang’s “Some Facts about Kurt
G?del,” and was read and approved by G?del:

塊 #2

Source Metadata:  {'id': 'doc:1c6f3e3f7ee14027bc856822871572dc:d15f62c453c64072b768e136080cb5ba', 'source': 'https://plato.stanford.edu/entries/goedel/'}

源文本:

The First Incompleteness Theorem provides a counterexample to
completeness by exhibiting an arithmetic statement which is neither
provable nor refutable in Peano arithmetic, though true in the
standard model. The Second Incompleteness Theorem shows that the
consistency of arithmetic cannot be proved in arithmetic itself. Thus
G?del’s theorems demonstrated the infeasibility of the
Hilbert program, if it is to be characterized by those particular
desiderata, consistency and completeness.

在這里,我們可以看到元數(shù)據(jù)包含塊的唯一 ID 和來源,這為塊提供了更多上下文并有助于輕松檢索。

5. 使用 GLiNER 生成元數(shù)據(jù)

你不會總是擁有大量的元數(shù)據(jù),但使用像 GLiNER 這樣的模型可以動態(tài)生成元數(shù)據(jù)!GLiNER 在攝取過程中標(biāo)記和標(biāo)記塊以創(chuàng)建元數(shù)據(jù)。

執(zhí)行

為每個塊添加標(biāo)簽以供 GLiNER 識別。如果找到標(biāo)簽,它會對其進(jìn)行標(biāo)記。如果沒有匹配的標(biāo)簽,則不會生成標(biāo)簽。 通常情況下效果良好,但對于小眾數(shù)據(jù)集可能需要進(jìn)行微調(diào)。這提高了檢索準(zhǔn)確率,但增加了一個處理步驟。GLiNER 可以解析傳入的查詢,并將其與元數(shù)據(jù)標(biāo)簽進(jìn)行匹配以進(jìn)行過濾。

GLiNER:使用雙向 Transformer 進(jìn)行命名實體識別的通用模型演示:

這些技術(shù)構(gòu)建了強(qiáng)大的 RAG 系統(tǒng),能夠高效地從大型數(shù)據(jù)集中檢索數(shù)據(jù)。分塊和元數(shù)據(jù)的使用取決于數(shù)據(jù)集的具體需求和特性。

檢索:找到正確的信息

現(xiàn)在,我們來關(guān)注一下 RAG 中的“R”。如何改進(jìn)向量數(shù)據(jù)庫的檢索?這指的是檢索與查詢相關(guān)的所有文檔。這大大提高了 LLM 生成高質(zhì)量結(jié)果的幾率。以下是一些技巧:

6.Hybrid Search混合搜索

結(jié)合向量搜索(查找語義含義)和關(guān)鍵詞搜索(查找精確匹配)?;旌纤阉骷婢邇烧叩膬?yōu)勢。在人工智能領(lǐng)域,許多術(shù)語都是特定的關(guān)鍵詞:算法名稱、技術(shù)術(shù)語、LLM (LLM)。單獨的向量搜索可能會遺漏這些術(shù)語。關(guān)鍵詞搜索可以確保這些重要術(shù)語得到考慮。結(jié)合兩種方法可以創(chuàng)建更完整的檢索流程。這些搜索同時運行。

使用加權(quán)系統(tǒng)對結(jié)果進(jìn)行合并和排序。例如,使用 Weaviate,你可以調(diào)整 alpha 參數(shù)來平衡向量和關(guān)鍵詞結(jié)果。這樣就可以創(chuàng)建一個合并的排序列表。

  • 優(yōu)點:平衡精度和召回率,提高檢索質(zhì)量。
  • 缺點:需要仔細(xì)調(diào)整重量。

動手混合搜索

from langchain_community.retrievers import WeaviateHybridSearchRetriever
from langchain_core.documents import Document
retriever = WeaviateHybridSearchRetriever(
   client=client,
   index_name="LangChain",
   text_key="text",
   attributes=[],
   create_schema_if_missing=True,
)
retriever.invoke("the ethical implications of AI")

此代碼初始化了一個 WeaviateHybridSearchRetriever,用于從 Weaviate 矢量數(shù)據(jù)庫中檢索文檔。它將矢量搜索和關(guān)鍵字搜索結(jié)合到了 Weaviate 的混合檢索功能中。最后,它執(zhí)行了一個名為“the ethical implications of AI”的查詢,并使用此混合方法檢索相關(guān)文檔。

7.查詢重寫

認(rèn)識到人類查詢可能并非數(shù)據(jù)庫或語言模型的最佳選擇。使用語言模型重寫查詢可以顯著提高檢索效果。

  • 向量數(shù)據(jù)庫重寫:這將用戶的初始查詢轉(zhuǎn)換為數(shù)據(jù)庫友好的格式。例如,“什么是人工智能代理以及為什么它們是 2025 年的下一個大事件”可以轉(zhuǎn)換為“人工智能代理是 2025 年的重大事件”。我們可以使用任何 LLM 來重寫查詢,以便它能夠捕捉查詢的重要方面。
  • 語言模型的提示重寫:這涉及自動創(chuàng)建提示以優(yōu)化與語言模型的交互。這可以提高結(jié)果的質(zhì)量和準(zhǔn)確性。我們可以使用 DSPy 等框架或任何 LLM 來重寫查詢。這些重寫的查詢和提示確保搜索過程檢索到相關(guān)文檔,并有效地提示語言模型。

多查詢檢索

查詢措辭的細(xì)微變化可能會導(dǎo)致檢索結(jié)果不同。如果嵌入不能準(zhǔn)確反映數(shù)據(jù)的含義,這個問題可能會更加突出。為了應(yīng)對這些挑戰(zhàn),通常會采用快速工程或調(diào)優(yōu)的方法,但這個過程可能非常耗時。

MultiQueryRetriever簡化了這項任務(wù)。它使用大型語言模型 (LLM),基于單個用戶輸入從不同角度創(chuàng)建多個查詢。對于每個生成的查詢,它會檢索一組相關(guān)文檔。MultiQueryRetriever通過整合所有查詢的獨特結(jié)果, 提供了更廣泛的潛在相關(guān)文檔集。這種方法提高了找到有用信息的機(jī)會,而無需進(jìn)行大量的手動調(diào)整。

from langchain_openai import ChatOpenAI
chatgpt = ChatOpenAI(model_name="gpt-4o", temperature=0)
from langchain.retrievers.multi_query import MultiQueryRetriever
# Set logging for the queries
import logging
similarity_retriever3 = chroma_db3.as_retriever(search_type="similarity",
                                               search_kwargs={"k": 2})
mq_retriever = MultiQueryRetriever.from_llm(
   retriever=similarity_retriever3, llm=chatgpt,
   include_original=True
)
logging.basicConfig()
# so we can see what queries are generated by the LLM
logging.getLogger("langchain.retrievers.multi_query").setLevel(logging.INFO)
query = "what is the capital of India?"
docs = mq_retriever.invoke(query)
docs

此代碼使用 LangChain 構(gòu)建了一個多查詢檢索系統(tǒng)。它會生成輸入查詢(“what is the capital of India?”)的多個變體。然后,這些變體會通過相似性檢索器查詢 Chroma 向量數(shù)據(jù)庫 (chroma_db3),旨在擴(kuò)大搜索范圍并捕獲各種相關(guān)文檔。MultiQueryRetriever 最終會聚合并返回檢索到的文檔。

輸出

[Document(metadata={'article_id': '5117', 'title': 'New Delhi'},
 page_cnotallow='New Delhi () is the capital of India and a union territory of
 the megacity of Delhi. It has a very old history and is home to several
 monuments where the city is expensive to live in. In traditional Indian
 geography it falls under the North Indian zone. The city has an area of
 about 42.7\xa0km. New Delhi has a population of about 9.4 Million people.'),

 Document(metadata={'article_id': '4062', 'title': 'Kolkata'},
 page_cnotallow="Kolkata (spelled Calcutta before 1 January 2001) is the
 capital city of the Indian state of West Bengal. It is the second largest
 city in India after Mumbai. It is on the east bank of the River Hooghly.
 When it is called Calcutta, it includes the suburbs. This makes it the third
 largest city of India. This also makes it the world's 8th largest
 metropolitan area as defined by the United Nations. Kolkata served as the
 capital of India during the British Raj until 1911. Kolkata was once the
 center of industry and education. However, it has witnessed political
 violence and economic problems since 1954. Since 2000, Kolkata has grown due
 to economic growth. Like other metropolitan cities in India, Kolkata
 struggles with poverty, pollution and traffic congestion."),

 Document(metadata={'article_id': '22215', 'title': 'States and union
 territories of India'}, page_cnotallow='The Republic of India is divided into
 twenty-eight States,and eight union territories including the National
 Capital Territory.')]

8. LLM基于提示的上下文壓縮檢索

上下文壓縮有助于提高檢索文檔的相關(guān)性。這主要通過兩種方式實現(xiàn):

  • 提取相關(guān)內(nèi)容:刪除檢索到的文檔中與查詢無關(guān)的部分。這意味著只保留回答問題的部分。
  • 過濾不相關(guān)文檔:排除與查詢無關(guān)的文檔,而不改變文檔本身的內(nèi)容。

為了實現(xiàn)這一點,我們可以使用 LLMChainExtractor,它會審查最初返回的文檔,并僅提取與查詢相關(guān)的內(nèi)容。它也可能刪除完全不相關(guān)的文檔。

以下是使用 LangChain 實現(xiàn)此目的的方法:

from langchain.retrievers import ContextualCompressionRetriever
from langchain.retrievers.document_compressors import LLMChainExtractor
from langchain_openai import ChatOpenAI
# Initialize the language model
chatgpt = ChatOpenAI(model_name="gpt-4o", temperature=0)

# Set up a similarity retriever
similarity_retriever = chroma_db3.as_retriever(search_type="similarity", search_kwargs={"k": 3})

# Create the extractor to get relevant content
compressor = LLMChainExtractor.from_llm(llm=chatgpt)

# Combine the retriever and the extractor
compression_retriever = ContextualCompressionRetriever(base_compressor=compressor, base_retriever=similarity_retriever)

# Example query
query = "What is the capital of India?"
docs = compression_retriever.invoke(query)
print(docs)

輸出:

[Document(metadata={'article_id': '5117', 'title': 'New Delhi'},
 page_cnotallow='New Delhi is the capital of India and a union territory of the 
megacity of Delhi.')]

對于不同的查詢:

query = "What is the old capital of India?"
docs = compression_retriever.invoke(query)
print(docs)

輸出

[Document(metadata={'article_id': '4062', 'title': 'Kolkata'},
 page_cnotallow='Kolkata served as the capital of India during the British Raj
 until 1911.')]

LLMChainFilter 提供了一種更簡單但有效的文檔過濾方法。它使用 LLM 鏈來決定哪些文檔需要保留、哪些文檔需要丟棄,且不會改變文檔的內(nèi)容。

以下是實現(xiàn)過濾器的方法:

from langchain.retrievers.document_compressors import LLMChainFilter
# Set up the filter
_filter = LLMChainFilter.from_llm(llm=chatgpt)
# Combine the retriever and the filter
compression_retriever = ContextualCompressionRetriever(base_compressor=_filter, base_retriever=similarity_retriever)

# Example query
query = "What is the capital of India?"
docs = compression_retriever.invoke(query)
print(docs)

輸出:

[Document(metadata={'article_id': '5117', 'title': 'New Delhi'},
 page_cnotallow='New Delhi is the capital of India and a union territory of the
 megacity of Delhi.')]

對于另一個查詢:

query = "What is the old capital of India?"
docs = compression_retriever.invoke(query)
print(docs)

輸出:

[Document(metadata={'article_id': '4062', 'title': 'Kolkata'},
 page_cnotallow='Kolkata served as the capital of India during the British Raj
 until 1911.')]

這些策略通過關(guān)注相關(guān)內(nèi)容來幫助優(yōu)化檢索過程。“LLMChainExtractor”僅提取文檔的必要部分,而“LLMChainFilter”則決定保留哪些文檔。這兩種方法都提高了檢索信息的質(zhì)量,使其與用戶的查詢更加相關(guān)。

9. 微調(diào)嵌入模型

預(yù)先訓(xùn)練好的嵌入模型是一個不錯的開始。根據(jù)你的數(shù)據(jù)對這些模型進(jìn)行微調(diào)可以顯著提升檢索效果。

選擇合適的模型:對于醫(yī)學(xué)等專業(yè)領(lǐng)域,請選擇基于相關(guān)數(shù)據(jù)預(yù)訓(xùn)練的模型。例如,你可以使用 MedCPT 系列查詢和文檔編碼器,這些編碼器已基于 PubMed 搜索日志中的 2.55 億個查詢-文章對進(jìn)行大規(guī)模預(yù)訓(xùn)練。

使用正樣本對和負(fù)樣本對進(jìn)行微調(diào):收集你自己的數(shù)據(jù),并創(chuàng)建相似(正樣本)和不相似(負(fù)樣本)的樣本對。對模型進(jìn)行微調(diào)以理解這些差異。這有助于模型學(xué)習(xí)特定領(lǐng)域的關(guān)系,從而改進(jìn)檢索。

  • 優(yōu)點:提高檢索性能。
  • 缺點:需要精心創(chuàng)建的訓(xùn)練數(shù)據(jù)。

這些技術(shù)的組合構(gòu)建了一個強(qiáng)大的檢索系統(tǒng)。這提高了提供給 LLM 的對象的相關(guān)性,從而提升了生成質(zhì)量。

生成:制作高質(zhì)量的響應(yīng)

最后,我們來討論一下如何提高語言模型 (LLM) 的生成質(zhì)量。目標(biāo)是為 LLM 提供盡可能與提示相關(guān)的上下文。不相關(guān)的數(shù)據(jù)可能會引發(fā)幻覺。以下是一些提高生成質(zhì)量的技巧:

10.自動剪切以刪除不相關(guān)信息

Autocut 會過濾掉從數(shù)據(jù)庫中檢索到的不相關(guān)信息,從而防止LLM 被誤導(dǎo)。

  • 檢索和評分相似度:進(jìn)行查詢時,將檢索具有相似度分?jǐn)?shù)的多個對象。
  • 識別并剔除:使用相似度得分找到一個得分顯著下降的臨界點。排除超出此點的對象。這確保只向 LLM 提供最相關(guān)的信息。例如,如果你檢索了六個對象,那么在第四個之后,得分可能會急劇下降。通過查看變化率,你可以確定要排除哪些對象。
from langchain_openai import OpenAIEmbeddings
from langchain_pinecone import PineconeVectorStore
from typing import List
from langchain_core.documents import Document
from langchain_core.runnables import chain
vectorstore = PineconeVectorStore.from_documents(
   docs, index_name="sample", embedding=OpenAIEmbeddings()
)
@chain
def retriever(query: str):
   docs, scores = zip(*vectorstore.similarity_search_with_score(query))
   for doc, score in zip(docs, scores):
       doc.metadata["score"] = score
   return docs
 result = retriever.invoke("dinosaur")
result

此代碼片段使用 LangChain 和 Pinecone 執(zhí)行相似性搜索。它使用 OpenAI 嵌入來嵌入文檔,將其存儲在 Pinecone 向量存儲中,并定義一個檢索器函數(shù)。檢索器搜索與給定查詢(“dinosaur”)相似的文檔,計算相似度分?jǐn)?shù),并將這些分?jǐn)?shù)添加到文檔元數(shù)據(jù)中,然后返回結(jié)果。

輸出

[Document(page_cnotallow='In her second book, Dr. Simmons delves deeper into
 the ethical considerations surrounding AI development and deployment. It is
 an eye-opening examination of the dilemmas faced by developers,
 policymakers, and society at large.', metadata={}),

 Document(page_cnotallow='A comprehensive analysis of the evolution of
 artificial intelligence, from its inception to its future prospects. Dr.
 Simmons covers ethical considerations, potentials, and threats posed by
 AI.', metadata={}),

 Document(page_cnotallow="In his follow-up to 'Symbiosis', Prof. Sterling takes
 a look at the subtle, unnoticed presence and influence of AI in our everyday
 lives. It reveals how AI has become woven into our routines, often without
 our explicit realization.", metadata={}),

 Document(page_cnotallow='Prof. Sterling explores the potential for harmonious
coexistence between humans and artificial intelligence. The book discusses
 how AI can be integrated into society in a beneficial and non-disruptive
manner.', metadata={})]

我們可以看到,它還給出了相似度分?jǐn)?shù),我們可以根據(jù)閾值進(jìn)行截斷。

11. 重新排序檢索到的對象

重新排序使用更高級的模型來重新評估和排序最初檢索到的對象。這可以提高最終檢索集的質(zhì)量。

  • 過度獲?。?/span>最初檢索的對象多于所需。
  • 應(yīng)用排序模型:使用高延遲模型(通常是交叉編碼器)重新評估相關(guān)性。該模型會逐對考慮查詢和每個對象,以重新評估相似度。
  • 重新排序結(jié)果:根據(jù)新的評估結(jié)果,重新排序?qū)ο蟆⒆钕嚓P(guān)的結(jié)果置于頂部。這可確保最相關(guān)的文檔優(yōu)先顯示,從而改進(jìn)提供給LLM (LLM) 的數(shù)據(jù)。
from langchain.retrievers import ContextualCompressionRetriever
from langchain.retrievers.document_compressors import FlashrankRerank
from langchain_openai import ChatOpenAI

llm = ChatOpenAI(temperature=0)

compressor = FlashrankRerank()
compression_retriever = ContextualCompressionRetriever(
   base_compressor=compressor, base_retriever=retriever
)
compressed_docs = compression_retriever.invoke(
   "What did the president say about Ketanji Jackson Brown"
)
print([doc.metadata["id"] for doc in compressed_docs])
pretty_print_docs(compressed_docs)

此代碼片段利用 ContextualCompressionRetriever 中的 FlashrankRerank 來提升檢索到的文檔的相關(guān)性。它根據(jù)查詢“總統(tǒng)對 Ketanji Jackson Brown 有何評價”的相關(guān)性,對基礎(chǔ)檢索器(用 retriever 表示)獲取的文檔進(jìn)行重新排序。最后,它會打印文檔 ID 以及壓縮后、重新排序后的文檔。

輸出

[0, 5, 3]

Document 1:

One of the most serious constitutional responsibilities a President has is nominating someone to serve on the United States Supreme Court.

And I did that 4 days ago, when I nominated Circuit Court of Appeals Judge Ketanji Brown Jackson. One of our nation’s top legal minds, who will continue Justice Breyer’s legacy of excellence.

----------------------------------------------------------------------------------------------------

Document 2:

He met the Ukrainian people.

From President Zelenskyy to every Ukrainian, their fearlessness, their courage, their determination, inspires the world.

Groups of citizens blocking tanks with their bodies. Everyone from students to retirees teachers turned soldiers defending their homeland.

In this struggle as President Zelenskyy said in his speech to the European Parliament “Light will win over darkness.” The Ukrainian Ambassador to the United States is here tonight.

----------------------------------------------------------------------------------------------------

Document 3:

And tonight, I’m announcing that the Justice Department will name a chief prosecutor for pandemic fraud.

By the end of this year, the deficit will be down to less than half what it was before I took office.  

The only president ever to cut the deficit by more than one trillion dollars in a single year.

Lowering your costs also means demanding more competition.

I’m a capitalist, but capitalism without competition isn’t capitalism.

It’s exploitation—and it drives up prices.

輸出顯示它根據(jù)相關(guān)性對檢索到的塊進(jìn)行重新排序。

12. 微調(diào)LLM

使用特定領(lǐng)域數(shù)據(jù)對 LLM 進(jìn)行微調(diào)可以顯著提升其性能。例如,使用 Meditron 70B 這樣的模型。這是針對醫(yī)療數(shù)據(jù)對 LLaMA 2 70b 進(jìn)行微調(diào)的版本,同時使用了以下兩種方法:

  • 無監(jiān)督微調(diào):繼續(xù)對大量特定領(lǐng)域的文本進(jìn)行預(yù)訓(xùn)練。
  • 監(jiān)督微調(diào):使用監(jiān)督學(xué)習(xí)針對特定領(lǐng)域任務(wù)(例如醫(yī)學(xué)多項選擇題)進(jìn)一步完善模型。這種專門的訓(xùn)練有助于模型在目標(biāo)領(lǐng)域表現(xiàn)良好。在某些特定任務(wù)上,它的表現(xiàn)優(yōu)于基礎(chǔ)模型以及規(guī)模更大、專業(yè)性較低的模型(例如 GPT-3.5)。

微調(diào)微調(diào)

此圖表示針對特定任務(wù)示例進(jìn)行微調(diào)的過程。這種方法允許開發(fā)人員指定所需的輸出、鼓勵某些行為,或更好地控制模型的響應(yīng)。

13. 使用 RAFT:將語言模型適配到特定領(lǐng)域的 RAG

RAFT(檢索增強(qiáng)微調(diào))是一種改進(jìn)大型語言模型 (LLM) 在特定領(lǐng)域工作方式的方法。它可以幫助這些模型利用文檔中的相關(guān)信息更準(zhǔn)確地回答問題。

  • 檢索增強(qiáng)微調(diào):RAFT 將微調(diào)與檢索方法相結(jié)合。這使得模型在訓(xùn)練過程中能夠從有用和不太有用的文檔中學(xué)習(xí)。
  • 思路鏈推理:該模型生成的答案展現(xiàn)了其推理過程。這有助于它根據(jù)檢索到的文檔提供清晰準(zhǔn)確的響應(yīng)。
  • 動態(tài)文檔處理:RAFT 訓(xùn)練模型查找和使用最相關(guān)的文檔,同時忽略那些無助于回答問題的文檔。

RAFT 的架構(gòu)

RAFT 架構(gòu)包含幾個關(guān)鍵組件:

  1. 輸入層:模型輸入一個問題(Q)和一組檢索到的文檔(D),其中包括相關(guān)文檔和不相關(guān)文檔。
  2. 處理層:
  • 該模型分析輸入以在文檔中查找重要信息。
  • 它創(chuàng)建了一個引用相關(guān)文檔的答案(A*)。
  1. 輸出層:模型根據(jù)相關(guān)文檔產(chǎn)生最終答案,同時忽略不相關(guān)的文檔。
  2. 訓(xùn)練機(jī)制:在訓(xùn)練過程中,一些數(shù)據(jù)包含相關(guān)和不相關(guān)的文檔,而其他數(shù)據(jù)僅包含不相關(guān)的文檔。這種設(shè)置鼓勵模型專注于上下文而不是記憶。
  3. 評估:根據(jù)模型使用檢索到的文檔準(zhǔn)確回答問題的能力來評估模型的性能。

通過采用這種架構(gòu),RAFT 增強(qiáng)了模型在特定領(lǐng)域的工作能力,并提供了一種生成準(zhǔn)確且相關(guān)響應(yīng)的可靠方法。

RAFT 的架構(gòu)RAFT 的架構(gòu)

左上圖展示了一種調(diào)整 LLM 的方法,使其能夠從一組正向文檔和干擾文檔中讀取解決方案。與標(biāo)準(zhǔn) RAG 設(shè)置不同,標(biāo)準(zhǔn) RAG 設(shè)置基于檢索器輸出進(jìn)行訓(xùn)練,檢索器輸出是記憶和閱讀的混合。測試時,所有方法均遵循標(biāo)準(zhǔn) RAG 設(shè)置,并在上下文中提供前 k 個檢索到的文檔。

結(jié)論

改進(jìn) RAG 系統(tǒng)的檢索和生成能力對于打造更優(yōu)秀的 AI 應(yīng)用至關(guān)重要。本文討論的技術(shù)涵蓋從低投入、高效率的方法(查詢重寫、重新排序)到更復(fù)雜的流程(嵌入和 LLM 微調(diào))。最佳技術(shù)取決于你應(yīng)用的具體需求和限制。先進(jìn)的 RAG 技術(shù),如果經(jīng)過深思熟慮地應(yīng)用,可以幫助開發(fā)人員構(gòu)建更準(zhǔn)確、更可靠、更具備情境感知能力的 AI 系統(tǒng),從而處理復(fù)雜的信息需求。

責(zé)任編輯:武曉燕 來源: 數(shù)據(jù)STUDIO
相關(guān)推薦

2019-03-15 10:25:00

技術(shù)研發(fā)指標(biāo)

2023-07-17 11:43:07

2020-03-09 08:00:00

技術(shù)管理套路

2025-02-06 13:50:06

2020-06-07 16:16:01

Python開發(fā)工具

2020-06-10 10:30:48

Python 開發(fā)編程語言

2025-03-10 03:25:00

2022-09-04 19:30:13

云原生系統(tǒng)

2021-04-27 07:52:19

C++promisefuture

2024-06-13 11:54:03

2022-02-22 09:58:09

搜索設(shè)計交互互聯(lián)網(wǎng)

2019-01-18 08:42:54

開源Fescar分布式

2020-02-05 16:23:32

邊緣資深專家

2022-03-30 15:53:18

標(biāo)簽頁用戶設(shè)計

2020-07-17 07:00:00

GitHubgit開源

2021-09-27 09:33:33

B端C端規(guī)范要求

2018-10-15 12:17:19

2022-03-01 15:23:02

設(shè)計師創(chuàng)新互聯(lián)網(wǎng)

2022-03-09 09:23:18

Windows 11UI視覺風(fēng)格

2020-07-10 14:25:32

Python編程代碼
點贊
收藏

51CTO技術(shù)棧公眾號