Architektur
Wie eine Recherchekampagne abläuft und was Ihren Rechner durch welche Tür verlässt, mit der Code-Datei hinter jeder Zeile.
Wie eine Recherchekampagne abläuft
manifest.json
│ campagne.py
▼
SearXNG ── Anfragen
▼
leichter HTTP-Abruf ──► echter Browser (nur wenn die Seite nicht reicht)
▼
collecte.jsonl + operations.jsonl
▼
OpenCode ── Rangfolge, dann der Bericht
▼
rapport_<Zeitstempel>.md
- Das Manifest ist eine JSON-Datei mit Zielen: eine
queryfür SearXNG, eine festeurl, einproduit(die eine Seite finden, die wirklich die Produktseite ist) oder einetable_reference(eine Liste vertrauenswürdiger Domains zu einem Thema). Pflicht sind nur die Kennung der Kampagne und die Ziele. - Die Suche. Ein
query-Ziel geht an die SearXNG-Instanz, die Sie konfiguriert haben; sie fragt ihrerseits andere Suchmaschinen ab, auf die Dinoer keinen Einfluss hat. - Die Erfassung. Jede Seite wird mit einer einfachen HTTP-Anfrage
abgerufen, nachdem ihre
robots.txtgelesen wurde. Nur eine Seite, deren Text sich so nicht lesen lässt, geht an einen echten Browser, ein Playwright-Prozess pro Seite. Ein Ziel, das scheitert, hält die anderen nicht auf. - Der Korpus. Eine
collecte.jsonlpro Kampagne, eine Zeile pro behaltener Seite, undoperations.jsonl, die jeden Versuch festhält, gescheitert oder nicht. - Der Bericht. Die Seiten werden neu geordnet (nach Zeitraum und nach
lokalen Embeddings, wenn das Manifest es verlangt), auf ein Größenbudget
gekürzt und an OpenCode übergeben, das den Hauptteil von
rapport_<Zeitstempel>.mdschreibt. Die Quellenliste hängt Dinoer selbst an; das Modell schreibt sie nie.
shot.py und rpa.py arbeiten anders: Jeder Aufruf ist ein eigener Prozess,
der endet, sobald er geantwortet hat. Warum →
Was Ihren Rechner verlässt, und durch welche Tür
| Was | Wohin | Wer entscheidet | Im Code |
|---|---|---|---|
| Suchanfragen | die SearXNG-Instanz, die Sie konfiguriert haben, die ihrerseits andere Suchmaschinen abfragt | Sie, mit DINOER_SEARXNG_URL | lib/searxng.py |
| Seitenabrufe | jede Website direkt, nach dem Lesen ihrer robots.txt | die Ziele in Ihrem Manifest | lib/fetch_leger.py, rpa.py |
| Erfasster Text | das OpenCode-Modell, das Sie benennen: für den Bericht, für die gezielte Extraktion und für die Wahl einer Produktseite (die ersten 1.500 Zeichen jedes Kandidaten) | Sie, mit DINOER_OPENCODE_MODEL | lib/modeles.py, lib/synthese.py, lib/extraction.py, lib/selection_candidats.py |
| Ein Thema, für eine Referenztabelle | dasselbe OpenCode-Modell, nur das Thema, wenn es dafür noch keine Tabelle gibt | das Ziel table_reference | lib/tables_reference.py |
| Embeddings | Ihr lokales Ollama, http://localhost:11434: Der Text bleibt auf dem Rechner, außer Sie richten DINOER_OLLAMA_URL anderswohin | Sie | lib/vector.py |
| Eine Benachrichtigung | ein ntfy-Server, https://ntfy.sh, sofern Sie keinen anderen angeben: die Kennung der Kampagne und die Zahl der Quellen. Nur wenn ein ntfy-topic gesetzt ist | Sie, mit ntfy_topic, DINOER_NTFY_TOPIC, DINOER_NTFY_URL | campagne.py, lib/ntfy.py |
| Ihre Zugangsdaten | nirgendwohin: im Playwright-Prozess aus dem verschlüsselten Verzeichnis aufgelöst | – | lib/repertoire_chiffre.py |
Quelle: der Code der Version 1.0.1, gelesen am 27. September 2026. Die Modelle
unter opencode/ werden von ihrem Anbieter gehostet (opencode.ai/zen, laut
opencode models --verbose, OpenCode 1.18.32). Was das Modell im Web darf,
steht auf der Seite zum Vertrauen.