Compétence de Recherche Locale
Recherche web locale avec bascule automatique entre les moteurs. Scraping HTML direct de DuckDuckGo / Bing / Google · résistant aux limites de débit · schéma de résultats canonique.
Cette compétence interroge directement les moteurs de recherche publics depuis votre machine. Aucune clé API, aucun SDK, aucun saut réseau. Si un moteur vous limite en débit, l'orchestrateur bascule silencieusement vers le suivant — l'appel réussit donc généralement du premier coup, même depuis des adresses IP de centre de données où Google est bloqué.
Chaque résultat est un SearchFunctionResultItem avec les 7 champs canoniques (url, name, snippet, host_name, rank, date, favicon) plus trois champs d'extension optionnels : source_engine, raw_html, score. Le code consommateur écrit pour toute compétence de recherche web de forme similaire fonctionne ici sans modification.
✨ Points forts
- Zéro dépendance SDK cloud — seulement
cheerio(analyseur HTML) et la fonctionfetchintégrée de Node. - Trois moteurs, bascule automatique — DuckDuckGo → Bing → Google avec
engine: "auto"(par défaut). - Sensible à la locale —
--locale fr-FR/en-US/ja-JP/ toute balise BCP-47. Essentiel pour les adresses IP hors des États-Unis où Bing sert autrement des résultats localisés même pour des requêtes en anglais. - Filtre de récence —
--recency-days 7restreint aux résultats de la semaine dernière. DDG prend en charge un nombre exact de jours ; Bing/Google utilisent des intervalles jour/semaine/mois. - Schéma de résultats canonique —
url/name/snippet/host_name/rank/date/favicon, de forme identique à d'autres compétences de recherche web du registre ClawHub. - CLI + SDK — utilisez
tsx bin/web-search.ts <requête>pour des recherches ponctuelles, ouimport { search } from "local-search"dans du code. - TypeScript ESM pur — s'exécute sur Node 18+ via
tsx, ou zéro configuration viabun.
🚀 Démarrage rapide
# 1. Installation (une dépendance d'exécution : cheerio)
cd skills/local-search && npm install
# 2. Recherche (bascule automatique entre DDG → Bing → Google)
tsx bin/web-search.ts "intelligence artificielle"
# 3. Forcer un moteur et une locale spécifiques
tsx bin/web-search.ts "apprentissage automatique" --engine bing --locale fr-FR --num 5
# 4. Actualités récentes au format JSON
tsx bin/web-search.ts "avancées en IA" --recency-days 7 --json -o ai_news.json
Utilisation programmatique :
import { search } from "local-search";
const outcome = await search("Quelle est la capitale de la France ?", { num: 5 });
if (outcome.success) {
console.log(`Répondu par ${outcome.engine} en ${outcome.elapsedMs}ms`);
outcome.results.forEach(r => console.log(`- ${r.name}\n ${r.url}`));
}
🎯 Quand utiliser cette compétence
Utilisez local-search chaque fois que l'utilisateur a besoin d'informations du web public — au-delà de ce qui se trouve dans les données d'apprentissage du modèle :
- Informations en temps réel : actualités, cours de bourse, météo, scores sportifs
- Documentation la plus récente : notes de version de frameworks, changements d'API, articles récemment publiés
- Vérification des faits : vérifier une affirmation à partir de sources web en direct
- Recherche : rassembler plusieurs sources sur un sujet, comparer les perspectives
- Découverte de contenu : trouver des tutoriels, articles de blog, conférences récentes
- Analyse concurrentielle / de marché : annonces de concurrents, tendances du secteur
- Recherche académique : trouver des articles, citations, pages d'auteurs
🔄 Comparaison des moteurs
| Moteur | Point d'accès | Clé API | IP résidentielle | IP de centre de données | Récence |
|---|---|---|---|---|---|
| DuckDuckGo | html.duckduckgo.com/html/ (GET) | aucune | ✅ élevée | ⚠️ limitations de débit sous charge | df=d<N> (jours exacts) |
| Bing | www.bing.com/search | aucune | ✅ élevée | ✅ élevée | freshness=d1|w1|m1 (intervalles) |
www.google.com/search | aucune | ⚠️ moyenne | ❌ faible (mur enablejs) | tbs=qdr:d|w|m|y (intervalles) |
engine: "auto" les essaie dans l'ordre DuckDuckGo → Bing → Google, retournant le premier ensemble de résultats non vide. Depuis une adresse IP de centre de données, la chaîne effective est DDG → Bing (Google est généralement bloqué) ; depuis une IP résidentielle, les trois sont viables. Modifiez AUTO_ENGINE_ORDER dans src/engines/index.ts pour changer la priorité.
📦 Chemin d'installation
Emplacement recommandé : {chemin_projet}/skills/local-search
Extrayez ce paquet de compétence vers le chemin ci-dessus dans votre projet.
Prérequis
- Node.js >= 18 (utilise la fonction
fetchglobale intégrée). - Une dépendance npm :
cheerio(analyseur HTML). - Une connexion internet fonctionnelle — la compétence interroge directement les moteurs de recherche publics.
Installez une fois dans le répertoire de la compétence :
cd {chemin_projet}/skills/local-search
npm install # ou : bun install / pnpm install
La compétence est en TypeScript ESM pur. Vous pouvez l'exécuter via
tsx(recommandé, convivial pour le développement) oubun(zéro configuration).node --experimental-strip-types bin/web-search.tsfonctionne également sur Node 22+.
Pourquoi local ?
| Aspect | Compétences cloud | Cette compétence (local-search) |
|---|---|---|
| Backend de recherche | Fonction cloud / API | HTTP direct vers DuckDuckGo / Bing / Google |
| Clé API / SDK | Requis | Aucun |
| Chemin réseau | Client → cloud → moteur de recherche | Client → moteur de recherche |
| Gestion des échecs | Dépend du SDK | Bascule automatique entre 3 moteurs |
| Schéma de résultats | SearchFunctionResultItem (7 champs) | Mêmes 7 champs + 3 champs d'extension optionnels |
| CLI | Spécifique au SDK | tsx bin/web-search.ts |
Architecture
local-search/
├── SKILL.md ← vous êtes ici
├── LICENSE.txt
├── package.json ← déclare la dépendance `cheerio`
├── tsconfig.json
├── bin/
│ └── web-search.ts ← point d'entrée CLI
├── src/
│ ├── index.ts ← exportations publiques du SDK
│ ├── search.ts ← orchestrateur avec bascule automatique
│ ├── types.ts ← SearchFunctionResultItem + options
│ └── engines/
│ ├── _shared.ts ← aides de récupération / analyse
│ ├── duckduckgo.ts ← POST https://html.duckduckgo.com/html/
│ ├── bing.ts ← GET https://www.bing.com/search
│ ├── google.ts ← GET https://www.google.com/search
│ └── index.ts ← registre des moteurs + AUTO_ENGINE_ORDER
└── scripts/
└── web_search.ts ← exemple de démarrage rapide
La seule dépendance d'exécution est cheerio (analyseur HTML), déclarée dans package.json. La fonction fetch intégrée de Node 18+ couvre la couche réseau — aucun autre SDK n'est importé dans ce paquet.
Utilisation en CLI
La CLI se trouve dans bin/web-search.ts. Exécutez-la via tsx, bun ou tout exécuteur compatible TS.
Recherche de base
# Par défaut : moteur automatique, 10 résultats, sortie lisible
est la plus susceptible d'être limité)
tsx bin/web-search.ts "dernières actualités tech" --engine google
# Par défaut — essaie DDG → Bing → Google, retourne le premier non vide
tsx bin/web-search.ts "dernières actualités tech" --engine auto
Filtre de récence
# Résultats des 7 derniers jours
tsx bin/web-search.ts "actualités crypto-monnaies" --num 10 --recency-days 7
# (option courte)
tsx bin/web-search.ts "actualités crypto-monnaies" -r 7
Sauvegarder les résultats en JSON
# Écrire le JSON dans un fichier (la bannière lisible est supprimée)
tsx bin/web-search.ts "recherche changement climatique" --num 5 --json -o resultats_recherche.json
# Ou rediriger le JSON vers la sortie standard
est supprimé)
tsx bin/web-search.ts "avancées IA" --quiet
Paramètres CLI
| Option | Court | Description |
|---|---|---|
--num <N> | -n | Nombre de résultats (défaut : 10, max : 50) |
--engine <id> | -e | duckduckgo | bing | google | auto (défaut : auto) |
--recency-days <N> | -r | Restreindre aux résultats des N derniers jours (défaut : 0 = aucun filtre) |
--timeout <ms> | — | Délai d'attente par moteur en ms (défaut : 8000) |
--json | — | Émettre du JSON au lieu d'une sortie lisible |
--output <chemin> | -o | Écrire le JSON dans un fichier au lieu de la sortie standard |
--pretty | — | Pretty-print JSON (activé par défaut ; passez --no-pretty pour désactiver — pas encore supporté, omettez --json à la place) |
--quiet | -q | Supprimer la bannière d'informations sur le moteur |
--help | -h | Afficher l'aide |
Structure du résultat de recherche
Chaque élément de résultat est un SearchFunctionResultItem :
interface SearchFunctionResultItem {
// ----- Champs canoniques (forme partagée entre les compétences de recherche web ClawHub) -----
url: string; // URL complète du résultat
name: string; // Titre de la page
snippet: string; // Texte d'aperçu / description
host_name: string; // Nom de domaine (ex. "fr.wikipedia.org")
rank: number; // Classement basé sur 1 dans l'ensemble de résultats du moteur
date: string; // Date de publication / mise à jour ; "N/A" si inconnue
favicon: string; // URL du favicon (Google S2)
// ----- Champs d'extension (nouveaux dans local-search) -----
source_engine: "duckduckgo" | "bing" | "google";
raw_html?: string; // HTML original de l'élément d'extrait (optionnel)
score?: number; // Score de pertinence heuristique [0, 100] (optionnel)
}
Utilisation du SDK
Si vous écrivez du code TypeScript/JavaScript (pas la CLI), importez depuis src/index.ts :
Recherche simple
import { search } from "local-search";
const outcome = await search("Quelle est la capitale de la France ?", { num: 5 });
if (outcome.success) {
console.log(`Moteur utilisé : ${outcome.engine}`);
console.log(`Essayés dans l'ordre : ${outcome.enginesTried.join(" → ")}`);
console.log(`Temps écoulé : ${outcome.elapsedMs}ms`);
for (const item of outcome.results) {
console.log(`- ${item.name} [${item.source_engine}]`);
console.log(` ${item.url}`);
console.log(` ${item.snippet}`);
}
} else {
console.error("La recherche a échoué :", outcome.error);
if (outcome.errors) {
// Mode automatique : voir quels moteurs ont été essayés et leurs rapports
for (const e of outcome.errors) {
console.error(` ${e.engine} :`, e.error);
}
}
}
Variante avec levée d'exception en cas d'échec
import { searchOrThrow, AllEnginesFailedError } from "local-search";
try {
const results = await searchOrThrow("Frameworks JavaScript", { num: 10 });
console.log(results);
} catch (err) {
if (err instanceof AllEnginesFailedError) {
console.error("Tous les moteurs ont échoué :", err.errors);
} else {
console.error("Erreur d'un seul moteur :", err);
}
}
Forcer un moteur spécifique
import { search } from "local-search";
// Sauter la chaîne de bascule — utiliser uniquement DuckDuckGo.
const outcome = await search("applications informatique quantique", {
num: 8,
engine: "duckduckgo",
});
Filtre de récence
const outcome = await search("recherche génomique", {
num: 5,
recency_days: 30, // 30 derniers jours
});
Fetch personnalisé (tests / environnements d'exécution spéciaux)
const outcome = await search("bonjour le monde", {
fetchImpl: monMockFetch, // toute fonction compatible WhatWG-fetch
userAgent: "mon-bot/1.0",
timeoutMs: 5000,
});
Backends des moteurs
DuckDuckGo (duckduckgo)
- Point d'accès :
https://html.duckduckgo.com/html/(formulaire POSTq=...) - Aucune clé API. Soumis à des limites de débit approximatives — une utilisation intensive prolongée retourne des ensembles de résultats vides.
- Récence : champ de formulaire
df=d<N>. - Meilleur pour : premier essai par défaut ; rarement bloqué ; respecte la vie privée.
Bing (bing)
- Point d'accès :
https://www.bing.com/search?q=...&count=... - Aucune clé API. La mise en page HTML est stable et facile à analyser.
- Récence : intervalle
freshness=d1/w1/m1(Bing n'a pas de filtre URL pour un nombre arbitraire de jours). - Meilleur pour : second recours ; bons résultats en anglais ; légers problèmes de locale (atténués par
ensearch=1).
Google (google)
- Point d'accès :
https://www.google.com/search?q=...&num=... - Aucune clé API, MAIS Google est le plus agressif pour bloquer les scrapers. Depuis des adresses IP de centre de données / cloud, Google renvoie généralement une page de redirection "merci d'activer JS" (
/httpservice/retry/enablejs) avec zéro résultat analysable — le moteur signale ceci comme un échec logiciel et la chaîne automatique passe à travers. Depuis des adresses IP résidentielles, le scraping HTML de Google fonctionne souvent bien. - Récence : intervalle
tbs=qdr:d|w|m|y. - Meilleur pour : dernier recours sur IP résidentielles ; échoue généralement sur IP cloud (où DDG+Bing couvrent déjà le besoin).
Stratégie de bascule automatique
Quand engine: "auto" (par défaut), l'orchestrateur essaie les moteurs dans cet ordre :
- DuckDuckGo — blocage le moins agressif, filtre de date le plus fin
- Bing — généralement stable depuis n'importe quelle IP, y compris les centres de données
- Google — meilleure qualité de résultat quand accessible ; souvent bloqué sur les IP de centre de données
Il retourne le premier moteur qui donne ≥ 1 résultat. Si les trois échouent, le résultat est { success: false, errors: [...] } avec l'erreur de chaque moteur — ou, en mode searchOrThrow, une AllEnginesFailedError.
Tableau de fiabilité pratique (observé lors des tests) :
| Type d'IP de l'appelant | DDG | Bing | Chaîne automatique effective | |
|---|---|---|---|---|
| Résidentielle | élevée | élevée | moyenne | DDG → Bing → Google (3 viables) |
| Centre de données / cloud | moyenne (limites de débit sous charge) | élevée | faible (mur enablejs) | effectivement DDG → Bing |
L'ordre est défini dans src/engines/index.ts (AUTO_ENGINE_ORDER) ; modifiez ce tableau si vous voulez une priorité différente.
Cas d'utilisation courants
- Informations en temps réel : actualités, cours de bourse, météo, scores sportifs. Utile pour des informations qui changent rapidement après la date de coupure des connaissances du modèle.
- Documentation la plus récente : notes de version de frameworks (React 19, TypeScript 5.5), changements d'API, articles récemment publiés. Essentiel lorsque l'utilisateur pose des questions sur des versions rendues publiques après l'entraînement du modèle.
- Vérification des faits : vérifier une affirmation à partir de sources web en direct. Le schéma canonique facilite l'extraction du nom d'hôte et de l'extrait pour une vérification croisée.
- Recherche : rassembler plusieurs sources (articles académiques, blogs, sites d'actualités). L'architecture multi-moteurs garantit que même si un moteur échoue (par ex. Google bloqué), vous obtenez toujours des résultats de Bing ou DDG.
- Découverte de contenu : trouver des tutoriels, articles de blog, conférences récentes sur des sujets de niche. Indispensable pour les développeurs qui cherchent les meilleures pratiques ou solutions à des problèmes techniques spécifiques.
- Analyse concurrentielle / de marché : annonces de produits, tendances du secteur, actualités sur les concurrents. Utile pour les analyses de marché en temps réel directement depuis le terminal.
- Recherche académique : trouver des articles, citations, pages d'auteurs. La prise en charge des locales permet des recherches précises dans différentes langues (par ex.
--locale ja-JPpour des résultats en japonais).