成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

手搓RAG新增功能:遞歸檢索與迭代查詢+重回成熟框架API

人工智能
在上那篇提到的我手搓的那個 RAG 項目新增功能中,漏掉了遞歸檢索與迭代查詢,這篇補上。

在上那篇提到的我手搓的那個 RAG 項目新增功能中,漏掉了遞歸檢索與迭代查詢,這篇補上(源碼見知識星球)。經過初步調試對召回效果有明顯提升,這種方法解決了傳統 RAG 的幾個關鍵問題:

  • 處理復雜多步驟問題:通過多次迭代,分解復雜問題
  • 信息不足的補充:當初始檢索結果不足以回答問題時,自動生成補充查詢
  • 多角度信息收集:能夠從不同角度收集相關信息

1、遞歸檢索具體實現

遞歸檢索函數(recursive_retrieval)

(支持最多三次迭代查詢)

每次迭代使用混合檢索(向量檢索+BM25)獲取信息

使用 LLM 分析當前檢索結果,判斷是否需要進一步查詢

如果需要,LLM 會生成新的查詢問題,用于下一輪檢索

換句話說,遞歸檢索的工作原理可以理解為"先檢索-后思考-再檢索"的過程,模擬了人解決問題的方式:先獲取一些信息,思考下是否足夠,如果不夠則繼續查找更多相關信息??傊玫慕Y果不是一蹴而就的。

為了更直觀的讓大家了解這個遞歸檢索的過程,貼幾張本地測試圖片,供參考。需要說明的是,目前這個版本中還沒做多模態的預處理和圖片的召回,后續結合具體案例更新在知識星球中。

圖片

圖片

圖片

圖片

2、核心組件全解析

下面再對整個代碼的核心組件做進一步的解析,大家可以在這個基礎上按照業務需求進一步優化:

圖片

2.1文檔處理和向量化

文本提?。菏褂?pdfminer.high_level.extract_text_to_fp 從 PDF 提取文本內容

文本分塊:使用 RecursiveCharacterTextSplitter 將長文本分割成更小的塊(在代碼中塊大小設為 400 字符,重疊為 40 字符)

向量化:使用 all-MiniLM-L6-v2 模型為每個文本塊生成嵌入向量

存儲:將文本塊、向量和元數據存儲到 ChromaDB 向量數據庫

輔助索引:同時構建 BM25Okapi 索引用于基于關鍵詞的檢索

分塊粒度和嵌入質量直接影響檢索性能,這部分大家需要結合自己的文檔結構特點自行調整,上述列出的做法僅供參考。

2.2混合檢索機制

結合了兩種不同的檢索方法:

語義向量檢索:基于嵌入向量的相似度搜索,能夠捕捉語義關系

BM25 關鍵詞檢索:基于詞頻的經典檢索算法,專注于關鍵詞匹配

混合策略:通過 hybrid_merge 函數融合兩種檢索結果,使用α參數(0.7)控制兩種方法的權重

這種混合策略結合了語義理解和關鍵詞匹配的優勢,提高了檢索的綜合表現。

2.3重排序機制

檢索到初步結果后,使用更精確的模型進行重排序:

交叉編碼器重排序:使用 CrossEncoder 模型,能夠同時考慮查詢和文檔內容進行更精確的相關性評分

LLM 重排序:可選使用 LLM 對查詢和文檔的相關性進行評分,利用大模型的理解能力

緩存機制:使用@lru_cache 減少重復計算,提高效率

重排序步驟使檢索結果更符合用戶的實際需求,大幅提升了檢索質量。

2.4遞歸檢索與迭代查詢

這是新增的一個功能,也是實測下來對最終效果有明顯提升的一點,由 recursive_retrieval 函數實現:

初始檢索:使用原始查詢進行首輪檢索

結果分析:使用 LLM 分析當前檢索結果是否充分回答問題

查詢改寫:如果信息不足,LLM 會生成一個新的、更具體或從不同角度的查詢

迭代過程:使用新查詢繼續檢索,直到獲取足夠信息或達到最大迭代次數

這個機制解決了單次檢索的局限性,能夠處理復雜問題、多步驟推理,以及需要從多個角度收集信息的場景。

2.5生成回答

系統支持兩種回答生成方式:

本地 Ollama 模型:使用 deepseek-r1:1.5b 或 deepseek-r1:7b 模型在本地生成回答

SiliconFlow API:調用云端 API 使用更強大的模型生成回答

圖片

https://cloud.siliconflow.cn/i/cmXGS5IJ

思維鏈處理:支持分離思考過程,以可折疊的形式展示給用戶

之所以選擇新增一個商業api選項,也是因為我自己的電腦跑本地模型是在太卡,問了一些復雜問題容易觸發超時機制。當然另外還有個重要原因是,在針對不同核心組件做調優時,保持 chat 模型的水準個人實踐下來也很重要,否則就變成了過度雕花。

3、優化方向參考

因為只是方便大家練手,大家感興趣的可以在目前代碼基礎上做如下優化:

3.1文檔格式支持擴展

當前系統僅支持 PDF 文件,可擴展支持:

# 支持更多文檔格式
def extract_text_from_file(file_path):
    """根據文件類型選擇適當的提取方法"""
    ext = os.path.splitext(file_path)[1].lower()
   
    if ext == '.pdf':
        return extract_text_from_pdf(file_path)
    elif ext == '.docx':
        return extract_text_from_docx(file_path)
    elif ext == '.pptx':
        return extract_text_from_pptx(file_path)
    elif ext in ['.txt', '.md', '.py', '.java', '.js', '.html', '.css']:
        with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:
            return f.read()
    elif ext in ['.csv', '.xlsx', '.xls']:
        return extract_text_from_spreadsheet(file_path)
    else:
        raise ValueError(f"不支持的文件類型: {ext}")

3.2高級分塊策略

可以實現更智能的分塊策略:

語義分塊:基于段落、章節或自然語義邊界進行分塊

結構感知分塊:識別文檔結構(標題、列表、表格等)

多粒度分塊:同時維護不同粒度的塊,靈活應對不同類型的查詢 

# 多粒度分塊示例
def create_multi_granularity_chunks(text):
    """創建多粒度分塊"""
    # 大塊(1000字符):適合概述類問題
    large_splitter = RecursiveCharacterTextSplitter(
        chunk_size=1000, chunk_overlap=100
    )
    # 中塊(400字符):平衡粒度
    medium_splitter = RecursiveCharacterTextSplitter(
        chunk_size=400, chunk_overlap=40
    )
    # 小塊(150字符):適合精確問答
    small_splitter = RecursiveCharacterTextSplitter(
        chunk_size=150, chunk_overlap=20
    )
    
    large_chunks = large_splitter.split_text(text)
    medium_chunks = medium_splitter.split_text(text)
    small_chunks = small_splitter.split_text(text)
    
    return {
        "large": large_chunks,
        "medium": medium_chunks,
        "small": small_chunks
    }

3.3嵌入模型優化

當前系統使用 all-MiniLM-L6-v2,可以考慮:

更強大的多語言模型:如 multilingual-e5-large 提升中文理解能力

領域特定微調:針對特定領域數據微調嵌入模型

多模型集成:使用多個嵌入模型并融合結果 

# 多模型嵌入示例
def generate_multi_model_embeddings(text):
    """使用多個模型生成嵌入并融合"""
    model1 = SentenceTransformer('all-MiniLM-L6-v2')
    model2 = SentenceTransformer('paraphrase-multilingual-mpnet-base-v2')
    
    # 生成嵌入
    emb1 = model1.encode(text)
    emb2 = model2.encode(text)
    
    # 簡單融合策略:歸一化后拼接
    emb1_norm = emb1 / np.linalg.norm(emb1)
    emb2_norm = emb2 / np.linalg.norm(emb2)
    
    # 返回融合嵌入
    return np.concatenate([emb1_norm, emb2_norm])

3.4檢索與重排序改進

可以考慮以下改進:

查詢擴展:使用同義詞擴展或關鍵詞擴展增強原始查詢

密集檢索與稀疏檢索結合:更高級的混合檢索方法

上下文感知重排序:考慮已檢索文檔間的關系進行重排序

多輪對話記憶:在多輪對話中利用歷史上下文改進檢索

# 查詢擴展示例
def expand_query(query):
    """使用LLM擴展查詢,生成多個角度的查詢變體"""
    prompt = f"""
    為以下查詢生成3個不同角度的變體,以提高檢索召回率:
    
    原始查詢: {query}
    
    變體應當包含同義詞替換、關鍵詞擴展或問題重構。
    僅返回三個變體,每行一個,不要有額外解釋。
    """
    
    response = call_llm_api(prompt)
    variants = [line.strip() for line in response.strip().split('\n')]
    return [query] + variants  # 返回原始查詢和變體

3.5其他可能的擴展方向

結果驗證機制:使用外部知識或規則驗證生成結果的準確性

用戶反饋學習:根據用戶反饋調整檢索策略和參數

多模態支持:處理圖像、表格等非文本內容

層次化索引:構建文檔的層次化表示,從概覽到細節

個性化調整:根據用戶歷史查詢和偏好調整檢索策略

4、RAG 學習路線全梳理

最后回到學習路線上來,最開始手搓這個 demo,也是自己為了更好的從底層理解 RAG 系統,不曾想收到了很多正反饋。

圖片

https://github.com/weiwill88/Local_Pdf_Chat_RAG

另外正如上篇所說,直接使用封裝度高的框架容易讓人"知其然不知其所以然"。如果你已經掌握了基礎原理,就可以考慮進一步探索 RAGFlow 或者 LlamaIndex 等成熟框架的 Python API,充分利用成熟框架提供的生產力優勢。按照個人近幾個月的學習和實踐經驗,整體學習路線參考如下:

4.1從自建到框架的過渡期

對比學習:將手搓實現的組件與成熟框架中對應功能進行比較

框架源碼閱讀:嘗試閱讀 LlamaIndex 或 RAGFlow 等框架的核心源碼,看看他們如何實現相同功能

增量替換:逐步用框架組件替換自建組件,對比性能和結果差異

4.2成熟框架深入學習

從示例入手:優先研究官方提供的示例代碼和教程

構建微型項目:使用框架 API 實現小型但完整的應用

實驗各種組件:測試不同的檢索器、嵌入模型、重排序策略等

4.3高級應用與定制

探索高級功能:如多模態 RAG、Agent 集成、自定義索引等

性能優化:學習如何調整參數提高檢索質量和速度

領域適配:根據特定行業或領域需求定制 RAG 系統

5、Python API vs Web 界面能做什么?

公眾號之前有篇文章詳細介紹了 RAGFlow 官方 Python API 各個模塊使用,后續有些盆友私信我問到,這些 api 除了可以批量的按照自定義方式處理文件外,還可以干啥?結合近期學習和實踐,提供以下五個方向供大家參考,具體參考示例代碼:

5.1系統集成能力

# 與現有系統集成示例
from ragflow import RAGPipeline
import your_company_database


# 從公司數據庫獲取文檔
documents = your_company_database.get_latest_documents()


# 使用RAGFlow處理
pipeline = RAGPipeline()
for doc in documents:
    pipeline.add_document(doc)
    
# 將結果同步回公司系統
processed_results = pipeline.get_indexed_status()
your_company_database.update_document_status(processed_results)

5.2定制化檢索策略

# 自定義混合檢索策略
from ragflow import RetrievalPipeline
from ragflow.retrievers import VectorRetriever, KeywordRetriever


# 創建自定義的檢索器組合
def custom_hybrid_retriever(query, top_k=10):
    # 使用向量檢索獲取語義相關結果
    semantic_results = vector_retriever.retrieve(query, top_k=top_k)
    
    # 使用關鍵詞檢索獲取精確匹配
    keyword_results = keyword_retriever.retrieve(query, top_k=top_k)
    
    # 自定義融合策略(比如考慮文檔及時性等)
    results = custom_merge_function(semantic_results, keyword_results, 
                                    recency_weight=0.2)
    return results

5.3高級處理流程自動化

# 創建復雜的數據處理和RAG工作流
from ragflow import DocumentProcessor, Indexer, QueryEngine
import schedule
import time


def daily_knowledge_update():
    # 從多個來源獲取新文檔
    new_docs = fetch_documents_from_sources()
    
    # 文檔預處理(去重、格式轉換等)
    processed_docs = DocumentProcessor().process_batch(new_docs)
    
    # 增量更新索引
    indexer = Indexer()
    indexer.update_incrementally(processed_docs)
    
    # 生成日報
    report = generate_daily_summary()
    send_email(report)


# 設置定時任務
schedule.every().day.at("01:00").do(daily_knowledge_update)


while True:
    schedule.run_pending()
    time.sleep(60)

5.4自定義評估和優化

# 構建RAG系統評估框架
from ragflow import RAGEvaluator
import matplotlib.pyplot as plt


# 準備測試數據集
test_queries = load_test_queries()
ground_truth = load_ground_truth_answers()


# 測試不同的配置
configurations = [
    {"embeddings": "minilm", "chunk_size": 200, "retriever": "hybrid"},
    {"embeddings": "e5-large", "chunk_size": 500, "retriever": "vector"},
    {"embeddings": "bge-large", "chunk_size": 300, "retriever": "hybrid"}
]


results = {}
for config in configurations:
    # 構建并測試每種配置
    rag_system = build_rag_with_config(config)
    eval_results = RAGEvaluator.evaluate(
        rag_system, test_queries, ground_truth
    )
    results[str(config)] = eval_results


# 可視化不同配置的性能比較
plot_evaluation_results(results)

5.5領域特定的增強

# 醫療領域RAG增強示例
from ragflow import RAGPipeline
from custom_medical_modules import MedicalTermNormalizer, DiseaseEntityExtractor


# 創建領域特定的文檔處理器
medical_processor = DocumentProcessor()
medical_processor.add_transformer(MedicalTermNormalizer())
medical_processor.add_transformer(DiseaseEntityExtractor())


# 構建醫療特定的RAG系統
medical_rag = RAGPipeline(
    document_processor=medical_processor,
    retrieval_augmentors=[
        CitationRetriever(),  # 添加醫學文獻引用
        EvidenceLevelClassifier()  # 分類證據等級
    ],
    response_formatters=[
        MedicalDisclaimerFormatter(),  # 添加醫療免責聲明
        CitationFormatter()  # 格式化引用
    ]
)

當然,還有結合多個框架使用的示例,我在Medium看到一個博主使用 LlamaIndex 整合多源數據并構建索引,然后通過 RAGFlow 的深度解析和重排序優化結果。最后利用 RAGFlow 的引用功能增強答案可信度,同時調用 LlamaIndex 的代理進行動態數據補充。不過,我還沒試過,感興趣的可以測試下看看。

RAGFlow 等框架的實際業務價值,不同實踐經驗的盆友可能有不同的體會,個人總結其實就是一句話,使用這些框架的 Python API 可以讓我們快速構建原型并迭代改進,比從 0-1 開發節省了大量時間。從而專注于解決業務問題,而非技術細節。

責任編輯:龐桂玉 來源: 韋東東
相關推薦

2025-03-04 11:01:00

2025-04-29 09:15:49

AI數據模型

2025-04-01 09:25:09

2024-05-22 09:38:25

2024-08-01 17:20:55

2023-12-18 10:45:31

2025-04-01 09:00:00

模型訓練開源

2024-10-31 14:46:31

2024-11-19 13:05:40

2009-06-26 10:37:32

樹的匯總

2009-09-08 11:26:35

Spring 3.0

2023-10-14 17:46:17

RAG提示工程GPT-3

2025-03-26 11:05:13

2024-10-17 09:09:04

2024-01-29 13:56:55

AI數據

2025-03-10 08:00:00

RAG檢索Reranker

2025-03-28 08:00:00

RAG文本檢索大模型

2025-04-24 09:04:42

2025-04-27 00:30:00

RAG檢索增強生成AI

2025-05-26 09:49:59

多模態智能體RAG
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 男女羞羞视频大全 | 久久国产高清 | 中文字幕av网站 | 一区二区三区国产精品 | 一区二区三区在线免费观看 | 国产婷婷综合 | 亚洲一区成人 | 一级毛片视频在线 | 成人在线视频一区 | 欧美日韩电影免费观看 | 欧美色影院 | 国产精品国产成人国产三级 | 日本字幕在线观看 | 欧美片网站免费 | 成人精品一区二区 | 午夜视频在线观看一区二区 | 亚洲精品美女在线观看 | 亚洲久草| 国产美女黄色片 | 欧美在线综合 | 久久99精品久久久久久国产越南 | 天天久| www国产成人免费观看视频,深夜成人网 | av一区二区三区在线观看 | 毛片网站免费观看 | 欧美日韩精品一区二区天天拍 | 国产成人网 | 女同久久另类99精品国产 | 成人免费看黄 | 一区二区中文 | 国产精品午夜电影 | 欧美精品在线免费 | 久久精品网 | 网站黄色在线免费观看 | 福利视频二区 | 一区二区三区免费在线观看 | 日本午夜一区二区三区 | 国产精品视频偷伦精品视频 | 天天色综 | 福利社午夜影院 | 中文字幕国产精品视频 |