diff --git a/notes/trading/system-docs/modul-17-hermes-agent.md b/notes/trading/system-docs/modul-17-hermes-agent.md index 6db9255..0f6044f 100644 --- a/notes/trading/system-docs/modul-17-hermes-agent.md +++ b/notes/trading/system-docs/modul-17-hermes-agent.md @@ -147,10 +147,72 @@ identische Aufrufe. - Paperclip (M16) bleibt Orchestrator; Hermes ist seine Worker-Ausführungsebene. --- + +## LLM-Schicht (KI-/Analyse-Erweiterung, M16 additiv `llm=true`) +Hermes kann Tasks zusätzlich über eine **LLM-Schicht** (Tool-Calling-Loop) ausführen. Die LLM-Schicht +ist **additiv** (M16 setzt `llm=true` im Task-Payload); ohne Flag bleibt das deterministische M17-Verhalten +unverändert. Die Tool-Whitelist und Task-Gates bleiben **deterministisch außerhalb des LLM** — das LLM +führt nie selbst Tools aus, sondern liefert `requested_tools[]`, die durch die bestehende Whitelist geprüft werden. + +### 2-Stufen-Modellkonzept (final, 21.08.2026) +| Stufe | Modell | Provider | Verwendung | +|-------|--------|----------|------------| +| **STANDARD** | `deepseek-v4-flash:cloud` | `ollama_cloud` | Normale Research-/Analyse-Tasks, voller Tool-Calling-Loop, Structured JSON, vollständiger Audit | +| **LOKAL** | `llama3.1:8b` | `ollama_local` | NUR expliziter Privacy-/Offline-Modus (`llm_mode=local`), **Analyse-only** (kein Tool-Loop), CPU-/Timeout-Schutz | + +**Regeln (hart):** +- **KEIN automatischer Cloud→Local-Fallback.** Cloud-Ausfall → Task **FAILED** (`LLM_UNAVAILABLE`), + kein minutenlanger Wechsel auf das lokale Modell. +- **LOKAL nur explizit** über `llm_mode=local` im Task-Payload (`extra.llm_mode`). Nicht als Standard verwenden. +- **LOKAL = Analyse-only**: genau EIN Analyse-Call, keine Tool-Anfragen. `llama3.1:8b` auf CPU versteht + den Tool-Calling-Loop nicht zuverlässig (LLM_MAX_ROUNDS) und ist langsam (~60-90s/Call). +- **FAIL-CLOSED**: LLM down/Timeout/invalid JSON/Schema/Max-Runden → Task FAILED, kein Trading-Core-Effekt. +- **Safety unverändert**: kein `execution.place_order`, kein `risk.set_limits`, kein `portfolio.rebalance`, + kein M15 pause/halt/resume, Proposal maximal DRAFT/PROPOSED. + +### LLM-Audit (`hermes_llm_run`, Migration `002_hermes_llm.sql`) +Fünfte Audit-Tabelle. Je LLM-Run: provider, model, config_version, input_context_hash, requested_tools, +executed_tools, rejected_tools, tokens_in/out, latency_ms, structured_result, status, error_code. +**Vollständig AUCH im FAILED-Pfad** (Timeout/Invalid-JSON/Max-Runden persistieren Metriken). Keine +vollständigen sensiblen Prompts, keine Secrets. + +### LLM-ENV (Compose M17-Block) +- `LLM_PROVIDER=ollama_cloud` (Standard = Cloud) +- `LLM_MODEL_CLOUD=deepseek-v4-flash:cloud` +- `LLM_MODEL_LOCAL=llama3.1:8b` +- `LLM_BASE_URL=http://10.0.4.2:11434` (Ollama-Netz) +- `LLM_TIMEOUT_SECONDS=300` + +### LLM-E2E-Verifikation (final, 21.08.2026) +- **Cloud-Standard** (`llm=true`, standard): **SUCCEEDED** (deepseek-v4-flash:cloud, 4 requested/2 executed, Audit vollständig). +- **Local explizit** (`llm=true`, `llm_mode=local`): **SUCCEEDED** (llama3.1:8b, Analyse-only, Audit vollständig). +- **Cloud-down** (isoliert, ungültige Base-URL): **FAILED** (`LLM_UNAVAILABLE`), **kein Auto-Fallback** (Provider bleibt Cloud). +- **llm=false**: **SUCCEEDED** (deterministisches M17, kein LLM-Run). +- **Audit vollständig**: requested/executed/rejected/tokens/latency/context_hash persistiert, auch im FAILED-Pfad. +- **M03–M15 unbeeinflusst**: alle Module healthy während der LLM-Tests. +- **Unit-Tests** `tests/test_llm.py`: **20/20 grün** (inkl. 4 REJECTED-Gate-Tests: place_order, monitoring_pause, risk_set_limits, unknown_tool). + +### LLM-Bugs / Fixes +1. **Audit-Metriken leer (Cloud-E2E)**: `finish_llm_run` schrieb nur status/result/error → um + requested/executed/rejected_tools, tokens_in/out, latency_ms, structured_result, provider/model/config_version erweitert. +2. **FAILED-Pfad verlor Audit-Metriken**: Max-Runden-Exception trug keine Metriken → Exception trägt jetzt + Audit-Dict, `execute()` persistiert sie auch bei LLM_MAX_ROUNDS/Timeout/Invalid-JSON. +3. **NOT NULL-Constraint**: `requested_tools` etc. `NOT NULL DEFAULT '[]'` → `finish_llm_run` koerziert `None`→`[]`. +4. **Structured Output**: Cloud-Modell ignoriert Schema ohne `format`-Constraint → `format`-Constraint im Payload. +5. **ToolCall-Format**: ToolCall-Modell erwartet `name`/`args` (nicht `tool`/`params`) → Skript/Executor angepasst. +6. **Lokales Modell ungeeignet für Tool-Loop**: `llama3.1:8b` auf CPU → LLM_MAX_ROUNDS (fragt endlos Tools an). + Fix: lokaler Modus = **Analyse-only** (kein Tool-Loop), wie vom User empfohlen. + ## Geändert ``` Geändert von: Rain Ocampo Datum: 21.08.2026 +Grund: LLM-Schicht (2-Stufen-Konzept) ergaenzt: STANDARD=deepseek-v4-flash:cloud (voller Tool-Loop), +LOKAL=llama3.1:8b (nur explizit llm_mode=local, Analyse-only), KEIN Auto-Fallback, Cloud-down->FAILED +(LLM_UNAVAILABLE), llm=false deterministisch, Audit hermes_llm_run vollstaendig (auch FAILED-Pfad), +Unit 20/20, E2E 5/5 Szenarien gruen, M03-M15 unbeeinflusst. FREIGEGEBEN. +Geändert von: Rain Ocampo +Datum: 21.08.2026 Grund: Modul-17-Hermes-Agent implementiert + E2E verifiziert (Research/Analytics/Backtest/Optimization/Monitoring-Success, Safety REJECTED 6/7/8/9, M12/M13/M15-Ausfall -> FAILED (FAIL-CLOSED), Idempotenz, Restart, keine Secrets, Port intern, Hermes-Ausfall beeinflusst M03-16 nicht). Tool-Whitelist strikt, 4 Audit-Tabellen (hermes_task/run/tool_call/result),