CommunityRecherche & Datenanalysegithub.com

Legwork – Entscheidungs-Recherche

Entscheidungs-Recherche-Skill für Claude Code und Codex – jede Behauptung gibt an, wie gut sie gestützt wird, und sagt, wenn die Beweise sie nicht klären können. Ein kostenloses Tool von DBHQ.

Was ist Legwork – Entscheidungs-Recherche?

Legwork ist ein spezieller Skill für KI-Agenten wie Claude Code und Codex, der Entscheidungs-Recherche (keine akademische Forschung) durchführt. Im Gegensatz zu herkömmlichen Deep-Research-Tools geht es nicht um Vollständigkeit, sondern darum, eine klare, handlungsleitende Antwort auf die Frage „Was sollen wir tun?“ zu liefern. Der Skill arbeitet in vier Stufen (Quick, Standard, Deep), wobei Standard die Voreinstellung ist. Er verfügt über einen mehrstufigen Abrufmechanismus (von kostenlosen Web- und Plattformsuchen bis hin zu kostenpflichtigen Bright-Data-Fallbacks) und bewertet Behauptungen nicht nach der Autorität der Quelle, sondern danach, ob die Quelle die richtige Art von Beleg für die Behauptung liefert. Ein zentrales Prinzip ist der Autonomie-Gedanke: Der Skill startet selbstständig, fragt den Benutzer nicht blockierend, und hält die Ergebnisse klar und prägnant, selbst wenn die Antwort lautet, dass die Frage nicht beantwortet werden kann. Legwork wird über SKILL.md konfiguriert und kann in Agentensystemen wie Claude Code und Codex (OpenAI) direkt eingesetzt werden. Es ist Open Source und wurde von DBHQ entwickelt.

Funktioniert mit✓Claude Code✓Codex CLI~Cursor
npx skills add dbhq-uk/legwork-skill

Installed? Explore more Recherche & Datenanalyse skills: affaan-m/uspto-database, affaan-m/scholar-evaluation, affaan-m/literature-review · View all 6 →

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

Legwork

Wofür dies gedacht ist

Entscheidungs-Recherche. Nicht akademische Forschung. Die Frage ist immer eine Variante von „Was sollen wir bezüglich X tun?“, und das Ergebnis wird danach beurteilt, ob es brauchbar ist, nicht ob es erschöpfend ist.

Das prägt alles unten. Eine Behauptung wird danach beurteilt, ob ihre Quelle die richtige Art von Quelle für diese Behauptung ist, nicht danach, ob ihr Fachgebiet angesehen ist. Drei übereinstimmende Quellen zählen nur, wenn sie hätten widersprechen können. Und ein Durchlauf, der die Frage nicht beantworten kann, sagt dies, anstatt abgewogene Längen zu produzieren.

Autonomieprinzip. Leite aus dem Kontext ab, was du brauchst, wähle eine Stufe und beginne. Gib die Stufe in einer Zeile bekannt und fahre fort; frage den Benutzer nicht, eine Wahl zu treffen. Der Benutzer kann den Lauf zwischendurch umleiten, was weit weniger kostet als eine blockierende Frage bei jeder Anfrage. Stoppe nur bei einem kritischen Fehler oder einer unverständlichen Anfrage.

Stufen

Tiefe erhöht die Sorgfalt. Sie erhöht niemals die Länge.

schnellstandardtiefgehend
RahmenEntscheidung plus 2–3 UnterfragenPlus benannte FalsifikatorenPlus Second-Order-Perspektiven
SammelnSERP-Schnipsel; Abruf nur, um eine Zahl zu fixierenDirekter Abruf der wichtigsten Quellen pro ErkenntnisEine Primärquelle pro Erkenntnis
HinterfragenNur UnabhängigkeitsgruppierungEine widerlegende Suche pro ErkenntnisPro Erkenntnis widerlegender Durchlauf plus Herkunftsprüfung
Formatkurzkurz oder BerichtBericht
Gate-Stufe--level quick--level standard--level deep
Ungefähre Zeit3–5 Min8–12 Min20–40 Min

Standard ist die Voreinstellung standard. Verwende die vom Benutzer genannte Stufe (quick, standard, deep oder ein Äquivalent wie „schnelle Suche“ oder „tief gehen“), ansonsten $LEGWORK_DEFAULT_MODE, ansonsten standard. „Deep Research“ allein ist ein Aufrufbegriff für diesen Skill, keine Anfrage für die tiefgehende Stufe – falle auf die Standardeinstellung zurück.

Eskaliere stillschweigend um eine Stufe, wenn die Abgrenzung ergibt, dass die Frage materiell höhere Einsätze hat, als die Anfrage implizierte, und gib dies in derselben Eröffnungszeile an.

Eröffnungszeile, dann direkt in Phase 1:

Führe standard aus (~8–12 Min). Sage „tief“ für Primärquellen und einen widerlegenden Durchlauf.

Pipeline

Vier Phasen. Vollständige Anweisungen in methodology.md.

  1. Rahmen – Benenne die Entscheidung, die Unterfragen, die sie klären würden, und welche Beweise die Antwort ändern würden.
  2. Sammeln – Rufe für jede Unterfrage ab und protokolliere jeden Abruf.
  3. Hinterfragen – Suche den widerlegenden Fall; gruppiere Quellen nach Unabhängigkeit.
  4. Schreiben – Erstelle das Ergebnis, dann führe die Qualitätsprüfung durch.

Die Phasen 2 und 3 werden pro Erkenntnis verschränkt, anstatt als strenge Tore zu laufen.

Bevor du beginnst

Verankere das Datum. Führe date -u +%Y-%m-%d aus und verwende diese Zeichenfolge für den Lauf, im Ausgabeordnernamen und in jeder Suchanfrage, die datiertes Material zurückgeben könnte. Verlasse dich niemals auf dein eigenes Wissen, welches Jahr es ist, und lasse niemals einen Unteragenten dies selbst herausfinden.

Überprüfe, ob dieser Lauf bereits durchgeführt wurde. Lies zuerst den Index. Er ist ein Verteiler: eine Zeile pro vergangenem Lauf, und die Einzeiler-Spalte existiert, damit du entscheiden kannst, ob du einen Bericht öffnen möchtest, ohne dafür zu bezahlen.

python3 ${CLAUDE_SKILL_DIR}/scripts/index.py list --base "$OUTPUT_BASE"

Wähle dann einen von vier Pfaden und gib in deiner Eröffnungszeile an, welchen:

Der Index sagtTue dies
Ein Lauf deckt dies ab und ist nicht veraltetAntworte daraus. Lies diesen Bericht, nicht das Internet.
Ein Lauf deckt dies ab, ist aber als veraltet markiertAktualisiere ihn
Ein Lauf ist nah dran, beantwortet aber eine andere FrageNeuer Lauf und verweise darauf
Nichts passtNeuer Lauf

Aus einem früheren Lauf zu antworten ist ein Erfolg, keine Abkürzung. Öffne den Bericht, lies die Erkenntnisse, die für die Frage relevant sind, und antworte mit ihren Konfidenzbereichen intakt. Sage klar, dass es von einem Lauf eines bestimmten Datums stammt. Bereits durchgeführte und noch gültige Forschung erneut durchzuführen ist die Verschwendung, die dieser Index verhindern soll.

Aktualisieren statt erneutes Durchführen

Eine Aktualisierung aktualisiert den vorhandenen Bericht an Ort und Stelle – gleicher Ordner, gleiche Datei. Erstelle keinen zweiten Ordner: Zwei Ordner, die eine Frage beschreiben, führen dazu, dass ein Leser basierend auf dem handelt, den er zufällig geöffnet hat.

  1. Nimm das Abrufprotokoll wieder auf, anstatt ein neues zu starten. Alles darin ist bereits bezahlt.

    python3 ${CLAUDE_SKILL_DIR}/scripts/sources.py resume --tsv "$OUT/$BASE.tsv"
    

    Dies gibt die bereits bearbeiteten Blickwinkel, die bereits abgerufenen Seiten und welche davon noch kein Zitat enthalten. Bearbeite die nicht abgedeckten Blickwinkel und überprüfe die Behauptungen, die die Antwort entscheiden; rufe nicht erneut ab, was bereits aufgezeichnet und aktuell ist.

  2. Verschiebe jede Behauptung, die jetzt falsch ist, in ## Überholt mit dem Datum und dem Grund. Lösche niemals eine Behauptung stillschweigend. Jemand könnte auf sie reagiert haben, und ein zukünftiger Lauf muss wissen, dass dieses Terrain bereits abgedeckt wurde. Wenn dieselbe Antwort jetzt zweimal widerlegt wurde, sage dies laut – das ist das stärkste Signal im Dokument, dass die Frage instabil ist.

  3. Füge eine ## Zeitleiste-Zeile hinzu, die besagt, was sich geändert hat.

  4. Aktualisiere die Indexzeile.

Den Lauf ablegen

Jeder Lauf endet im Index, auch einer, der die Frage nicht beantworten konnte – „wir haben nachgeschaut und nichts gefunden“ ist genau das, was eine zukünftige Sitzung braucht, um nicht noch einmal nachzusehen.

python3 ${CLAUDE_SKILL_DIR}/scripts/index.py add --base "$OUTPUT_BASE" \
  --folder "$BASE" --topic "Outlook-Triage für kleine Praxen" --level deep \
  --one-liner "Keine native Triage unter E5; die Lücke ist real, aber schmal"

Der Einzeiler sagt, was der Lauf geschlussfolgert hat, nicht, worum es ging. „Notizen zur Plugin-Galerie“ ist in sechs Monaten nutzlos; „Es gibt keinen Übermittlungsweg, die Installation erfolgt per URL oder gar nicht“ beantwortet die Frage von selbst. Das Gate warnt, wenn ein Lauf in einem vorhandenen Index fehlt.

Abrufstrategie

Zwei Leitern, zuerst kostenlose Sprossen. Klettere nur so weit, wie du musst.

Zum Suchen:

SprosseAufrufWann
1WebSearchImmer. Drei Suchbegriffvarianten pro Blickwinkel.
2platforms.py search --on ...Die Antwort ist ein Datensatz, den eine Plattform hält: ein Thread, ein Paket, ein Repository, ein datierter Nachrichtenartikel, ein Änderungsprotokoll eines Anbieters. Kostenlos, schlüssellos, und gibt den Datensatz zurück, nicht eine Seite darüber.
3bd_search.py -m general --engine bing --country XX --language yyWenig nach drei Varianten, oder die Frage ist geografisch spezifisch. Eine zweite Engine ist der Grund zu zahlen.
4bd_search.py -m discover --intent "..."Zwei Engines sind immer noch wenig.

Zum Öffnen einer Seite:

SprosseAufrufWann
1fetch.py "<url>" --find "Begriff"Immer zuerst. Kostenlos und die einzige kostenlose Übertragung, die Seitentext liefert, sodass Zahlen nachvollziehbar und Zitate überprüfbar sind.
2WebFetchfetch.py beendete mit 3 und die Seite ist es nicht wert, zu zahlen.
3bd_search.py "<url>" -m scrapeBlockiert: Bot-Schutz, Paywall, 403-Fehler.
4bd_search.py "<url>" -m renderEine clientseitig gerenderte Hülle.
5bd_search.py "<url>" -m pipeline --pipeline NAMEEine Plattform, die alles oben blockiert. Wird pro Datensatz abgerechnet; -m reddit ist der Fall, in dem dies die einzige Route ist, nicht eine letzte Möglichkeit.

Führe platforms.py list für die zehn kostenlosen Plattformen und bd_search.py --help für die kostenpflichtigen Modi aus. Bei Exit-Code 2 (Authentifizierung oder Kontingent) sage dem Benutzer, brightdata login auszuführen. Wiederhole nicht.

Ein Suchergebnis ist ein Hinweis, keine Seite, die du liest. Bei „standard“ und „tiefgehend“ öffne, was du zitierst: Das Gate behandelt ein Zitat, das nur auf websearch-Zeilen beruht, als nicht geöffnet – eine Warnung bei „standard“ und ein Fehler bei „tiefgehend“. „Quick“ ist von Natur aus snippet-first und wird nicht verlangt.

Protokolliere den Fehler vor dem Fallback. Eine Seite, die sich nicht öffnen ließ, ist ein Beweis für den Lauf – --status blocked – und die Quittung zählt ihn.

Begrenze, was du abrufst. --max-chars 8000 bei Scrape-Aufrufen, und bevorzuge --find gegenüber einer blinden Begrenzung: Auf einer langen Seite sind die ersten achttausend Zeichen normalerweise die Navigation.

Welche Quellen du verwenden darfst

Recherche ist das, was ein Außenstehender feststellen könnte. Diese Grenze ist in beide Richtungen wichtig.

Präsentiere niemals die eigenen Aufzeichnungen des Benutzers als eine Erkenntnis. Wenn die Frage das eigene Unternehmen des Benutzers, sein Produkt oder seine Marktposition betrifft, greife nicht auf seine privaten Konten zu – seinen Registrar, seine Abrechnung, seinen Posteingang, seine internen Dateien – und berichte nicht, was du dort gefunden hast, als wäre es entdeckt worden. Er weiß es bereits. Es ist zirkulär, es bläht die scheinbare Evidenz auf, und es verschleiert, wie wenig ein Außenstehender tatsächlich sehen kann. Suche nach dem öffentlichen Äquivalent und berichte, was ein Außenstehender finden würde, einschließlich nichts.

Nutze exklusiven Zugang, den dir der Benutzer gewährt hat, bei Dritten. Ein bezahltes Abonnement, ein privater Datensatz oder eine interne Datenbank, die der Benutzer ausdrücklich angeboten hat, ist ein echter Vorteil bei der Recherche von Wettbewerbern, Lieferanten oder einem Markt. Nutze es, protokolliere es wie jede andere Quelle und vermerke in den Einschränkungen, dass die Erkenntnis auf Zugang beruht, den der Leser möglicherweise nicht hat.

Wenn sich herausstellt, dass eine Einheit überhaupt keinen öffentlichen Fußabdruck hat, ist dies die Antwort. Liste auf, was du überprüft hast, sage, dass Existenz oder Umfang von außen nicht verifiziert werden konnten, und fülle die Lücke nicht aus privilegiertem Zugang. Es ist die Form „konnte nicht antworten“ auf eine einzelne Einheit angewendet, nicht auf die gesamte Frage.

Das Abrufprotokoll

Jeder Abruf, auf jeder Stufe, fügt eine Zeile hinzu:

python3 ${CLAUDE_SKILL_DIR}/scripts/sources.py log \
  --tsv "$OUT/$BASE.tsv" \
  --url "https://acme.example/pricing" \
  --kind vendor_pricing \
  --angle "Was verlangt der etablierte Anbieter?" \
  --via webfetch \
  --date 2026-07-01 \
  --title "Preise" \
  --quote "Team-Plan: 30 US-Dollar pro Benutzer und Monat, jährlich abgerechnet." \
  --text-file /tmp/page.txt

Zwei Felder tragen die Hauptlast, und keines kann von nachgeschalteten Prozessen überprüft werden.

--angle ist die Unterfrage, die dieser Abruf beantwortete. Bestätigung wird nach Blickwinkeln und nicht nach Quellen gezählt, weil die eigene Aufteilung von Legwork die Quellenanzahl aufbläht. Protokolliere den Blickwinkel ehrlich – die Wiederverwendung einer Zeichenfolge über einen Lauf hinweg zerstört stillschweigend die Überprüfung, und kein Skript kann erkennen, dass du dies getan hast.

--quote ist der wörtliche Satz, der die Quelle zitierenswert machte. Protokolliere einen für jede Quelle, die du zu zitieren beabsichtigst, während du sie liest. Ungefähr die Hälfte aller Erkenntnisse enthält keine Zahl, daher ist das Zitat für diese der einzige Beweis, den es gibt, und es ist der einzige Teil, der die Änderung der Seite überlebt. Wenn der Seitentext auf der Festplatte ist – alles, was mit fetch.py geöffnet wurde, oder ein -m scrape mit --out – wird das Zitat dagegen überprüft, und quote_verified: false bedeutet, dass du die Seite falsch zitiert hast.

--from-fetch füllt die URL, den Titel, das Datum und den Seitentext aus dem Sidecar, das diese beiden schreiben, sodass nichts neu eingegeben werden muss:

python3 ${CLAUDE_SKILL_DIR}/scripts/sources.py log --tsv "$OUT/$BASE.tsv" \
  --from-fetch /tmp/legwork/ab12cd34ef56.json \
  --angle "Was verlangt der etablierte Anbieter?" --kind vendor_pricing \
  --query "site:acme.example pricing" --quote "Team-Plan: 30 US-Dollar ..."

sources.py log --help deckt den Rest ab: --via Transporte (einschließlich api, local und mcp), --text-file numerische Extraktion, --kind. Protokolliere den Transport, den du tatsächlich verwendet hast – das erneute Abrufen einer Seite über einen anderen, um sie protokollierbar zu machen, verzerrt die Spur, anstatt sie aufzuzeichnen. sources.py kinds gibt aus, welche Quellenarten zu welchen Behauptungen passen.

Unteragenten

Der Abruf ist die eine Phase, die sich für Parallelisierung lohnt, ein Unteragent pro Blickwinkel. Weise sie ein mit subagent-brief.md, das die Vorlage wörtlich, die erforderliche Rückgabeform und den Grund für jede Zeile enthält. Ein Unteragent hat keinen Kontext, daher muss alles, was er benötigt, in der Aufgabenbeschreibung stehen.

Drei Dinge bleiben bei dir und nicht in der Aufgabenbeschreibung:

  • Passe das Modell an die Form des Blickwinkels an. Das Sammeln von Schnipseln und das Fixieren einer bekannten Zahl laufen gut auf einem billigen Modell – übergib die Überschreibung explizit, lass niemals einen Unteragenten versehentlich das Sitzungsmodell erben. Aber die Quellenarbeit auf tiefgehender Stufe und alles, was eine Aufzählung rekonstruiert, bleibt auf dem Modell des Orchestrators. Gemessen: In einem Vergleich öffneten Orchestratoren 3, 8 und 32 Anbieterseiten in der günstig-bis-fähigen Spanne, und nur das schwächste füllte jede Zelle des Rasters von einem einzigen Aggregator aus, während es Erfolg meldete.
  • Füge niemals das Transkript eines Unteragenten in deine Synthese ein. Nimm die strukturierte Rückgabe, überprüfe, ob die Blickwinkelzeichenfolge unverändert zurückkam, protokolliere jede Zeile und arbeite vom Protokoll aus.
  • Abgrenzung, Hinterfragen und Synthese sind Urteilsentscheidungen. Sie bleiben beim Hauptmodell.

Skripte

Alle reine Standardbibliothek. Keine virtuelle Umgebung. Jeder python3 >= 3.9.

SkriptZweck
fetch.py "<url>" --find BEGRIFFÖffne eine Seite kostenlos und behalte ihren Text; beendet mit 3 bei Blockierung oder leerer Seite
platforms.py list | search --on XZehn kostenlose plattformnative Quellen, die Datensätze statt Seiten zurückgeben
sources.py kinds | log | scoreQuellenarten-Vokabular, das Abrufprotokoll, Eignungsbewertung pro Behauptungsart
sources.py receiptDie Abrufzahlen für die Quittungszeile, aus dem Protokoll entnommen
sources.py stale --claim-kind KWelche protokollierten Quellen abgelaufen sind, basierend auf der Halbwertszeit dieser Behauptungsart
sources.py resumeWas ein vorheriger Lauf bereits abgerufen hat, damit ein erneuter Lauf es überspringt
independence.py groups | checkReduziere Quellen auf unabhängige Stimmen; zähle blickwinkelbewusste Bestätigung
independence.py portfolioQuellenkonzentration über den gesamten Lauf hinweg, nicht innerhalb einer Erkenntnis
index.py add | listDer Forschungsindex – einen Lauf ablegen, einen vergangenen finden, veraltete erkennen
matrix.py check --report PFADVollständigkeit einer Vergleichsmatrix
check.py --report PFAD --level STUFEDas Versandqualitäts-Gate
finish.py --report PFAD --level STUFEGate, Veralterungsdurchlauf und Ablage in einem Aufruf
`bd_search.py "<abfrageurl>" -m MODUS --json`

Ausgabe

Löse das Ausgabebasisverzeichnis einmal zu Beginn des Laufs auf:

OUTPUT_BASE="${LEGWORK_OUTPUT:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)/docs/research}"
BASE="[Thema]_Research_$(date +%Y%m%d)"
OUT="$OUTPUT_BASE/$BASE"; mkdir -p "$OUT"

…

[gekürzt für die Übersetzung]

Verwandte Skills