@@ -88,6 +88,14 @@ def get_content_from_url(request, url: str) -> str:
8888 return content , docs
8989
9090
91+ CHUNK_HASH_KEY = "_chunk_hash"
92+
93+
94+ def _content_hash (text : str ) -> str :
95+ """SHA-256 hash of text, used as a stable chunk identifier for RRF dedup."""
96+ return hashlib .sha256 (text .encode ()).hexdigest ()
97+
98+
9199class VectorSearchRetriever (BaseRetriever ):
92100 collection_name : Any
93101 embedding_function : Any
@@ -126,9 +134,11 @@ async def _aget_relevant_documents(
126134
127135 results = []
128136 for idx in range (len (ids )):
137+ metadata = metadatas [idx ]
138+ metadata [CHUNK_HASH_KEY ] = _content_hash (documents [idx ])
129139 results .append (
130140 Document (
131- metadata = metadatas [ idx ] ,
141+ metadata = metadata ,
132142 page_content = documents [idx ],
133143 )
134144 )
@@ -240,15 +250,21 @@ async def query_doc_with_hybrid_search(
240250
241251 log .debug (f"query_doc_with_hybrid_search:doc { collection_name } " )
242252
253+ original_texts = collection_result .documents [0 ]
254+ bm25_metadatas = [
255+ {** meta , CHUNK_HASH_KEY : _content_hash (original_texts [idx ])}
256+ for idx , meta in enumerate (collection_result .metadatas [0 ])
257+ ]
258+
243259 bm25_texts = (
244260 get_enriched_texts (collection_result )
245261 if enable_enriched_texts
246- else collection_result . documents [ 0 ]
262+ else original_texts
247263 )
248264
249265 bm25_retriever = BM25Retriever .from_texts (
250266 texts = bm25_texts ,
251- metadatas = collection_result . metadatas [ 0 ] ,
267+ metadatas = bm25_metadatas ,
252268 )
253269 bm25_retriever .k = k
254270
@@ -258,18 +274,24 @@ async def query_doc_with_hybrid_search(
258274 top_k = k ,
259275 )
260276
277+ # Use CHUNK_HASH_KEY for dedup so enriched BM25 texts don't defeat RRF
261278 if hybrid_bm25_weight <= 0 :
262279 ensemble_retriever = EnsembleRetriever (
263- retrievers = [vector_search_retriever ], weights = [1.0 ]
280+ retrievers = [vector_search_retriever ],
281+ weights = [1.0 ],
282+ id_key = CHUNK_HASH_KEY ,
264283 )
265284 elif hybrid_bm25_weight >= 1 :
266285 ensemble_retriever = EnsembleRetriever (
267- retrievers = [bm25_retriever ], weights = [1.0 ]
286+ retrievers = [bm25_retriever ],
287+ weights = [1.0 ],
288+ id_key = CHUNK_HASH_KEY ,
268289 )
269290 else :
270291 ensemble_retriever = EnsembleRetriever (
271292 retrievers = [bm25_retriever , vector_search_retriever ],
272293 weights = [hybrid_bm25_weight , 1.0 - hybrid_bm25_weight ],
294+ id_key = CHUNK_HASH_KEY ,
273295 )
274296
275297 compressor = RerankCompressor (
0 commit comments