RAGMeUp核心组件探秘:PostgresHybridRetriever如何实现高效检索
2026/8/15 15:14:04 网站建设 项目流程

RAGMeUp核心组件探秘:PostgresHybridRetriever如何实现高效检索

【免费下载链接】RAGMeUpGeneric rag framework to apply the power of LLMs on any given dataset项目地址: https://gitcode.com/gh_mirrors/ra/RAGMeUp

RAGMeUp作为一款强大的通用RAG框架,能够将LLM的强大能力应用于任何给定数据集。而在其众多核心组件中,PostgresHybridRetriever扮演着至关重要的角色,它通过创新的混合检索技术,为整个系统提供了高效、精准的文档检索能力。本文将深入探讨PostgresHybridRetriever的工作原理、核心功能以及实现高效检索的关键技术。

什么是PostgresHybridRetriever?

PostgresHybridRetriever是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_embeddingsragmeup_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 (m='16', ef_construction='64');

这里使用了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_field='id');

这里创建了一个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(total=len(documents), desc="Adding documents to Postgres") as pbar: for i in range(0, len(documents), 1000): chunk = documents[i:i+1000] # Add to the BM25 index # ... # Now the dense embeddings # ...

这种批量处理的方式可以提高数据插入的效率,特别是当处理大量文档时。

高效检索的实现

PostgresHybridRetriever的核心功能是get_relevant_documents方法,该方法会根据查询和查询嵌入来检索相关文档。它支持两种检索模式:min-max归一化排序和Reciprocal Rank Fusion(RRF)排序。

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排序

RRF(Reciprocal 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(), key=lambda d: d["rrf_score"], reverse=True)[: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(f"DELETE FROM ragmeup_sparse_embeddings WHERE metadata->>'source' IN ({placeholders});", tuple(filenames)) # ... cursor.execute(f"DELETE 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稀疏检索和向量密集检索,实现了高效、准确的文档检索。其主要优势包括:

  1. 混合检索:结合了稀疏检索和密集检索的优点,能够处理各种类型的查询。
  2. 灵活的结果融合:支持min-max归一化和RRF两种结果融合方法,可以根据实际需求选择合适的方法。
  3. 高效的数据库操作:通过批量处理、索引优化等手段,提高了数据插入和检索的效率。
  4. 丰富的功能:提供了文档添加、删除、查询处理等一系列功能,满足了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),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询