RAGMeUp核心组件探秘:PostgresHybridRetriever如何实现高效检索
RAGMeUp核心组件探秘PostgresHybridRetriever如何实现高效检索【免费下载链接】RAGMeUpGeneric rag framework to apply the power of LLMs on any given dataset项目地址: https://gitcode.com/gh_mirrors/ra/RAGMeUpRAGMeUp作为一款强大的通用RAG框架能够将LLM的强大能力应用于任何给定数据集。而在其众多核心组件中PostgresHybridRetriever扮演着至关重要的角色它通过创新的混合检索技术为整个系统提供了高效、精准的文档检索能力。本文将深入探讨PostgresHybridRetriever的工作原理、核心功能以及实现高效检索的关键技术。什么是PostgresHybridRetrieverPostgresHybridRetriever是RAGMeUp框架中的一个核心组件它巧妙地结合了稀疏检索BM25和密集检索向量搜索两种技术充分发挥了各自的优势从而实现了更全面、更准确的文档检索。该组件通过PostgreSQL数据库来存储和管理文档数据并利用PostgreSQL的强大功能来执行检索操作。在RAGHelper类的初始化过程中我们可以看到PostgresHybridRetriever的实例化和配置过程# Set up the PostgresHybridRetriever self.retriever PostgresHybridRetriever(self.db_pool) self.retriever.setup_database(self.embeddings.get_sentence_embedding_dimension())这表明PostgresHybridRetriever需要一个数据库连接池来与PostgreSQL进行交互并且需要根据嵌入模型的维度来设置数据库表结构。数据库表结构设计PostgresHybridRetriever在PostgreSQL中创建了两个主要的表来存储文档数据ragmeup_dense_embeddings和ragmeup_sparse_embeddings。密集嵌入表ragmeup_dense_embeddings该表用于存储文档的密集向量表示其结构如下CREATE TABLE IF NOT EXISTS ragmeup_dense_embeddings ( id VARCHAR(32) PRIMARY KEY, embedding public.vector({embedding_dimension}) NOT NULL, content varchar NOT NULL, metadata jsonb NOT NULL ); CREATE INDEX IF NOT EXISTS ragmeup_dense_embedding_index ON ragmeup_dense_embeddings USING hnsw (embedding vector_cosine_ops) WITH (m16, ef_construction64);这里使用了PostgreSQL的vector扩展来存储向量数据并创建了一个基于hnsw算法的索引以加速向量相似度搜索。稀疏嵌入表ragmeup_sparse_embeddings该表用于存储文档的原始内容以便进行BM25检索CREATE TABLE IF NOT EXISTS ragmeup_sparse_embeddings ( id VARCHAR(32) PRIMARY KEY, content TEXT, metadata JSONB ); CREATE INDEX ragmeup_sparse_embeddings_bm25 ON ragmeup_sparse_embeddings USING bm25 (id, content) WITH (key_fieldid);这里创建了一个BM25索引以加速基于关键词的检索。此外还为两个表创建了基于dataset元数据的索引以支持按数据集进行过滤CREATE INDEX idx_metadata_dense_dataset ON ragmeup_dense_embeddings (((metadata::jsonb - dataset)::text)); CREATE INDEX idx_metadata_sparse_dataset ON ragmeup_sparse_embeddings (((metadata::jsonb-dataset)::text));文档添加流程PostgresHybridRetriever提供了add_documents方法用于将文档添加到数据库中。该方法会将文档同时添加到密集嵌入表和稀疏嵌入表中def add_documents(self, documents) - List[str]: # Batch these documents into chunks of 1000, with TQDM with tqdm(totallen(documents), descAdding documents to Postgres) as pbar: for i in range(0, len(documents), 1000): chunk documents[i:i1000] # Add to the BM25 index # ... # Now the dense embeddings # ...这种批量处理的方式可以提高数据插入的效率特别是当处理大量文档时。高效检索的实现PostgresHybridRetriever的核心功能是get_relevant_documents方法该方法会根据查询和查询嵌入来检索相关文档。它支持两种检索模式min-max归一化排序和Reciprocal Rank FusionRRF排序。Min-max归一化排序在min-max归一化排序模式下系统会分别执行BM25检索和向量检索然后将两种检索结果进行归一化处理并以50:50的权重进行组合SELECT id, content, metadata, score_bm25, distance, sources, ( 0.5 * COALESCE(score_bm25 / NULLIF(max_bm25, 0), 0) 0.5 * COALESCE(1 - (distance - min_distance) / NULLIF((max_distance - min_distance), 0), 0) ) AS hybrid_score FROM scored ORDER BY hybrid_score DESC LIMIT %s;这种方法通过将BM25得分和向量距离都归一化到[0, 1]范围内然后进行加权平均从而得到最终的混合得分。RRF排序RRFReciprocal Rank Fusion是一种基于排名的结果融合方法它通过为每个结果分配一个得分1/(k rank)其中k是平滑常数默认为60然后将不同检索方法得到的得分相加来得到最终的排序结果。# Process BM25 results for rank, row in enumerate(bm25_rows): doc_id, content, metadata row rrf_score 1.0 / (rrf_k rank 1) # ... # Process vector results for rank, row in enumerate(vector_rows): doc_id, content, metadata, distance row rrf_score 1.0 / (rrf_k rank 1) # ... # Sort by combined RRF score descending, take top_k ranked sorted(doc_map.values(), keylambda d: d[rrf_score], reverseTrue)[:k]RRF方法的优势在于它对分数的绝对值不敏感只关注结果的排名这使得不同检索方法的结果可以更公平地进行融合。此外RRF方法实现简单不需要复杂的参数调优。其他核心功能除了上述主要功能外PostgresHybridRetriever还提供了其他一些重要的功能数据存在性检查has_data方法用于检查数据库中是否存在文档数据def has_data(self): conn None try: conn self.connection_pool.getconn() with conn.cursor() as cursor: cursor.execute(SELECT COUNT(*) FROM ragmeup_sparse_embeddings;) return cursor.fetchone()[0] 0 # ...文档删除delete方法用于根据文件名删除文档def delete(self, filenames: List[str]) - None: # ... cursor.execute(fDELETE FROM ragmeup_sparse_embeddings WHERE metadata-source IN ({placeholders});, tuple(filenames)) # ... cursor.execute(fDELETE FROM ragmeup_dense_embeddings WHERE metadata-source IN ({placeholders});, tuple(filenames)) # ...查询处理escape_query方法用于对查询进行预处理包括分词和特殊字符过滤def escape_query(self, query): # Tokenize the query into words tokens nltk.word_tokenize(query) # Use regex to keep alphanumeric characters and diacritics, remove all others tokens [regex.sub(r[^\p{L}\p{N}\s], , token) for token in tokens] # Rejoin tokens into a sanitized string sanitized_query .join(tokens) return sanitized_query总结PostgresHybridRetriever作为RAGMeUp框架的核心组件通过巧妙地结合BM25稀疏检索和向量密集检索实现了高效、准确的文档检索。其主要优势包括混合检索结合了稀疏检索和密集检索的优点能够处理各种类型的查询。灵活的结果融合支持min-max归一化和RRF两种结果融合方法可以根据实际需求选择合适的方法。高效的数据库操作通过批量处理、索引优化等手段提高了数据插入和检索的效率。丰富的功能提供了文档添加、删除、查询处理等一系列功能满足了RAG系统的各种需求。通过深入了解PostgresHybridRetriever的实现细节我们可以更好地理解RAGMeUp框架的工作原理从而更好地使用和扩展该框架。无论是对于新手还是有经验的开发者PostgresHybridRetriever都是一个值得深入研究的组件它展示了如何在实际应用中有效地结合不同的检索技术以提供更好的搜索体验。要开始使用RAGMeUp框架你可以通过以下命令克隆仓库git clone https://gitcode.com/gh_mirrors/ra/RAGMeUp然后按照项目文档中的说明进行安装和配置体验PostgresHybridRetriever带来的高效检索能力。【免费下载链接】RAGMeUpGeneric rag framework to apply the power of LLMs on any given dataset项目地址: https://gitcode.com/gh_mirrors/ra/RAGMeUp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考