Arquitectura
Cómo se desarrolla una campaña de investigación y qué sale de su máquina y por qué puerta, con el archivo de código detrás de cada línea.
Cómo se desarrolla una campaña de investigación
manifiesto.json
│ campagne.py
▼
SearXNG ── consultas
▼
recopilación HTTP ligera ──► navegador real (solo si la página no basta)
▼
collecte.jsonl + operations.jsonl
▼
OpenCode ── clasificación, después el informe
▼
rapport_<marca_de_tiempo>.md
- El manifiesto es un archivo JSON de objetivos: una
querypara SearXNG, unaurlfija, unproduit(encontrar la página que de verdad es la del producto) o unatable_reference(una lista de dominios de confianza para un tema). Solo son obligatorios el identificador de la campaña y los objetivos. - La búsqueda. Un objetivo
queryva a la instancia de SearXNG que usted configuró, que a su vez consulta otros buscadores sobre los que Dinoer no tiene control. - La recopilación. Cada página se obtiene con una simple solicitud HTTP,
tras leer su
robots.txt. Solo una página cuyo texto no puede leerse así pasa a un navegador real, un proceso de Playwright por página. Un objetivo que falla no detiene a los demás. - El corpus. Un
collecte.jsonlpor campaña, una línea por página conservada, yoperations.jsonl, que registra cada intento, fallido o no. - El informe. Las páginas se reordenan (por periodo y por embeddings
locales, si el manifiesto lo pide), se recortan a un presupuesto de tamaño
y se entregan a OpenCode, que redacta el cuerpo de
rapport_<marca_de_tiempo>.md. Dinoer añade él mismo la lista de fuentes; el modelo nunca la escribe.
shot.py y rpa.py funcionan de otro modo: cada llamada es un proceso
propio, que termina en cuanto ha respondido. Por qué →
Qué sale de su máquina, y por qué puerta
| Qué | Adónde va | Quién decide | En el código |
|---|---|---|---|
| Las consultas de búsqueda | la instancia de SearXNG que usted configuró, que a su vez consulta otros buscadores | usted, con DINOER_SEARXNG_URL | lib/searxng.py |
| Las solicitudes de páginas | cada sitio directamente, tras leer su robots.txt | los objetivos de su manifiesto | lib/fetch_leger.py, rpa.py |
| El texto recopilado | el modelo de OpenCode que usted indique: para el informe, para la extracción dirigida y para elegir una página de producto (los primeros 1500 caracteres de cada candidata) | usted, con DINOER_OPENCODE_MODEL | lib/modeles.py, lib/synthese.py, lib/extraction.py, lib/selection_candidats.py |
| Un tema, para una tabla de referencia | el mismo modelo de OpenCode, solo el tema, cuando aún no existe tabla para él | el objetivo table_reference | lib/tables_reference.py |
| Los embeddings | su Ollama local, http://localhost:11434: el texto se queda en la máquina, salvo que dirija DINOER_OLLAMA_URL a otro sitio | usted | lib/vector.py |
| Una notificación | un servidor ntfy, https://ntfy.sh si no indica otro: el identificador de la campaña y el número de fuentes. Solo si hay un topic de ntfy definido | usted, con ntfy_topic, DINOER_NTFY_TOPIC, DINOER_NTFY_URL | campagne.py, lib/ntfy.py |
| Sus credenciales | a ninguna parte: se resuelven dentro del proceso de Playwright, desde el directorio cifrado | — | lib/repertoire_chiffre.py |
Fuente: el código de la versión 1.0.1, leído el 27 de septiembre de 2026. Los
modelos agrupados bajo opencode/ los aloja su proveedor (opencode.ai/zen,
según opencode models --verbose, OpenCode 1.18.32). Lo que el modelo puede
hacer en la web figura en la página sobre la confianza.