自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

18種RAG技術大比拼:誰才是檢索增強生成的最佳選擇? 原創(chuàng) 精華

發(fā)布于 2025-3-25 09:44
瀏覽
0收藏

在當今信息爆炸的時代,如何從海量數(shù)據(jù)中快速準確地獲取所需信息,是人工智能領域的一大挑戰(zhàn)。Retrieval-Augmented Generation(RAG,檢索增強生成)技術應運而生,它結合了檢索和生成的優(yōu)勢,通過從大量文檔中檢索相關信息,再利用這些信息生成高質(zhì)量的回答。然而,RAG 的實現(xiàn)方式多種多樣,不同的技術路徑有著不同的優(yōu)勢和局限。今天,我們就來深入探討一下這些 RAG 技術,看看誰才是真正的“最佳選手”。

1. Simple RAG:基礎而不失經(jīng)典

18種RAG技術大比拼:誰才是檢索增強生成的最佳選擇?-AI.x社區(qū)

在探索各種復雜的 RAG 技術之前,我們先從最簡單的 RAG 方法說起。**簡單 RAG **的工作流程非常直觀:從 PDF 文檔中提取文本,將其分割成小塊(chunks),將這些文本塊轉(zhuǎn)換為數(shù)值化的嵌入向量(embeddings),根據(jù)查詢(query)搜索最相關的文本塊,最后利用檢索到的文本塊生成回答。

# 定義 PDF 文件路徑
pdf_path = "data/AI_information.pdf"

# 提取文本并分割成文本塊
extracted_text = extract_text_from_pdf(pdf_path)
text_chunks = chunk_text(extracted_text, chunk_size=1000, overlap=200)

# 打印文本塊數(shù)量
print("Number of text chunks:", len(text_chunks))

這種方法雖然簡單,但卻為后續(xù)更復雜的技術奠定了基礎。它就像是一個“新手村”,讓我們能夠初步了解 RAG 的工作原理。然而,簡單 RAG 也有它的局限性。由于文本塊是按照固定大小分割的,可能會導致一些句子被拆分開,或者將不相關的句子組合在一起,從而影響檢索的準確性。

2. Semantic Chunking語義分塊:讓文本塊更有意義

18種RAG技術大比拼:誰才是檢索增強生成的最佳選擇?-AI.x社區(qū)

為了解決簡單 RAG 中文本塊分割不夠合理的問題,語義分塊(Semantic Chunking)應運而生。與簡單 RAG 不同,語義分塊不再是按照固定大小來分割文本,而是嘗試根據(jù)文本的語義來劃分,將語義相關的句子組合在一起形成文本塊。

# 將提取的文本分割成句子
sentences = extracted_text.split(". ")

# 為每個句子生成嵌入向量
embeddings = [get_embedding(sentence) for sentence in sentences]

# 計算連續(xù)句子之間的相似度
similarities = [cosine_similarity(embeddings[i], embeddings[i + 1]) for i in range(len(embeddings) - 1)]

# 使用百分位法計算斷點
breakpoints = compute_breakpoints(similarities, method="percentile", threshold=90)

# 根據(jù)斷點將句子分組成語義塊
text_chunks = split_into_chunks(sentences, breakpoints)

這種方法聽起來很完美,但在實際測試中,它的表現(xiàn)卻不盡如人意。語義分塊的評分甚至低于簡單 RAG,這說明僅僅改變文本塊的分割策略,并不能保證檢索效果的提升。這也提醒我們,技術的改進并非一蹴而就,需要更多的思考和嘗試。

3. 上下文增強檢索:鄰居也能提供幫助

18種RAG技術大比拼:誰才是檢索增強生成的最佳選擇?-AI.x社區(qū)

既然語義分塊沒有達到預期的效果,我們不妨換個思路。簡單 RAG 的問題在于文本塊過于孤立,缺乏上下文信息。那么,如果我們能夠為每個文本塊添加一些上下文信息,是不是就能提高檢索的準確性呢?上下文增強檢索(Context Enriched Retrieval)正是基于這樣的想法。

# 定義上下文增強檢索函數(shù)
def context_enriched_search(query, text_chunks, embeddings, k=1, context_size=1):
    query_embedding = create_embeddings(query).data[0].embedding
    similarity_scores = []

    for i, chunk_embedding in enumerate(embeddings):
        similarity_score = cosine_similarity(np.array(query_embedding), np.array(chunk_embedding.embedding))
        similarity_scores.append((i, similarity_score))

    similarity_scores.sort(key=lambda x: x[1], reverse=True)
    top_index = similarity_scores[0][0]

    start = max(0, top_index - context_size)
    end = min(len(text_chunks), top_index + context_size + 1)

    return [text_chunks[i] for i in range(start, end)]

在上下文增強檢索中,我們不僅檢索與查詢最相關的文本塊,還會檢索其周圍的文本塊作為上下文信息。這些“鄰居”文本塊能夠為檢索提供更多的背景信息,幫助生成更準確的回答。經(jīng)過測試,上下文增強檢索的評分達到了 0.6,相較于簡單 RAG 和語義分塊有了顯著的提升。這表明,上下文信息在檢索過程中確實起到了關鍵作用。

4. 上下文塊頭:給文本塊加上“標簽”

18種RAG技術大比拼:誰才是檢索增強生成的最佳選擇?-AI.x社區(qū)

上下文增強檢索雖然有效,但仍然存在一個問題:即使有了上下文信息,文本塊本身可能仍然缺乏足夠的語義信息。例如,一個文檔可能包含多個主題,每個主題都對應著不同的文本塊。在這種情況下,如何快速準確地找到與查詢最相關的文本塊呢?

上下文塊頭(Contextual Chunk Headers)技術為我們提供了一個解決方案。它在每個文本塊的前面添加了一個描述性的標題(header),這個標題就像是一個“標簽”,能夠概括文本塊的主要內(nèi)容。

# 為每個文本塊生成描述性標題
text_chunks_with_headers = chunk_text_with_headers(extracted_text, chunk_size=1000, overlap=200)

# 打印一個樣本以查看效果
print("Sample Chunk with Header:")
print("Header:", text_chunks_with_headers[0]['header'])
print("Content:", text_chunks_with_headers[0]['text'])

在檢索過程中,系統(tǒng)不僅會考慮文本塊的內(nèi)容,還會參考其標題,從而更準確地找到與查詢相關的文本塊。經(jīng)過測試,上下文塊頭的評分達到了 0.5,雖然沒有上下文增強檢索高,但也比簡單 RAG 和語義分塊有了明顯的提升。這說明,通過給文本塊添加標題,我們能夠為檢索提供更多的語義信息,從而提高檢索的準確性。

5. 文檔增強:從文本塊到問題

18種RAG技術大比拼:誰才是檢索增強生成的最佳選擇?-AI.x社區(qū)

上下文塊頭雖然能夠提供更多的語義信息,但仍然存在局限性。在某些情況下,文本塊的內(nèi)容可能過于復雜,難以用一個簡單的標題來概括。那么,有沒有一種方法能夠讓文本塊更容易被檢索到呢?

文檔增強(Document Augmentation)技術為我們提供了一個新的思路。它不僅將文本塊轉(zhuǎn)換為嵌入向量,還會為每個文本塊生成一些相關的問題,并將這些問題也轉(zhuǎn)換為嵌入向量。

# 處理文檔,提取文本、創(chuàng)建文本塊、生成問題并構建向量庫
text_chunks, vector_store = process_document(
    pdf_path,
    chunk_size=1000,
    chunk_overlap=200,
    questions_per_chunk=3
)

這樣一來,在檢索過程中,系統(tǒng)不僅能夠匹配文本塊的內(nèi)容,還能夠匹配與查詢相關的問題,從而提高檢索的準確性。經(jīng)過測試,文檔增強的評分達到了 0.8,這是一個非常高的分數(shù),表明文檔增強技術能夠顯著提高檢索的準確性。這也說明,通過為文本塊生成相關問題,我們能夠為檢索提供更多的入口,從而更容易找到與查詢相關的文本塊。

6. 查詢轉(zhuǎn)換:讓查詢更“友好”

18種RAG技術大比拼:誰才是檢索增強生成的最佳選擇?-AI.x社區(qū)

在前面的討論中,我們主要關注了如何改進文本塊的表示和檢索策略。然而,我們忽略了一個重要的因素:用戶提出的查詢可能并不總是能夠很好地匹配文檔中的內(nèi)容,這可能會導致檢索結果不準確。那么,有沒有一種方法能夠讓查詢更“友好”,更容易被檢索到呢?

查詢轉(zhuǎn)換(Query Transformation)技術為我們提供了一個解決方案。它通過三種不同的方法來改進查詢:查詢重寫(Query Rewriting)、后退提示(Step-back Prompting)和子查詢分解(Sub-query Decomposition)。

# 查詢重寫
rewritten_query = rewrite_query(query)

# 后退提示
step_back_query = generate_step_back_query(query)

# 子查詢分解
sub_queries = decompose_query(query, num_subqueries=4)

查詢重寫是將查詢變得更加具體和詳細;后退提示是創(chuàng)建一個更廣泛的查詢,以檢索有用的背景信息;子查詢分解則是將一個復雜的查詢分解為多個簡單的子查詢。經(jīng)過測試,查詢轉(zhuǎn)換的評分達到了 0.5。雖然這個分數(shù)并不高,但它仍然表明查詢轉(zhuǎn)換技術在某些情況下能夠提高檢索的準確性。這也提醒我們,在 RAG 系統(tǒng)中,不僅需要關注文本塊的表示和檢索策略,還需要關注查詢的質(zhì)量。

7. 重排序:讓檢索結果更有條理

18種RAG技術大比拼:誰才是檢索增強生成的最佳選擇?-AI.x社區(qū)

在前面的討論中,我們主要關注了如何改進文本塊的表示和檢索策略,以及如何改進查詢的質(zhì)量。然而,我們忽略了一個重要的環(huán)節(jié):檢索結果的排序。簡單相似性搜索通常會返回一組相關性和不相關性混雜的結果,這可能會導致生成的回答不夠準確。那么,有沒有一種方法能夠讓檢索結果更有條理,更容易被利用呢?

重排序(Reranker)技術為我們提供了一個解決方案。它在初始檢索的基礎上,通過一個額外的步驟對檢索結果進行重新排序,將最相關的文本塊放在最前面。重排序可以使用不同的方法,例如基于關鍵詞的重排序或基于 LLM 的重排序。

# 定義重排序函數(shù)
def rag_with_reranking(query, vector_store, reranking_method="llm", top_n=3, model="meta-llama/Llama-3.2-3B-Instruct"):
    query_embedding = create_embeddings(query)
    initial_results = vector_store.similarity_search(query_embedding, k=10)

    if reranking_method == "llm":
        reranked_results = rerank_with_llm(query, initial_results, top_n=top_n)
    else:
        reranked_results = initial_results[:top_n]

    context = "\n\n===\n\n".join([result["text"] for result in reranked_results])
    response = generate_response(query, context, model)

    return {
        "query": query,
        "reranking_method": reranking_method,
        "initial_results": initial_results[:top_n],
        "reranked_results": reranked_results,
        "context": context,
        "response": response
    }

這種方法的效果如何呢?經(jīng)過測試,重排序的評分達到了 0.7。這個分數(shù)表明,重排序技術能夠顯著提高檢索結果的質(zhì)量,從而提高生成回答的準確性。這也說明,對檢索結果進行重新排序是一個非常重要的步驟,能夠幫助我們更好地利用檢索到的信息。

8. 相關段落提取(RSE):尋找連續(xù)的相關文本

18種RAG技術大比拼:誰才是檢索增強生成的最佳選擇?-AI.x社區(qū)

在前面的討論中,我們主要關注了如何改進文本塊的表示和檢索策略,以及如何改進查詢的質(zhì)量和檢索結果的排序。然而,我們忽略了一個重要的問題:有時候,最佳的信息可能分散在多個連續(xù)的文本塊中。那么,有沒有一種方法能夠讓系統(tǒng)自動識別并提取這些連續(xù)的相關文本呢?

相關段落提?。≧elevant Segment Extraction,RSE)技術為我們提供了一個解決方案。它不是簡單地檢索最相關的文本塊,而是嘗試識別并提取整個相關段落。

# 運行 RAG 并應用相關段落提取
rse_result = rag_with_rse(pdf_path, query)

這種方法能夠為生成回答提供更連貫和完整的上下文信息,從而提高回答的質(zhì)量。經(jīng)過測試,相關段落提取的評分達到了 0.8。這個分數(shù)表明,相關段落提取技術能夠顯著提高檢索結果的質(zhì)量,從而提高生成回答的準確性。這也說明,識別并提取連續(xù)的相關文本是一個非常重要的步驟,能夠幫助我們更好地利用檢索到的信息。

9. 上下文壓縮:讓信息更精煉

18種RAG技術大比拼:誰才是檢索增強生成的最佳選擇?-AI.x社區(qū)

在前面的討論中,我們主要關注了如何改進文本塊的表示和檢索策略,以及如何改進查詢的質(zhì)量和檢索結果的排序,以及如何識別并提取連續(xù)的相關文本。然而,我們忽略了一個重要的問題:有時候,檢索到的信息可能過于冗長,包含了大量與查詢不相關的內(nèi)容。這不僅會浪費計算資源,還可能會影響生成回答的質(zhì)量。那么,有沒有一種方法能夠讓檢索到的信息更精煉,只保留與查詢最相關的內(nèi)容呢?

上下文壓縮(Contextual Compression)技術為我們提供了一個解決方案。它在檢索到文本塊之后,通過一個額外的步驟對文本塊進行壓縮,只保留與查詢最相關的內(nèi)容。

# 定義上下文壓縮函數(shù)
def rag_with_compression(pdf_path, query, k=10, compression_type="selective", model="meta-llama/Llama-3.2-3B-Instruct"):
    vector_store = process_document(pdf_path)
    results = vector_store.similarity_search(create_embeddings(query), k=k)
    retrieved_chunks = [r["text"] for r in results]

    compressed = batch_compress_chunks(retrieved_chunks, query, compression_type, model)
    compressed_chunks, compression_ratios = zip([(c, r) for c, r in compressed if c.strip()] or [(chunk, 0.0) for chunk in retrieved_chunks])

    context = "\n\n---\n\n".join(compressed_chunks)
    response = generate_response(query, context, model)

    return {
        "query": query,
        "original_chunks": retrieved_chunks,
        "compressed_chunks": compressed_chunks,
        "compression_ratios": compression_ratios,
        "context_length_reduction": f"{sum(compression_ratios)/len(compression_ratios):.2f}%",
        "response": response
    }

這種方法的效果如何呢?經(jīng)過測試,上下文壓縮的評分達到了 0.75。這個分數(shù)表明,上下文壓縮技術能夠顯著提高檢索結果的質(zhì)量,從而提高生成回答的準確性。這也說明,對檢索到的信息進行壓縮是一個非常重要的步驟,能夠幫助我們更好地利用檢索到的信息。

10. 反饋循環(huán):讓系統(tǒng)不斷學習

18種RAG技術大比拼:誰才是檢索增強生成的最佳選擇?-AI.x社區(qū)

在前面的討論中,我們主要關注了如何改進文本塊的表示和檢索策略,以及如何改進查詢的質(zhì)量和檢索結果的排序,以及如何識別并提取連續(xù)的相關文本,以及如何對檢索到的信息進行壓縮。然而,我們忽略了一個重要的問題:這些改進都是基于預先設定的策略,系統(tǒng)無法根據(jù)實際的使用情況進行自我調(diào)整。那么,有沒有一種方法能夠讓系統(tǒng)根據(jù)用戶的反饋不斷學習和調(diào)整呢?

反饋循環(huán)(Feedback Loop)技術為我們提供了一個解決方案。它允許用戶對系統(tǒng)的回答進行評價,并將這些評價作為反饋信息存儲起來。在后續(xù)的檢索過程中,系統(tǒng)會根據(jù)這些反饋信息對檢索策略進行調(diào)整,從而提高檢索結果的質(zhì)量。

# 定義完整的 RAG 流程,包含反饋機制
def full_rag_workflow(pdf_path, query, feedback_data=None, feedback_file="feedback_data.json", fine_tune=False):
    if feedback_data isNone:
        feedback_data = load_feedback_data(feedback_file)
        print(f"Loaded {len(feedback_data)} feedback entries from {feedback_file}")

    chunks, vector_store = process_document(pdf_path)

    if fine_tune and feedback_data:
        vector_store = fine_tune_index(vector_store, chunks, feedback_data)

    result = rag_with_feedback_loop(query, vector_store, feedback_data)

    print("\n=== Would you like to provide feedback on this response? ===")
    print("Rate relevance (1-5, with 5 being most relevant):")
    relevance = input()

    print("Rate quality (1-5, with 5 being highest quality):")
    quality = input()

    print("Any comments? (optional, press Enter to skip)")
    comments = input()

    feedback = get_user_feedback(
        query=query,
        respnotallow=result["response"],
        relevance=int(relevance),
        quality=int(quality),
        comments=comments
    )

    store_feedback(feedback, feedback_file)
    print("Feedback recorded. Thank you!")

    return result

這種方法的效果如何呢?經(jīng)過測試,反饋循環(huán)的評分達到了 0.7。雖然這個分數(shù)并不高,但它仍然表明反饋循環(huán)技術能夠讓系統(tǒng)不斷學習和調(diào)整,從而提高檢索結果的質(zhì)量。這也說明,用戶反饋是一個非常重要的資源,能夠幫助系統(tǒng)更好地滿足用戶的需求。

11. Adaptive RAG:智能選擇檢索策略

18種RAG技術大比拼:誰才是檢索增強生成的最佳選擇?-AI.x社區(qū)

在前面的討論中,我們主要關注了如何改進文本塊的表示和檢索策略,以及如何改進查詢的質(zhì)量和檢索結果的排序,以及如何識別并提取連續(xù)的相關文本,以及如何對檢索到的信息進行壓縮,以及如何根據(jù)用戶的反饋不斷學習和調(diào)整。然而,我們忽略了一個重要的問題:不同的查詢可能需要不同的檢索策略。那么,有沒有一種方法能夠讓系統(tǒng)根據(jù)查詢的類型自動選擇最合適的檢索策略呢?

自適應 RAG(Adaptive RAG)技術為我們提供了一個解決方案。它根據(jù)查詢的類型,自動選擇最合適的檢索策略。例如,對于事實性查詢,系統(tǒng)會選擇事實檢索策略;對于分析性查詢,系統(tǒng)會選擇分析檢索策略;對于觀點性查詢,系統(tǒng)會選擇觀點檢索策略;對于上下文相關查詢,系統(tǒng)會選擇上下文檢索策略。

# 定義自適應 RAG 函數(shù)
def rag_with_adaptive_retrieval(pdf_path, query, k=4, user_cnotallow=None):
    chunks, vector_store = process_document(pdf_path)
    query_type = classify_query(query)
    print(f"Query classified as: {query_type}")

    retrieved_docs = adaptive_retrieval(query, vector_store, k, user_context)
    response = generate_response(query, retrieved_docs, query_type)

    return {
        "query": query,
        "query_type": query_type,
        "retrieved_documents": retrieved_docs,
        "response": response
    }

這種方法的效果如何呢?經(jīng)過測試,自適應 RAG 的評分達到了 0.86,這是所有方法中最高的分數(shù)。這個分數(shù)表明,自適應 RAG 技術能夠顯著提高檢索結果的質(zhì)量,從而提高生成回答的準確性。這也說明,根據(jù)查詢的類型自動選擇檢索策略是一個非常重要的步驟,能夠幫助我們更好地利用檢索到的信息。

12. Self RAG:讓系統(tǒng)自我反思

18種RAG技術大比拼:誰才是檢索增強生成的最佳選擇?-AI.x社區(qū)

在前面的討論中,我們主要關注了如何改進文本塊的表示和檢索策略,以及如何改進查詢的質(zhì)量和檢索結果的排序,以及如何識別并提取連續(xù)的相關文本,以及如何對檢索到的信息進行壓縮,以及如何根據(jù)用戶的反饋不斷學習和調(diào)整,以及如何根據(jù)查詢的類型自動選擇檢索策略。然而,我們忽略了一個重要的問題:系統(tǒng)是否能夠自我反思,判斷是否需要檢索,以及如何利用檢索到的信息呢?

自我 RAG(Self RAG)技術為我們提供了一個解決方案。它不僅能夠檢索和生成回答,還能夠自我反思,判斷是否需要檢索,以及如何利用檢索到的信息。

# 運行自我 RAG
result = self_rag(query, vector_store)

這種方法的效果如何呢?經(jīng)過測試,自我 RAG 的評分達到了 0.65。雖然這個分數(shù)并不高,但它仍然表明自我 RAG 技術能夠讓系統(tǒng)更加智能和靈活。這也說明,自我反思是一個非常重要的能力,能夠幫助系統(tǒng)更好地適應不同的查詢需求。

13. Knowledge Graph:構建知識網(wǎng)絡

18種RAG技術大比拼:誰才是檢索增強生成的最佳選擇?-AI.x社區(qū)

在前面的討論中,我們主要關注了如何改進文本塊的表示和檢索策略,以及如何改進查詢的質(zhì)量和檢索結果的排序,以及如何識別并提取連續(xù)的相關文本,以及如何對檢索到的信息進行壓縮,以及如何根據(jù)用戶的反饋不斷學習和調(diào)整,以及如何根據(jù)查詢的類型自動選擇檢索策略,以及如何讓系統(tǒng)自我反思。然而,我們忽略了一個重要的問題:文檔中的信息可能是相互關聯(lián)的,如何構建一個知識網(wǎng)絡,將這些信息有機地結合起來呢?

知識圖譜 RAG(Knowledge Graph RAG)技術為我們提供了一個解決方案。它將文檔中的信息構建成一個知識圖譜,其中節(jié)點代表概念、實體或信息片段,邊代表這些節(jié)點之間的關系。

# 構建知識圖譜
def build_knowledge_graph(chunks):
    graph, texts = nx.Graph(), [c["text"] for c in chunks]
    embeddings = create_embeddings(texts)

    for i, (chunk, emb) in enumerate(zip(chunks, embeddings)):
        graph.add_node(i, text=chunk["text"], cnotallow=extract_concepts(chunk["text"]), embedding=emb)

    for i, j in ((i, j) for i in range(len(chunks)) for j in range(i + 1, len(chunks))):
        if shared_concepts := set(graph.nodes[i]["concepts"]) & set(graph.nodes[j]["concepts"]):
            sim = np.dot(embeddings[i], embeddings[j]) / (np.linalg.norm(embeddings[i]) * np.linalg.norm(embeddings[j]))
            weight = 0.7 * sim + 0.3 * (len(shared_concepts) / min(len(graph.nodes[i]["concepts"]), len(graph.nodes[j]["concepts"])))
            if weight > 0.6:
                graph.add_edge(i, j, weight=weight, similarity=sim, shared_cnotallow=list(shared_concepts))

    print(f"Graph built: {graph.number_of_nodes()} nodes, {graph.number_of_edges()} edges")
    return graph, embeddings

在檢索過程中,系統(tǒng)不僅能夠檢索與查詢直接相關的節(jié)點,還能夠通過遍歷知識圖譜找到間接相關的節(jié)點,從而為生成回答提供更全面的上下文信息。經(jīng)過測試,知識圖譜 RAG 的評分達到了 0.78。這個分數(shù)表明,知識圖譜 RAG 技術能夠顯著提高檢索結果的質(zhì)量,從而提高生成回答的準確性。這也說明,構建知識圖譜是一個非常重要的步驟,能夠幫助我們更好地利用文檔中的信息。

18種RAG技術大比拼:誰才是檢索增強生成的最佳選擇?-AI.x社區(qū)

14. 層次化索引:平衡上下文和精確性

18種RAG技術大比拼:誰才是檢索增強生成的最佳選擇?-AI.x社區(qū)

在前面的討論中,我們主要關注了如何改進文本塊的表示和檢索策略,以及如何改進查詢的質(zhì)量和檢索結果的排序,以及如何識別并提取連續(xù)的相關文本,以及如何對檢索到的信息進行壓縮,以及如何根據(jù)用戶的反饋不斷學習和調(diào)整,以及如何根據(jù)查詢的類型自動選擇檢索策略,以及如何讓系統(tǒng)自我反思,以及如何構建知識圖譜。然而,我們忽略了一個重要的問題:如何平衡上下文信息和檢索的精確性呢?

層次化索引(Hierarchical Indices)技術為我們提供了一個解決方案。它創(chuàng)建了兩個層次的表示:摘要和詳細文本塊。首先,系統(tǒng)在摘要層次進行檢索,快速縮小相關文檔的范圍;然后,在詳細文本塊層次進行檢索,提供精確的檢索結果。

# 定義層次化 RAG 函數(shù)
def hierarchical_rag(query, pdf_path, chunk_size=1000, chunk_overlap=200, k_summaries=3, k_chunks=5, regenerate=False):
    summary_store_file = f"{os.path.basename(pdf_path)}_summary_store.pkl"
    detailed_store_file = f"{os.path.basename(pdf_path)}_detailed_store.pkl"

    if regenerate ornot os.path.exists(summary_store_file) ornot os.path.exists(detailed_store_file):
        print("Processing document and creating vector stores...")
        summary_store, detailed_store = process_document_hierarchically(pdf_path, chunk_size, chunk_overlap)

        with open(summary_store_file, 'wb') as f:
            pickle.dump(summary_store, f)
        with open(detailed_store_file, 'wb') as f:
            pickle.dump(detailed_store, f)
    else:
        print("Loading existing vector stores...")
        with open(summary_store_file, 'rb') as f:
            summary_store = pickle.load(f)
        with open(detailed_store_file, 'rb') as f:
            detailed_store = pickle.load(f)

    retrieved_chunks = retrieve_hierarchically(query, summary_store, detailed_store, k_summaries, k_chunks)
    response = generate_response(query, retrieved_chunks)

    return {
        "query": query,
        "response": response,
        "retrieved_chunks": retrieved_chunks,
        "summary_count": len(summary_store.texts),
        "detailed_count": len(detailed_store.texts)
    }

這種方法既保留了上下文信息,又提高了檢索的精確性。經(jīng)過測試,層次化索引的評分達到了 0.84。這個分數(shù)表明,層次化索引技術能夠顯著提高檢索結果的質(zhì)量,從而提高生成回答的準確性。這也說明,平衡上下文信息和檢索精確性是一個非常重要的步驟,能夠幫助我們更好地利用檢索到的信息。

15. HyDE:從假設文檔出發(fā)

18種RAG技術大比拼:誰才是檢索增強生成的最佳選擇?-AI.x社區(qū)

在前面的討論中,我們主要關注了如何改進文本塊的表示和檢索策略,以及如何改進查詢的質(zhì)量和檢索結果的排序,以及如何識別并提取連續(xù)的相關文本,以及如何對檢索到的信息進行壓縮,以及如何根據(jù)用戶的反饋不斷學習和調(diào)整,以及如何根據(jù)查詢的類型自動選擇檢索策略,以及如何讓系統(tǒng)自我反思,以及如何構建知識圖譜,以及如何平衡上下文信息和檢索精確性。然而,我們忽略了一個重要的問題:如何更好地表示查詢,以便更準確地檢索到相關信息呢?

HyDE(Hypothetical Document Embedding)技術為我們提供了一個解決方案。它不是直接對查詢進行嵌入,而是先生成一個假設文檔,這個文檔是查詢的理想答案。然后,系統(tǒng)對這個假設文檔進行嵌入,并利用這個嵌入進行檢索。

# 定義 HyDE RAG 函數(shù)
def hyde_rag(query, vector_store, k=5, should_generate_respnotallow=True):
    print(f"\n=== Processing query with HyDE: {query} ===\n")

    print("Generating hypothetical document...")
    hypothetical_doc = generate_hypothetical_document(query)
    print(f"Generated hypothetical document of {len(hypothetical_doc)} characters")

    print("Creating embedding for hypothetical document...")
    hypothetical_embedding = create_embeddings([hypothetical_doc])[0]

    print(f"Retrieving {k} most similar chunks...")
    retrieved_chunks = vector_store.similarity_search(hypothetical_embedding, k=k)

    results = {
        "query": query,
        "hypothetical_document": hypothetical_doc,
        "retrieved_chunks": retrieved_chunks
    }

    if should_generate_response:
        print("Generating final response...")
        response = generate_response(query, retrieved_chunks)
        results["response"] = response

    return results

這種方法能夠更好地捕捉查詢的語義信息,從而提高檢索的準確性。經(jīng)過測試,HyDE 的評分達到了 0.5。雖然這個分數(shù)并不高,但它仍然表明 HyDE 技術在某些情況下能夠提高檢索的準確性。這也說明,從假設文檔出發(fā)是一個非常有趣的思路,能夠幫助我們更好地表示查詢。

16. 融合 RAG:結合多種檢索方法

18種RAG技術大比拼:誰才是檢索增強生成的最佳選擇?-AI.x社區(qū)

在前面的討論中,我們主要關注了如何改進文本塊的表示和檢索策略,以及如何改進查詢的質(zhì)量和檢索結果的排序,以及如何識別并提取連續(xù)的相關文本,以及如何對檢索到的信息進行壓縮,以及如何根據(jù)用戶的反饋不斷學習和調(diào)整,以及如何根據(jù)查詢的類型自動選擇檢索策略,以及如何讓系統(tǒng)自我反思,以及如何構建知識圖譜,以及如何平衡上下文信息和檢索精確性,以及如何從假設文檔出發(fā)。然而,我們忽略了一個重要的問題:不同的檢索方法有各自的優(yōu)缺點,如何將它們結合起來,發(fā)揮各自的優(yōu)點呢?

融合 RAG(Fusion RAG)技術為我們提供了一個解決方案。它結合了向量檢索和關鍵詞檢索兩種方法,取兩者的優(yōu)點,為檢索結果提供更全面的語義信息和精確的關鍵詞匹配。

# 定義融合檢索函數(shù)
def fusion_retrieval(query, chunks, vector_store, bm25_index, k=5, alpha=0.5):
    query_embedding = create_embeddings(query)
    vector_results = {r["metadata"]["index"]: r["similarity"] for r in vector_store.similarity_search_with_scores(query_embedding, len(chunks))}
    bm25_results = {r["metadata"]["index"]: r["bm25_score"] for r in bm25_search(bm25_index, chunks, query, len(chunks))}

    all_docs = vector_store.get_all_documents()
    scores = [(i, alpha * vector_results.get(i, 0) + (1 - alpha) * bm25_results.get(i, 0)) for i in range(len(all_docs))]
    top_docs = sorted(scores, key=lambda x: x[1], reverse=True)[:k]

    return [{"text": all_docs[i]["text"], "metadata": all_docs[i]["metadata"], "score": s} for i, s in top_docs]

這種方法能夠更好地滿足不同查詢的需求,提高檢索的準確性。經(jīng)過測試,融合 RAG 的評分達到了 0.83。這個分數(shù)表明,融合 RAG 技術能夠顯著提高檢索結果的質(zhì)量,從而提高生成回答的準確性。這也說明,結合多種檢索方法是一個非常有效的策略,能夠幫助我們更好地利用檢索到的信息。

17. 多模態(tài)RAG:解鎖圖像信息

18種RAG技術大比拼:誰才是檢索增強生成的最佳選擇?-AI.x社區(qū)

在前面的討論中,我們主要關注了如何改進文本塊的表示和檢索策略,以及如何改進查詢的質(zhì)量和檢索結果的排序,以及如何識別并提取連續(xù)的相關文本,以及如何對檢索到的信息進行壓縮,以及如何根據(jù)用戶的反饋不斷學習和調(diào)整,以及如何根據(jù)查詢的類型自動選擇檢索策略,以及如何讓系統(tǒng)自我反思,以及如何構建知識圖譜,以及如何平衡上下文信息和檢索精確性,以及如何從假設文檔出發(fā),以及如何結合多種檢索方法。然而,我們忽略了一個重要的問題:文檔中的信息不僅包含文本,還可能包含圖像、圖表等其他形式的信息,如何將這些信息也納入檢索范圍呢?

多模態(tài) RAG(Multi Model RAG)技術為我們提供了一個解決方案。它不僅從文檔中提取文本,還會提取圖像,并為圖像生成描述性的標題。然后,系統(tǒng)將文本和圖像的嵌入向量一起存儲在向量庫中,從而實現(xiàn)對文本和圖像的聯(lián)合檢索。

# 處理多模態(tài)文檔
def process_document(pdf_path, chunk_size=1000, chunk_overlap=200):
    image_dir = "extracted_images"
    os.makedirs(image_dir, exist_ok=True)

    text_data, image_paths = extract_content_from_pdf(pdf_path, image_dir)
    chunked_text = chunk_text(text_data, chunk_size, chunk_overlap)
    image_data = process_images(image_paths)

    all_items = chunked_text + image_data
    contents = [item["content"] for item in all_items]
    embeddings = create_embeddings(contents)

    vector_store = MultiModalVectorStore()
    vector_store.add_items(all_items, embeddings)

    doc_info = {
        "text_count": len(chunked_text),
        "image_count": len(image_data),
        "total_items": len(all_items),
    }

    print(f"Added {len(all_items)} items to vector store ({len(chunked_text)} text chunks, {len(image_data)} image captions)")
    return vector_store, doc_info

這種方法能夠更好地利用文檔中的信息,提高檢索的準確性。經(jīng)過測試,多模態(tài) RAG 的評分達到了 0.79。這個分數(shù)表明,多模態(tài) RAG 技術能夠顯著提高檢索結果的質(zhì)量,從而提高生成回答的準確性。這也說明,將圖像信息納入檢索范圍是一個非常重要的步驟,能夠幫助我們更好地利用文檔中的信息。

18. CRAG:動態(tài)調(diào)整檢索策略

18種RAG技術大比拼:誰才是檢索增強生成的最佳選擇?-AI.x社區(qū)

在前面的討論中,我們主要關注了如何改進文本塊的表示和檢索策略,以及如何改進查詢的質(zhì)量和檢索結果的排序,以及如何識別并提取連續(xù)的相關文本,以及如何對檢索到的信息進行壓縮,以及如何根據(jù)用戶的反饋不斷學習和調(diào)整,以及如何根據(jù)查詢的類型自動選擇檢索策略,以及如何讓系統(tǒng)自我反思,以及如何構建知識圖譜,以及如何平衡上下文信息和檢索精確性,以及如何從假設文檔出發(fā),以及如何結合多種檢索方法,以及如何將圖像信息納入檢索范圍。然而,我們忽略了一個重要的問題:檢索到的信息可能并不總是理想的,如何動態(tài)調(diào)整檢索策略,以應對不同的情況呢?

糾正性 RAG(Corrective RAG,CRAG)技術為我們提供了一個解決方案。它在檢索之后,對檢索到的信息進行評估,根據(jù)評估結果動態(tài)調(diào)整檢索策略。如果檢索到的信息質(zhì)量高,系統(tǒng)會直接利用這些信息生成回答;如果檢索到的信息質(zhì)量低,系統(tǒng)會轉(zhuǎn)而進行網(wǎng)絡搜索;如果檢索到的信息質(zhì)量中等,系統(tǒng)會結合文檔信息和網(wǎng)絡搜索結果生成回答。

# 運行糾正性 RAG
crag_result = rag_with_compression(pdf_path, query, compression_type="selective")

這種方法能夠更好地應對不同的情況,提高檢索的準確性和可靠性。經(jīng)過測試,糾正性 RAG 的評分達到了 0.824。這個分數(shù)表明,糾正性 RAG 技術能夠顯著提高檢索結果的質(zhì)量,從而提高生成回答的準確性。這也說明,動態(tài)調(diào)整檢索策略是一個非常重要的步驟,能夠幫助我們更好地利用檢索到的信息。

結論:選擇最適合的 RAG 技術

通過上述對 18 種 RAG 技術的測試和分析,我們可以看到,不同的技術有各自的優(yōu)缺點,適用于不同的場景和需求。簡單 RAG 提供了一個基礎的框架,但其檢索效果有限;語義分塊、上下文增強檢索、上下文塊頭、文檔增強等技術通過改進文本塊的表示和檢索策略,提高了檢索的準確性;查詢轉(zhuǎn)換、重排序、相關段落提取、上下文壓縮等技術通過改進查詢的質(zhì)量和檢索結果的排序,進一步提高了檢索的效果;反饋循環(huán)、自適應 RAG、自我 RAG 等技術通過引入反饋機制和動態(tài)調(diào)整檢索策略,讓系統(tǒng)能夠更好地適應不同的查詢需求;知識圖譜 RAG、層次化索引、HyDE、融合 RAG、多模態(tài) RAG、糾正性 RAG 等技術通過結合多種方法和信息源,顯著提高了檢索的準確性和可靠性。

在這些技術中,自適應 RAG 以 0.86 的評分脫穎而出,成為表現(xiàn)最佳的 RAG 技術。它通過根據(jù)查詢的類型自動選擇最合適的檢索策略,能夠更好地滿足不同用戶的需求,生成更準確的回答。然而,這并不意味著其他技術沒有價值。實際上,不同的技術可以在不同的場景下發(fā)揮重要作用,關鍵在于根據(jù)具體的需求和場景選擇最適合的技術。

未來,隨著人工智能技術的不斷發(fā)展,RAG 技術也將不斷進化。我們可以預見,結合多種技術的優(yōu)點,開發(fā)出更加智能、高效、可靠的 RAG 系統(tǒng),將為信息檢索和自然語言處理領域帶來更多的可能性和突破。


以上就是對 18 種 RAG 技術的詳細分析和代碼示例。希望這篇文章能夠幫助你更好地了解 RAG 技術的多樣性和潛力。如果你對某一種技術特別感興趣,或者有其他問題,歡迎在評論區(qū)留言,我們一起探討!


本文轉(zhuǎn)載自公眾號Halo咯咯    作者:基咯咯

原文鏈接:??https://mp.weixin.qq.com/s/16Ra_wrH1igwiySPV9KkNA??


?著作權歸作者所有,如需轉(zhuǎn)載,請注明出處,否則將追究法律責任
收藏
回復
舉報
回復
相關推薦