Hermes v0.13.0 est livré avec un outil de recherche web défaillant qui renvoie des résultats vides ou expire pour de nombreuses requêtes. Le problème provient de son backend de recherche par défaut qui est limité en débit et peu fiable. Plutôt que d'attendre un correctif, vous pouvez le remplacer par un backend d'API de recherche fonctionnel en quelques minutes. Ce tutoriel montre comment remplacer l'outil de recherche d'Hermes par l'API Scavio, qui renvoie des données SERP structurées de manière fiable à 0,005 $ par requête. Le correctif ne nécessite de modifier que la fonction de recherche -- aucun autre changement de code de l'agent n'est requis.
Prérequis
- Hermes v0.13.x installé
- Python 3.9+ installé
- Bibliothèque requests installée
- Une clé API Scavio depuis scavio.dev
Parcours
Étape 1: Diagnostiquer l'outil de recherche défaillant
D'abord, confirmez le problème de recherche en exécutant une requête test via Hermes et en vérifiant la sortie de l'outil. Les modes de défaillance typiques sont des résultats vides, des erreurs de temporisation ou du JSON mal formé.
# Test the current Hermes search tool:
# In your Hermes agent, run a query that requires search:
# "What is the current price of Bitcoin?"
#
# Common error outputs:
# - {"results": []} (empty results)
# - TimeoutError: Search request timed out after 30s
# - JSONDecodeError: Expecting value (malformed response)
#
# If you see any of these, the search backend is broken.
import requests
# Quick test of the default Hermes search endpoint:
try:
resp = requests.get('http://localhost:8080/search?q=test', timeout=10)
print(f'Status: {resp.status_code}')
print(f'Results: {len(resp.json().get("results", []))}')
except Exception as e:
print(f'Search broken: {e}')Étape 2: Construire la fonction de recherche de remplacement
Créez un remplacement direct qui correspond à l'interface de l'outil de recherche d'Hermes. La fonction prend une chaîne de requête et renvoie les résultats dans le format attendu par Hermes.
import requests, os
SCAVIO_KEY = os.environ['SCAVIO_API_KEY']
def hermes_search_replacement(query: str, num_results: int = 5) -> dict:
"""Drop-in replacement for broken Hermes search tool.
Returns results in Hermes-compatible format."""
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'},
timeout=15)
resp.raise_for_status()
data = resp.json()
results = [{
'title': r['title'],
'url': r['link'],
'content': r.get('snippet', ''),
} for r in data.get('organic_results', [])[:num_results]]
return {'results': results}
except Exception as e:
return {'results': [], 'error': str(e)}
# Test the replacement:
result = hermes_search_replacement('current bitcoin price')
print(f'Results: {len(result["results"])}')
for r in result['results']:
print(f' {r["title"]}')Étape 3: Corriger l'enregistrement de l'outil de recherche d'Hermes
Remplacez l'outil de recherche par défaut dans la configuration de votre agent Hermes. Cela remplace le backend défaillant sans modifier le code source d'Hermes.
# Option 1: Override in your agent setup script
# Find where Hermes registers its search tool and replace it:
def register_fixed_search(agent):
"""Replace the broken Hermes search with working API."""
# Remove the broken tool
if hasattr(agent, 'tools'):
agent.tools = {name: tool for name, tool in agent.tools.items()
if name != 'web_search'}
# Register the working replacement
agent.register_tool(
name='web_search',
description='Search the web for current information.',
function=hermes_search_replacement,
parameters={
'query': {'type': 'string', 'description': 'Search query'},
'num_results': {'type': 'integer', 'description': 'Number of results', 'default': 5}
}
)
print('Search tool replaced successfully')
# Option 2: Environment variable override
# Some Hermes configs support:
# HERMES_SEARCH_BACKEND=custom
# HERMES_SEARCH_ENDPOINT=https://api.scavio.dev/api/v1/searchÉtape 4: Vérifier que le correctif fonctionne de bout en bout
Exécutez des requêtes test via l'agent Hermes corrigé pour confirmer que la recherche fonctionne correctement. Testez les cas limites comme les résultats vides et les longues requêtes.
def verify_search_fix():
test_cases = [
('current bitcoin price', True),
('best python frameworks 2026', True),
('xyznonexistentquery12345', False), # should return empty gracefully
('a' * 500, False), # very long query
]
passed = 0
for query, expect_results in test_cases:
result = hermes_search_replacement(query)
has_results = len(result.get('results', [])) > 0
has_error = 'error' in result
if expect_results and has_results:
status = 'PASS'
passed += 1
elif not expect_results and not has_error:
status = 'PASS'
passed += 1
else:
status = 'FAIL'
print(f'[{status}] "{query[:40]}" -> {len(result.get("results", []))} results')
print(f'\n{passed}/{len(test_cases)} tests passed')
print(f'Cost: ${len(test_cases) * 0.005:.3f}')
verify_search_fix()Exemple Python
import os, requests
SCAVIO_KEY = os.environ['SCAVIO_API_KEY']
def hermes_search(query: str, num_results: int = 5) -> dict:
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'}, timeout=15)
results = [{'title': r['title'], 'url': r['link'], 'content': r.get('snippet', '')}
for r in resp.json().get('organic_results', [])[:num_results]]
return {'results': results}
except Exception as e:
return {'results': [], 'error': str(e)}
# Quick test
for q in ['bitcoin price', 'python tutorial', 'nonexistent12345']:
r = hermes_search(q)
print(f'{q}: {len(r["results"])} results')Exemple JavaScript
const SCAVIO_KEY = process.env.SCAVIO_API_KEY;
async function hermesSearch(query, numResults = 5) {
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' })
});
const data = await resp.json();
return { results: (data.organic_results || []).slice(0, numResults)
.map(r => ({ title: r.title, url: r.link, content: r.snippet || '' })) };
} catch (e) {
return { results: [], error: e.message };
}
}
async function main() {
for (const q of ['bitcoin price', 'python tutorial']) {
const r = await hermesSearch(q);
console.log(`${q}: ${r.results.length} results`);
}
}
main();Sortie attendue
Search broken: TimeoutError: Search request timed out after 10s
Results: 5
Bitcoin Price Today - Live BTC Chart
BTC/USD - Bitcoin Price & Market Cap
[PASS] "current bitcoin price" -> 5 results
[PASS] "best python frameworks 2026" -> 5 results
[PASS] "xyznonexistentquery12345" -> 0 results
[PASS] "aaaaaaaaaa..." -> 0 results
4/4 tests passed
Cost: $0.020