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