Normal path: execute → tool → observe.
Problem (aus der Praxis)
Alles ist gut.
Dann wird dein Agent “smarter”.
Er packt rein:
- mehr History
- mehr Tool Output
- mehr “helpful context”
Latenz driftet hoch. Cost driftet hoch. Und irgendwann wird Policy truncat’t und der Agent verhält sich seltsam.
Token Overuse ist kein Theorieproblem. Es ist ein Incident, den du grafen kannst.
Warum das in Production bricht
1) Kontext wächst per Default
Ohne Cap wächst:
- Chat History
- Memory
- Tool Outputs (HTML ist besonders böse)
Das Modell kennt deine Budgets nicht. Es frisst alles.
2) Prompt Bloat → Truncation
Große Prompts erhöhen die Chance, dass:
- der Anfang droppt
- und dort steht meist deine Policy
Ohne Policy ist das Modell nicht “evil”. Es ist unconstrained.
3) Tool Outputs sind Token Bomben
Raw HTML/Logs/Stack Traces sind riesig. Wenn du sie 1:1 pastest:
- Tokens explodieren
- das Modell kann’s oft nicht gut nutzen
Extract → summarize → kleine Slice.
4) Memory macht’s schlimmer
“Store everything” Memory wird oft zu “show everything”. Das ist prompt inflation.
5) “Nimm einfach ein bigger context Modell” fix’t es nicht
Größere Context Windows:
- kosten mehr
- sind langsamer
- truncaten trotzdem (später)
Fix: Context Budget + Context Builder.
Implementierungsbeispiel (echter Code)
Cheap Prompt Budgeter:
- cap total context
- keep newest
- summarise oldest when over budget (placeholder)
Chars hier; Tokens in real systems.
from dataclasses import dataclass
from typing import Iterable
@dataclass(frozen=True)
class ContextBudget:
max_chars: int = 12_000
def summarize(text: str) -> str:
return text[:2000] + "…"
def build_context(chunks: Iterable[str], *, budget: ContextBudget) -> str:
parts: list[str] = []
for c in chunks:
parts.append(c)
ctx = "\n\n".join(parts)
if len(ctx) <= budget.max_chars:
return ctx
over = len(ctx) - budget.max_chars
head = ctx[: over + 1000]
tail = ctx[over + 1000 :]
return summarize(head) + "\n\n" + tailexport function summarize(text) {
return text.slice(0, 2000) + "…";
}
export function buildContext(chunks, { maxChars = 12_000 } = {}) {
const ctx = chunks.join("\\n\\n");
if (ctx.length <= maxChars) return ctx;
const over = ctx.length - maxChars;
const head = ctx.slice(0, over + 1000);
const tail = ctx.slice(over + 1000);
return summarize(head) + "\\n\\n" + tail;
}Das gibt dir nicht perfekte “Memory”. Es gibt dir den ersten Win: ein Budget gegen runaway prompts.
Echter Incident (mit Zahlen)
Agent beantwortete “warum ist der Job gefailt?” und packte full Logs in den Prompt.
Dann paste ein Kunde 2MB Log Blob.
Impact:
- tokens/request: 4k → 45k
- p95 Latenz: 3.2s → 19s
- spend: ~$520 an einem Tag
- worst: Policy truncat’t → unsichere Tool Vorschläge
Fix:
- input caps (max chars) auf user logs
- structured extraction statt raw dumps
- context budgeter + summarization tier
- metrics/alerts auf tokens/request
Logs sind nützlich. Raw logs sind kein Prompt-Format.
Abwägungen
- Summaries verlieren Details (die raw dumps eh nicht geholfen haben).
- Strikte Caps können Power User nerven; biete async upload an.
- Token Counting ist extra Arbeit. Es zahlt sich schnell aus.
Wann du es NICHT nutzen solltest
- Wenn du exaktes Reasoning über lange Docs brauchst: eher targeted retrieval + workflows.
- Wenn du untrusted Text nicht safe summarizen kannst: nicht wholesale reinpasten.
- Wenn du Tokens nicht messen kannst: starte mit chars, fix tokens danach.
Checkliste (Copy/Paste)
- [ ] Cap user text size (logs/HTML/PDF)
- [ ] Cap tool output size vor Kontext
- [ ] Context builder mit hard budget (tokens/chars)
- [ ] Summarization tier mit eigenem Budget
- [ ] Policy Constraints jeden Turn wiederholen
- [ ] Metrics: tokens/request, latency, spend/run
- [ ] Alerts auf spikes und drift
Sicheres Default-Config-Snippet (JSON/YAML)
context:
max_prompt_tokens: 2500
max_untrusted_chars: 8000
summarize_when_over_budget: true
policy:
repeat_critical_constraints_every_turn: true
metrics:
track: ["tokens_per_request", "latency_p95", "spend_per_run"]
FAQ (3–5)
Von Patterns genutzt
Verwandte Failures
Q: Kann ich nicht einfach ein bigger context Modell kaufen?
A: Kannst du, aber du zahlst Latenz+Cost und truncat’t trotzdem irgendwann. Budgeting ist billiger.
Q: Wie zähle ich Tokens korrekt?
A: Provider Tokenizer. Wenn du’s nicht kannst: char caps jetzt, token counting als follow-up.
Q: Soll ich alles in Memory speichern?
A: Events speichern: ja. Alles dem Modell zeigen: nein. Memory ≠ Prompt Size.
Q: Warum Policy Constraints wiederholen?
A: Truncation killt den Anfang. Repetition hält Constraints am Leben.
Verwandte Seiten (3–6 Links)
- Foundations: Agent Memory Types · LLM-Limits
- Failure: Budget Explosion · Halluzinierte Quellen
- Governance: Tool Permissions
- Production stack: Production Stack