98 lines
5.0 KiB
Markdown
98 lines
5.0 KiB
Markdown
# OpenRouter-Kosten-Governance (reale USD-Werte)
|
||
|
||
Verifizierte Mechanik (2026-08) für echtes USD-Kosten-Tracking + Budget-Bremse im
|
||
Multi-Agent-Mesh. Lebt unter `operational-dashboard-archive` (Kostenanzeige-Sektion).
|
||
|
||
## Drei OpenRouter-Endpoints (verifiziert)
|
||
|
||
| Endpoint | Liefert | Verwendung |
|
||
|----------|---------|-----------|
|
||
| `GET /api/v1/credits` | `total_credits`, `total_usage` | **verbindlicher USD-Verbrauch, account-weit** |
|
||
| `GET /api/v1/auth/key` | `usage` (pro Key) | grobe pro-Agent-Verteilung |
|
||
| `POST /api/v1/chat/completions` | `usage.cost` (Body) | exakter Pro-Request-USD |
|
||
|
||
```python
|
||
import json, re, urllib.request
|
||
env = open('/root/.hermes/.env').read()
|
||
m = re.search(r'OPENROUTER_API_KEY=([A-Za-z0-9_.\-]+)', env)
|
||
h = {"Authorization": f"Bearer {m.group(1)}"}
|
||
d = json.load(urllib.request.urlopen(
|
||
urllib.request.Request("https://openrouter.ai/api/v1/credits", headers=h),
|
||
timeout=20))["data"]
|
||
print(d["total_credits"]) # aufgeladen gesamt
|
||
print(d["total_usage"]) # verbraucht (USD, KUMULATIV über Konto-Leben!)
|
||
```
|
||
|
||
Sub-Agenten: gleicher Aufruf per SSH auf deren `.env` (Key bleibt lokal, nur Zahl zurück).
|
||
Alle Keys eines Accounts melden denselben `total_usage`; `/auth/key usage` unterscheidet pro Key.
|
||
|
||
## ⚠️ Der große Stolperstein: total_usage ist KUMULATIV
|
||
|
||
`total_usage` zählt über das **gesamte Konto-Leben**, nicht pro Monat. Ein Monats-Cap
|
||
darf NICHT `total_usage > limit` prüfen — ein altes Konto stünde sofort dauerhaft über
|
||
dem Limit (alles gebremst, niemand kann mehr arbeiten).
|
||
|
||
Monats-Delta statt Gesamtwert:
|
||
|
||
```python
|
||
monat = today[:7] # z.B. "2026-08"
|
||
vormonat = monat[:5] + str(int(monat[5:7]) - 1).zfill(2) if int(monat[5:7]) > 1 else ""
|
||
basis = None
|
||
if vormonat:
|
||
vm = [r for r in rows if r["ts"][:7] == vormonat]
|
||
basis = vm[-1] # letzter Vormonats-Wert (stabil)
|
||
if basis is None:
|
||
ma = [r for r in rows if r["ts"][:7] == monat]
|
||
basis = ma[0] if ma else rows[0]
|
||
monats_delta = max(0.0, rows[-1]["total_usage_usd"] - basis["total_usage_usd"])
|
||
```
|
||
|
||
Fehler, den NUR das Team-Review fand: Basis `rows[0]` ist falsch, wenn der Monat noch
|
||
keinen Eintrag hat (dann = Konto-Eröffnung → Delta = Gesamtverbrauch → Falschbremse).
|
||
Also IMMER Vormonats-Wert als Basis bevorzugen.
|
||
|
||
## Kill-Switch-Bremsen-Muster (harter Halt)
|
||
|
||
1. Master schreibt `/srv/work/costs/kill_switches.json` `{"kill_switches":{agent:{"status":"PAUSED"}}}` (chmod 0666).
|
||
2. Jeder Sub-Agent-Poller liest sie per SSH VOR jeder Task-Übernahme:
|
||
```bash
|
||
KILL=$($SSH_CMD "python3 -c \"import json;d=json.load(open('/srv/work/costs/kill_switches.json'));ks=d.get('kill_switches',{});sw=ks.get('$MEINE_ID',{});print('PAUSED' if sw and sw.get('status')=='PAUSED' else 'OK')\" 2>/dev/null")
|
||
[ "$KILL" = "PAUSED" ] && { log "Budget-BREMSE aktiv,$MEINE_ID"; exit 0; }
|
||
```
|
||
3. **Master (VPSHermes) in der Gesamt-Bremse ausgenommen** (`continue`) — er muss sein
|
||
System + den Nutzer betreuen; nur Sub-Agenten hart pausieren.
|
||
|
||
Getestet: Sub-Agent mit PAUSED lässt Task in `offen/` liegen; nach Reset `{}` nimmt sofort wieder an.
|
||
|
||
## Modell hart blockieren
|
||
|
||
`hermes config set model.providers.openrouter.blocked_models '["modell/id"]'`
|
||
- WICHTIG: **`model.`** (Singular), nicht `models.` — sonst eigener Top-Level-Key, ungenutzt.
|
||
- Danach weg aus `hermes models list`; Fallback greift aufs nächste.
|
||
- Robuster: **Allowlist** (`allowed_models`) nur günstige Modelle → neue teure automatisch geblockt.
|
||
- Schnellster Kostenspar-Hebel: ein einzelnes teures Modell (z.B. deepseek-v4-pro = ~64%
|
||
der Kosten) hart blocken → dessen Anteil → fast 0.
|
||
|
||
## Nutzer-Budget-Modell (FINAL, 2026-08-08 — ersetzt früheres 20$/Monat-Modell)
|
||
|
||
Die einzige harte Grenze ist **1$ pro Tag und Agent**. Solange OpenRouter-Credits
|
||
(Guthaben) vorhanden sind, wird weitergearbeitet — KEIN Team-Monats-Stopp, kein hartes
|
||
20$-Cap als Abrisskriterium. Rest = `total_credits − total_usage` (aus `/api/v1/credits`).
|
||
Der Nutzer lädt am Monatsanfang ~20$ auf (evtl. am 15. nochmal ~20$, nicht garantiert);
|
||
ist das Guthaben real aufgebraucht, fällt Arbeit von selbst auf **Free-Modelle oder
|
||
lokales VPS-Ollama** (`deepseek-r1:7b`). Master überwacht Gesamtkosten (stündl. Cron:
|
||
`mesh-cost-track.sh` → `mesh-cost-break.py`), bremst automatisch via Kill-Switches;
|
||
Master selbst bleibt dabei immer aktiv.
|
||
|
||
## Team-Pflicht bei Kosten-Logik
|
||
|
||
Kosten/Deckel/Basislogik NIEMALS solo absegnen — gegenprüfen lassen (anderer Agent).
|
||
Ein vergessenes Detail (Basiswahl, Monatswechsel, Reset) wird sonst erst als
|
||
Dauer-Falschbremse real. "4 günstige Agents zusammen sind besser als 1 teurer Agent
|
||
und halten die Kosten niedrig."
|
||
|
||
**Pitfall beim Verteilen von Review-Tasks:** Prompts, die den Agenten zum Laden von
|
||
Dateien/Skills anregen, laufen in dessen Iterationslimit (3) → nur Reasoning, kein
|
||
`# Ergebnis`, Task wird als "kein Ergebnis" gewertet. Neu stellen mit *"antworte NUR aus
|
||
deinem Wissen, LADE KEINE Dateien/Skills, antworte sofort"* — dann liefert auch ein
|
||
kleines Agent-Modell verwertbares Ergebnis. |