依赖单个搜索提供程序意味着当该提供程序出现停机、速率限制或特定查询类型的覆盖范围较差时,您的代理会失败。本教程构建了一个多引擎搜索代理,该代理通过提供程序(Scavio、Brave、SearXNG)进行级联并选择最佳结果集。代理首先尝试最便宜的提供商,仅在需要时才使用替代方案,从而将成本保持在最低水平。
前置条件
- 已安装 Python 3.9+
- 请求已安装库
- 来自 scavio.dev 的 Scavio API 密钥
- 可选:用于后备的 Brave API 密钥
操作指南
步骤 1: 定义搜索引擎级联
按优先级顺序配置多个搜索提供程序。每个都有一个搜索功能、成本和接受结果的质量阈值。
Python
import requests, os, time
SCAVIO_KEY = os.environ.get('SCAVIO_API_KEY', '')
BRAVE_KEY = os.environ.get('BRAVE_API_KEY', '')
def search_scavio(query: str, count: int = 10) -> list:
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': count},
timeout=10)
if resp.status_code != 200:
return []
return [{'title': r['title'], 'link': r['link'], 'snippet': r.get('snippet', '')}
for r in resp.json().get('organic_results', [])]
def search_brave(query: str, count: int = 10) -> list:
if not BRAVE_KEY:
return []
resp = requests.get('https://api.search.brave.com/res/v1/web/search',
headers={'X-Subscription-Token': BRAVE_KEY},
params={'q': query, 'count': count}, timeout=10)
if resp.status_code != 200:
return []
return [{'title': r['title'], 'link': r['url'], 'snippet': r.get('description', '')}
for r in resp.json().get('web', {}).get('results', [])]
ENGINES = [
{'name': 'scavio', 'fn': search_scavio, 'cost': 0.005, 'min_results': 3},
{'name': 'brave', 'fn': search_brave, 'cost': 0.005, 'min_results': 3},
]
print(f'Configured {len(ENGINES)} search engines in cascade')
for e in ENGINES:
print(f' {e["name"]}: ${e["cost"]}/query, min {e["min_results"]} results')步骤 2: 构建级联搜索功能
按顺序尝试每个引擎。如果结果符合质量阈值,则接受结果。跟踪哪个引擎成功了以及总成本。
Python
def cascade_search(query: str, count: int = 10) -> dict:
"""Search with cascading fallback across engines."""
attempts = []
for engine in ENGINES:
start = time.time()
try:
results = engine['fn'](query, count)
latency = int((time.time() - start) * 1000)
attempts.append({
'engine': engine['name'], 'results': len(results),
'latency_ms': latency, 'cost': engine['cost']
})
if len(results) >= engine['min_results']:
total_cost = sum(a['cost'] for a in attempts)
return {
'results': results,
'engine': engine['name'],
'attempts': attempts,
'total_cost': total_cost
}
except Exception as e:
attempts.append({
'engine': engine['name'], 'error': str(e),
'cost': engine['cost']
})
# All engines failed or returned poor results
total_cost = sum(a['cost'] for a in attempts)
best = max(attempts, key=lambda a: a.get('results', 0))
return {
'results': [],
'engine': 'none',
'attempts': attempts,
'total_cost': total_cost,
'note': 'All engines returned insufficient results'
}
result = cascade_search('best python web framework 2026')
print(f'Engine: {result["engine"]}')
print(f'Results: {len(result["results"])}')
print(f'Cost: ${result["total_cost"]:.3f}')
for a in result['attempts']:
print(f' {a["engine"]}: {a.get("results", "error")} results, {a.get("latency_ms", "N/A")}ms')步骤 3: 添加根据查询类型智能选择引擎
将不同的查询类型路由到最佳引擎。技术查询可能在一种引擎上效果更好,而新闻查询在另一种引擎上效果更好。
Python
def smart_search(query: str, count: int = 10) -> dict:
"""Route query to best engine based on query type."""
query_lower = query.lower()
# Classify query type
if any(w in query_lower for w in ['news', 'latest', 'today', 'just', 'announced']):
query_type = 'news'
elif any(w in query_lower for w in ['site:', 'filetype:', 'inurl:']):
query_type = 'advanced'
elif any(w in query_lower for w in ['how to', 'tutorial', 'guide', 'example']):
query_type = 'tutorial'
else:
query_type = 'general'
# Reorder engines based on query type
# For most queries, default cascade works fine
# For advanced queries, Scavio handles operators better
result = cascade_search(query, count)
result['query_type'] = query_type
return result
# Test different query types
test_queries = [
'latest AI news today',
'site:github.com python search api',
'how to build a search agent',
]
for q in test_queries:
r = smart_search(q)
print(f'[{r["query_type"]}] {q[:40]} -> {r["engine"]} ({len(r["results"])} results, ${r["total_cost"]:.3f})')Python 示例
Python
import requests, os, time
SCAVIO_KEY = os.environ.get('SCAVIO_API_KEY', '')
BRAVE_KEY = os.environ.get('BRAVE_API_KEY', '')
def search(query, count=10):
# Try Scavio first
try:
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': count}, timeout=10)
results = resp.json().get('organic_results', [])
if len(results) >= 3:
return {'results': results, 'engine': 'scavio', 'cost': 0.005}
except Exception:
pass
# Fallback to Brave
if BRAVE_KEY:
try:
resp = requests.get('https://api.search.brave.com/res/v1/web/search',
headers={'X-Subscription-Token': BRAVE_KEY},
params={'q': query, 'count': count}, timeout=10)
results = resp.json().get('web', {}).get('results', [])
return {'results': results, 'engine': 'brave', 'cost': 0.010}
except Exception:
pass
return {'results': [], 'engine': 'none', 'cost': 0}
r = search('python web framework 2026')
print(f'{r["engine"]}: {len(r["results"])} results, ${r["cost"]}')JavaScript 示例
JavaScript
const SCAVIO_KEY = process.env.SCAVIO_API_KEY;
const BRAVE_KEY = process.env.BRAVE_API_KEY;
async function search(query, count = 10) {
try {
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, country_code: 'us', num_results: count })
});
const results = (await resp.json()).organic_results || [];
if (results.length >= 3) return { results, engine: 'scavio', cost: 0.005 };
} catch {}
if (BRAVE_KEY) {
try {
const resp = await fetch(`https://api.search.brave.com/res/v1/web/search?q=${encodeURIComponent(query)}&count=${count}`, {
headers: { 'X-Subscription-Token': BRAVE_KEY }
});
const results = (await resp.json()).web?.results || [];
return { results, engine: 'brave', cost: 0.01 };
} catch {}
}
return { results: [], engine: 'none', cost: 0 };
}
search('python framework 2026').then(r => console.log(`${r.engine}: ${r.results.length} results`));预期输出
JSON
Configured 2 search engines in cascade
scavio: $0.005/query, min 3 results
brave: $0.005/query, min 3 results
Engine: scavio
Results: 10
Cost: $0.005
scavio: 10 results, 245ms
[news] latest AI news today -> scavio (10 results, $0.005)
[advanced] site:github.com python search api -> scavio (8 results, $0.005)
[tutorial] how to build a search agent -> scavio (10 results, $0.005)