Le grounding par recherche signifie donner à votre agent IA un accès aux résultats web en direct afin qu'il puisse répondre à des questions sur l'actualité, les prix et les changements récents sans halluciner. Vous n'avez pas besoin de LangChain, LlamaIndex, ni d'aucun framework – une simple fonction Python qui appelle une API de recherche et injecte les résultats dans le prompt fonctionne tout aussi bien. Ce tutoriel emmène un débutant de zéro à un agent grounded en moins de 15 minutes en utilisant seulement la bibliothèque requests et l'API Scavio à 0,005 $ par recherche.
Prérequis
- Python 3.8+ installé
- bibliothèque requests installée (pip install requests)
- Une clé API Scavio de scavio.dev (250 crédits gratuits/mois)
- N'importe quelle clé API LLM (OpenAI, Anthropic, etc.) ou un modèle local
Parcours
Étape 1: Obtenez votre clé API et testez-la
Inscrivez-vous sur scavio.dev et copiez votre clé API. Testez-la avec une simple commande curl ou un script Python pour vérifier qu'elle fonctionne.
import requests, os
API_KEY = os.environ.get('SCAVIO_API_KEY', 'your_key_here')
resp = requests.post('https://api.scavio.dev/api/v1/search',
headers={'x-api-key': API_KEY, 'Content-Type': 'application/json'},
json={'query': 'hello world', 'country_code': 'us'})
if resp.status_code == 200:
results = resp.json().get('organic_results', [])
print(f'API works. Got {len(results)} results.')
else:
print(f'Error: {resp.status_code} - {resp.text}')Étape 2: Écrivez la fonction de recherche
Créez une fonction unique qui prend une question et renvoie des résultats de recherche formatés. C'est le cœur de votre système de grounding – seulement 10 lignes de code.
def search_web(question: str) -> str:
resp = requests.post('https://api.scavio.dev/api/v1/search',
headers={'x-api-key': API_KEY, 'Content-Type': 'application/json'},
json={'query': question, 'country_code': 'us'})
if resp.status_code != 200:
return 'Search failed. Answer from your own knowledge.'
results = resp.json().get('organic_results', [])[:5]
if not results:
return 'No results found.'
return '\n'.join(
f'{r["title"]}\n{r.get("snippet", "")}\nSource: {r["link"]}\n'
for r in results
)Étape 3: Construisez le prompt grounded
Combinez les résultats de recherche avec la question de l'utilisateur dans un template de prompt. Dites au LLM d'utiliser les résultats de recherche et de citer les sources.
def make_prompt(question: str) -> str:
search_results = search_web(question)
return f"""Answer the following question using ONLY the search results below.
If the results do not contain enough info, say so.
Cite your sources with URLs.
Search Results:
{search_results}
Question: {question}
Answer:"""
# Test it:
prompt = make_prompt('What is the cheapest CRM in 2026?')
print(prompt)Étape 4: Connectez-vous à votre LLM
Passez le prompt grounded à n'importe quel LLM. Cet exemple utilise OpenAI mais fonctionne de manière identique avec Anthropic, Ollama local, ou toute API de chat.
from openai import OpenAI
client = OpenAI() # uses OPENAI_API_KEY env var
def ask(question: str) -> str:
prompt = make_prompt(question)
response = client.chat.completions.create(
model='gpt-4o-mini',
messages=[{'role': 'user', 'content': prompt}],
max_tokens=500
)
return response.choices[0].message.content
# Your first grounded query:
answer = ask('What is the cheapest CRM in 2026?')
print(answer)Étape 5: Ajoutez une boucle de conversation
Transformez la requête unique en un agent conversationnel. Chaque message de l'utilisateur est grounded avec des résultats de recherche frais.
def chat_loop():
print('Grounded Agent (type "quit" to exit)')
print(f'Search cost: $0.005 per question\n')
while True:
question = input('You: ').strip()
if question.lower() in ('quit', 'exit', 'q'):
break
if not question:
continue
answer = ask(question)
print(f'\nAgent: {answer}\n')
if __name__ == '__main__':
chat_loop()Exemple Python
import os, requests
from openai import OpenAI
API_KEY = os.environ['SCAVIO_API_KEY']
client = OpenAI()
def search_web(question: str) -> str:
resp = requests.post('https://api.scavio.dev/api/v1/search',
headers={'x-api-key': API_KEY, 'Content-Type': 'application/json'},
json={'query': question, 'country_code': 'us'})
results = resp.json().get('organic_results', [])[:5]
return '\n'.join(f'{r["title"]}\n{r.get("snippet", "")}\nSource: {r["link"]}' for r in results)
def ask(question: str) -> str:
ctx = search_web(question)
prompt = f'Use these search results to answer:\n\n{ctx}\n\nQuestion: {question}'
resp = client.chat.completions.create(
model='gpt-4o-mini',
messages=[{'role': 'user', 'content': prompt}],
max_tokens=500)
return resp.choices[0].message.content
if __name__ == '__main__':
print(ask('Best free CRM 2026'))Exemple JavaScript
const API_KEY = process.env.SCAVIO_API_KEY;
async function searchWeb(question) {
const resp = await fetch('https://api.scavio.dev/api/v1/search', {
method: 'POST',
headers: { 'x-api-key': API_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({ query: question, country_code: 'us' })
});
const data = await resp.json();
return (data.organic_results || []).slice(0, 5)
.map(r => `${r.title}\n${r.snippet || ''}\nSource: ${r.link}`).join('\n\n');
}
async function main() {
const question = 'Best free CRM 2026';
const context = await searchWeb(question);
console.log(`Search context (cost: $0.005):\n${context}`);
// Pass context + question to your LLM of choice
}
main().catch(console.error);Sortie attendue
API works. Got 10 results.
Grounded Agent (type "quit" to exit)
Search cost: $0.005 per question
You: What is the cheapest CRM in 2026?
Agent: Based on search results, HubSpot CRM remains the most popular
free option in 2026 with unlimited users. For paid plans, Freshsales
starts at $9/user/month. Zoho CRM offers a free tier for up to 3 users.
Source: https://www.hubspot.com/pricing
Source: https://www.freshworks.com/crm/pricing/