tensorx adapter
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
---
|
||||
name: run-experiment
|
||||
description: Führt einen Versuchs-Prompt aus einer Prompt-Datei als messbaren Headless-Lauf mit Claude Code oder Codex CLI aus und schreibt ein Messprotokoll mit Start-/Endzeit, Modell, Tokenverbrauch und weiteren Metriken. Verwenden bei "/run-experiment <Pfad-zur-Prompt-Datei>" oder wenn der User einen Versuch/ein Experiment ausführen und tracken will.
|
||||
description: Führt einen Versuchs-Prompt aus einer Prompt-Datei als messbaren Headless-Lauf mit Claude Code, Codex CLI oder dem Python-API-Adapter (GLM/Kimi) aus und schreibt ein Messprotokoll mit Start-/Endzeit, Modell, Tokenverbrauch und weiteren Metriken. Verwenden bei "/run-experiment <Pfad-zur-Prompt-Datei>" oder wenn der User einen Versuch/ein Experiment ausführen und tracken will.
|
||||
argument-hint: <Pfad zur Prompt-Datei> <Root-Verzeichnis>
|
||||
version: 7.0.0
|
||||
version: 8.0.0
|
||||
---
|
||||
|
||||
# RunExperiment – Versuchslauf mit Messprotokoll
|
||||
@@ -101,7 +101,7 @@ Der Skill ist zweigeteilt:
|
||||
- **`## Prozess`** beschreibt werkzeugneutral, **was** je Lauf zu tun und zu erheben ist. Dieser
|
||||
Teil gilt unabhängig davon, mit welchem LLM oder welcher CLI gearbeitet wird.
|
||||
- **`## Werkzeugadapter`** beschreibt **wie** das mit einem konkreten Werkzeug umgesetzt wird.
|
||||
Ausgearbeitet sind Adapter für Claude Code und Codex CLI. Konkrete Flags und Rohfelder sind
|
||||
Ausgearbeitet sind Adapter für Claude Code, Codex CLI und den Python-API-Adapter (GLM/Kimi). Konkrete Flags und Rohfelder sind
|
||||
ausschließlich dem gewählten Adapterabschnitt zu entnehmen.
|
||||
|
||||
**Arbeitsteilung mit der Prompt-Datei:** Der Prompt enthält ausschließlich die *Analyseanweisung*
|
||||
@@ -124,7 +124,8 @@ per stdin übergebenen Text angehängt (siehe Schritt „Prompt zusammenstellen"
|
||||
frühere Läufe entstanden sind, und dürfen nicht nachträglich angepasst werden.
|
||||
2. Aus dem Metadaten-Block der Prompt-Datei (falls vorhanden) Versuch/Prompt-Version übernehmen.
|
||||
3. **Werkzeugadapter bestimmen und CLI-Pfad auflösen.** Die Modell-ID entscheidet eindeutig:
|
||||
`claude-*` verwendet Claude Code, OpenAI-IDs wie `gpt-*` oder `o*` verwenden Codex CLI.
|
||||
`claude-*` verwendet Claude Code, OpenAI-IDs wie `gpt-*` oder `o*` verwenden Codex CLI,
|
||||
`z-ai/*` und `moonshotai/*` verwenden den Python-API-Adapter über den TensorX-Gateway.
|
||||
Keine Modell-ID an eine CLI übergeben, die sie nicht unterstützt.
|
||||
|
||||
Unter Windows liegt `claude` in der Regel **nicht im PATH**. Erst
|
||||
@@ -162,6 +163,11 @@ per stdin übergebenen Text angehängt (siehe Schritt „Prompt zusammenstellen"
|
||||
| `gpt-5.6-terra` | ausgewogenes Verhältnis aus Leistung und Verbrauch |
|
||||
| `gpt-5.6-luna` | schnelle und günstige GPT-5.6-Variante |
|
||||
|
||||
| TensorX-Modell-ID | Einordnung |
|
||||
|---|---|
|
||||
| `z-ai/glm-5.2` | Z.AI GLM 5.2 über TensorX-Gateway |
|
||||
| `moonshotai/kimi-k3` | Moonshot Kimi K3 – 1-Mio.-Kontext, 2,8T Parameter |
|
||||
|
||||
In der Frage den letzten verwendeten Stand nennen, damit der User bewusst wechseln oder
|
||||
bewusst wiederholen kann (z. B. „Lauf 3 lief mit `claude-sonnet-5`, 11.516.200 Tokens, 23:40").
|
||||
|
||||
@@ -256,7 +262,7 @@ per stdin übergebenen Text angehängt (siehe Schritt „Prompt zusammenstellen"
|
||||
Sort-Object { [int]($_.Name -replace '\D','') }
|
||||
$iteration = if ($iterationen) { $iterationen[-1].Name } else { 'Iteration 1' }
|
||||
$zelle = Join-Path (Join-Path (Join-Path $iteration $modell) $modus) $effort
|
||||
$skillVer = 'v7.0.0' # entspricht version: im Frontmatter dieses Skills
|
||||
$skillVer = 'v8.0.0' # entspricht version: im Frontmatter dieses Skills
|
||||
do {
|
||||
$id4 = '{0:x4}' -f (Get-Random -Maximum 65536)
|
||||
$lauf = Join-Path "<promptverzeichnis>\$zelle" "<NN>_Lauf_$(Get-Date -Format 'yyyy-MM-dd_HHmmss')_${skillVer}-$id4"
|
||||
@@ -997,6 +1003,114 @@ die angeforderte ID; da `codex exec --json` sie im Ereignisstrom nicht wiederhol
|
||||
Modellkontrolle im Protokoll `nicht prüfbar`. Temperatur und weitere Sampling-Parameter sind in
|
||||
diesem CLI-Ablauf nicht steuerbar; Effort und Service-Tier werden dagegen explizit festgelegt.
|
||||
|
||||
### Adapter: Python API / GLM & Kimi-Modelle über TensorX
|
||||
|
||||
Dieser Adapter wurde für Modelle entwickelt, die über den **TensorX API-Gateway**
|
||||
(`https://api.tensorx.ai/v1`) erreichbar sind. Er nutzt das Skript `glm-kimi-adapter.py`,
|
||||
das einen minimalen Agent-Loop mit Tool-Calling direkt gegen die OpenAI-kompatible
|
||||
REST-API implementiert. Referenzstand bei Einführung: **Python 3.13, requests 2.34**.
|
||||
|
||||
**Verfügbare Modell-IDs über TensorX:**
|
||||
|
||||
| TensorX-Modell-ID | Hersteller | Effort-Parameter |
|
||||
|---|---|---|
|
||||
| `z-ai/glm-5.2` | Z.AI (Zhipu AI) | `thinking` (`{"type":"enabled","level":"…"}`) |
|
||||
| `moonshotai/kimi-k3` | Moonshot AI | `reasoning_effort` (top-level) |
|
||||
|
||||
Das Modell-Präfix (`z-ai/` bzw. `moonshotai/`) bestimmt, welcher Effort-Parameter an die
|
||||
API gesendet wird. Der Adapter wählt ihn automatisch anhand des Präfixes.
|
||||
|
||||
**Authentifizierung.** Der API-Key wird **automatisch aus der Cline providers.json**
|
||||
gelesen (`~/.cline/data/settings/providers.json`, Provider `tensorx`). Alternativ kann
|
||||
er per `--api-key` oder Umgebungsvariable `TENSORX_API_KEY` übergeben werden. Der Key
|
||||
wird **nicht** in Laufartefakten gespeichert.
|
||||
|
||||
**Unterstützter Agentenmodus:** Nur `solo`. Der Adapter implementiert keine Subagenten;
|
||||
`builtin` und `custom` sind nicht freigegeben und führen zum Abbruch.
|
||||
|
||||
**Isolation.** Der Adapter ist ein eigenständiges Python-Skript, das nur die
|
||||
Python-Standardbibliothek und `requests` benötigt. Es liest die Codebasis über die
|
||||
implementierten Tools (`read_file`, `list_directory`, `search_files`,
|
||||
`execute_command`) und schreibt Ergebnisdateien ausschließlich über das `write_file`-Tool
|
||||
ins Ausgabeverzeichnis. Schreibende und bauende Shell-Kommandos sind durch eine
|
||||
Denylist gesperrt (analog zum Claude-Code-Adapter). Der bereinigte Snapshot bleibt
|
||||
zusätzliche Pflicht.
|
||||
|
||||
**Effort-Steuerung.** Der Adapter mappt die Skill-Effort-Stufen auf beide APIs:
|
||||
|
||||
| Skill-Effort | GLM `thinking.level` | Kimi `reasoning_effort` |
|
||||
|---|---|---|
|
||||
| `low` | `low` | `low` |
|
||||
| `medium` | `medium` | `medium` |
|
||||
| `high` | `high` | `high` |
|
||||
| `xhigh` | `xhigh` | `high` (höchste verfügbare Stufe) |
|
||||
| `max` | `xhigh` | `high` |
|
||||
|
||||
**Der Aufruf** (als Background-Task starten):
|
||||
|
||||
```powershell
|
||||
$skillDir = "<Verzeichnis des Skills>"
|
||||
$lauf = "<absoluter Pfad zum Laufverzeichnis>"
|
||||
$root = "<Root-Verzeichnis der Codebasis>"
|
||||
$modell = "<vom User gewählte Modell-ID, z.B. z-ai/glm-5.2>"
|
||||
$effort = "<vom User gewählte Stufe>"
|
||||
|
||||
# Prompt zusammenstellen (wie bei den anderen Adaptern)
|
||||
$prompt = (Get-Content "<prompt-datei>" -Raw) + "`n`n<Werkzeugkontext-Block>`n`n<Ausgabe-Block>"
|
||||
Set-Content -Path "$lauf\_meta\combined_prompt.md" -Value $prompt -Encoding utf8
|
||||
Set-Content -Path "$lauf\_meta\startzeit.txt" -Value (Get-Date -Format o)
|
||||
|
||||
# API-Key wird automatisch aus Cline providers.json gelesen
|
||||
python "$skillDir\glm-kimi-adapter.py" `
|
||||
--prompt "$lauf\_meta\combined_prompt.md" `
|
||||
--root $root `
|
||||
--output "$lauf\Ergebnisse" `
|
||||
--model $modell `
|
||||
--effort $effort `
|
||||
--max-turns 50 `
|
||||
--result-dir $lauf `
|
||||
2> "$lauf\Stderr.log"
|
||||
|
||||
Set-Content -Path "$lauf\_meta\endzeit.txt" -Value (Get-Date -Format o)
|
||||
```
|
||||
|
||||
**Gelieferte Messgrößen** – vollständig aus `RawResult.json` (vom Adapter geschrieben):
|
||||
|
||||
| Messgröße | Feld |
|
||||
|---|---|
|
||||
| Abbruchstatus | `is_error`, `subtype`, `finish_reason` |
|
||||
| Dauer | `duration_ms` (Wanduhr, selbst gemessen; keine separate API-Zeit) |
|
||||
| Tokens gesamt | `usage.total_tokens` über alle Turns akkumuliert |
|
||||
| Input-Tokens | `usage.prompt_tokens` |
|
||||
| Output-Tokens | `usage.completion_tokens` |
|
||||
| Reasoning-Tokens | `usage.reasoning_tokens` (aus `completion_tokens_details.reasoning_tokens`) |
|
||||
| Cache-Read-Tokens | `usage.cached_tokens` (soweit von TensorX geliefert) |
|
||||
| Cache-Write-Tokens | **nicht erfasst** – TensorX liefert keine |
|
||||
| Agent-Turns | `num_turns` |
|
||||
| Tatsächlich eingesetztes Modell | `model` (aus API-Antwort; mit `model_requested` abzugleichen) |
|
||||
| Tool-Aufrufe | `tool_call_count`, `tool_call_types` (nach Werkzeugname) |
|
||||
| Erzeugte Artefakte | `written_files` (Pfad und Größe je Datei) |
|
||||
| Abschlusstext | `result` |
|
||||
|
||||
**Semantik der Token-Zählung.** `usage.total_tokens` wird über alle Turns aufsummiert.
|
||||
Jeder Turn umfasst dabei den vollen Kontext (Eingabe + Ausgabe); die Token-Zahl ist
|
||||
daher die Summe aller API-Aufrufe, nicht die eines einzelnen Austauschs.
|
||||
Reasoning-Tokens sind eine Teilmenge von `completion_tokens` und werden nicht erneut
|
||||
addiert.
|
||||
|
||||
**Nicht erfasst und niemals schätzen:** Cache-Write-Tokens, Permission-Denials (das
|
||||
Deny-Modell ist ein hartes Blockieren, keine zählbaren Denials), Subagenten-Stats (keine
|
||||
Subagenten), Session-ID (keine persistierte Session), API-Dauer (nicht von der API
|
||||
geliefert). Sampling-Parameter: Temperatur ist steuerbar (`--temperature`),
|
||||
Reasoning-Effort ist steuerbar (`--effort`).
|
||||
|
||||
**Pflichtprüfung nach dem Lauf:**
|
||||
1. `Ergebnisse\` ist **nicht leer** – sonst Fehlmessung (analog zu MAJOR 6.1.0).
|
||||
2. `Stderr.log` enthält keine Abbruchmeldung.
|
||||
3. `model` in `RawResult.json` stimmt mit `model_requested` überein (Modellkontrolle).
|
||||
4. `tool_call_count` > 0 (ein Lauf ohne Tool-Aufrufe hat die Codebasis nicht analysiert).
|
||||
|
||||
|
||||
### Weitere Adapter (für Versuch 4 nachzurüsten)
|
||||
|
||||
Kapitel 4 der Arbeit sieht zusätzlich Qwen Code CLI über LM Studio und DeepSeek über die
|
||||
@@ -1057,6 +1171,8 @@ der Historie unten – im selben Arbeitsschritt.
|
||||
|
||||
| Version | Änderung | Grund | Verwendet in |
|
||||
|---|---|---|---|
|
||||
| **8.0.0** | **Neuer Python-API-Adapter für GLM- und Kimi-Modelle über den TensorX-Gateway.** Das Skript `glm-kimi-adapter.py` implementiert einen minimalen Agent-Loop mit Tool-Calling (read_file, list_directory, search_files, execute_command, write_file) direkt gegen die OpenAI-kompatible TensorX-API (`https://api.tensorx.ai/v1`). Modelle: `z-ai/glm-5.2` und `moonshotai/kimi-k3`. Der API-Key wird automatisch aus der Cline providers.json gelesen. Token-Verbrauch wird pro Turn aus dem API-Response `usage`-Objekt akkumuliert, inkl. Reasoning-Tokens (`completion_tokens_details.reasoning_tokens`). Effort-Mapping anhand des Modell-Präfixes: `z-ai/*` nutzt `thinking.level`, `moonshotai/*` nutzt `reasoning_effort`. Nur Modus `solo` freigegeben. Neue Modell-Tabelle für TensorX-Modell-IDs im Vorbereitungsabschnitt. | Die Cline CLI (`npm i -g cline`) versprach einen Headless-Modus mit GLM-Support, ihr natives Binary (143 MB, Bun-kompiliert) wurde jedoch durch die Application-Control-Richtlinie der Maschine blockiert (EPERM/Zugriff verweigert). Der Python-Adapter umgeht dieses Problem und bietet zusätzliche Vorteile: exakte Token-Metriken direkt aus der API (inkl. Reasoning-Tokens, die Claude Code nur als `thinking_tokens` liefert), keine externen Binary-Abhängigkeiten, API-Key aus bestehender Cline-Konfiguration. MAJOR, da neues Werkzeug mit anderer Isolationsarchitektur und anderen Metrik-Quellen eine neue Versuchsbedingung bildet; der nächste Lauf eröffnet eine neue Iteration. | ab dem ersten GLM/Kimi-Lauf |
|
||||
|
||||
| **7.0.0** | **Isolationsmechanismus wird modusabhängig.** In den Modi `solo` und `builtin` unverändert `--safe-mode`; im Modus `custom` und bei jedem Lauf mit `--mcp-config` **kein** `--safe-mode`, stattdessen `--strict-mcp-config` plus `--disallowedTools Skill WebSearch WebFetch SlashCommand`. Neue Pflicht-Umgebungsprüfung auf Hooks, Plugins und Output-Styles im User-Profil; neue Protokollfelder für die MCP-Konfiguration und die Umgebungsprüfung. | `--safe-mode` schaltet ausweislich der CLI-Hilfe „MCP servers, custom commands and agents" ab – also genau das, was V2 und V3 untersuchen. Smoke-Test am 2026-08-26 (CLI 2.1.246, identischer Aufruf, nur `--safe-mode` variiert): mit Flag `spawned` = 0 und die Meldung, die Rollen seien „nicht in der Agent-Registry registriert"; ohne Flag `spawned` = 2 mit `{"modulinventar": 1, "konsistenzpruefer": 1}`. Ohne Ersatz hätte der erste V2-Lauf stillschweigend als V1-Lauf gemessen. Der Ersatz wurde gegengeprüft: nichts vorgeladen, keine Skills, kein Webzugriff, alle Rollen verfügbar. **MAJOR: Läufe im Modus `custom` sind hinsichtlich der Isolation nicht unmittelbar mit `solo`- und `builtin`-Läufen vergleichbar** – Plugins, Hooks und Output-Styles sind dort nicht durch das Flag, sondern nur durch die Umgebungsprüfung ausgeschlossen. | ab dem ersten V2-Lauf |
|
||||
| **6.1.0** | Zwei adapterunabhängige Pflichtprüfungen nach jedem Lauf: **(a)** `Ergebnisse\` darf nicht leer sein – sonst Fehlmessung, unabhängig von `is_error`; **(b)** `Stderr.log` auf Abbruchmeldungen prüfen. Der Ausführungsabschnitt setzt `CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS=0`. Neues Protokollfeld „Gültigkeit". Dokumentiert, dass die Rückgabe eines Hintergrund-Subagenten eine Start-Quittung ist und ihre Länge kein Ertragsmaß. | Lauf `…160037_v4.5.0-116d` meldete `is_error: false`, `subtype: success` und lieferte **null Ergebnisdateien** bei 193,4 Mio. Tokens – der Headless-Modus hatte nach 600 s abgebrochen, während zehn Hintergrund-Subagenten noch liefen. Ohne die neue Prüfung wäre der Lauf als gültiger Messpunkt mit „0 Anforderungen" in den Modellvergleich eingegangen. MINOR: neue Prüfschritte; die Umgebungsvariable ändert die Versuchsbedingung für künftige `builtin`-Läufe und ist dort zu vermerken. | ab sofort |
|
||||
| **6.0.0** | **Windows-taugliche Codex-Isolation.** Pro Lauf wird im System-Temp-Verzeichnis außerhalb des IDE-Projektbaums eine Kopie der versionierten und nicht ignorierten Dateien des Codebasis-Roots erstellt. Codex läuft ausschließlich dort mit `--sandbox workspace-write`; SHA-256-Manifeste vor und nach dem Lauf erkennen jede Änderung. Ergebnisse und Nachweise bleiben im Laufverzeichnis, die temporäre Kopie wird danach entfernt. | Der erste Codex-Lauf mit 5.0.0 konnte fachlich nicht starten, weil die Windows-Read-only-Sandbox sämtliche lesenden Kindprozesse vor dem Start blockierte. Eine Kopie im Laufverzeichnis wurde zudem vom C#-Projektservice automatisch mit ignorierten `obj`-Dateien verändert. MAJOR, weil Sandboxmodus und Arbeitsverzeichnis eine neue Versuchsbedingung bilden; der erste Lauf eröffnet deshalb eine neue Iteration. | ab dem ersten wiederholten Codex-Lauf |
|
||||
|
||||
Reference in New Issue
Block a user