Claude Code agent_summary: Tokenverbrauch messen und senken
Miss die Modellanfragen hinter den Fortschrittsanzeigen der Hintergrundagenten in Claude Code. Vergleiche die geschätzten 16.4% eines Teams mit den vom Team von Claude Code gemeldeten 2% insgesamt und 6% im Terminal. Ermittle deinen Anteil mit einem lokalen OpenTelemetry-Empfänger und prüfe die Cache-Korrektur in 2.1.311+, die Agentensteuerung und Community-Patches.
Inhalt

Aktualisiere Claude Code auf 2.1.311 oder neuer und miss agent_summary mit OpenTelemetry, bevor du Agentenfunktionen deaktivierst. Diese Anfragen für Fortschrittszusammenfassungen können zusätzliche Kosten verursachen, während Hintergrundagenten arbeiten. Die häufig genannte Zahl 16.4% ist der geschätzte Kostenanteil eines Teams, kein allgemeiner Aufschlag auf den Tokenverbrauch.
Was agent_summary macht
agent_summary erstellt Fortschrittstexte durch separate Modellanfragen. Im Bericht zu Claude Code 2.1.312 beschreibt dblumenau diesen Ablauf. Jede Anfrage schickte den Gesprächsverlauf eines arbeitenden Hintergrundagenten an dessen eigenes Modell. Das Modell sollte einen Text mit drei bis fünf Wörtern liefern. Das Beispiel verwendete Haiku; der Mechanismus ist also nicht auf Opus beschränkt.
Arbeitende Hintergrundagenten können solche Anfragen ungefähr alle 30 Sekunden auslösen. Bei unverändertem Gesprächsverlauf können einzelne Aufrufe entfallen, wie das offizielle Änderungsprotokoll dokumentiert. Zähle deshalb tatsächliche Anfragen, statt die verstrichenen Minuten mit zwei zu multiplizieren.
Die Länge des Kontexts kann daher mehr ausmachen als die Länge des angezeigten Textes. Prüfe bei der Kostenanalyse das gemeldete Modell und die Cache-Nutzung.
Die konfigurierbare Statuszeile deines Terminals funktioniert anders. Die Dokumentation zur eigenen Statuszeile beschreibt ein lokales Skript, das keine API-Tokens verbraucht. Wenn du dieses Skript entfernst, bleiben die separaten Modellanfragen für Zusammenfassungen davon unberührt.
Was 16.4%, 2% und 6% tatsächlich messen
Die drei Kostenanteile beziehen sich auf unterschiedliche Gruppen. Stand 2026-11-01 liegen diese Berichte vor:
| Bericht | Gruppe und Zeitraum | Gemeldeter Kostenanteil der Zusammenfassungen | Berechnungsgrundlage |
|---|---|---|---|
| Flamerix AI | Eine gemessene Woche eines Teams | 16.4% | Claude Codes Schätzungen in cost_usd je Anfrage |
| edwinarbus vom Team von Claude Code | Nutzer, die Telemetrie senden; Woche vor der Antwort vom 29. Oktober | Etwa 2% | Kosten zu API-Listenpreisen |
| Dieselbe Teamantwort, Teilgruppe Terminal | Terminalnutzung innerhalb dieser Telemetriestichprobe | Etwa 6% | Kosten zu API-Listenpreisen |
Flamerix berichtete außerdem, dass Zusammenfassungen 19.7% der API-Anfragen ausmachten. Anfrageanteil und Kostenanteil haben unterschiedliche Bezugsgrößen. Keiner der beiden Werte zeigt, welchen Anteil deines Abonnementkontingents die Zusammenfassungen verbrauchen.
Nutze diese Berichte als Anlass, deinen eigenen Einsatz zu messen. Ein Team, das viele lange Aufgaben delegiert, kann deutlich andere Werte erreichen als jemand, der überwiegend im Hauptdialog arbeitet.
Zuerst aktualisieren, ohne feste Einsparungen anzunehmen
Version 2.1.311+ behebt laut der Antwort des Teams von Claude Code teure Zusammenfassungsanfragen, bei denen der Prompt-Cache nicht greift. Die Korrektur entfernt die Zusammenfassungsanfragen nicht. Eine bestimmte Ersparnis für deine Sitzungen lässt sich daraus nicht ableiten.
Bei einer nativen Installation führe diese Befehle in Bash aus:
claude --version
claude update
claude --version
Starte Claude Code danach neu. Verwaltet ein Paketmanager die Installation, nutze dessen Aktualisierungsbefehl aus der offiziellen Installationsanleitung. Prüfe anschließend die installierte Version. Der Update-Kanal oder Organisationsrichtlinien können die verfügbare Version begrenzen.
Dieselbe Teamantwort beschreibt die Arbeit an einem günstigeren Modus mit kurzen Notizen und einem kleineren Modell. Ein Veröffentlichungstermin wird nicht genannt. Stand 2026-11-01 ist keine öffentliche Einstellung dokumentiert, mit der sich dieser Modus aktivieren lässt. Plane diese Einsparung noch nicht in dein Budget ein.
Deine Sitzung mit OpenTelemetry messen
Sammle die Log-Ereignisse claude_code.api_request und gruppiere sie nach query_source. Die Monitoring-Referenz beschreibt dieses Attribut, das gemeldete model und die geschätzten Kosten in cost_usd.
Wenn deine Organisation diese Ereignisse bereits sammelt, nutze ihr Monitoring-System. Filtere eine Sitzung oder einen festgelegten Zeitraum. Zähle die Ereignisse zu API-Anfragen und summiere cost_usd je Quelle. Für Modellvergleiche gruppiere zusätzlich nach model.
Für das lokale Beispiel brauchst du Bash, Python 3 und Claude Code mit bereits eingerichteter Authentifizierung. Verwende einen Rechner, auf dem du das Telemetrieziel selbst festlegen kannst. Der Empfänger hält aggregierte Werte im Arbeitsspeicher und gibt Metadaten aus. Dafür musst du keine vollständigen Prompts oder Antworten aufzeichnen.
Lokalen Empfänger starten
Führe den folgenden Block im ersten Terminal aus. Der Empfänger nimmt OTLP HTTP JSON über die lokale Loopback-Schnittstelle entgegen und zeigt fortlaufend die Gesamtsummen je Quelle:
python3 -u - <<'PY'
import gzip, json, math
from collections import defaultdict
from http.server import BaseHTTPRequestHandler, HTTPServer
rows = defaultdict(lambda: [0, 0.0, 0])
models = defaultdict(set)
seen = set()
def scalar(value):
return next((value[k] for k in ("stringValue", "doubleValue", "intValue", "boolValue")
if k in value), None)
def report():
count = sum(row[0] for row in rows.values())
cost = sum(row[1] for row in rows.values())
missing = sum(row[2] for row in rows.values())
print("\nquery_source\trequests\trequest_%\tknown_USD\tcost_%\tmissing_cost\tmodels")
for source, (n, usd, absent) in sorted(rows.items()):
share = f"{100 * usd / cost:.2f}" if cost > 0 and not missing else "n/a"
names = ",".join(sorted(models[source]))
print(f"{source}\t{n}\t{100 * n / count:.2f}\t{usd:.6f}\t{share}\t{absent}\t{names}")
print(f"Total API records: {count}; missing costs: {missing}", flush=True)
class Receiver(BaseHTTPRequestHandler):
def log_message(self, *args):
pass
def do_POST(self):
if self.path != "/v1/logs":
self.send_error(404)
return
raw = self.rfile.read(int(self.headers.get("Content-Length", "0")))
try:
if self.headers.get("Content-Encoding") == "gzip":
raw = gzip.decompress(raw)
data = json.loads(raw)
except (ValueError, OSError):
self.send_error(400)
return
for resource in data.get("resourceLogs", []):
for scope in resource.get("scopeLogs", []):
for record in scope.get("logRecords", []):
a = {item["key"]: scalar(item["value"])
for item in record.get("attributes", [])}
event = a.get("event.name") or scalar(record.get("body", {}))
if event in ("user_prompt", "claude_code.user_prompt"):
print("Received user_prompt event.", flush=True)
if event not in ("api_request", "claude_code.api_request"):
continue
identity = a.get("request_id") or json.dumps(record, sort_keys=True)
if identity in seen:
continue
seen.add(identity)
source = str(a.get("query_source") or "(missing)")
models[source].add(str(a.get("model") or "(missing)"))
row = rows[source]
row[0] += 1
try:
usd = (float(a["cost_usd"]) if a.get("cost_usd") is not None
else float(a["cost_usd_micros"]) / 1_000_000)
if not math.isfinite(usd) or usd < 0:
raise ValueError()
row[1] += usd
except (KeyError, ValueError, TypeError):
row[2] += 1
self.send_response(200)
self.send_header("Content-Type", "application/json")
self.end_headers()
self.wfile.write(b"{}")
report()
server = HTTPServer(("127.0.0.1", 4318), Receiver)
print("Listening on 127.0.0.1:4318. Stop after Claude exits with Ctrl+C.", flush=True)
try:
server.serve_forever()
except KeyboardInterrupt:
pass
finally:
server.server_close()
report()
PY
Sitzung für die Messung starten
Führe diesen Block im zweiten Terminal aus. Die Subshell begrenzt die Änderungen der Umgebungsvariablen auf diesen Start von Claude Code:
(
export CLAUDE_CODE_ENABLE_TELEMETRY=1
export OTEL_LOGS_EXPORTER=otlp
export OTEL_METRICS_EXPORTER=none
export OTEL_TRACES_EXPORTER=none
export OTEL_EXPORTER_OTLP_LOGS_PROTOCOL=http/json
export OTEL_EXPORTER_OTLP_LOGS_ENDPOINT=http://127.0.0.1:4318/v1/logs
export OTEL_LOGS_EXPORT_INTERVAL=1000
claude
)
Nutze eine normale Aufgabe, für die Hintergrundarbeit sinnvoll ist. Bitte etwa einen Hintergrundagenten, Authentifizierungstests zu prüfen, ohne Dateien zu ändern. Arbeite im Hauptdialog weiter und vergewissere dich, dass der Hintergrundagent tatsächlich startet.
Bleibe in einer interaktiven Sitzung und leite Claudes Ausgabe nicht durch eine Pipe. claude -p ändert den Ausführungsmodus und kann damit auch das Verhalten der Zusammenfassungen ändern.
Im ersten Terminal sollte nach deinem Prompt zuerst Received user_prompt event. erscheinen. Danach sollten Zeilen für API-Anfragen folgen. Lass die Aufgabe abschließen und beende Claude regulär. Warte auf den letzten Telemetrieexport, bevor du den Empfänger mit Ctrl+C stoppst. Kopiere die abschließende Tabelle aus dem Ausgabeverlauf des Terminals.
Ergebnisse auswerten und fehlende Daten prüfen
Lies die Zeile agent_summary für deinen Messzeitraum. Der Nenner von request_% ist die Zahl aller erfassten Ereignisse zu API-Anfragen. Für cost_% ist es die Summe der geschätzten Kosten aller erfassten API-Anfragen:
summary cost share = 100 × summary estimated USD / all captured estimated USD
Die Spalte models listet die gemeldeten Modelle je Quelle auf. Wenn du den Cache in einem bestehenden Monitoring-System untersuchst, prüfe auch input_tokens, cache_read_tokens, cache_creation_tokens und output_tokens.
Anfragen ohne Quellenangabe bleiben als (missing) im Nenner enthalten. Fehlt bei einer erfassten Anfrage ein gültiger Kostenwert, zeigt der Empfänger für Kostenanteile n/a. Kläre fehlende Felder, bevor du die Aufschlüsselung als vollständig behandelst.
Fehlt die Zeile agent_summary, wurden in diesem Zeitfenster keine solchen Anfragen beobachtet. Das belegt nicht, dass die Funktion deaktiviert ist. Prüfe zuerst, ob Prompt-Ereignisse, Ereignisse zu API-Anfragen und tatsächliche Hintergrundarbeit vorhanden waren.
Wenn nichts ankommt, prüfe den laufenden Empfänger, http/json als Protokoll und einen Endpunkt mit /v1/logs am Ende. Ein von deiner Organisation verwaltetes Ziel kann lokale Einstellungen übersteuern. Starte für weitere Diagnosen claude --debug-file ./otel-debug.log in derselben Subshell. Suche anhand der Monitoring-Anleitung nach Exporterfehlern mit dem Präfix [3P telemetry].
Warum Gesprächsverlauf, /usage und Rechnung abweichen können
Eine fehlende Zeile im Gesprächsverlauf kann die Zuordnung zu einer Quelle verbergen, obwohl die Gesamtsumme der Sitzung stimmt. In Issue #104358 berichtet rabitlord1324 von fehlenden Einträgen für Hintergrundanfragen, bezeichnet den internen Kostenabgleich von Claude Code aber als korrekt.
Die aktuelle Dokumentation zu /usage erklärt Sitzungssummen und den Verbrauch nach Modell. Die hier nötige Aufschlüsselung nach query_source beschreibt sie nicht. Wenn ein Parser Zusammenfassungen im Gesprächsverlauf übersieht, belegt das also nicht, dass sie auch in /usage fehlen.
cost_usd bleibt eine Schätzung. Claude Code rechnet normalerweise mit Listenpreisen. Eine verwaltete modelPricing-Tabelle kann jedoch andere Preise für die Berichte festlegen. Verbrauchtes Abonnementkontingent und API-Gebühren sind unterschiedliche Größen. Gleiche bei nutzungsabhängiger Abrechnung die Ergebnisse mit den tatsächlichen Nutzungsdaten deines Anbieters ab.
Wenn du BetterToken nutzt, lautet die dokumentierte Basis-URL für Claude Code https://bettertoken.ai. Der Katalog führt claude-opus-5-5 mit Stand 2026-11-01. Gleiche deinen Messzeitraum mit Modell, Tokenverbrauch und Gebühren in der Konsole ab.
Kosten senken und nützliche Arbeit erhalten
Wenn die gemessenen Zusatzkosten ins Gewicht fallen, beginne mit enger gefassten Aufgaben oder weniger Hintergrundagenten. Stand 2026-11-01 dokumentieren weder die Referenz zu Umgebungsvariablen noch die Subagentenreferenz einen Schalter, der nur Zusammenfassungen deaktiviert.
| Option | Was sich ändert | Abwägung |
|---|---|---|
| Weniger oder kürzere Hintergrundaufgaben | Verringert die Gelegenheiten für wiederholte Zusammenfassungen des Gesprächsverlaufs | Kann nützliche Parallelität kosten; vergleiche die Ausführungszeit |
| Ein kleineres Modell für einen Subagenten mit klar begrenzter Aufgabe | Ändert das Modell, das die delegierte Arbeit ausführt | Prüfe die Ergebnisqualität und das tatsächlich in der Telemetrie gemeldete Modell |
CLAUDE_CODE_DISABLE_BACKGROUND_TASKS=1 claude | Deaktiviert die Hintergrundausführung über die betroffenen Werkzeuge weitgehend | Claude setzt die Arbeit erst fort, wenn die Subagenten fertig sind |
CLAUDE_CODE_FORK_SUBAGENT=0 claude | Verhindert, dass Claude selbstständig Gesprächsverzweigungen startet | Hintergrundsubagenten bleiben möglich; ausbleibende Zusammenfassungen sind nicht garantiert |
| Community-Patch über Bun preload | Versucht, den Timer für Zusammenfassungen abzufangen | Führt fremden Code in Claude Code aus und kann nach einem Update nicht mehr funktionieren |
Die Variable für Hintergrundaufgaben entfernt den Parameter run_in_background und verhindert die automatische Hintergrundausführung über die betroffenen Werkzeuge. Für MCP-Aufgaben, das Werkzeug Monitor und separate Hintergrundsitzungen gelten Ausnahmen oder eigene Einstellungen. Die Variable schaltet nicht jede Hintergrundaktivität ab.
Die Steuerung des Fork-Modus, also der Gesprächsverzweigungen, ist dokumentiert. Dass dadurch auch Zusammenfassungen ausbleiben, ist jedoch nicht garantiert. Unter 2.1.312 berichtete chrisvaillancourt von ausbleibenden Zusammenfassungen auf macOS. dblumenau beobachtete auf Linux weiterhin solche Anfragen. Die Berichte unterscheiden sich bei Konfiguration und Ausführungsmodus.
Setze die Variable vor dem Start einer neuen Sitzung. Prüfe widersprüchliche env-Einträge in ~/.claude/settings.json und den Projekteinstellungen. Sie können Werte ersetzen, die aus der Shell übernommen wurden.
Betrachte den Flamerix-Preload-Patch als experimentelle Community-Lösung. Prüfe zunächst den Code einer festgelegten Revision. Kontrolliere nach jedem Clientupdate die Zahl der Anfragen. Ein eingefrorener Fortschrittstext allein zeigt nicht, dass keine Anfragen mehr gesendet werden.
Nutze für klar begrenzte Rechercheaufgaben die Anleitung zur Modellprüfung bei Subagenten mit rein lesendem Zugriff. Vergrößern umfangreiche Werkzeugdefinitionen den Kontext, prüfe mit dem Kostenvergleich für MCP-Kontext den Nutzen eines kleineren Werkzeugumfangs.
Ändere jeweils nur eine Variable. Vergleiche dieselbe Aufgabe, dasselbe Modell, die Kontextbedingungen, das akzeptierte Ergebnis und die Laufzeit zusammen mit den Kosten je Quelle. Aktiviere die Hintergrundarbeit wieder, wenn der Verlust sinnvoller Parallelität mehr kostet als die gemessene Einsparung.