Hybrid RAG (MongoDB Integration)
Retrieval-Augmented Generation (RAG) is traditionally binary: you either query a local Vector Database containing your private data, OR you search the live web.
Hybrid RAG merges these two paradigms. The TavilyHybridClient allows you to query a local MongoDB Vector Search index and the live Tavily web search simultaneously. The client then combines the results, reranks them using a cross-encoder model to ensure absolute relevance, and returns a unified list of sources.
Prerequisites
To use the Hybrid Client, you must install the optional dependencies:
pip install pymongo cohere
You must also have a MongoDB Atlas cluster with a properly configured vectorSearch index using cosine similarity.
1. Initializing the Hybrid Client
The client requires connections to both Tavily (via API key) and MongoDB (via pymongo.MongoClient). By default, it uses Cohere's V3 embedding and reranking models, meaning the COHERE_API_KEY environment variable must be set unless you provide custom functions.
import os
from pymongo import MongoClient
from tavily.hybrid_rag import TavilyHybridClient
# 1. Connect to your MongoDB cluster
# Ensure MONGO_URI is set in your environment
client = MongoClient(os.environ["MONGO_URI"])
collection = client["my_database"]["internal_knowledge"]
# 2. Initialize the Hybrid Client
hybrid_client = TavilyHybridClient(
api_key=os.environ.get("TAVILY_API_KEY"),
db_provider='mongodb',
collection=collection,
index='vector_search_index_name', # The name of your Atlas Vector index
embeddings_field='embeddings', # The field storing vector data
content_field='content' # The field storing raw text
)
2. Executing a Hybrid Search
Call .search() on the hybrid client just as you would the standard client.
# Search across both internal DB and external web
results = hybrid_client.search(
query="What is the company policy on remote work and how does it compare to industry standards?",
max_results=5, # Total results to return after reranking
max_local=10, # Max docs to pull from Mongo before reranking
max_foreign=10 # Max web results to pull from Tavily before reranking
)
for doc in results:
# 'origin' tells you if it came from 'local' (Mongo) or 'foreign' (Tavily)
print(f"\n--- Origin: {doc['origin'].upper()} | Score: {doc['score']:.4f} ---")
print(doc['content'][:200] + "...")
Behind the scenes, this executes:
- Embeds the query string.
- Runs a
$vectorSearchaggregation against MongoDB. - Runs a
search()call against the Tavily API. - Combines the arrays and passes them through a Cohere Reranker.
- Returns the top
max_results.
3. Autonomous Knowledge Base Expansion (save_foreign)
One of the most powerful features of the TavilyHybridClient is its ability to learn. If a web search yields highly relevant results that aren't in your database, the client can automatically embed and ingest them into MongoDB.
This is controlled by the save_foreign parameter.
Using a Custom Transform Function
Rather than passing save_foreign=True (which saves raw unstructured data), it is best practice to pass a function that formats the web document to match your MongoDB schema.
from datetime import datetime
def my_document_formatter(document):
"""
Takes a raw Tavily result dict and returns a formatted dict for MongoDB.
Return None to skip saving this document.
"""
# Only save extremely relevant web results to prevent DB bloat
if document['score'] < 0.7:
return None
return {
'content': document['content'],
'site_title': document.get('title', 'Unknown Source'),
'url': document.get('url', ''),
'ingested_at': datetime.now(),
'source_type': 'tavily_auto_ingest'
}
results = hybrid_client.search(
query="Recent breakthroughs in fusion energy",
max_results=5,
save_foreign=my_document_formatter
)
Now, the next time someone asks about fusion energy, your local MongoDB will be queried, and the previously ingested web results will be surfaced instantly without spending Tavily API credits.