Architektur
Warum Dinoer so aufgebaut ist, wie es ist: was es garantiert, was es ablehnt und wo seine Grenzen liegen – wobei diese Grenzen bereits einmal auf der Grundlage von Beweisen verengt wurden.
Wie eine Forschungskampagne abläuft
manifest.json
│ campagne.py
▼
SearXNG ── Suchanfragen
▼
einfacher HTTP-Abruf ──► echter Browser (nur wenn die Seite nicht genügt)
▼
collecte.jsonl + operations.jsonl
▼
OpenCode ── Rangfolge, dann Bericht
▼
rapport_<timestamp>.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). Nur die Kampagnenkennung und die Ziele sind Pflicht. - Entdeckung. Ein
query-Ziel geht an die SearXNG-Instanz, die Sie konfiguriert haben. Diese Instanz fragt ihrerseits andere Suchmaschinen ab, worauf Dinoer keinen Einfluss hat. - Sammlung. Jede Seite wird mit einer einfachen HTTP-Anfrage geholt, nachdem ihre
robots.txtgelesen wurde. Nur eine Seite, die nicht genügt, wird an einen echten Browser weitergereicht, ein Playwright-Prozess pro Aufruf. Ein Ziel, das scheitert, hält die anderen nicht auf. - Der Korpus. Eine
collecte.jsonlpro Kampagne, eine Zeile pro erfolgreicher Extraktion, undoperations.jsonl, das jeden Versuch festhält, ob erfolgreich oder nicht. - Der Bericht. Die Seiten werden geordnet (mit lokalen Embeddings, wenn Sie ein Thema angeben), auf ein Größenbudget gekürzt und an OpenCode übergeben, das den Text von
rapport_<timestamp>.mdschreibt. Die Quellenliste hängt Dinoer selbst an; das Modell schreibt sie nie.
shot.py und rpa.py sind anders: unabhängige Aufrufe, je ein Prozess, die enden, sobald sie geantwortet haben. Warum →
Was verlässt Ihre Maschine, und durch welchen Ausgang?
| Was | Wohin es geht | Wer entscheidet | Im Code |
|---|---|---|---|
| Suchanfragen | die SearXNG-Instanz, die Sie konfiguriert haben, die wiederum andere Suchmaschinen abfragt | Sie, mit DINOER_SEARXNG_URL | lib/searxng.py |
| Seitenanfragen | jede Website direkt, zuerst deren robots.txt | die Ziele in Ihrer Manifestdatei | lib/fetch_leger.py, rpa.py |
| Gesammelter Text | OpenCode’s Modell, standardmäßig gehostet, für den Bericht, für die gezielte Extraktion und zur Auswahl 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 | OpenCode’s Modell, nur das Thema, wenn noch keine Tabelle dafür existiert | das table_reference Ziel | lib/tables_reference.py |
| Embeddings | Ihr lokales Ollama, http://localhost:11434: der Text bleibt auf dem Rechner, es sei denn, Sie verweisen DINOER_OLLAMA_URL woanders hin | Sie | lib/vector.py |
| Eine Benachrichtigung | ein ntfy-Server, https://ntfy.sh es sei denn, Sie haben einen anderen festgelegt: die Kampagnen-ID und die Anzahl der Quellen, niemals der lokale Pfad des Berichts. Nur wenn ein ntfy-Thema festgelegt ist | Sie, mit ntfy_topic, DINOER_NTFY_TOPIC, DINOER_NTFY_URL | campagne.py, lib/ntfy.py |
| Ihre Anmeldedaten | nirgendwo: werden innerhalb des Playwright-Prozesses aus dem verschlüsselten Verzeichnis aufgelöst | – | lib/repertoire_chiffre.py |
Quelle: der Code der Version 1.0.1, gelesen am 25. September 2026. Die opencode/-Modelle werden gehostet: Dieser Anbieter antwortet unter opencode.ai/zen (laut opencode models --verbose, OpenCode 1.18.32). Was das Modell anschließend mit dem Web tun darf, steht auf der Vertrauensseite, samt der Grenze, die sie nicht abdeckt.