Google a abandonné son niveau gratuit de l'API JSON Custom Search Engine début 2026, cassant des milliers de configurations LLM locales qui dépendaient de lui pour l'ancrage web. Si votre assistant basé sur Ollama utilisait CSE pour la recherche, vous avez besoin d'un remplacement direct qui renvoie du JSON structuré, ne nécessite pas OAuth et fonctionne avec une simple clé API. Le point de terminaison de recherche Scavio accepte le même modèle requête-résultat et renvoie des données plus riches, y compris les Aperçus IA et les questions similaires. Ce tutoriel migre votre intégration de recherche Ollama de CSE vers Scavio en moins de 20 lignes de code.
Prérequis
- Ollama installé et exécuté localement
- Python 3.9+ installé
- bibliothèque requests installée
- Une clé API Scavio depuis scavio.dev
Parcours
Étape 1: Supprimez l'ancienne intégration CSE
Identifiez et supprimez le code client Google CSE. Le modèle CSE typique utilise un paramètre cx et un point de terminaison googleapis.com qui ne fonctionne plus.
# OLD CSE code (no longer works as of 2026):
# response = requests.get(
# 'https://www.googleapis.com/customsearch/v1',
# params={'key': CSE_KEY, 'cx': CSE_ID, 'q': query}
# )
# NEW: Scavio replaces the above
import os, requests
SCAVIO_KEY = os.environ['SCAVIO_API_KEY']
H = {'x-api-key': SCAVIO_KEY, 'Content-Type': 'application/json'}
URL = 'https://api.scavio.dev/api/v1/search'Étape 2: Construisez la fonction de recherche Scavio pour Ollama
Créez une fonction de recherche qui correspond à l'interface attendue par votre outil Ollama. Renvoyez les résultats dans un format que le LLM peut analyser.
def web_search(query: str, num_results: int = 5) -> str:
"""Search the web and return formatted results for the LLM."""
resp = requests.post(URL, headers=H,
json={'query': query, 'country_code': 'us', 'num_results': num_results})
resp.raise_for_status()
data = resp.json()
results = data.get('organic_results', [])
formatted = []
for r in results:
formatted.append(f"Title: {r['title']}\nURL: {r['link']}\nSnippet: {r.get('snippet', '')}")
return '\n\n'.join(formatted)Étape 3: Intégrez la recherche dans l'appel d'outil d'Ollama
Enregistrez la fonction de recherche comme un outil qu'Ollama peut appeler pendant la génération. Cela utilise le client Python d'Ollama avec prise en charge des outils.
import ollama
def run_ollama_with_search(prompt: str, model: str = 'llama3.1') -> str:
tools = [{
'type': 'function',
'function': {
'name': 'web_search',
'description': 'Search the web for current information',
'parameters': {
'type': 'object',
'properties': {
'query': {'type': 'string', 'description': 'Search query'}
},
'required': ['query']
}
}
}]
response = ollama.chat(model=model, messages=[{'role': 'user', 'content': prompt}], tools=tools)
# Handle tool calls
if response.message.tool_calls:
for tc in response.message.tool_calls:
if tc.function.name == 'web_search':
search_results = web_search(tc.function.arguments.get('query', prompt))
# Feed results back to the model
messages = [
{'role': 'user', 'content': prompt},
response.message,
{'role': 'tool', 'content': search_results}
]
final = ollama.chat(model=model, messages=messages)
return final.message.content
return response.message.content
print(run_ollama_with_search('What are the top Python web frameworks in 2026?'))Exemple Python
import os, requests, ollama
SCAVIO_KEY = os.environ['SCAVIO_API_KEY']
H = {'x-api-key': SCAVIO_KEY, 'Content-Type': 'application/json'}
def web_search(query, num=5):
resp = requests.post('https://api.scavio.dev/api/v1/search', headers=H,
json={'query': query, 'country_code': 'us', 'num_results': num})
results = resp.json().get('organic_results', [])
return '\n'.join(f'{r["title"]}: {r.get("snippet","")}' for r in results)
def ask_with_search(prompt, model='llama3.1'):
tools = [{'type': 'function', 'function': {
'name': 'web_search', 'description': 'Search the web',
'parameters': {'type': 'object', 'properties': {
'query': {'type': 'string'}}, 'required': ['query']}}}]
resp = ollama.chat(model=model, messages=[{'role': 'user', 'content': prompt}], tools=tools)
if resp.message.tool_calls:
results = web_search(resp.message.tool_calls[0].function.arguments.get('query', prompt))
final = ollama.chat(model=model, messages=[
{'role': 'user', 'content': prompt}, resp.message,
{'role': 'tool', 'content': results}])
return final.message.content
return resp.message.content
print(ask_with_search('Latest AI news 2026'))Exemple JavaScript
const SCAVIO_KEY = process.env.SCAVIO_API_KEY;
async function webSearch(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, country_code: 'us', num_results: 5 })
});
const data = await resp.json();
return (data.organic_results || []).map(r => `${r.title}: ${r.snippet || ''}`).join('\n');
}
async function askOllamaWithSearch(prompt) {
const resp = await fetch('http://localhost:11434/api/chat', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
model: 'llama3.1', messages: [{ role: 'user', content: prompt }],
tools: [{ type: 'function', function: { name: 'web_search',
description: 'Search the web', parameters: { type: 'object',
properties: { query: { type: 'string' } }, required: ['query'] }}}]
})
});
const data = await resp.json();
if (data.message?.tool_calls?.length) {
const results = await webSearch(data.message.tool_calls[0].function.arguments.query);
console.log('Search results:', results);
}
}
askOllamaWithSearch('Latest AI news 2026');Sortie attendue
Search results for: 'top Python web frameworks 2026'
Title: FastAPI 1.0 Released: The Modern Python Web Framework
URL: https://fastapi.tiangolo.com/release-notes/
Snippet: FastAPI 1.0 brings stable APIs and improved performance...
Title: Django 6.0 Features Overview
URL: https://docs.djangoproject.com/en/6.0/
Snippet: Django 6.0 introduces async-first ORM and built-in AI...
Ollama response: Based on current search results, the top Python web frameworks in 2026 are FastAPI 1.0, Django 6.0, and Litestar...