Lokaler Such-Skill
Lokale Websuche mit automatischem Engine-Fallback. Direktes HTML-Scraping von DuckDuckGo / Bing / Google · widerstandsfähig gegen Ratenbegrenzung · kanonisches Ergebnis-Schema.
Dieser Skill ruft die öffentlichen Suchmaschinen direkt von Ihrem Rechner aus auf. Kein API-Schlüssel, kein SDK, kein Netzwerk-Hop. Wenn eine Engine Ihre Anfragen limitiert, schaltet der Orchestrator stillschweigend auf die nächste um – so gelingt der Aufruf normalerweise beim ersten Versuch, selbst von Rechenzentrums-IPs, bei denen Google blockiert ist.
Jedes Ergebnis ist ein SearchFunctionResultItem mit den kanonischen 7 Feldern (url, name, snippet, host_name, rank, date, favicon) plus drei optionalen Erweiterungsfeldern: source_engine, raw_html, score. Verbrauchercode, der für einen beliebigen gleichartigen Web-Such-Skill geschrieben wurde, funktioniert hier ohne Änderungen.
✨ Highlights
- Keine Cloud-SDK-Abhängigkeit – nur
cheerio(HTML-Parser) und der integriertefetchvon Node. - Drei Engines, automatischer Fallback – DuckDuckGo → Bing → Google bei
engine: "auto"(Standard). - Ortsabhängig –
--locale de-DE/en-US/ja-JP/ beliebiges BCP-47-Tag. Entscheidend für Nicht-US-IPs, bei denen Bing ansonsten lokalisierte Ergebnisse selbst für englische Abfragen ausliefert. - Aktualitätsfilter –
--recency-days 7schränkt auf Ergebnisse der letzten Woche ein. DDG unterstützt exakte N Tage; Bing/Google verwenden Tag/Woche/Monat-Buckets. - Kanonisches Ergebnis-Schema –
url/name/snippet/host_name/rank/date/favicon-Felder, identisch aufgebaut wie bei anderen Web-Such-Skills in der ClawHub-Registry. - CLI + SDK – verwenden Sie
tsx bin/web-search.ts <Abfrage>für einmalige Aufrufe oderimport { search } from "local-search"im Code. - Reines TypeScript ESM – läuft auf Node 18+ mittels
tsxoder nullkonfiguration viabun.
🚀 Schnellstart
# 1. Installation (eine Laufzeitabhängigkeit: cheerio)
cd skills/local-search && npm install
# 2. Suche (Auto-Fallback über DDG → Bing → Google)
tsx bin/web-search.ts "künstliche Intelligenz"
# 3. Bestimmte Engine + Sprache festlegen
tsx bin/web-search.ts "maschinelles Lernen" --engine bing --locale en-US --num 5
# 4. Aktuelle Nachrichten als JSON
tsx bin/web-search.ts "KI-Durchbrüche" --recency-days 7 --json -o ki_nachrichten.json
Programmatische Nutzung:
import { search } from "local-search";
const outcome = await search("Was ist die Hauptstadt von Frankreich?", { num: 5 });
if (outcome.success) {
console.log(`Beantwortet von ${outcome.engine} in ${outcome.elapsedMs}ms`);
outcome.results.forEach(r => console.log(`- ${r.name}\n ${r.url}`));
}
🎯 Wann Dieser Skill Verwendet Werden Sollte
Verwenden Sie local-search, wenn der Benutzer Informationen benötigt, die im öffentlichen Web leben – über das hinaus, was in den Trainingsdaten des Modells enthalten ist:
- Echtzeit-Informationen: aktuelle Nachrichten, Aktienkurse, Wetter, Sportergebnisse
- Neueste Dokumentation: Framework-Release-Notizen, API-Änderungen, kürzlich veröffentlichte Arbeiten
- Faktenprüfung: Überprüfen einer Behauptung anhand von Live-Webquellen
- Recherche: Sammeln mehrerer Quellen zu einem Thema, Vergleichen von Perspektiven
- Inhaltsentdeckung: Finden von Tutorials, Blogbeiträgen, aktuellen Vorträgen
- Wettbewerbs- / Marktanalyse: Ankündigungen von Wettbewerbern, Branchentrends
- Akademische Suche: Finden von Arbeiten, Zitaten, Autorenseiten
🔄 Engine-Vergleich
| Engine | Endpunkt | API-Schlüssel | Residential-IP | Rechenzentrums-IP | Aktualität |
|---|---|---|---|---|---|
| DuckDuckGo | html.duckduckgo.com/html/ (GET) | keiner | ✅ hoch | ⚠️ Ratenbegrenzung unter Last | df=d<N> (exakte Tage) |
| Bing | www.bing.com/search | keiner | ✅ hoch | ✅ hoch | `freshness=d1 |
www.google.com/search | keiner | ⚠️ mittel | ❌ niedrig (enablejs-Wand) | `tbs=qdr:d |
engine: "auto" probiert sie in der Reihenfolge DuckDuckGo → Bing → Google und gibt die erste nicht leere Ergebnisliste zurück. Von einer Rechenzentrums-IP aus ist die effektive Kette DDG → Bing (Google ist normalerweise blockiert); von einer Residential-IP aus sind alle drei nutzbar. Bearbeiten Sie AUTO_ENGINE_ORDER in src/engines/index.ts, um die Priorität zu ändern.
📦 Installationspfad
Empfohlener Speicherort: {Projektpfad}/skills/local-search
Extrahieren Sie dieses Skill-Paket in den obigen Pfad in Ihrem Projekt.
Voraussetzungen
- Node.js >= 18 (verwendet den integrierten globalen
fetch). - Eine npm-Abhängigkeit:
cheerio(HTML-Parser). - Eine funktionierende Internetverbindung – der Skill ruft die öffentlichen Suchmaschinen direkt auf.
Einmalig im Skill-Verzeichnis installieren:
cd {Projektpfad}/skills/local-search
npm install # oder: bun install / pnpm install
Der Skill ist reines TypeScript ESM. Sie können ihn mittels
tsx(empfohlen, entwicklerfreundlich) oderbun(nullkonfiguration) ausführen. Ein laufzeitagnostischer Aufruf vonnode --experimental-strip-types bin/web-search.tsfunktioniert ebenfalls unter Node 22+.
Warum Lokal?
| Aspekt | Cloud-Such-Skills | Dieser Skill (local-search) |
|---|---|---|
| Such-Backend | Cloud-Funktion / API | Direktes HTTP zu DuckDuckGo / Bing / Google |
| API-Schlüssel / SDK | Erforderlich | Keiner |
| Netzwerkpfad | Client → Cloud → Suchmaschine | Client → Suchmaschine |
| Fehlerbehandlung | SDK-abhängig | Automatischer Fallback über 3 Engines |
| Ergebnis-Schema | SearchFunctionResultItem (7 Felder) | Gleiche 7 Felder + 3 optionale Erweiterungsfelder |
| CLI | SDK-spezifisch | tsx bin/web-search.ts |
Architektur
local-search/
├── SKILL.md ← Sie sind hier
├── LICENSE.txt
├── package.json ← deklariert die `cheerio`-Abhängigkeit
├── tsconfig.json
├── bin/
│ └── web-search.ts ← CLI-Einstieg
├── src/
│ ├── index.ts ← öffentliche SDK-Exporte
│ ├── search.ts ← Orchestrator mit automatischem Fallback
│ ├── types.ts ← SearchFunctionResultItem + Optionen
│ └── engines/
│ ├── _shared.ts ← fetch / parse-Hilfsfunktionen
│ ├── 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 ← Engine-Registry + AUTO_ENGINE_ORDER
└── scripts/
└── web_search.ts ← Schnellstart-Beispiel
Die einzige Laufzeitabhängigkeit ist cheerio (HTML-Parser), deklariert in package.json. Der integrierte fetch von Node 18+ deckt die Netzwerkebene ab – kein weiteres SDK wird irgendwo in diesem Paket importiert.
CLI-Nutzung
Das CLI lebt unter bin/web-search.ts. Führen Sie es mittels tsx, bun oder einem beliebigen TS-fähigen Runner aus.
Grundlegende Suche
# Standard: Auto-Engine, 10 Ergebnisse, menschenlesbare Ausgabe
tsx bin/web-search.ts "künstliche Intelligenz"
# Anzahl der Ergebnisse begrenzen
tsx bin/web-search.ts "maschinelles Lernen" --num 5
# (Kurzform funktioniert auch)
tsx bin/web-search.ts "maschinelles Lernen" -n 5
Bestimmte Engine Festlegen
# Nur DuckDuckGo erzwingen
tsx bin/web-search.ts "aktuelle Technik-News" --engine duckduckgo
# Nur Bing erzwingen
tsx bin/web-search.ts "aktuelle Technik-News" --engine bing
# Nur Google erzwingen (höchste Qualität, am wahrscheinlichsten rate-limitiert)
tsx bin/web-search.ts "aktuelle Technik-News" --engine google
# Standard – versuche DDG → Bing → Google, gib die erste nicht leere zurück
tsx bin/web-search.ts "aktuelle Technik-News" --engine auto
Aktualitätsfilter
# Ergebnisse der letzten 7 Tage
tsx bin/web-search.ts "Kryptowährungs-Nachrichten" --num 10 --recency-days 7
# (Kurzform)
tsx bin/web-search.ts "Kryptowährungs-Nachrichten" -r 7
Ergebnisse als JSON Speichern
# JSON in eine Datei schreiben (menschenlesbarer Banner wird unterdrückt)
tsx bin/web-search.ts "Klimaforschung" --num 5 --json -o suchergebnisse.json
# Oder JSON an stdout pipen
tsx bin/web-search.ts "KI-Durchbrüche" --num 3 --recency-days 1 --json > ki_nachrichten.json
Leiser Modus (Skripte / Piping)
# Den "Engine / Zeit"-Banner unterdrücken – nur die Ergebnisse ausgeben
tsx bin/web-search.ts "React Hooks" --quiet
CLI-Parameter
| Flag | Kurzform | Beschreibung |
|---|---|---|
--num <N> | -n | Anzahl der Ergebnisse (Standard: 10, max: 50) |
--engine <id> | -e | duckduckgo | bing | google | auto (Standard: auto) |
--recency-days <N> | -r | Auf Ergebnisse der letzten N Tage beschränken (Standard: 0 = kein Filter) |
--timeout <ms> | — | Timeout pro Engine in ms (Standard: 8000) |
--json | — | JSON statt menschenlesbarer Ausgabe ausgeben |
--output <pfad> | -o | JSON in Datei statt stdout schreiben |
--pretty | — | JSON hübsch ausgeben (Standard aktiv; übergeben Sie --no-pretty zum Deaktivieren – noch nicht unterstützt, lassen Sie stattdessen --json weg) |
--quiet | -q | Engine-Info-Banner unterdrücken |
--help | -h | Hilfe anzeigen |
Struktur der Suchergebnisse
Jedes Ergebniselement ist ein SearchFunctionResultItem:
interface SearchFunctionResultItem {
// ----- Kanonische Felder (gemeinsame Form über ClawHub-Web-Such-Skills hinweg) -----
url: string; // Vollständige URL des Ergebnisses
name: string; // Titel der Seite
snippet: string; // Vorschautext / Beschreibung
host_name: string; // Domainname (z. B. "de.wikipedia.org")
rank: number; // 1-basierte Rangfolge innerhalb der Ergebnismenge der Engine
date: string; // Veröffentlichungs- / Aktualisierungsdatum; "N/A" wenn unbekannt
favicon: string; // Favicon-URL (Google S2)
// ----- Erweiterungsfelder (neu in local-search) -----
source_engine: "duckduckgo" | "bing" | "google";
raw_html?: string; // Original-HTML des Snippet-Elements (optional)
score?: number; // Heuristischer Relevanz-Score [0, 100] (optional)
}
SDK-Nutzung
Wenn Sie TypeScript/JavaScript-Code schreiben (nicht das CLI ausführen), importieren Sie von src/index.ts:
Einfache Suche
import { search } from "local-search";
const outcome = await search("Was ist die Hauptstadt von Frankreich?", { num: 5 });
if (outcome.success) {
console.log(`Verwendete Engine: ${outcome.engine}`);
console.log(`Versucht in Reihenfolge: ${outcome.enginesTried.join(" → ")}`);
console.log(`Verstrichene Zeit: ${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("Suche fehlgeschlagen:", outcome.error);
if (outcome.errors) {
// Auto-Modus: sehen, welche Engines versucht wurden und was sie gemeldet haben
for (const e of outcome.errors) {
console.error(` ${e.engine}:`, e.error);
}
}
}
Variante mit Ausnahme bei Fehlschlag
import { searchOrThrow, AllEnginesFailedError } from "local-search";
try {
const results = await searchOrThrow("JavaScript-Frameworks", { num: 10 });
console.log(results);
} catch (err) {
if (err instanceof AllEnginesFailedError) {
console.error("Alle Engines fehlgeschlagen:", err.errors);
} else {
console.error("Einzel-Engine-Fehler:", err);
}
}
Bestimmte Engine Festlegen
import { search } from "local-search";
// Die Fallback-Kette überspringen – nur DuckDuckGo verwenden.
const outcome = await search("Quantencomputer-Anwendungen", {
num: 8,
engine: "duckduckgo",
});
Aktualitätsfilter
const outcome = await search("Genomforschung", {
num: 5,
recency_days: 30, // letzte 30 Tage
});
Benutzerdefiniertes Fetch (Tests / Edge-Runtimes)
const outcome = await search("Hallo Welt", {
fetchImpl: myMockFetch, // beliebige WhatWG-fetch-kompatible Funktion
userAgent: "mein-bot/1.0",
timeoutMs: 5000,
});
Engine-Backends
DuckDuckGo (duckduckgo)
- Endpunkt:
https://html.duckduckgo.com/html/(POST-Formularq=...) - Kein API-Schlüssel. Unterliegt groben Ratenbegrenzungen – anhaltendes Hämmern gibt leere Ergebnislisten zurück.
- Aktualität:
df=d<N>Formularfeld. - Am besten für: Standard erster Versuch; selten vollständig blockiert; respektiert Privatsphäre.
Bing (bing)
- Endpunkt:
https://www.bing.com/search?q=...&count=... - Kein API-Schlüssel. Das HTML-Layout ist stabil und leicht zu parsen.
- Aktualität:
freshness=d1/w1/m1Bucket (Bing hat keinen URL-Filter für beliebige N Tage). - Am besten für: zweiter Fallback; gute englischsprachige Ergebnisse; gelegentliche Gebietsschema-Besonderheiten (gemildert durch
ensearch=1).
Google (google)
- Endpunkt:
https://www.google.com/search?q=...&num=... - Kein API-Schlüssel, ABER Google ist am aggressivsten beim Blockieren von Scrapern. Von Rechenzentrums-/Cloud-IPs gibt Google normalerweise eine "Bitte JavaScript aktivieren"-Weiterleitungsseite (
/httpservice/retry/enablejs) mit null parsebaren Ergebnissen zurück – die Engine zeigt dies als weichen Fehlschlag an, und die Auto-Kette fällt durch. Von Residential-IPs funktioniert das HTML-Scraping von Google oft einwandfrei. - Aktualität:
tbs=qdr:d|w|m|yBucket. - Am besten für: letzter Ausweg-Fallback auf Residential-IPs; wird auf Cloud-IPs normalerweise fehlschlagen (wo DDG+Bing den Bedarf bereits decken).
Auto-Fallback-Strategie
Wenn engine: "auto" (Standard), probiert der Orchestrator Engines in dieser Reihenfolge:
- DuckDuckGo – am wenigsten aggressives Blockieren, feinstmöglicher Datumsfilter
- Bing – normalerweise stabil von jeder IP, einschließlich Rechenzentrum
- Google – beste Ergebnisqualität, wenn erreichbar; oft auf Rechenzentrums-IPs blockiert
Es wird die erste Engine zurückgegeben, die ≥ 1 Ergebnis liefert. Wenn alle drei fehlschlagen, ist das Ergebnis { success: false, errors: [...] } mit den Fehlern jeder Engine – oder, im searchOrThrow-Modus, ein AllEnginesFailedError.
Praktische Zuverlässigkeitstabelle (während des Testens beobachtet):
| IP-Typ des Aufrufers | DDG | Bing | Effektive Auto-Kette | |
|---|---|---|---|---|
| Residential | hoch | hoch | mittel | DDG → Bing → Google (3 nutzbar) |
| Rechenzentrum / Cloud | mittel (Ratenbegrenzung unter Last) | hoch | niedrig (enablejs-Wand) | effektiv DDG → Bing |
Die Reihenfolge ist in src/engines/index.ts (AUTO_ENGINE_ORDER) definiert; bearbeiten Sie dieses Array, wenn Sie eine andere Priorität wünschen.
Häufige Anwendungsfälle
- Echtzeit-Informationen – Aktuelle Nachrichten, Aktienkurse, Wetter, Sportergebnisse
- Neueste Dokumentation – Framework-Release-Notizen, API-Änderungen, kürzlich veröffentlichte Arbeiten
- Faktenprüfung – Überprüfen einer Behauptung anhand von Live-Webquellen
- Recherche – Sammeln mehrerer Quellen zu einem Thema, Vergleichen von Perspektiven
- Inhaltsentdeckung – Finden von Tutorials, Blogbeiträgen, aktuellen Vorträgen
- Wettbewerbs- / Marktanalyse – Ankündigungen von Wettbewerbern, Branchentrends
- Akademische Suche – Finden von Arbeiten, Zitaten, Autorenseiten
Fehlerbehebung
Keine Ergebnisse von einer bestimmten Engine
- DuckDuckGo: Wenn Sie viele Anfragen schnell hintereinander senden, erhalten Sie möglicherweise vorübergehend leere Ergebnisse. Warten Sie einige Sekunden oder wechseln Sie zu einer anderen Engine.
- Bing: Überprüfen Sie Ihre Locale-Einstellung. Verwenden Sie
--locale en-US, um englische Ergebnisse zu erzwingen, wenn Sie sich außerhalb der USA befinden. - Google: Von Rechenzentrums-IPs wird Google fast immer blockiert. Verwenden Sie stattdessen DDG oder Bing, oder führen Sie den Skill von einer Residential-IP aus.
Timeout-Fehler
Erhöhen Sie den Timeout-Wert mit --timeout <ms> (Standard: 8000ms). Einige Engines können bei komplexen Abfragen oder unter Last länger brauchen.
JSON-Ausgabeformat
Wenn Sie --json verwenden, wird die Ausgabe als JSON-Array von Objekten formatiert. Verwenden Sie --pretty, um die Lesbarkeit zu verbessern (standardmäßig aktiviert).
Lizenz
MIT