We want to be able to use Find api in rag tools. I add a new rag backend class to do so.
17 KiB
Brave Web Search Tools
Overview
The Brave web search tools enable the conversation agent to search the web using the Brave Search API. Brave Search is a privacy-focused search engine that provides comprehensive web search results.
This documentation covers three related tools:
web_search_brave- Standard web search with optional summarizationweb_search_brave_with_document_backend- Web search with RAG-based document processingweb_search_albert_rag- ⚠️ Deprecated - Useweb_search_brave_with_document_backendinstead
Table of Contents
- Common Configuration
- web_search_brave
- web_search_brave_with_document_backend
- Deprecated: web_search_albert_rag
- Comparison
- Best Practices
- Troubleshooting
Common Configuration
Prerequisites
- Brave Search API Key: Sign up at Brave Search API to get an API key
- Environment Variables: Configure the required settings
Common Environment Variables
All Brave tools share these common settings:
| Variable | Required | Default | Description |
|---|---|---|---|
BRAVE_API_KEY |
Yes | None | Your Brave Search API key |
BRAVE_API_TIMEOUT |
No | 5 | API request timeout in seconds |
BRAVE_MAX_RESULTS |
No | 8 | Maximum number of search results |
BRAVE_CACHE_TTL |
No | 1800 | Cache time-to-live in seconds (30 minutes) |
Search Parameters
Check on the Brave API documentation for more details on these parameters:
| Variable | Required | Default | Description |
|---|---|---|---|
BRAVE_SEARCH_COUNTRY |
No | None | Country code for search (e.g., "US", "FR") |
BRAVE_SEARCH_LANG |
No | None | Language code (e.g., "en", "fr") |
BRAVE_SEARCH_SAFE_SEARCH |
No | "moderate" | Safe search level: "off", "moderate", or "strict" |
BRAVE_SEARCH_SPELLCHECK |
No | True | Enable spell checking |
BRAVE_SEARCH_EXTRA_SNIPPETS |
No | True | Fetch extra snippets from pages |
Note: even if BRAVE_SEARCH_EXTRA_SNIPPETS is enabled, the API may not include them if you don't have a plan for this.
This is why, in web_search_brave, we also fetch the page content ourselves when needed.
Configuration Example
# .env file
BRAVE_API_KEY=BSA-your-api-key-here
BRAVE_MAX_RESULTS=8
BRAVE_MAX_WORKERS=4
BRAVE_SEARCH_COUNTRY=US
BRAVE_SEARCH_LANG=en
BRAVE_SEARCH_SAFE_SEARCH=moderate
Django Settings
All Brave settings are defined in src/backend/conversations/brave_settings.py:
class BraveSettings:
"""Brave settings for web_search_brave tool."""
BRAVE_API_KEY = values.Value(
default=None,
environ_name="BRAVE_API_KEY",
environ_prefix=None,
)
# ... more settings
web_search_brave
Overview
Standard Brave web search tool with optional LLM-based summarization of page content.
Purpose
- Search the web for up-to-date information
- Extract content from web pages
- Optionally summarize content using an LLM
- Provide structured results with snippets
Additional Configuration
| Variable | Required | Default | Description |
|---|---|---|---|
BRAVE_SUMMARIZATION_ENABLED |
No | False | Enable LLM-based summarization of fetched pages |
Function Signature
def web_search_brave(query: str) -> ToolReturn:
"""
Search the web for up-to-date information
Args:
query (str): The query to search for.
Returns:
ToolReturn: Formatted search results with metadata
"""
Return Value
Returns a ToolReturn object with:
ToolReturn(
return_value={
"0": {
"url": "https://example.com/page1",
"title": "Example Page Title",
"snippets": ["Extracted or summarized content..."]
},
"1": {
"url": "https://example.com/page2",
"title": "Another Page",
"snippets": ["More content..."]
}
},
metadata={
"sources": {
"https://example.com/page1",
"https://example.com/page2"
}
}
)
How It Works
- Query API: Sends search query to Brave Search API
- Receive Results: Gets list of matching web pages
- Fetch Content: For results without extra_snippets:
- Fetches the HTML content using
trafilatura - Extracts the main text content
- Caches the extracted content
- Fetches the HTML content using
- Summarize (Optional): If
BRAVE_SUMMARIZATION_ENABLED=True:- Sends extracted content to summarization agent
- Receives concise summary focused on the query
- Format Results: Returns structured data with URLs, titles, and snippets
Workflow Diagram
User Query
↓
Brave Search API
↓
Search Results (URLs, titles, descriptions)
↓
[For each result without snippets]
↓
Fetch HTML (trafilatura) → Extract Text → Cache
↓
[If BRAVE_SUMMARIZATION_ENABLED]
↓
Summarization Agent (LLM)
↓
Summary Text
↓
Format & Return
Caching
Extracted content is cached to avoid repeated fetches:
cache_key = f"web_search_brave:extract:{url}"
cache.set(cache_key, document, settings.BRAVE_CACHE_TTL)
Cache Duration: Controlled by BRAVE_CACHE_TTL (default: 30 minutes)
Summarization
When enabled, the tool uses the SummarizationAgent to condense page content:
prompt = f"""
Based on the following request, summarize the following text in a concise manner,
focusing on the key points regarding the user request.
The result should be up to 30 lines long.
<user request>
{query}
</user request>
<text to summarize>
{text}
</text to summarize>
"""
Note: Summarization is costly (additional LLM calls).
Use only when necessary, we prefer the document vector search from web_search_brave_with_document_backend.
Add to Model
{
"models": [
{
"hrid": "my-model",
"tools": [
"web_search_brave"
]
}
]
}
Example Usage
User: "What are the new features in Django 5.0?"
Tool Call: web_search_brave("Django 5.0 new features")
Tool Response:
{
"0": {
"url": "https://docs.djangoproject.com/en/5.0/releases/5.0/",
"title": "Django 5.0 release notes",
"snippets": ["Django 5.0 introduces several new features including..."]
},
# ... more results
}
Registration
"web_search_brave": Tool(
web_search_brave,
takes_ctx=False,
prepare=only_if_web_search_enabled
)
web_search_brave_with_document_backend
Overview
Advanced Brave web search tool that uses RAG (Retrieval-Augmented Generation) with a document backend for intelligent content processing and retrieval.
Purpose
- Search the web and process results through a RAG system
- Store fetched documents in a temporary vector database
- Perform semantic search across fetched content
- Return the most relevant chunks based on the query
Additional Configuration
| Variable | Required | Default | Description |
|---|---|---|---|
BRAVE_RAG_WEB_SEARCH_CHUNK_NUMBER |
No | 10 | Number of chunks to retrieve from RAG search |
RAG_DOCUMENT_SEARCH_BACKEND |
No | AlbertRagBackend | Document backend for RAG processing |
Function Signature
def web_search_brave_with_document_backend(ctx: RunContext, query: str) -> ToolReturn:
"""
Search the web for up-to-date information
Args:
ctx (RunContext): The run context containing the conversation.
query (str): The query to search for.
Returns:
ToolReturn: Formatted search results with RAG-enhanced snippets
"""
How It Works
- Query API: Sends search query to Brave Search API
- Receive Results: Gets list of matching web pages
- Create Temporary Collection: Creates a temporary vector database collection
- Fetch & Store: For each result:
- Fetches the HTML content
- Extracts the main text
- Stores in the temporary document backend
- RAG Search: Performs semantic search across stored documents
- Map Results: Maps RAG chunks back to original search results
- Format & Return: Returns structured data with enhanced snippets
- Cleanup: Temporary collection is automatically deleted
Workflow Diagram
User Query
↓
Brave Search API
↓
Search Results (URLs)
↓
Create Temporary Vector Collection
↓
[For each URL]
↓
Fetch HTML → Extract Text → Store in Vector DB
↓
RAG Semantic Search
↓
Retrieve Most Relevant Chunks
↓
Map Chunks to Original URLs
↓
Format & Return
↓
Delete Temporary Collection
Temporary Collection
The tool creates a temporary collection with a unique ID:
with document_store_backend.temporary_collection(f"tmp-{uuid.uuid4()}") as document_store:
# Fetch and store documents
# Perform search
# Collection is automatically deleted on exit
RAG Search
The RAG backend performs semantic search to find the most relevant content:
rag_results = document_store.search(
query,
results_count=settings.BRAVE_RAG_WEB_SEARCH_CHUNK_NUMBER,
**kwargs, # Additional search parameters like session with access_token
)
Returns chunks ranked by relevance to the query, not just keyword matching.
Token Usage Tracking
The tool tracks LLM tokens used during RAG processing:
ctx.usage += RunUsage(
input_tokens=rag_results.usage.prompt_tokens,
output_tokens=rag_results.usage.completion_tokens,
)
Document Backend
The default backend is AlbertRagBackend, but you can configure a different one:
RAG_DOCUMENT_SEARCH_BACKEND=chat.agent_rag.document_rag_backends.custom_backend.CustomBackend
Add to Model
{
"models": [
{
"hrid": "my-model",
"tools": [
"web_search_brave_with_document_backend"
]
}
]
}
Example Usage
User: "Explain the concept of async views in Django"
Tool Call: web_search_brave_with_document_backend(ctx, "Django async views explained")
Tool Response:
{
"0": {
"url": "https://docs.djangoproject.com/en/stable/topics/async/",
"title": "Asynchronous support",
"snippets": [
"Django has support for writing asynchronous views...",
"Async views are declared using Python's async def syntax..."
]
},
# ... more results with relevant chunks
}
Registration
"web_search_brave_with_document_backend": Tool(
web_search_brave_with_document_backend,
takes_ctx=True,
prepare=only_if_web_search_enabled,
)
Advantages Over Standard web_search_brave
| Feature | web_search_brave | web_search_brave_with_document_backend |
|---|---|---|
| Content Retrieval | Full page or summary | Semantic chunks |
| Relevance | Keyword-based | Semantic similarity |
| Token Efficiency | May include irrelevant content | Only relevant chunks |
| Processing | Simpler, faster | More intelligent, slower |
| Cost | Lower | Higher (RAG processing) |
| Best For | General search | Deep research, technical queries |
Deprecated: web_search_albert_rag
⚠️ Deprecation Notice
The web_search_albert_rag tool is deprecated and should not be used in new implementations.
Replacement: Use web_search_brave_with_document_backend instead, which provides:
- Better performance
- More control over the RAG backend
- Temporary collections (no cleanup issues)
- Token usage tracking
- Parallel processing support
Why Deprecated?
- Limited to Albert API only
- No control over document backend
- Less flexible than the new approach
- Maintenance burden
Timeline
- Current: Still functional but not recommended
- Future: Will be removed in a future version
Comparison
When to Use Which Tool?
Use web_search_brave
✅ Best for:
- General web search queries
- Quick information retrieval
- When speed is important
- Lower cost requirements
- Simple fact-finding
❌ Not ideal for:
- Deep research requiring precise context
- Technical documentation queries
- When semantic relevance is crucial
Use web_search_brave_with_document_backend
✅ Best for:
- Complex technical queries
- Research requiring precise context
- When semantic relevance is important
- Questions needing deep understanding
- Documentation and how-to queries
❌ Not ideal for:
- Simple factual queries
- When speed is critical
- Budget-constrained scenarios
- High-volume usage
Best Practices
Query Formulation
Help the LLM formulate effective queries:
# Good queries
"Python asyncio tutorial 2024"
"Django REST framework authentication"
"React hooks best practices"
# Poor queries
"tell me about programming" # Too vague
"how do I do the thing with the stuff" # Unclear
Performance Optimization
1. Optimize Cache
# Longer cache for stable content
BRAVE_CACHE_TTL=3600 # 1 hour
# Shorter cache for dynamic content
BRAVE_CACHE_TTL=300 # 5 minutes
2. Control Result Count
# Fewer results = faster responses
BRAVE_MAX_RESULTS=5
# More results = more comprehensive
BRAVE_MAX_RESULTS=10
Summarization Best Practices
Only enable summarization when needed:
# Enable for long-form content
BRAVE_SUMMARIZATION_ENABLED=True
# Disable for speed
BRAVE_SUMMARIZATION_ENABLED=False
Cost consideration: Summarization makes additional LLM calls for each result, significantly increasing costs (and execution time).
RAG Configuration
For web_search_brave_with_document_backend:
# More chunks = more context, higher cost
BRAVE_RAG_WEB_SEARCH_CHUNK_NUMBER=10
# Fewer chunks = faster, less context
BRAVE_RAG_WEB_SEARCH_CHUNK_NUMBER=5
Search Parameters
# Localize results
BRAVE_SEARCH_COUNTRY=FR
BRAVE_SEARCH_LANG=fr
# Safe search for public deployments
BRAVE_SEARCH_SAFE_SEARCH=strict
# Enable spell check for better results
BRAVE_SEARCH_SPELLCHECK=True
Troubleshooting
Common Issues
1. No Results Returned
Symptoms: Empty results or no snippets
Causes:
- Query too specific
- Content extraction failed
- Trafilatura couldn't parse the pages
Solutions:
# Enable extra snippets
BRAVE_SEARCH_EXTRA_SNIPPETS=True
# Increase result count
BRAVE_MAX_RESULTS=10
# Check logs for extraction errors
2. API Errors
Symptoms: HTTP errors, authentication failures
Causes:
- Invalid API key
- Rate limit exceeded
- API service issues
Solutions:
# Verify API key is set
echo $BRAVE_API_KEY
# Check Brave API dashboard for limits
# Implement rate limiting in your application
3. The tool is not being called
Symptoms: LLM doesn't use the tool even when appropriate
Causes:
- Web search not enabled for the conversation
- Tool not in model configuration
Solutions:
- Check conversation settings have
web_search_enabled=True - Verify tool is in the model's
toolslist
Security Considerations
This tool is quite "raw", so be cautious about:
- the results returned by the web search
- the context size which might be large when not using summarization or RAG if long results are returned
- the query content which might include sensitive information
- ...
Content Validation
Be aware that fetched content may contain:
- Malicious scripts (mitigated by text extraction)
- Inappropriate content
- Misinformation
- Biased information
The LLM should evaluate sources critically.