用技術(shù)原理:RAG 向量庫選型、混合檢索與 Agent Function Call 實戰(zhàn))
Langchain-Chatchat 大模型應(yīng)用技術(shù)原理RAG 向量庫選型、混合檢索與 Agent Function Call 實戰(zhàn)【免費下載鏈接】Langchain-ChatchatLangchain-Chatchat原Langchain-ChatGLM基于 Langchain 與 ChatGLM, Qwen 與 Llama 等語言模型的 RAG 與 Agent 應(yīng)用 | Langchain-Chatchat (formerly langchain-ChatGLM), local knowledge based LLM (like ChatGLM, Qwen and Llama) RAG and Agent app with langchain項目地址: https://gitcode.com/GitHub_Trending/la/Langchain-Chatchat本文圍繞 Langchain-Chatchat 內(nèi)置樣例知識庫文檔《大模型應(yīng)用技術(shù)原理》展開系統(tǒng)梳理 RAG 應(yīng)用的技術(shù)骨架——向量數(shù)據(jù)庫選型標(biāo)準(zhǔn)、索引算法與量化方法、Embedding 模型、混合檢索向量檢索 BM25 關(guān)鍵字檢索以及 RAG 增強Self-RAG與 Agent 的 function call 機制并逐一對照本倉庫源碼中的知識庫服務(wù)與檢索器實現(xiàn)。讀完本文你既能掌握大模型應(yīng)用技術(shù)選型的方法論也能在 Langchain-Chatchat 的代碼中找到每項技術(shù)的落地點。一、RAG 應(yīng)用的總體技術(shù)骨架從樣例文檔的思維導(dǎo)圖結(jié)構(gòu)看一個完整的 RAGRetrieval-Augmented Generation檢索增強生成應(yīng)用由以下層次組成向量數(shù)據(jù)庫存儲文本切片chunk的向量表示支持相似度檢索是 RAG 的存儲底座Embedding 模型把文本編碼為向量分為 bi-encoder雙塔編碼器與 cross-encoder交叉編碼器兩類【可選】文本檢索引擎如 ElasticSearch、OpenSearch提供關(guān)鍵字/全文檢索能力【可選】圖數(shù)據(jù)庫用于結(jié)構(gòu)化知識檢索配合 NL2Cypher 使用檢索向量檢索、關(guān)鍵字檢索BM25、NL2Cypher、NL2SQL 等多種方式組合RAG 增強如 Self-RAG通過反思機制提升檢索與生成質(zhì)量Agent通過 function call 讓大模型調(diào)用外部工具ToolFormer 是這一方向的經(jīng)典工作。Langchain-Chatchat 本身就是這條技術(shù)鏈路的一個完整工程實現(xiàn)其知識庫子系統(tǒng)chatchat/server/knowledge_base/覆蓋文檔加載、文本切片、向量化、存儲與檢索Agent 子系統(tǒng)chatchat/server/agent/則以工具注冊表的方式實現(xiàn) function call。下文逐層展開。二、向量數(shù)據(jù)庫選型標(biāo)準(zhǔn)文檔給出了四個維度的選型標(biāo)準(zhǔn)這是向量庫選型時的通用方法論。2.1 開源 vs 閉源 vs 源碼可見開源項目如 faiss、milvus可自托管、可修改源碼便于審計與二次開發(fā)閉源/托管服務(wù)如 pinecone以完全云原生方式交付上手成本最低但依賴廠商與網(wǎng)絡(luò)環(huán)境源碼可見介于兩者之間商業(yè)支持更完善。2.2 客戶端/SDK 語言選型時需確認(rèn)服務(wù)端是否有目標(biāo)語言的官方 SDKPython、Java、Go、Node.js 等。faiss 支持 C、Python、Go 客戶端milvus 提供 Python、Java、Go、Node.js SDK還提供 milvus lite 這種 in-memory 運行形態(tài)。2.3 托管方式文檔將向量庫按部署形態(tài)劃分為四類形態(tài)代表方案特點self-hosted / on-premiseredis、pgvector、milvus自托管數(shù)據(jù)留在本地運維成本自擔(dān)managed / cloud-nativezilliz、pinecone云托管開箱即用embeded cloud-nativechroma、LanceDB嵌入式部署本地輕量使用self-hosted cloud-nativevald、drant、weaviate、vespa、elasticsearch兩種形態(tài)均支持Langchain-Chatchat 的kbs_config配置恰好體現(xiàn)了這一譜系同一個應(yīng)用內(nèi)同時支持 faiss本地文件、milvus自托管、zilliz云托管、pg/relytpgvector 路線、esElasticSearch、chromadb嵌入式等多種后端詳見 settings.py 中的 KBSettings。2.4 索引方法與量化文檔列出了向量索引算法的完整分類樹Flat暴力精確檢索小數(shù)據(jù)集下精度最高Tree-basedAnnoy、KD-Tree、Trinary Projection TreesIVFInverted File含 IVMFInverted Multi-index FileGraph-basedHNSW、NSG、VamanaDiskANNHashing-basedLSH、Spherical Hashing、Spectral Hashing。量化方面文檔給出了兩種壓縮手段的定義PQProduct Quantization乘積量化將特征空間分解為多個低維子空間的笛卡爾乘積然后單獨地對每一個子空間進(jìn)行量化從而大幅壓縮向量存儲SQScalar Quantization標(biāo)量量化將每一個維度量化成指定位數(shù)的一個數(shù)。倉庫中的實現(xiàn)印證Langchain-Chatchat 對 Milvus 的默認(rèn)索引配置就是 Graph-based 中的 HNSW見 settings.py 的 milvus_kwargsmilvus_kwargs: { search_params: { metric_type: L2 }, index_params: { metric_type: L2, index_type: HNSW } }這段配置在 MilvusKBService._load_milvus 中被直接傳入Milvus向量庫構(gòu)造函數(shù)的index_params與search_params參數(shù)說明用戶修改kb_settings.yaml后索引算法如 HNSW 換 IVF與距離度量L2、IP 等可以隨配置切換。三、主流向量庫方案解析3.1 文檔中的方案要點文檔將主流方案分為 professional專業(yè)向量庫與 traditional傳統(tǒng)數(shù)據(jù)庫擴展兩類專業(yè)向量庫weaviate文檔豐富容易上手提供混合索引支持自托管 云原生支持 Python、JS、TS、Go、Java 等客戶端支持 HNSW、HNSW-PQ、DiskANN 等索引chroma、LanceDB嵌入式 云原生形態(tài)適合本地輕量場景pinecone完全云原生非常容易上手支持自建復(fù)合索引faiss來自 Meta AI 的開源項目同時支持 CPU 和 GPU支持 C、Python、Go 客戶端支持 IVF、HNSW 等常見索引方式與 PQ 量化in-memory 運行self-hostedmilvus通過代理、負(fù)載均衡器、消息代理、Kafka 和 Kubernetes 的組合實現(xiàn)了高度可擴展性系統(tǒng)也因此變得復(fù)雜和資源密集截至 2023 年它是唯一一個提供可工作 DiskANN 實現(xiàn)的主要供應(yīng)商支持在向量相似度檢索過程中進(jìn)行標(biāo)量字段過濾實現(xiàn)混合查詢采用存儲與計算分離的架構(gòu)設(shè)計提供 Python、Java、Go、Node.js 等語言 SDK也提供 milvus lite 等 in-memory 運行方式提供圖形界面客戶端。傳統(tǒng)方案ESElasticSearch、redis、pgvector。3.2 Langchain-Chatchat 中的向量庫落地支持的后端清單。kb_service/base.py 中的SupportedVSType枚舉定義了當(dāng)前倉庫實際接入的全部向量后端class SupportedVSType: FAISS faiss MILVUS milvus DEFAULT default ZILLIZ zilliz PG pg RELYT relyt ES es CHROMADB chromadb工廠分發(fā)。KBServiceFactory.get_service 按vs_type字符串惰性導(dǎo)入并實例化對應(yīng)的KBService子類faiss 返回FaissKBServicemilvus/zilliz/default 返回MilvusKBServicepg/relyt/es/chromadb 各自對應(yīng)獨立服務(wù)類。每個知識庫在元數(shù)據(jù)庫中記錄自己的vs_type與embed_modelget_service_by_name可以按名重建服務(wù)實例實現(xiàn)了一個應(yīng)用、多種向量后端、互不干擾的架構(gòu)。faiss 的實現(xiàn)要點。FaissKBService 印證了文檔中 faissin-memory 運行 self-hosted的定位向量庫通過kb_faiss_pool線程安全的 FAISS 連接池按(kb_name, vector_name)鍵加載與緩存對應(yīng)配置項CACHED_VS_NUM緩存向量庫數(shù)量見 settings.py增刪文檔后調(diào)用vs.save_local(self.vs_path)持久化到磁盤重啟后可從磁盤重新加載每個知識庫的向量目錄名由 Embedding 模型決定self.vector_name self.embed_model.replace(:, _)。這意味著同一個知識庫換用不同 Embedding 模型時必須重建向量庫——因為不同模型對同一段文本產(chǎn)生的向量并不可比。milvus 的實現(xiàn)要點。MilvusKBService 體現(xiàn)了文檔所述 milvus高度可擴展的一面連接參數(shù)host/port/user/password/secure從kbs_config[milvus]讀取刪除文檔時用主鍵表達(dá)式pk in {id_list}批量刪除搜索參數(shù)使用metric_type: L2、nprobe: 10見 MilvusKBService.search。各后端的連接配置。以 settings.py 的 kbs_config 為準(zhǔn)faiss: {}, milvus: {host: 127.0.0.1, port: 19530, user: , password: , secure: False}, zilliz: {host: ...vectordb.zilliz.com.cn, port: 19530, secure: True}, pg: {connection_uri: postgresql://postgres:postgres127.0.0.1:5432/langchain_chatchat}, relyt: {connection_uri: postgresqlpsycopg2://postgres:postgres127.0.0.1:7000/langchain_chatchat}, es: {scheme: http, host: 127.0.0.1, port: 9200, index_name: test_index, ...}, chromadb: {}這與文檔中self-hosted / managed / embedded的分類一一對應(yīng)milvus 走本地自托管zilliz 走云托管secureTruepg/relyt 走 pgvector 路線es 走傳統(tǒng)檢索引擎chromadb 走嵌入式。四、Embedding 模型bi-encoder 與 cross-encoder文檔將 Embedding 模型分為兩類bi-encoder雙塔編碼器查詢與文檔分別獨立編碼為向量再做相似度計算。因為文檔向量可以離線預(yù)計算并存入向量數(shù)據(jù)庫所以它是 RAG 在線檢索的標(biāo)準(zhǔn)選擇cross-encoder交叉編碼器查詢與文檔拼接后共同編碼、直接輸出相關(guān)性分?jǐn)?shù)精度通常更高但每次查詢都需實時推理無法預(yù)計算一般用于**重排rerank**環(huán)節(jié)。在 Langchain-Chatchat 中的體現(xiàn)知識庫服務(wù)構(gòu)造時都會接收embed_model參數(shù)見 KBService.init默認(rèn)值來自get_default_embedding()并向量庫的向量目錄名直接由該模型字符串派生第二節(jié)已述。KBService.add_doc在入庫前會先調(diào)用check_embed_model()校驗?zāi)P涂捎眯允t拒絕寫入防止不可用模型產(chǎn)生的向量污染知識庫。從源碼結(jié)構(gòu)看文檔中bi-encoder/cross-encoder的分工在本倉庫體現(xiàn)為入庫與檢索階段使用可預(yù)計算的編碼模型排序階段可結(jié)合 reranker 模塊chatchat/server/reranker/后者即 cross-encoder 思想的應(yīng)用場景。五、混合檢索向量檢索 BM25 關(guān)鍵字檢索文檔檢索一節(jié)點列出向量檢索、關(guān)鍵字檢索BM25、NL2Cypher、NL2SQL 四類方式。Langchain-Chatchat 前兩者的結(jié)合實現(xiàn)最為完整是混合檢索的典型工程范式。5.1 檢索器工廠retrievers 提供三種檢索服務(wù)由 get_Retriever 統(tǒng)一分發(fā)Retrivals { milvusvectorstore: MilvusVectorstoreRetrieverService, vectorstore: VectorstoreRetrieverService, ensemble: EnsembleRetrieverService, }5.2 純向量檢索VectorstoreRetrieverService.from_vectorstore 使用similarity_score_threshold搜索類型傳入score_threshold與k兩個參數(shù)構(gòu)造檢索器并在返回時再截斷到top_k。5.3 混合檢索ensemble的實現(xiàn)EnsembleRetrieverService.from_vectorstore 完整實現(xiàn)了文檔中向量檢索 關(guān)鍵字檢索BM25的組合faiss_retriever vectorstore.as_retriever( search_typesimilarity_score_threshold, search_kwargs{score_threshold: score_threshold, k: top_k}, ) import jieba docs list(vectorstore.docstore._dict.values()) bm25_retriever BM25Retriever.from_documents( docs, preprocess_funcjieba.lcut_for_search, # 中文分詞預(yù)處理 ) bm25_retriever.k top_k ensemble_retriever EnsembleRetriever( retrievers[bm25_retriever, faiss_retriever], weights[0.5, 0.5] )三個值得注意的工程細(xì)節(jié)中文分詞BM25 的preprocess_func使用jieba.lcut_for_search做中文搜索模式分詞避免英文按空格切分對中文語料失效——源碼注釋中還保留了用 cutword 替換的 TODO說明分詞器是可插拔的加權(quán)融合EnsembleRetriever以[0.5, 0.5]的權(quán)重對兩路檢索的歸一化分?jǐn)?shù)加權(quán)平均即向量語義匹配與 BM25 詞頻匹配各占一半FAISS 路徑默認(rèn)走 ensembleFaissKBService.do_search 明確調(diào)用get_Retriever(ensemble)而 Milvus 路徑調(diào)用get_Retriever(milvusvectorstore)——因為 Milvus 自身的標(biāo)量過濾能力已經(jīng)覆蓋了部分關(guān)鍵字需求與文檔中 milvus支持標(biāo)量字段過濾實現(xiàn)混合查詢的描述一致。5.4 檢索參數(shù)top_k 與 score_threshold兩個關(guān)鍵參數(shù)在 settings.py 的 KBSettings 中定義VECTOR_SEARCH_TOP_K: int 3 # 知識庫匹配向量數(shù)量 SCORE_THRESHOLD: float 2.0 # 知識庫匹配相關(guān)度閾值取值范圍在0-2之間 # SCORE越小相關(guān)度越高取到2相當(dāng)于不篩選建議設(shè)置在0.5左右對 FAISS 距離度量而言分?jǐn)?shù)是距離而非相似度SCORE_THRESHOLD2.0意味著默認(rèn)不篩選任何文檔配置為 0.5 附近可過濾低相關(guān)結(jié)果。這兩個參數(shù)沿search_docs → do_search → as_retriever(search_kwargs...)的調(diào)用鏈最終注入向量庫檢索器構(gòu)成可調(diào)的召回質(zhì)量閘門。六、可選組件文本檢索引擎與圖數(shù)據(jù)庫文檔把文本檢索引擎ElasticSearch、OpenSearch與圖數(shù)據(jù)庫列為 RAG 的可選增強文本檢索引擎Langchain-Chatchat 將其作為一類向量后端接入SupportedVSType.ESes_kb_service.py配置見 settings.py 的 es 段scheme/host/port/index_name 及證書選項復(fù)用統(tǒng)一的KBService抽象圖數(shù)據(jù)庫配合 NL2Cypher 做結(jié)構(gòu)化知識檢索。當(dāng)前倉庫源碼中未見圖數(shù)據(jù)庫實現(xiàn)文檔將其標(biāo)記為【可選】屬于技術(shù)路線預(yù)留而非現(xiàn)有功能。七、RAG 增強Self-RAG文檔用較大篇幅介紹了 Self-RAGSelf-Reflective Retrieval-Augmented Generation自反思檢索增強生成其核心設(shè)計分三個層面7.1 框架Self-RAG 不僅可以根據(jù)需要自適應(yīng)地檢索段落模型可以判斷是否有必要進(jìn)行檢索增強還引入了名為**反思令牌reflection tokens**的特殊令牌使 LM 在推理階段可控。7.2 訓(xùn)練訓(xùn)練分兩步首先訓(xùn)練評論家critic使用檢索器檢索到的段落以及反思令牌增強指令-輸出數(shù)據(jù)然后使用標(biāo)準(zhǔn)的下一個 token 預(yù)測目標(biāo)來訓(xùn)練生成器 LM使其學(xué)會生成自然延續(xù)continuations以及特殊 tokens用來檢索或批評其自己的生成內(nèi)容。7.3 推理推理時模型可以適應(yīng)性地使用檢索令牌進(jìn)行檢索自發(fā)判斷是否有必要檢索它引入多種細(xì)粒度的批評令牌用于評估生成內(nèi)容各個方面的質(zhì)量。生成過程中使用期望的批評令牌概率的線性插值進(jìn)行segment 級 beam search以在每一個時間步驟中確定最佳的 K 個續(xù)寫方案。在 Langchain-Chatchat 中的對照當(dāng)前倉庫的 RAG 鏈路屬于經(jīng)典 RAG檢索-拼接-生成未內(nèi)置 Self-RAG 的反思令牌機制。從源碼結(jié)構(gòu)看chatchat/server/chat/與chatchat/server/agent/的模塊劃分檢索工具與對話生成解耦為未來在 Agent 層引入是否需要檢索的自適應(yīng)判斷提供了掛載點但這屬于從代碼結(jié)構(gòu)出發(fā)的推斷并非現(xiàn)有實現(xiàn)。八、Agent 與 Function Call文檔的 Agent 部分從function call以 ToolFormer 為代表讓模型通過預(yù)測特殊標(biāo)記來自主決定何時、調(diào)用哪個工具展開。Langchain-Chatchat 的 Agent 子系統(tǒng)正是這一思路的工程化實現(xiàn)。8.1 工具注冊機制tools_registry.py 提供regist_tool裝飾器作為 Langchaintool裝飾器的封裝支持自定義title、description、return_direct、args_schema、infer_schema等參數(shù)并維護(hù)全局_TOOLS_REGISTRY注冊表。同目錄下的tools_factory/內(nèi)置了 weather、search_internet、search_youtube、arxiv、text2sql、text2promql、search_local_knowledgebase 等一系列工具實現(xiàn)。8.2 知識庫檢索作為 Agent 工具值得注意的是Agent 與 RAG 在倉庫中并非割裂tools_factory/search_local_knowledgebase.py把知識庫檢索封裝為一個可被 LLM 調(diào)用的 function call 工具配合 settings.py 的 KB_INFO 配置每個知識庫的初始化介紹……用于在初始化知識庫時顯示和 Agent 調(diào)用沒寫則沒有介紹不會被 Agent 調(diào)用由大模型自主決定何時向哪個知識庫發(fā)起檢索——這正是文檔中 Self-RAG模型自發(fā)判斷是否有必要檢索思想在工程上的輕量近似。8.3 輸出解析鏈路langchain_chatchat/agents/output_parsers/目錄下按模型族glm3、qwen、structured_chat、platform_tools提供了不同的輸出解析器負(fù)責(zé)把模型輸出的工具調(diào)用文本解析為結(jié)構(gòu)化動作是 function call 循環(huán)中解析-執(zhí)行-回填環(huán)節(jié)的關(guān)鍵組件。九、小結(jié)回到樣例文檔《大模型應(yīng)用技術(shù)原理.md》的脈絡(luò)本文完成了兩條線的工作方法論線向量庫選型四標(biāo)準(zhǔn)開源形態(tài)/SDK 語言/托管方式/索引方法、Flat-Tree-IVF-Graph-Hashing 五類索引算法、PQ/SQ 兩種量化、bi-encoder 與 cross-encoder 兩類 Embedding 模型、向量BM25 混合檢索、Self-RAG 自適應(yīng)檢索增強、Agent function call實現(xiàn)線Langchain-Chatchat 用SupportedVSTypeKBServiceFactory覆蓋了 faiss/milvus/zilliz/pg/relyt/es/chromadb 七類后端用EnsembleRetrieverService實現(xiàn)了 jieba 分詞 BM25 與向量檢索的 0.5/0.5 加權(quán)融合用milvus_kwargs暴露了 HNSW 索引與 L2 度量配置并用tools_registry 輸出解析器實現(xiàn)了 function call 的注冊與解析。對于需要在自有知識庫上做本地化問答與 Agent 應(yīng)用的開發(fā)者建議的深入閱讀順序是先讀 settings.py 的 KBSettings 理解全部可調(diào)參數(shù)再對照 kb_service/base.py 的抽象接口理解各后端的統(tǒng)一契約最后進(jìn)入 retrievers 理解檢索融合細(xì)節(jié)?!久赓M下載鏈接】Langchain-ChatchatLangchain-Chatchat原Langchain-ChatGLM基于 Langchain 與 ChatGLM, Qwen 與 Llama 等語言模型的 RAG 與 Agent 應(yīng)用 | Langchain-Chatchat (formerly langchain-ChatGLM), local knowledge based LLM (like ChatGLM, Qwen and Llama) RAG and Agent app with langchain項目地址: https://gitcode.com/GitHub_Trending/la/Langchain-Chatchat創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考