Nebius a acquis Tavily en février 2026, ce qui soulève des questions sur les changements de prix, la gestion des données et la disponibilité à long terme. Si vous souhaitez vous diversifier loin de Tavily ou avoir besoin d'une recherche multiplateforme au-delà des résultats web, Scavio fournit Google, Amazon, YouTube, Walmart, Reddit et TikTok depuis un seul point d'accès. Tavily facture 30 $/mois pour 10 000 requêtes. Scavio facture 30 $/mois pour 7 000 crédits à 0,005 $ chacun, mais couvre six plateformes au lieu de la seule recherche web. Ce tutoriel vous guide dans la migration.
Prérequis
- Une intégration Tavily existante à migrer
- Python 3.9+ installé
- Une clé API Scavio depuis scavio.dev
- bibliothèque requests installée
Parcours
Étape 1: Mapper les appels API de Tavily vers les équivalents Scavio
Tavily utilise un point d'accès de recherche avec les paramètres topic et search_depth. Scavio utilise un point d'accès POST avec query et num_results. Identifiez les principales différences.
# Tavily API call (what you currently have)
# POST https://api.tavily.com/search
# Body: {"api_key": "tvly-...", "query": "...", "search_depth": "advanced",
# "topic": "general", "max_results": 5}
#
# Scavio API call (replacement)
# POST https://api.scavio.dev/api/v1/search
# Headers: {"x-api-key": "your-key"}
# Body: {"query": "...", "country_code": "us", "num_results": 5}
import os, requests
SCAVIO_KEY = os.environ['SCAVIO_API_KEY']
def tavily_to_scavio_search(query: str, max_results: int = 5, **kwargs) -> dict:
"""Drop-in replacement for tavily.search()."""
resp = requests.post('https://api.scavio.dev/api/v1/search',
headers={'x-api-key': SCAVIO_KEY, 'Content-Type': 'application/json'},
json={'query': query, 'country_code': 'us', 'num_results': max_results})
resp.raise_for_status()
data = resp.json()
# Return Tavily-compatible response shape
return {
'query': query,
'results': [{'title': r['title'], 'url': r['link'],
'content': r.get('snippet', ''), 'score': 0.9 - (i * 0.05)}
for i, r in enumerate(data.get('organic_results', []))]
}
result = tavily_to_scavio_search('AI agent frameworks 2026')
print(f'Query: {result["query"]}')
for r in result['results']:
print(f' {r["title"][:60]} (score: {r["score"]:.2f})')Étape 2: Remplacer le client Python de Tavily
Si vous utilisez le package tavily-python, créez une classe wrapper compatible qui imite TavilyClient. Votre code existant appelle les mêmes méthodes mais atteint Scavio à la place.
class ScavioSearchClient:
"""Drop-in replacement for TavilyClient."""
def __init__(self, api_key: str = None):
self.api_key = api_key or os.environ['SCAVIO_API_KEY']
self.base_url = 'https://api.scavio.dev/api/v1/search'
def search(self, query: str, max_results: int = 5, **kwargs) -> dict:
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': max_results})
resp.raise_for_status()
organic = resp.json().get('organic_results', [])
return {
'query': query,
'results': [{'title': r['title'], 'url': r['link'],
'content': r.get('snippet', ''), 'score': 0.9}
for r in organic]
}
def get_search_context(self, query: str, max_results: int = 5, **kwargs) -> str:
results = self.search(query, max_results)
return '\n\n'.join(f"{r['title']}\n{r['content']}\nSource: {r['url']}"
for r in results['results'])
# Replace: client = TavilyClient(api_key=TAVILY_KEY)
client = ScavioSearchClient()
context = client.get_search_context('latest Python release 2026')
print(context[:300])Étape 3: Mettre à jour l'intégration LangChain
Si vous utilisez TavilySearchResults dans LangChain, remplacez-le par un outil Scavio personnalisé. L'interface de l'outil est identique, donc votre code de chaîne ou d'agent reste le même.
from langchain_core.tools import tool
@tool
def search(query: str) -> str:
"""Search the web for current information. Returns titles, snippets, and URLs."""
resp = requests.post('https://api.scavio.dev/api/v1/search',
headers={'x-api-key': SCAVIO_KEY, 'Content-Type': 'application/json'},
json={'query': query, 'country_code': 'us', 'num_results': 5})
results = resp.json().get('organic_results', [])
return '\n\n'.join(
f"Title: {r['title']}\nSnippet: {r.get('snippet', '')}\nURL: {r['link']}"
for r in results
)
# BEFORE (Tavily):
# from langchain_community.tools.tavily_search import TavilySearchResults
# tools = [TavilySearchResults(max_results=5)]
# AFTER (Scavio):
tools = [search]
# Your agent code stays the same
print(f'Tool name: {tools[0].name}')
print(f'Tool description: {tools[0].description}')
result = tools[0].invoke('best AI frameworks 2026')
print(result[:200])Étape 4: Valider la migration avec des requêtes de test
Exécutez vos requêtes les plus courantes via les deux API et comparez la qualité des résultats. Vérifiez que les titres, les extraits et les URL sont renseignés.
def validate_migration(queries: list[str]):
client = ScavioSearchClient()
print('Tavily -> Scavio Migration Validation')
print('=' * 45)
all_pass = True
for q in queries:
result = client.search(q, max_results=5)
items = result.get('results', [])
has_results = len(items) > 0
has_content = all(r.get('content') for r in items[:3])
has_urls = all(r.get('url') for r in items)
status = 'PASS' if (has_results and has_urls) else 'FAIL'
if status == 'FAIL':
all_pass = False
print(f'\n[{status}] {q}')
print(f' Results: {len(items)}, Content: {has_content}, URLs: {has_urls}')
if items:
print(f' Top: {items[0]["title"][:50]}')
print(f'\nOverall: {"PASS" if all_pass else "SOME FAILURES"}')
print(f'\nPricing comparison:')
print(f' Tavily: $30/mo for 10K searches (web only)')
print(f' Scavio: $30/mo for 7K credits (6 platforms)')
validate_migration([
'latest AI news 2026',
'best python web framework',
'how to deploy on railway',
])Exemple Python
import os, requests
SCAVIO_KEY = os.environ['SCAVIO_API_KEY']
class ScavioSearchClient:
def __init__(self, api_key=None):
self.key = api_key or SCAVIO_KEY
def search(self, query, max_results=5):
resp = requests.post('https://api.scavio.dev/api/v1/search',
headers={'x-api-key': self.key, 'Content-Type': 'application/json'},
json={'query': query, 'country_code': 'us', 'num_results': max_results})
return {'results': [{'title': r['title'], 'url': r['link'],
'content': r.get('snippet', '')} for r in resp.json().get('organic_results', [])]}
def get_search_context(self, query, max_results=5):
results = self.search(query, max_results)
return '\n'.join(f"{r['title']}: {r['content']}" for r in results['results'])
client = ScavioSearchClient()
print(client.get_search_context('AI frameworks 2026'))Exemple JavaScript
const SCAVIO_KEY = process.env.SCAVIO_API_KEY;
class ScavioSearchClient {
constructor(apiKey) { this.key = apiKey || SCAVIO_KEY; }
async search(query, maxResults = 5) {
const resp = await fetch('https://api.scavio.dev/api/v1/search', {
method: 'POST',
headers: { 'x-api-key': this.key, 'Content-Type': 'application/json' },
body: JSON.stringify({ query, country_code: 'us', num_results: maxResults })
});
const data = await resp.json();
return { results: (data.organic_results || []).map(r => ({
title: r.title, url: r.link, content: r.snippet || ''
}))};
}
async getSearchContext(query, maxResults = 5) {
const { results } = await this.search(query, maxResults);
return results.map(r => `${r.title}: ${r.content}`).join('\n');
}
}
const client = new ScavioSearchClient();
client.getSearchContext('AI frameworks 2026').then(console.log);Sortie attendue
Tavily -> Scavio Migration Validation
=============================================
[PASS] latest AI news 2026
Results: 5, Content: True, URLs: True
Top: AI News Roundup: Top Developments in 2026
[PASS] best python web framework
Results: 5, Content: True, URLs: True
Overall: PASS
Pricing comparison:
Tavily: $30/mo for 10K searches (web only)
Scavio: $30/mo for 7K credits (6 platforms)