I recently attempted to prototype a RAG model that would be able to not only retrieve information but also compare documents containing complex, domain-specific jargon inside multiple tables and summarize the differences. The documents were in DOCX format and since so much of the information was tabular, it was an interesting challenge. After trying several methods, I settled on a hybrid search approach implemented via an EnsembleRetriever using a BM25Retriever and a MultiVectorRetriever.
Traditional search engines, Google being a prominent example, have long relied on models like BM25 (Best Match 25) to execute text matching. However, text matching alone isn’t enough for most use cases.
BM25 quantifies the relevance of documents based on the frequency and placement of search terms. That approach is effective but can’t capture documents’ intricate semantic relationships and context. This limitation leads to suboptimal search results when dealing with complex queries or nuanced information.
Alternately, a MultiVectorRetriever is exactly what it sounds like. It allows for the storage of multiple vectors per document. In my case, I wanted to summarize tables and text from my documents and store those with the raw documents themselves. The MultiVectorRetriever made this possible.
But how do you use both retrievers together? The EnsembleRetriever. Instead of trying to describe its function myself, here is how the LangChain Docs describe it: