OpenWebUI prend en charge la recherche web via Tavily, SearXNG et des endpoints personnalisés. Après l'acquisition de Tavily par Nebius en février 2026, de nombreux utilisateurs cherchent une alternative. Scavio propose un endpoint de recherche compatible couvrant Google, Amazon, YouTube, Walmart, Reddit et TikTok. Ce tutoriel explique comment configurer OpenWebUI pour utiliser Scavio comme source de recherche web, que ce soit via les paramètres de recherche intégrés ou via un outil de fonction personnalisé.
Prérequis
- OpenWebUI installé et en cours d'exécution
- Une clé API Scavio depuis scavio.dev
- Python 3.9+ pour l'approche avec fonction personnalisée
- Accès administrateur à votre instance OpenWebUI
Parcours
Étape 1: Créer une fonction de recherche Scavio pour OpenWebUI
OpenWebUI permet d'utiliser des fonctions Python personnalisées comme outils. Créez une fonction de recherche qui appelle l'API Scavio et renvoie des résultats formatés que le LLM peut exploiter.
# OpenWebUI Function Tool: scavio_search.py
# Add this as a Function in OpenWebUI Admin > Functions
import os
import requests
from typing import Optional
class Tools:
def __init__(self):
self.api_key = os.environ.get('SCAVIO_API_KEY', '')
self.base_url = 'https://api.scavio.dev/api/v1/search'
def search_web(self, query: str, num_results: Optional[int] = 5) -> str:
"""Search the web for current information using Scavio.
Returns titles, snippets, and source URLs.
"""
try:
resp = requests.post(self.base_url,
headers={'x-api-key': self.api_key,
'Content-Type': 'application/json'},
json={'query': query, 'country_code': 'us',
'num_results': num_results or 5},
timeout=10)
resp.raise_for_status()
results = resp.json().get('organic_results', [])
if not results:
return 'No results found.'
return '\n\n'.join(
f'[{i+1}] {r["title"]}\n{r.get("snippet", "")}\nSource: {r["link"]}'
for i, r in enumerate(results)
)
except Exception as e:
return f'Search error: {str(e)}'Étape 2: Ajouter des outils de recherche par plateforme
Étendez la fonction avec des outils de recherche pour Reddit, YouTube et Amazon. OpenWebUI affichera chacun comme un outil distinct que le LLM pourra appeler.
# Extended Tools class with platform-specific methods
class Tools:
def __init__(self):
self.api_key = os.environ.get('SCAVIO_API_KEY', '')
self.base_url = 'https://api.scavio.dev/api/v1/search'
self.headers = {'x-api-key': self.api_key, 'Content-Type': 'application/json'}
def _search(self, query: str, num: int = 5) -> list:
resp = requests.post(self.base_url, headers=self.headers,
json={'query': query, 'country_code': 'us', 'num_results': num}, timeout=10)
resp.raise_for_status()
return resp.json().get('organic_results', [])
def search_web(self, query: str) -> str:
"""Search the web for current information."""
results = self._search(query)
return '\n\n'.join(f'[{i+1}] {r["title"]}\n{r.get("snippet","")}\nURL: {r["link"]}'
for i, r in enumerate(results)) or 'No results.'
def search_reddit(self, query: str) -> str:
"""Search Reddit for community discussions and opinions."""
results = self._search(f'site:reddit.com {query}')
return '\n\n'.join(f'[{i+1}] {r["title"]}\n{r.get("snippet","")}\nURL: {r["link"]}'
for i, r in enumerate(results)) or 'No Reddit results.'
def search_youtube(self, query: str) -> str:
"""Search YouTube for videos on a topic."""
results = self._search(f'site:youtube.com {query}')
return '\n\n'.join(f'[{i+1}] {r["title"]}\nURL: {r["link"]}'
for i, r in enumerate(results)) or 'No YouTube results.'
def search_amazon(self, query: str) -> str:
"""Search Amazon for product information."""
results = self._search(f'site:amazon.com {query}')
return '\n\n'.join(f'[{i+1}] {r["title"]}\n{r.get("snippet","")}\nURL: {r["link"]}'
for i, r in enumerate(results)) or 'No Amazon results.'Étape 3: Configurer l'environnement et déployer
Définissez la variable d'environnement SCAVIO_API_KEY dans votre déploiement OpenWebUI et ajoutez la fonction via le panneau d'administration.
# Docker deployment: add to your docker-compose.yml or .env
# SCAVIO_API_KEY=your_key_here
# Or set in the OpenWebUI admin panel:
# 1. Go to Admin Panel > Functions
# 2. Click 'Create Function'
# 3. Paste the Tools class code
# 4. Set the function name to 'scavio_search'
# 5. Enable it globally or per-model
# Verify the setup with a test
import os, requests
def verify_openwebui_search():
key = os.environ.get('SCAVIO_API_KEY')
if not key:
print('ERROR: SCAVIO_API_KEY not set')
return False
tools = Tools()
result = tools.search_web('test query 2026')
if 'error' in result.lower():
print(f'ERROR: {result}')
return False
print('OpenWebUI search configured successfully')
print(f'Test result preview: {result[:150]}')
return True
verify_openwebui_search()Étape 4: Tester les requêtes multi-plateformes dans OpenWebUI
Vérifiez que chaque recherche par plateforme fonctionne correctement en exécutant des requêtes de test. Le LLM doit automatiquement choisir le bon outil de recherche en fonction de la question de l'utilisateur.
# Test all search functions
def test_all_tools():
tools = Tools()
tests = [
('search_web', 'latest AI news 2026'),
('search_reddit', 'best mechanical keyboard'),
('search_youtube', 'python tutorial beginners'),
('search_amazon', 'noise cancelling headphones'),
]
for method_name, query in tests:
method = getattr(tools, method_name)
result = method(query)
lines = result.split('\n')
has_results = len(lines) > 1
print(f'[{"PASS" if has_results else "FAIL"}] {method_name}')
print(f' Query: {query}')
print(f' First result: {lines[0][:60]}')
print()
test_all_tools()
print('All tools ready for OpenWebUI')
print('Cost: $0.005 per search (250 free/month)')Exemple Python
import os, requests
class ScavioOpenWebUI:
def __init__(self):
self.key = os.environ.get('SCAVIO_API_KEY', '')
self.url = 'https://api.scavio.dev/api/v1/search'
self.h = {'x-api-key': self.key, 'Content-Type': 'application/json'}
def search(self, query, num=5):
resp = requests.post(self.url, headers=self.h,
json={'query': query, 'country_code': 'us', 'num_results': num})
return resp.json().get('organic_results', [])
def search_web(self, query):
results = self.search(query)
return '\n'.join(f'[{i+1}] {r["title"]}: {r.get("snippet","")}' for i, r in enumerate(results))
def search_reddit(self, query):
return self.search_web(f'site:reddit.com {query}')
tools = ScavioOpenWebUI()
print(tools.search_web('AI news 2026'))Exemple JavaScript
const SCAVIO_KEY = process.env.SCAVIO_API_KEY;
async function searchForOpenWebUI(query, platform = 'web') {
const prefixes = { reddit: 'site:reddit.com ', youtube: 'site:youtube.com ', amazon: 'site:amazon.com ' };
const q = (prefixes[platform] || '') + query;
const resp = await fetch('https://api.scavio.dev/api/v1/search', {
method: 'POST',
headers: { 'x-api-key': SCAVIO_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({ query: q, country_code: 'us', num_results: 5 })
});
const results = (await resp.json()).organic_results || [];
return results.map((r, i) => `[${i+1}] ${r.title}\n${r.snippet || ''}\n${r.link}`).join('\n\n');
}
searchForOpenWebUI('AI agent tools 2026').then(console.log);Sortie attendue
[PASS] search_web
Query: latest AI news 2026
First result: [1] AI News: Latest Developments in Artificial
[PASS] search_reddit
Query: best mechanical keyboard
First result: [1] r/MechanicalKeyboards - Best keyboards mid-2
[PASS] search_youtube
Query: python tutorial beginners
First result: [1] Python Tutorial for Beginners - Full Course
[PASS] search_amazon
Query: noise cancelling headphones
First result: [1] Sony WH-1000XM6 Wireless Noise Cancelling
All tools ready for OpenWebUI
Cost: $0.005 per search (250 free/month)