Eine Forschungskampagne durchführen
Ein Manifest, ein delegiertes Modell, das in der Datei opencode.jsonc enthalten ist, und ein Bericht, der jeden Anspruch auf eine tatsächlich erfasste Seite zurückverfolgt. Die Anleitung für campagne.py – die eigentliche Hauptanwendung des Tools.
campagne.py ist eine Schicht oberhalb des bestehenden Browser-Kerns und ersetzt ihn nicht: Die Suchmaschinen-Funktionalität von SearXNG, eine leichte HTTP-Sammlung, die Eskalation zu rpa.py/shot.py erfolgt nur für Seiten, die dies benötigen, und ein Bericht, der von einem delegierten Modell erstellt wird, basierend auf dem, was tatsächlich gesammelt wurde.
python3 /opt/dinoer/campagne.py --manifeste manifeste.json
Das Manifest
Nur id_campagne und cibles sind erforderlich – alles andere hat einen Standardwert.
{
"id_campagne": "concerts-finistere-2026-07-28",
"cibles": [
{"type": "query", "valeur": "concerts finistere sud ete"},
{"type": "url", "valeur": "https://exemple.fr/agenda"},
{"type": "produit", "valeur": "boulangerie Corentin a Quimper", "max_candidats": 5},
{"type": "table_reference", "valeur": "mairies du Finistere sud", "cle_thematique": "mairies_finistere_sud"}
],
"max_resultats": 15,
"max_pages_par_hostname": 3,
"delai_min_secondes": 4.5,
"delai_max_secondes": 8.5,
"revisite_apres_jours": 30
}
Vier Zieltypen: query (eine SearXNG-Suche), url (eine feste Seite), produit
(Entdecken und Vergleichen von Kandidaten für einen bestimmten Begriff), table_reference (Erstellen
oder Erweitern einer persistenten, referenzierten Tabelle bekannter Seiten zu einem Thema).
Jedes Ziel ist ein vollständig isolierter Aufruf – das Scheitern eines Ziels beeinträchtigt niemals die anderen, im Gegensatz zu einer einzigen Szenario-Aktionsliste, die beim ersten Fehler stoppt.
Zwei Artefakte, zwei Zwecke
operations.jsonl (gemeinsam, nur zum Anhängen) protokolliert jeden Versuch, ob erfolgreich oder nicht, mit dem Tag intention="dinoer-campagne" – derselbe Protokollierungsmechanismus, den auch alle anderen Dinoer-Tools verwenden.
<campaigns_dir>/<id_campagne>/collecte.jsonl (pro Kampagne, neu) enthält
eine Zeile pro erfolgreicher Extraktion. Dies ist das Artefakt, aus dem der Bericht erstellt wird, und es ist die Information, anhand derer Sie überprüfen können, ob ein bestimmter Eintrag tatsächlich auf einer erfassten Seite zu finden ist.
Sortiere den automatischen Bericht neu, bevor er abgeschnitten wird
Der Standardbericht verkettet den Korpus in der Reihenfolge des Dateischreibens und kürzt ihn auf 60.000 Zeichen – ohne Rangordnung. Zwei optionale Manifestfelder beheben dies, beide ordnen neu an, keiner schließt etwas aus:
{
"motifs_annee": ["2026"],
"motifs_mois": ["août", "aout", "/08", "-08-"],
"sujet_synthese": "concerts and festivals, south Finistère, summer 2026"
}
motifs_annee/motifs_mois ist ein textbasierter Durchlauf ohne Modellaufrufe – Seiten, die
eindeutig den angeforderten Inhalt nicht enthalten, werden bis zum Ende sortiert, einschließlich
numerischer Datumsformate, die einige Agenda-Widgets anstelle eines ausgeschriebenen Monats verwenden.
sujet_synthese ist ein semantischer Durchlauf – ein gruppierter Ollama-Embedding-Aufruf,
der Seiten nach ihrer Cosinus-Ähnlichkeit zu diesem Satz bewertet. Verwenden Sie beide, nicht nur einen.
Bei einer echten Referenzkampagne ließ der textbasierte Durchlauf allein immer noch eine tatsächlich
relevante PDF-Datei an 27. Stelle von 29 “wahrscheinlichen” Seiten – also außerhalb des
Beschneidungslimits. Der semantische Durchlauf verschob sie innerhalb dieses Limits. Gemessen anhand
dieses Korpus, nicht aufgrund von Annahmen.
Eine offene Frage ist besser als eine enge Frage
Für eine einzelne, gezielte Extraktion außerhalb einer vollständigen Kampagne:
python3 /opt/dinoer/campagne.py --extraire-cible "<demande>" \
--id-campagne <id> --format-extraction markdown
--extraire-cible akzeptiert jede Anfrage in natürlicher Sprache – nicht nur eine strikte
trouve/valeur/url Faktenabfrage. Bei einer echten Referenzkampagne ermöglichte eine offene,
beschreibende Frage dem delegierten Modell selbst zu beurteilen, ob es
eine einzelne Tatsache oder ein mehrstufiges Ereignis las: 17 von 47 Anfragen ergaben
positive, detailliertere Ergebnisse als die engere Formulierung auf demselben Korpus.
Für Ergebnisse, die dasselbe reale Ereignis auf mehreren Seiten beschreiben,
lib/extraction.py::fusionner_evenements() gruppiert diese – nennen wir es “Gruppierung” – und zwar bei den
gefilterten positiven Ergebnissen, bevor ein abschließender Bericht erstellt wird, anstatt
diese manuell zusammenzufassen. Eine einzelne Quelle, die mehrere
unterschiedliche Ereignisse korrekt beschreibt, ist kein Fehler; dieselbe Quelle wird in jeder Gruppe zitiert, zu der sie gehört.
Der Korpus ist das, was dem Modell erlaubt ist, zu generieren
Dinoer verweigert dem delegierten Modell seine eigenen
websearch/webfetch Tools für den gesamten Syntheseprozess, unabhängig vom Verzeichnis, aus dem die Kampagne gestartet wird (opencode.jsonc im Repository-Wurzelverzeichnis sagt dasselbe, und OPENCODE_CONFIG_CONTENT trägt sie bei jedem Aufruf) –
ohne diese würde eine einzelne Ausführung zwölf eigene, unsichtbare Suchvorgänge durchführen,
die im zurückgegebenen Text nicht sichtbar sind. Der vollständige Bericht, einschließlich dessen, was er nicht abdeckt →
Die Zielgruppe respektieren, im großen Maßstab einer Kampagne
delai_min_secondes/delai_max_secondes Nach jeder rechercher() Anforderung wird eine Pause eingelegt, nicht
nur bei den nachfolgenden Seitenabrufen – eine echte Kampagne fand diesen Fehler auf die harte Tour heraus, und er wurde überall behoben, wo diese Verzögerung nun gelten soll.
revisite_apres_jours (standardmäßig 30) verhindert, dass eine Kampagne eine
Seite erneut abruft, nur weil ein späteres Ziel sie erneut referenziert.
Das gleiche Prinzip, vollständig →
Der Vektorsuch-Cache
lib/cache_recherche.py, ChromaDB-gestützt, vermeidet erneute Abfragen für
nahezu identische Anfragen. --desactiver-cache überspringt ihn für einen Durchlauf;
--purger-cache oder --purger-cache-avant-jours N leeren ihn explizit.
Kurz gesagt
- Nur
id_campagneundciblessind erforderlich; alle anderen Felder haben einen dokumentierten Standardwert. - Vier Zieltypen:
query,url,produit,table_reference. collecte.jsonlist das Artefakt, auf das eine Behauptung zurückverweist – lesen Sie es, vertrauen Sie dem Bericht nicht allein.motifs_annee/motifs_moisplussujet_synthesezusammen, nicht entweder allein, beheben die blinde Stelle der Standardberichterstellung.- Eine offene
--extraire-cibleFrage übertrifft eine enge Faktenabfrage bei echten Korpora. opencode.jsoncist das, was den Bericht nachvollziehbar zum Korpus macht – lesen Sie seine tatsächliche Grenze, nicht nur sein Versprechen.