From 7a247cb879dfbe92ecac23682a923e4b50d88615 Mon Sep 17 00:00:00 2001 From: Benjamin Tenke Date: Sun, 4 Oct 2026 16:36:05 +0200 Subject: [PATCH 01/12] docs(plans): plan run cost measurement per bpmn element Co-Authored-By: Claude Opus 5.5 --- docs/plans/laufkosten/plan.md | 105 ++++++++++++++++++ docs/plans/laufkosten/tasks.md | 192 +++++++++++++++++++++++++++++++++ 2 files changed, 297 insertions(+) create mode 100644 docs/plans/laufkosten/plan.md create mode 100644 docs/plans/laufkosten/tasks.md diff --git a/docs/plans/laufkosten/plan.md b/docs/plans/laufkosten/plan.md new file mode 100644 index 0000000..f1a24c6 --- /dev/null +++ b/docs/plans/laufkosten/plan.md @@ -0,0 +1,105 @@ +# Laufkosten je BPMN-Element messen + +Status: Entwurf, abgestimmt am 2026-10-04. Aufgaben: [`tasks.md`](tasks.md). + +## Ziel + +Nach jedem Lauf eines generierten Workflows soll feststehen, **was der Lauf gekostet hat und +welcher Teil des Diagramms wie viel davon**. Die Zahl soll ohne Schätzung durch das Modell +zustande kommen: Tokens aus den API-Antworten, Preise aus einer versionierten Tabelle, Zuordnung +über die BPMN-Element-IDs, die die Pipeline ohnehin überall mitführt. + +Deterministisch ist die **Messung**. Die Läufe selbst sind es nicht; deshalb gehören wiederholte +Läufe mit Median und Streuung dazu. + +## Was es schon gibt (geprüft am 2026-10-04) + +- **Session-Transkripte** unter `~/.claude/projects//`: + - `.jsonl` für den Hauptthread, `/subagents/agent-.jsonl` je Subagent + - daneben `agent-.meta.json` mit `agentType` und `description` + - Assistant-Einträge tragen `message.usage` (Input, Output, Cache-Write 5m/1h, Cache-Read), + `message.model`, `requestId` und, wenn ein Skill aktiv ist, `attributionSkill` + (bei MCP-Aufrufen zusätzlich `attributionMcpServer`/`attributionMcpTool`) + - ein `cost-state`-Eintrag mit `totalCostUSD` und `modelUsage` je Modell (Tokens, + `webSearchRequests`, `costUSD`) +- **Doppelte Zeilen:** Eine API-Anfrage erscheint oft in mehreren Einträgen mit identischer + `usage` (in einer Stichprobe 124 von 165 Anfragen). Summiert wird deshalb **je `requestId`**. +- **Das Format ist intern** und kann sich mit jeder Claude-Code-Version ändern. Der Leser ist + deshalb ein kleiner Adapter mit Fixtures, der bei Formatänderungen laut scheitert. +- **OpenTelemetry:** `claude_code.cost.usage`/`claude_code.token.usage` mit `agent.name`, + `skill.name`, `plugin.name`, `query_source`, `model`. Gut für Dashboards über viele Läufe, aber + ohne Element-ID und ohne eigene Attribute je Subagent. Dient hier nur zum Gegenprüfen. +- **Hooks** bekommen `transcript_path` (SubagentStop zusätzlich `agent_id`/`agent_type`), aber + keine Tokens. Ein Hook kann die Kosten also nicht direkt lesen, wohl aber aus dem Transkript + berechnen. +- **dark-factory** setzt schon `label: "