Problem (die „kleine Änderung“, die dir eine Woche klaut)
Du änderst einen Prompt, weil der Agent etwas komisch klingt.
In dev sieht’s okay aus.
Dann kommt Production:
- tool calls/run kriechen hoch (merkt erstmal niemand)
- Latenz verdoppelt sich unter Load
- der Agent ignoriert plötzlich Stop‑Conditions
- ein seltener Edge Case wird ein täglicher Incident
Prompt‑Optimierung ist Engineering, kein Copywriting. Wenn du’s als „Text so lange ändern bis es gut wirkt“ behandelst, shippst du Regressionen mit Ansage.
Warum das in Prod scheitert
Prompts hängen in Prod an Dingen, die du nicht „wegprompten“ kannst:
- Tool‑Schemas (ein umbenanntes Feld und das Modell versteht’s nicht mehr)
- Budgets (Token‑Inflation macht Loops teuer)
- Stop Reasons (ein Prompt kann „probier’s noch einmal“ unbeabsichtigt fördern)
- externe Varianz (Search driftet, APIs werden flaky, Rate Limits greifen)
Der unbequeme Teil: ohne Harness kannst du Prompts nicht sicher optimieren. Der Harness muss nicht fancy sein. Er muss konsistent sein.
Diagramm: sichere Prompt‑Pipeline
Echter Code: versioniere Prompts wie Code (Python + JS)
Minimum, das sich lohnt:
- jeder Prompt hat eine stabile
prompt_id(Hash oder Versions‑String) - jeder Run loggt
prompt_id - Rollback ist ein Config‑Switch
import hashlib
from dataclasses import dataclass
from typing import Any, Dict
def prompt_id(text: str) -> str:
return hashlib.sha256(text.encode("utf-8")).hexdigest()[:12]
@dataclass(frozen=True)
class Prompt:
name: str
version: str
text: str
@property
def id(self) -> str:
return f"{self.name}:{self.version}:{prompt_id(self.text)}"
class Logger:
def event(self, name: str, fields: Dict[str, Any]) -> None: ...
def build_system_prompt(p: Prompt) -> str:
return (
"You are a production agent. You must follow tool policies and budgets.\n"
"Always stop with a stop_reason.\n\n"
f"[prompt_id={p.id}]\n"
+ p.text.strip()
)
def run_agent(task: str, *, prompt: Prompt, logger: Logger, budgets: Dict[str, Any]) -> Dict[str, Any]:
_sys = build_system_prompt(prompt)
logger.event("agent_start", {"prompt_id": prompt.id, "budget": budgets})
return {"output": "ok", "prompt_id": prompt.id, "stop_reason": "finish"}
PROMPTS = {
"support:v12": Prompt("support", "v12", "Answer using KB. If unsure, ask a clarifying question."),
"support:v13": Prompt("support", "v13", "Answer using KB. Cite tool results. If unsure, ask a clarifying question."),
}
ACTIVE_PROMPT = PROMPTS["support:v13"]import crypto from "node:crypto";
export function promptId(text) {
return crypto.createHash("sha256").update(text, "utf8").digest("hex").slice(0, 12);
}
export function makePrompt({ name, version, text }) {
const id = `${name}:${version}:${promptId(text)}`;
return { name, version, text, id };
}
export function buildSystemPrompt(prompt) {
return [
"You are a production agent. You must follow tool policies and budgets.",
"Always stop with a stop_reason.",
"",
"[prompt_id=" + prompt.id + "]",
prompt.text.trim(),
].join("\n");
}
export function runAgent(task, { prompt, logger, budgets }) {
buildSystemPrompt(prompt);
logger.event("agent_start", { prompt_id: prompt.id, budget: budgets });
return { output: "ok", prompt_id: prompt.id, stop_reason: "finish" };
}
const PROMPTS = {
"support:v12": makePrompt({ name: "support", version: "v12", text: "Answer using KB. If unsure, ask a clarifying question." }),
"support:v13": makePrompt({ name: "support", version: "v13", text: "Answer using KB. Cite tool results. If unsure, ask a clarifying question." }),
};
const ACTIVE_PROMPT = PROMPTS["support:v13"];Kombiniere das mit Golden Tasks + Invariants:
- driftet
stop_reason? - spiked
tool_calls/run? - steigen Tokens/Request?
Realer Ausfall (incident-style, mit Zahlen)
Wir haben einen Support‑Prompt „verbessert“, indem wir „sei gründlich“ reingeschrieben haben.
Nichts ist gecrasht. Aber das Modell hat gemacht, was wir wollten: es wurde gründlich.
Impact über 36 Stunden:
- p95 tokens/run: 7.5k → 14.2k
- avg tool calls/run: 4 → 11
- spend: +$620 (Tokens + Tool Credits)
- On‑Call: ~2 Stunden, um zu beweisen, dass es prompt‑getrieben war
Fix:
- Budgets cap’en (Steps/Tool Calls/Tokens)
- Golden‑Task‑Invariant: max Tool Calls + max Tokens pro Run
- „Gründlichkeit“ als bedingte Regel (nur wenn Tool‑Ergebnis fehlt)
Abwägungen
- Aggressive Prompts können Qualität erhöhen und Spend erhöhen. Beides gratis gibt’s nicht.
- Kurze Prompts sind schnell, aber oft zu schwammig bei Safety.
- Explizite Contracts sehen hässlich aus und sind in Prod besser.
Wann du Prompts NICHT optimieren solltest
Prompt‑Optimierung ersetzt nicht:
- Budgets (
/de/governance/budget-controls) - Tool‑Validation (
/de/tools/input-validation) - Logging (
/de/observability-monitoring/agent-logging) - Tests (
/de/testing-evaluation/unit-testing-agents)
Wenn dein Agent instabil ist, ist Prompt‑Tuning nur Random Walk.
Copy/Paste Checkliste
- [ ] Stabile
prompt_idpro Run loggen - [ ] Golden Tasks (10–50) aus realem Traffic
- [ ] Invariants: stop_reason, tool_calls Bound, Token Bound
- [ ] Canary + Rollback‑Switch
- [ ] Monitor: spend/run, tool_calls/run, latency/run
- [ ] Ein Golden Task pro Incident
Safe default config (YAML)
prompts:
active: "support:v13"
rollback: "support:v12"
require_prompt_id: true
testing:
golden_tasks:
- id: "kb_lookup"
expect_stop_reason: "finish"
max_tool_calls: 6
max_tokens: 9000
budgets:
max_steps: 25
max_tool_calls: 12
max_seconds: 60
observability:
log_prompt_id: true
alert_on_token_spike: true
In OnceOnly umsetzen (optional)
# onceonly-python: budgets + safe rollout guardrails
import os
from onceonly import OnceOnly
client = OnceOnly(api_key=os.environ["ONCEONLY_API_KEY"])
agent_id = "support-bot"
# Set budgets/limits before you ship prompt changes
client.gov.upsert_policy({
"agent_id": agent_id,
"max_actions_per_hour": 200,
"max_spend_usd_per_day": 50.0,
"max_calls_per_tool": {"kb.search": 6},
"allowed_tools": ["kb.search", "send_email"],
})
# After rollout, watch for spend/tool spikes
m = client.gov.agent_metrics(agent_id, period="day")
print("actions=", m.total_actions, "spend_usd=", m.total_spend_usd)
FAQ (3–5)
Von Patterns genutzt
Verwandte Failures
Verwandte Seiten (3–6 Links)
- Grundlagen: How agents use tools · Planning vs reactive agents
- Failures: Hallucinated sources · Budget explosion
- Governance: Budget controls · Tool permissions
- Observability: Logging für KI‑Agenten
- Testing: Unit Tests für KI‑Agenten