227 lines
12 KiB
Markdown
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`.
|