Les échecs de recherche d'un agent sont la raison la plus courante pour laquelle les agents d'IA produisent des réponses incorrectes ou incomplètes. Les modes de défaillance sont prévisibles : mauvaise configuration de la clé API, requêtes mal formées, analyse de résultats vides, délai d'attente sur des réseaux lents, et limitation de débit. Ce tutoriel fournit une liste de vérification systématique de débogage et des fonctions de diagnostic réutilisables que vous pouvez intégrer dans n'importe quel agent. Chaque test utilise le point de terminaison de l'API Scavio, mais les modèles s'appliquent à tout backend de recherche.
Prérequis
- Python 3.9+ installé
- bibliothèque requests installée
- Une clé API Scavio provenant de scavio.dev
- Un agent avec une intégration d'outil de recherche à déboguer
Parcours
Étape 1: Tester la connectivité et l'authentification de l'API
La première chose à vérifier est si votre clé API fonctionne et si le point de terminaison est accessible. Cette fonction exécute une vérification minimale de l'état de santé.
import requests, os
def test_api_health(api_key: str = None) -> dict:
key = api_key or os.environ.get('SCAVIO_API_KEY', '')
if not key:
return {'status': 'FAIL', 'error': 'No API key found'}
try:
resp = requests.post('https://api.scavio.dev/api/v1/search',
headers={'x-api-key': key, 'Content-Type': 'application/json'},
json={'query': 'test', 'country_code': 'us'},
timeout=10)
return {'status': 'OK' if resp.status_code == 200 else 'FAIL',
'http_code': resp.status_code,
'has_results': bool(resp.json().get('organic_results'))}
except requests.exceptions.Timeout:
return {'status': 'FAIL', 'error': 'Timeout after 10s'}
except Exception as e:
return {'status': 'FAIL', 'error': str(e)}
print(test_api_health())Étape 2: Diagnostiquer les résultats vides
Si l'API renvoie 200 mais aucun résultat, la requête peut être trop spécifique, mal formée, ou dans une langue sans couverture. Testez avec des requêtes progressivement plus simples.
def diagnose_empty_results(original_query: str) -> dict:
api_key = os.environ['SCAVIO_API_KEY']
test_queries = [
original_query,
' '.join(original_query.split()[:3]), # first 3 words
'python programming', # known good query
]
results = {}
for q in test_queries:
resp = requests.post('https://api.scavio.dev/api/v1/search',
headers={'x-api-key': api_key, 'Content-Type': 'application/json'},
json={'query': q, 'country_code': 'us'})
count = len(resp.json().get('organic_results', []))
results[q] = count
return results
diag = diagnose_empty_results('xylophone quantum blockchain synergy 2026')
for query, count in diag.items():
status = 'OK' if count > 0 else 'EMPTY'
print(f'[{status}] "{query}" -> {count} results')Étape 3: Ajouter une journalisation structurée à l'outil de recherche
Enveloppez votre fonction de recherche avec une journalisation afin de pouvoir tracer chaque appel, sa latence, le nombre de résultats et toute erreur.
import time, logging
logging.basicConfig(level=logging.INFO)
log = logging.getLogger('agent_search')
def logged_search(query: str, country: str = 'us') -> dict:
start = time.time()
log.info(f'Searching: "{query}" country={country}')
try:
resp = requests.post('https://api.scavio.dev/api/v1/search',
headers={'x-api-key': os.environ['SCAVIO_API_KEY'],
'Content-Type': 'application/json'},
json={'query': query, 'country_code': country},
timeout=15)
elapsed = time.time() - start
data = resp.json()
count = len(data.get('organic_results', []))
log.info(f'Result: {resp.status_code}, {count} results, {elapsed:.2f}s')
return data
except Exception as e:
elapsed = time.time() - start
log.error(f'Failed after {elapsed:.2f}s: {e}')
return {'organic_results': [], 'error': str(e)}Étape 4: Construire un wrapper de réessai avec backoff exponentiel
Les défaillances transitoires (perturbations réseau, limites de débit) sont mieux gérées avec des réessais. Utilisez un backoff exponentiel pour éviter de marteler l'API.
def search_with_retry(query: str, max_retries: int = 3) -> dict:
for attempt in range(max_retries):
try:
data = logged_search(query)
if data.get('organic_results'):
return data
if attempt < max_retries - 1:
wait = 2 ** attempt
log.warning(f'Empty results, retrying in {wait}s...')
time.sleep(wait)
except Exception as e:
if attempt < max_retries - 1:
wait = 2 ** attempt
log.warning(f'Error: {e}, retrying in {wait}s...')
time.sleep(wait)
else:
raise
return {'organic_results': [], 'error': 'All retries exhausted'}Étape 5: Exécuter la suite de diagnostic complète
Combinez toutes les vérifications en une seule fonction de diagnostic qui rapporte la santé de l'intégration de recherche de votre agent.
def full_diagnostic() -> None:
print('=== Agent Search Diagnostic ===')
# 1. API Health
health = test_api_health()
print(f'1. API Health: {health["status"]}')
if health['status'] != 'OK':
print(f' Error: {health.get("error", health.get("http_code"))}')
return
# 2. Result quality
data = logged_search('best crm software 2026')
results = data.get('organic_results', [])
print(f'2. Result quality: {len(results)} results')
if results:
print(f' Top result: {results[0]["title"]}')
# 3. Retry behavior
retry_data = search_with_retry('obscure test query 12345')
print(f'3. Retry test: {len(retry_data.get("organic_results", []))} results')
print('=== Diagnostic complete ===')
full_diagnostic()Exemple Python
import os, time, requests, logging
logging.basicConfig(level=logging.INFO)
log = logging.getLogger('debug')
API_KEY = os.environ['SCAVIO_API_KEY']
def search(query: str) -> dict:
start = time.time()
resp = requests.post('https://api.scavio.dev/api/v1/search',
headers={'x-api-key': API_KEY, 'Content-Type': 'application/json'},
json={'query': query, 'country_code': 'us'}, timeout=15)
elapsed = time.time() - start
data = resp.json()
count = len(data.get('organic_results', []))
log.info(f'"{query}" -> {count} results in {elapsed:.2f}s')
return data
def main():
# Health check
health = search('test')
print(f'Health: {"OK" if health.get("organic_results") else "FAIL"}')
# Real query
data = search('best crm 2026')
for r in data.get('organic_results', [])[:3]:
print(f' #{r["position"]} {r["title"]}')
if __name__ == '__main__':
main()Exemple JavaScript
const API_KEY = process.env.SCAVIO_API_KEY;
async function search(query) {
const start = Date.now();
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, country_code: 'us' })
});
const data = await resp.json();
const ms = Date.now() - start;
console.log(`"${query}" -> ${(data.organic_results || []).length} results in ${ms}ms`);
return data;
}
async function main() {
const health = await search('test');
console.log(`Health: ${health.organic_results?.length ? 'OK' : 'FAIL'}`);
const data = await search('best crm 2026');
(data.organic_results || []).slice(0, 3).forEach(r => {
console.log(` #${r.position} ${r.title}`);
});
}
main().catch(console.error);Sortie attendue
=== Agent Search Diagnostic ===
1. API Health: OK
INFO:agent_search:Searching: "best crm software 2026" country=us
INFO:agent_search:Result: 200, 10 results, 0.87s
2. Result quality: 10 results
Top result: Best CRM Software for Small Business (2026)
3. Retry test: 0 results
=== Diagnostic complete ===