Files
glpi-neural-brain/SOURCE-AGENT-MODE.md
jbergner 440423c5b6
release-tag / release-image (push) Successful in 2m43s
RC-3
2026-08-09 11:29:13 +02:00

227 lines
12 KiB
Markdown

# Integrated Source-Agent mode
The same `neural-brain` binary and Docker image now has two runtime roles:
```env
BRAIN_MODE=brain
```
starts the full graph/AI application, while
```env
BRAIN_MODE=agent
```
starts only the distributed source poller. Agent mode does **not** initialize the graph, Ollama, SearXNG, GLPI sync, AI-THINK or article synthesis.
## Brain-side flow
The Brain owns Agent identities, source tasks and the Source Inbox in `source-agents.db`.
1. Open `/source-agents.html`.
2. Create an Agent. The plaintext token is returned exactly when it is created or rotated; only its SHA-256 hash is stored by the Brain.
3. Add RSS, Atom, sitemap or generic Web tasks and a polling interval.
4. The remote Agent obtains its task list from `GET /api/v1/agent/config`.
5. New documents are sent in batches to `POST /api/v1/agent/ingest`.
6. Documents enter the Inbox as `received`, not as graph nodes.
7. The Brain embeds a bounded Inbox batch and checks it against the existing KB. Relevant documents become `candidate`; weak matches become `archived`.
8. Adaptive article/reviewer research queries the `candidate` Inbox before SearXNG. For freshness-sensitive requests, only sufficiently recent Inbox documents are reused.
9. A Web document becomes a graph node only when a generated article actually grounds a supported claim in it. Then the Inbox row becomes `used`.
This deliberately separates `discovered` from `knowledge`.
## Agent bootstrap
Minimal remote Agent configuration:
```env
BRAIN_MODE=agent
BRAIN_AGENT_BRAIN_URL=https://brain.example.org
BRAIN_AGENT_ID=security-news-01
BRAIN_AGENT_TOKEN=brain_agent_...
```
Optional Agent settings:
```env
BRAIN_AGENT_CONFIG_REFRESH=5m
BRAIN_AGENT_HTTP_TIMEOUT=30s
BRAIN_AGENT_CONCURRENCY=3
BRAIN_AGENT_BATCH_SIZE=50
BRAIN_AGENT_ALLOW_PRIVATE=false
```
The Agent caches the last successful remote task configuration in its data volume. Source polling uses SSRF-safe DNS/redirect handling and rejects private, loopback and link-local targets by default; set `BRAIN_AGENT_ALLOW_PRIVATE=true` only for intentionally trusted intranet sources. This restriction applies to source URLs, not to the Brain control-plane URL, so the Brain itself may live on a private LAN.
A local bootstrap JSON can be used instead of the three connection ENV values:
```json
{
"brain_url": "https://brain.example.org",
"agent_id": "security-news-01",
"token": "brain_agent_..."
}
```
and:
```env
BRAIN_MODE=agent
BRAIN_AGENT_CONFIG_FILE=/run/secrets/brain-agent.json
```
## Source task schema
Example task returned by the Brain:
```json
{
"id": "microsoft-security",
"agent_id": "security-news-01",
"name": "Microsoft Security",
"type": "rss",
"url": "https://example.org/feed.xml",
"enabled": true,
"poll_interval": "2h",
"categories": ["Microsoft", "Security"],
"max_items": 20,
"config": {
"refetch_seen": "false"
}
}
```
Supported task types in v1 are `rss`, `atom`, `sitemap` and `web`. Set `config.refetch_seen=true` for sources whose existing URLs are expected to change (for example rolling advisories). Otherwise the Agent optimizes for discovery of new article URLs.
## Agent API permissions
Agent Bearer tokens are accepted only on:
- `GET /api/v1/agent/config`
- `POST /api/v1/agent/heartbeat`
- `POST /api/v1/agent/ingest`
- `GET /api/v1/agent/compute/claim`
- `POST /api/v1/agent/compute/{id}/result`
They are separate from `BRAIN_API_KEY` and do not authorize graph, runtime, research, THINK or administration APIs. Agent-management and Source-Inbox management endpoints use the normal `BRAIN_API_KEY` whenever it is configured.
## Source Inbox tuning
Brain-side defaults:
```env
BRAIN_SOURCE_INBOX_ENABLED=true
BRAIN_SOURCE_INBOX_INTERVAL=30s
BRAIN_SOURCE_INBOX_BATCH_SIZE=12
BRAIN_SOURCE_INBOX_MIN_SIMILARITY=0.55
BRAIN_SOURCE_INBOX_MIN_PRIORITY=0.55
BRAIN_SOURCE_INBOX_NOVELTY_FLOOR=0.35
BRAIN_SOURCE_INBOX_MIN_RESULTS=2
BRAIN_SOURCE_INBOX_FRESH_MAX_AGE=168h
```
Classification is deliberately cheap: one batched embedding operation plus the configured precise/clustered nearest-neighbour retrieval and deterministic freshness/task/advisory scoring. There is no Gemma/Qwen call just to classify every incoming news item.
## Docker
`deployment/docker-compose.source-agent.yml` is a minimal example that builds the exact same project with `BRAIN_MODE=agent`. The Agent only needs a persistent `/app/data` volume for local dedupe state and its cached remote configuration.
## Verbindungsdiagnose und Docker-Adressen
Ein Agent registriert sich aus Sicherheitsgründen **nicht selbst**. Er muss zuerst im Brain unter `/source-agents.html` angelegt werden; dort entsteht der Token. Ein Agent darf bereits Tasks zugewiesen bekommen, bevor er das erste Mal online ist.
`BRAIN_AGENT_BRAIN_URL=http://127.0.0.1:...` oder `localhost` ist bei einem separaten Docker-Container fast immer falsch: Loopback zeigt auf den Agent-Container selbst. Für einen Agent auf demselben Docker-Host kann stattdessen `http://host.docker.internal:<BRAIN_PORT>` verwendet werden. Auf einem gemeinsamen Docker-Netz ist der Brain-Service-Name vorzuziehen.
Das Brain kann mit `BRAIN_PUBLIC_URL` die korrekte, aus Agent-Sicht erreichbare Adresse veröffentlichen. Das Webinterface verwendet diese Adresse beim Erzeugen/Rotieren von Tokens.
Der Agent stellt auf `/` eine kleine Statusseite und auf `/api/status` Diagnosedaten bereit. `brain_connected`, `last_config_success_at`, `last_heartbeat_success_at` und `last_connection_error` zeigen die tatsächliche Verbindung; `config_issued_at` kann dagegen aus dem lokalen Cache stammen und ist allein kein Verbindungsnachweis. Das Agent-Compose veröffentlicht die Statusseite standardmäßig über `BRAIN_AGENT_PORT=8092`.
### Inbox-Klassifizierung für News und Advisories
Seit Classifier v2 ist `BRAIN_SOURCE_INBOX_MIN_SIMILARITY` kein alleiniger Ausschlussfilter mehr. Ein Dokument wird `candidate`, wenn es entweder direkt genug KB-Nähe erreicht oder oberhalb des Novelty-Floors durch einen kombinierten Prioritätsscore aus KB-Nähe, kuratiertem Task-/Quellenkontext, Aktualität und News-/Advisory-Signalen relevant bleibt.
- `BRAIN_SOURCE_INBOX_MIN_SIMILARITY=0.55`: direkte semantische Übernahme als Candidate.
- `BRAIN_SOURCE_INBOX_MIN_PRIORITY=0.55`: Mindestscore des kombinierten News-/Knowledge-Routings.
- `BRAIN_SOURCE_INBOX_NOVELTY_FLOOR=0.35`: harte Mindestnähe zur KB; darunter bleibt auch ein frischer Security-Alert archiviert.
Beim ersten Start einer neuen Classifier-Version werden bereits archivierte Dokumente einmalig auf `received` zurückgesetzt und mit der aktuellen Logik neu klassifiziert. Classifier v3 ergänzt dabei die proaktive Security-Ausnahme; bestehende `candidate`-Security-Meldungen werden beim Start ebenfalls einmalig für die Security-Queue erkannt.
## Proaktive Security-/Advisory-Verarbeitung
Ab Classifier v3 gibt es bewusst zwei Inbox-Pfade:
- Normale `candidate`-Dokumente bleiben passiv und werden erst bei einem konkreten Evidenzbedarf vor SearXNG durchsucht.
- Security-/Advisory-/CVE-Candidates können proaktiv verarbeitet werden. Die Erkennung nutzt den kuratierten Task-/Quellenkontext und starke Security-/Advisory-Signale; pro Task kann sie im Webinterface auf `auto`, `proaktiv` oder `passiv` gesetzt werden.
Brain-seitige Defaults:
```env
BRAIN_SOURCE_INBOX_SECURITY_PROACTIVE=true
BRAIN_SOURCE_INBOX_SECURITY_BATCH_SIZE=2
BRAIN_SOURCE_INBOX_SECURITY_MIN_PRIORITY=0.58
BRAIN_SOURCE_INBOX_SECURITY_MIN_CONFIDENCE=0.72
BRAIN_SOURCE_INBOX_SECURITY_FETCH_MIN_CHARS=1800
BRAIN_SOURCE_INBOX_SECURITY_RESEARCH_RESULTS=3
```
Der proaktive Ablauf ist begrenzt und quellengebunden:
1. Der Agent liefert RSS-/Atom-/Web-Volltext und markiert den Task-Modus mit `security_proactive`.
2. Ein ausreichend priorisierter Security-Candidate wird in eine kleine Security-Queue gestellt, behält aber bis zur Materialisierung den öffentlichen Status `candidate`.
3. Ist der Agent-Text kürzer als `BRAIN_SOURCE_INBOX_SECURITY_FETCH_MIN_CHARS` oder war der ursprüngliche Fetch fehlerhaft, lädt das Brain die kanonische Artikel-URL noch einmal direkt mit den Research-SSRF-Regeln.
4. Gemma (das konfigurierte `BRAIN_ARTICLE_SYNTHESIS_MODEL`) extrahiert ausschließlich aus den gelieferten Quellen einen strukturierten Security-Faktensatz: Ereignistyp, Vendor/Produkte, CVEs, betroffene/fixe Versionen, konkrete Fakten und Maßnahmen. Parametrisches Modellwissen darf fehlende Angaben nicht ergänzen.
5. Meldet Gemma `research_needed=true`, werden höchstens zwei präzise Suchfragen über SearXNG ausgeführt und insgesamt maximal `BRAIN_SOURCE_INBOX_SECURITY_RESEARCH_RESULTS` zusätzliche Volltexte geladen. Danach bewertet Gemma den Faktensatz erneut.
6. Nur bei `security_relevant=true`, `materialize=true`, ausreichender Confidence und mindestens einem konkreten Fakt entsteht ein `external`-Node mit `validation_state=security_verified`, Origin `source-agent-security` und einer `security_update_for`-Kante zum semantisch passendsten KB-Node.
7. Der Inbox-Status wird `materialized`. Das Dokument bleibt weiterhin als lokale Evidenz vor SearXNG auffindbar. Wird es später von einem akzeptierten Artikel-Claim zitiert, wechselt es wie bisher auf `used`.
Damit ist eine kuratierte Security-Quelle ein priorisierter, bestätigter Discovery-Kanal, aber kein Freibrief für unbelegte CVE-/Versions-/Severity-Angaben. Normale News-/Dokumentationsquellen behalten weiterhin den ressourcenschonenden passiven Candidate-Pfad.
## Crash-Recovery und genaue Provenienz
Security-Lifecycles werden im Source-Inbox-Store persistiert. Nach einem Neustart werden verwaiste `processing`-Claims sofort freigegeben. Meldet der Store `materialized`, der deterministische Security-Node fehlt aber nach einem harten Abbruch im Graph, wird der Eintrag automatisch requeued und idempotent neu materialisiert.
Inbox-Evidenz trägt eine `source_inbox_id`. Späteres Claim-Grounding setzt damit exakt die tatsächlich verwendete Content-Version auf `used`; ältere Revisionen derselben URL werden nicht mehr pauschal mitmarkiert.
## CPU compute jobs (`vector_graph`)
An integrated Source Agent can also act as a model-free CPU worker. This is independent of RSS/Web polling tasks: an Agent with zero source tasks can still advertise and execute `vector_graph` jobs.
Enable on the Agent:
```env
BRAIN_AGENT_COMPUTE_ENABLED=true
BRAIN_AGENT_COMPUTE_POLL_INTERVAL=5s
BRAIN_AGENT_COMPUTE_MAX_BYTES=134217728
```
Enable offload on the Brain:
```env
BRAIN_VECTOR_GRAPH_ENABLED=true
BRAIN_VECTOR_GRAPH_AGENT_OFFLOAD=true
BRAIN_VECTOR_GRAPH_AGENT_REQUIRED=false
BRAIN_VECTOR_GRAPH_AGENT_WAIT=2m
```
The Agent receives already existing embeddings and performs deterministic LSH/k-NN/Cosine/local-scaling arithmetic. It does not start or call Ollama. Results are accepted only for the claimed job and are validated by the Brain before the Brain persists `semantic_neighbor` edges. With `BRAIN_VECTOR_GRAPH_AGENT_REQUIRED=false`, unavailable/stale/failed remote jobs automatically fall back to the identical local CPU implementation.
Agent tokens now additionally authorize only these compute endpoints:
- `GET /api/v1/agent/compute/claim`
- `POST /api/v1/agent/compute/{id}/result`
The claim endpoint requires the Agent to have advertised the `vector_graph` capability in its heartbeat. These endpoints still do not authorize graph administration, THINK, research or runtime settings.
See `VECTOR-GRAPH-AGENT-OFFLOAD-V3.md` for the protocol and security boundaries.
## v8: modellfreie Artikelprüfung
Ein Agent mit aktiviertem Compute-Worker meldet nun zwei CPU-Capabilities: `vector_graph` und `article_quality`. `article_quality` berechnet ausschließlich deterministische Struktur-, Redundanz-, Evidenzabdeckungs- und Informationsdichte-Metriken. Es werden weder Ollama noch Embeddings oder Chatmodelle aufgerufen. Das Brain rekonstruiert Pass/Fail und Rewrite-Empfehlungen aus festen Regeln und bleibt damit Owner der Qualitätsentscheidung.
## Docker-Controller-Rolle (v9)
Die Controller-Rolle ist eine zusätzliche, explizit freizugebende Agent-Capability. `BRAIN_AGENT_DOCKER_CONTROLLER_ENABLED=true` allein genügt nicht: Das Brain muss zusätzlich die zentrale Controller-Policy aktivieren. Der normale Source-Agent-Compose mountet Docker.sock absichtlich nicht; dafür existiert `deployment/docker-compose.controller-agent.yml` als Opt-in-Override.
Der Agent meldet `docker_controller` und, falls verfügbar, `docker_compose`. Autonome Jobs kommen ausschließlich aus freigegebenen Controller-Profilen; der Agent führt keine beliebigen vom LLM erzeugten Shell-Kommandos aus. Siehe `DOCKER-CONTROLLER-V9.md`.