Latenz messen und analysieren
Auf dieser Seite
Warum Latenz Ihre wichtigste Kennzahl ist
Wenn Sie eine von LLMs gesteuerte Anwendung in die Produktion bringen, bestimmt die von den Nutzern wahrgenommene Latenz direkt die Akzeptanz. Eine Antwort, die 8 Sekunden dauert, vertreibt 70 % der Nutzer: Sie schließen den Tab, versuchen die Anfrage erneut oder schließen, dass das Werkzeug nicht funktioniert. Keine Qualitätsverbesserung kann diesen Verlust ausgleichen, da er stattfindet, bevor der Nutzer die Antwort überhaupt liest.
Die Herausforderung in der Produktion besteht darin, dass „es ist langsam” keine Diagnose ist. Die gleiche Dauer von acht Sekunden kann auf einen zu großen Systemprompt, eine zu ehrgeizige Einstellung für das Nachdenken, einen schlecht platzierten Anwendungsserver oder eine Nachbearbeitung zurückzuführen sein, die auf die vollständige Antwort wartet, bevor etwas angezeigt wird. Jede Ursache erfordert eine andere Lösung, und die falsche Lösung ändert nichts. Diese Lektion lehrt Sie, die End-to-End-Latenz zu messen, zu zerlegen und zu diagnostizieren, damit Sie aus einer Beschwerde eine handlungsorientierte Zahl machen können.
Latenzkomponenten
Die Gesamtlatenz eines API-Aufrufs lässt sich in vier Segmente unterteilen, die Sie trennen müssen. Netzwerklatenz ist die Übertragungszeit zwischen Ihrem Server und der OpenAI API; sie ist in Ihren Anwendungsprotokollen unsichtbar, kann aber 100 Millisekunden überschreiten, wenn Ihr Server weit vom Endpunkt entfernt ist. Time to First Token (TTFT) misst die Verzögerung vor der Generierung des ersten Tokens: Dies ist das Segment, das Nutzer als „Warten” empfinden, da der Bildschirm leer bleibt, bis es abgeschlossen ist. Time Per Output Token (TPOT) beschreibt dann die Generierungsgeschwindigkeit für jedes nachfolgende Token; multipliziert mit der Antwortlänge ergibt dies die Dauer des Textscrollens. Schließlich umfasst die Anwendungslatenz alles, was Ihr eigener Server vor und nach dem Aufruf tut: Abrufen von Dokumenten, Zusammenstellen des Prompts, Validierung von JSON-Ausgaben und Schreiben in die Datenbank.
Diese Zerlegung ist nicht nur akademisch. Ein Team, das feststellt, dass sein TTFT in Ordnung ist, aber seine Anwendungslatenz zwei Sekunden hinzufügt, wird keine Modelle wechseln: Es wird seine SQL-Abfrage zum Abrufen des Kontexts untersuchen.
Messen mit Python
So instrumentieren Sie einen Aufruf an die Responses API, um jedes Segment zu erfassen:
import time
import openai
client = openai.OpenAI()
def measure_latency(prompt: str, model: str = "gpt-5.6-terra") -> dict:
"""Misst die zerlegte Latenz eines API-Aufrufs."""
metrics = {}
start_total = time.perf_counter()
# Streamen Sie den Aufruf, um das TTFT zu messen
stream = client.responses.create(
model=model,
input=prompt,
stream=True,
)
first_token = True
output_tokens = 0
for event in stream:
if event.type == "response.output_text.delta":
if first_token:
metrics["ttft"] = time.perf_counter() - start_total
start_generation = time.perf_counter()
first_token = False
output_tokens += 1
metrics["total_duration"] = time.perf_counter() - start_total
metrics["output_tokens"] = output_tokens
if output_tokens > 1:
metrics["tpot"] = (
(metrics["total_duration"] - metrics["ttft"]) / (output_tokens - 1)
)
return metrics
result = measure_latency("Explain Bayes' theorem in 3 sentences.")
for key, value in result.items():
print(f"{key}: {value:.4f}" if isinstance(value, float) else f"{key}: {value}")
Die wichtigste Erkenntnis aus diesem Code ist die Verwendung von stream=True. Ohne Streaming können Sie das TTFT nicht isolieren: Die API gibt erst nach der vollständigen Antwort zurück, sodass Sie nur eine Gesamtzeit messen. Der Timer startet vor dem Aufruf, stoppt beim ersten Text-Delta, und die verbleibende Dauer geteilt durch die Anzahl der verbleibenden Tokens ergibt das TPOT. Führen Sie denselben Prompt gegen zwei Modelle oder zwei Einstellungen für das Nachdenken durch, und innerhalb weniger Minuten haben Sie den quantitativen Vergleich, der die Vermutungen Ihres Teams ersetzt.
Engpässe diagnostizieren
Ein hohes TTFT, über zwei Sekunden, weist auf drei Ursachen hin. Die häufigste ist ein zu langer Systemprompt, der nicht zwischengespeichert ist: Das Modell muss bei jedem Aufruf mehrere tausend Tokens aufnehmen, bevor es mit dem Schreiben beginnt. Als Nächstes kommt eine hohe Einstellung für das Nachdenken – hoch, xhigh oder max bei GPT-5.6 – die das Modell absichtlich dazu bringt, zu denken, bevor es irgendeine sichtbare Ausgabe produziert; dies ist kein Fehler, sondern erwartetes Verhalten, aber es sollte eine bewusste Entscheidung sein und keine Einstellung, die von einem Prototypen vererbt wurde. Schließlich könnte es einen Lastspitz auf der OpenAI-Seite geben, den Sie nicht steuern können: Genau deshalb benötigen Sie eine kontinuierliche Messung statt einer einmaligen Prüfung, um dies von den anderen beiden zu unterscheiden.
Ein hohes TPOT, über 50 ms pro Token, liest sich anders. Ein sehr hohes max_output_tokens zwingt das Modell, lange Sequenzen zu produzieren, und die Gesamtdauer steigt mechanisch an, auch wenn jedes Token mit normaler Geschwindigkeit ankommt. Der Einsatz komplexer Funktionsaufrufe mit vielen deklarierten Werkzeugen belastet die Generierung. Konkret zahlt ein Team, das fünfzehn Tools in seinem Schema belassen hat, obwohl die Hälfte davon nicht mehr verwendet werden, diese Overhead-Kosten bei jedem Aufruf.
Überwachungs-Tools
Einmaliges Messen reicht nicht aus: Sie müssen die Verteilung über die Zeit verfolgen, da der Schwanz der Verteilung Support-Tickets generiert. Für die kontinuierliche Überwachung in der Produktion integrieren Sie diese Metriken in Ihren Observability-Stack:
import logging
from dataclasses import dataclass, field
@dataclass
class LatencyMetrics:
"""Aggregiert Latenzmetriken über ein gleitendes Fenster."""
measurements: list[dict] = field(default_factory=list)
def add(self, measurement: dict) -> None:
self.measurements.append(measurement)
if len(self.measurements) > 1000:
self.measurements = self.measurements[-1000:]
@property
def ttft_p50(self) -> float:
values = sorted(m["ttft"] for m in self.measurements if "ttft" in m)
if not values:
return 0.0
return values[len(values) // 2]
@property
def ttft_p99(self) -> float:
values = sorted(m["ttft"] for m in self.measurements if "ttft" in m)
if not values:
return 0.0
idx = int(len(values) * 0.99)
return values[min(idx, len(values) - 1)]
def report(self) -> str:
return (
f"TTFT p50={self.ttft_p50:.3f}s p99={self.ttft_p99:.3f}s | "
f"Samples: {len(self.measurements)}"
)
Das gleitende Fenster mit tausend Messungen verhindert unbeschränktes Speicherwachstum, während es eine repräsentative Stichprobe des aktuellen Verkehrs erhält. Entscheidend ist, dass diese Klasse zwei Perzentile, nicht einen Durchschnitt, ausliefert: Ein p50 von 700 ms mit einem p99 von 6 Sekunden beschreibt einen Dienst, den die meisten Nutzer als schnell empfinden und eine Minderheit als unbrauchbar. Ein Durchschnitt hätte beide Realitäten verdeckt. Haken Sie report() in Ihr Metrik-Tool ein und setzen Sie einen Warnschwellenwert für das p99, bevor Sie das übrige System berühren.
Kernaussagen
- Latenz zerlegt sich in TTFT + Generierung (TPOT × Tokens) + Netzwerk
- Messen Sie immer mit Streaming, um das echte TTFT zu erhalten
- Verfolgen Sie p50- und p99-Perzentile, nicht nur den Durchschnitt
- Modellwahl und Einstellungen für das Nachdenken wirken sich direkt auf die Latenz aus: GPT-5.6 Terra mit niedrigem Nachdenken reagiert schneller als GPT-5.6 Sol mit hohem Nachdenken