Für die Qwen API gibt es zwei verbreitete Zugriffswege: die native DashScope-Schnittstelle von Alibaba Cloud Model Studio und die OpenAI-kompatible Schnittstelle. Die Fehlerstrukturen unterscheiden sich teilweise, die Diagnosereihenfolge ist jedoch gleich: zuerst den HTTP-Statuscode prüfen, dann code und message im Antwortkörper lesen, anschließend die request_id suchen, den Fehler mit einer minimalen Anfrage reproduzieren und erst zuletzt Parameter ändern oder das Modell wechseln.

Dieser Beitrag gliedert nach 401, 404, 429, 400, 5xx und Timeouts und liefert eine Fehlercode-Übersicht, Log-Felder, Wiederholungscode sowie eine Checkliste für die Kontaktaufnahme mit dem Support. Modelle, Quoten und Abrechnung richten sich nach der offiziellen Dokumentation und den Modellpreisen auf dieser Website.

Hinweis: Qwen, Tongyi Qianwen, Alibaba Cloud, Bailian und DashScope sind Marken der Alibaba Group und der jeweiligen Rechteinhaber. Dieser Beitrag dient ausschließlich der technischen Fehleranalyse; es besteht keine Zugehörigkeit, Vertretungs- oder Partnerschaftsbeziehung zu den genannten Unternehmen. Fehlercodes, Drosselungsregeln und Schnittstellenverhalten können sich mit der Version ändern; maßgeblich sind die offizielle Dokumentation und die tatsächliche Antwort.

1. Zuerst Schnittstellenmodus und Fehlerstruktur unterscheiden

Die native DashScope-Schnittstelle gibt code, message und request_id üblicherweise auf der obersten Ebene der Antwort zurück. Die OpenAI-kompatible Schnittstelle folgt dem OpenAI-Stil; der Fehlerkörper sieht aus wie {"error": {"message": "...", "type": "...", "code": "..."}}. Im Kompatibilitätsmodus kann die request_id in den Antwort-Headern oder im Antwortkörper stehen; das Feld richtet sich nach der tatsächlichen Rückgabe.

In der Implementierung sollte nicht nur eine Struktur ausgewertet werden. Zuerst den vollständigen Antwortkörper unverändert ins Log schreiben, dann Werte in der Reihenfolge error.code und oberste Ebene code entnehmen. So muss der Fehlercode bei einem Wechsel des Schnittstellenmodus nicht neu geschrieben werden.

2. 401: Authentifizierung fehlgeschlagen – zuerst die Region prüfen

401 bedeutet, dass die Identität nicht verifiziert wurde, und hängt meist nicht von Modellfähigkeit oder Guthaben ab. Bei Bailian sind drei Fehlertypen verbreitet:

  • InvalidApiKey oder invalid_api_key: Key falsch, unvollständig kopiert oder Base-URL und Region des Keys stimmen nicht überein.
  • invalid access token or token expired: Token abgelaufen oder eine paketspezifische Adresse mit einem normalen Key konfiguriert.
  • Zugriff verweigert: WorkspaceId ungültig oder das Konto gehört nicht zu diesem Workspace.

Qwen-API-Keys sind an eine Region gebunden; Keys für Peking und Singapur dürfen nicht gemischt werden. Das ist der am leichtesten übersehene Punkt: Der Code bleibt unverändert, nur die Base-URL wird getauscht, und schon tritt reproduzierbar 401 auf.

Die Prüfung in dieser Reihenfolge:

  1. Bestätigen, dass der Header Authorization: Bearer <key> lautet und nach dem Doppelpunkt ein Leerzeichen steht.
  2. Das Präfix der Umgebungsvariable ausgeben und sicherstellen, dass sie nicht leer, veraltet oder mit Zeilenumbruch behaftet ist.
  3. Prüfen, ob Base-URL und Region des Keys übereinstimmen.
  4. Key-Typ und Schnittstelle abgleichen: Adressen für nutzungsbasierte Zahlung, Coding-Paket und Token-Paket unterscheiden sich.
  5. Mit einem neuen Key eine minimale Anfrage senden, um Key-Probleme von Proxy- oder Gateway-Problemen zu trennen.

3. 404 und 400: Modellname, Freischaltung und Kontext

Ein 404 ist meist kein Dienstausfall, sondern ein Problem mit Modellname oder Verfügbarkeit. Bei ModelNotFound oder model_not_found sind drei Dinge zu prüfen: Ist der Modellname falsch geschrieben, ist das Modell freigeschaltet, und ist es in der aktuellen Region verfügbar? model_not_supported bedeutet, dass das Modell den OpenAI-kompatiblen Modus nicht unterstützt; dann ist die Schnittstelle oder das Modell zu wechseln.

400 hat vielfältigere Ursachen. InvalidParameter zeigt einen Parameter außerhalb des Bereichs an, etwa temperature oder top_p. InvalidParameter.NotSupportEnableThinking bedeutet, dass das Modell den Parameter für den Denkmodus nicht unterstützt. Eine Kontextüberschreitung liefert häufig Range of input length should be [1, xxx] mit dem zugrunde liegenden Code InternalError.Algo.InvalidParameter; auch eine Gesamtnachrichtenlänge über dem Modelllimit kommt infrage. Die Lösung besteht im Kürzen des Verlaufs, in blockweisen Zusammenfassungen oder einem Modell mit längerem Kontext – nicht im wiederholten Retry.

4. 429: zuerst vier Drosselungsarten und zwei Quotentypen unterscheiden

429 wird am häufigsten falsch behandelt. Ein 429 bei Bailian umfasst mindestens die folgenden Klassen; die Tabelle nennt auch Fehler wegen Zahlungsrückstand und nicht freigeschalteter Dienste, die leicht mit Drosselung verwechselt werden:

HTTP Fehlercode Bedeutung Geeignet für Retry
429 Throttling.RateQuota, LimitRequests Anfragen pro Minute (RPM) überschritten Ja, nach Backoff
429 Throttling.AllocationQuota, insufficient_quota Tokens pro Minute (TPM) überschritten Ja, Backoff und Eingabe reduzieren
429 Throttling.BurstRate Kurzfristiger Verkehrsanstieg löst Schutz aus Ja, Zustellung glätten
429 Throttling.Concurrency Zu viele gleichzeitige Anfragen Ja, Parallelität senken
429 AllocationQuota.FreeTierOnly Kostenloses Kontingent erschöpft und Nur-kostenlos-Modus aktiv Nein, aufladen oder Schalter aus
429 BudgetLimitExceeded Kontobudget aufgebraucht Nein, Budget anpassen
400 Arrearage Konto im Rückstand oder Status anomal Nein, zuerst Konto wiederherstellen
403 AccessDenied.Unpurchased Dienst nicht freigeschaltet Nein, zuerst freischalten

Die Drosselung wird pro Alibaba-Cloud-Hauptkonto gezählt; Aufrufe von RAM-Unterkonten, Workspaces und mehreren Keys werden zusammengerechnet. „Ein Key pro Dienst“ umgeht das Gesamtkontingent daher nicht, sondern verhindert nur gegenseitige Verdrängung. Drosselung erholt sich üblicherweise im Minutenbereich; während der Wartezeit nicht hochfrequent wiederholen.

5. Timeouts und 5xx: in drei Abschnitten lokalisieren

Timeouts sind in drei Abschnitten zu betrachten: Ein Verbindungs-Timeout deutet meist auf DNS, Egress oder einen nicht erreichbaren Proxy hin; ein langsames erstes Token auf Warteschlange beim Upstream oder zu lange Eingabe; ein Lese-Timeout auf zu lange Ausgabe oder lange Inferenz. Die Behandlung unterscheidet sich, daher reicht es nicht, nur den Timeout-Wert zu erhöhen.

RequestTimeOut bei Bailian bedeutet, dass die Anfrage abgelaufen ist; die offizielle Erläuterung nennt ein Zeitlimit von 300 Sekunden. GatewayTimeout.InputDownload hängt mit dem Download von Eingabedateien zusammen. Die OpenAI-kompatible Schnittstelle kann außerdem 503 zurückgeben, was eine Überlastung der Engine anzeigt. Bricht eine Streaming-Anfrage ab, kann ein Fehlercode fehlen; dann zuerst die bereits empfangenen Inhalte, das letzte Datensegment und den Endgrund protokollieren und danach beurteilen, ob Netzwerkfluktuation, Proxy-Abbruch oder Upstream-Timeout vorliegt.

6. request_id und Logs: der Nachweis für die Fehlersuche

Laut offizieller Erläuterung wird die request_id mit der Antwort zurückgegeben, entweder in den Headern oder im Antwortkörper. In der Praxis empfiehlt sich eine doppelte Erfassung: Der Client erzeugt eine trace_id, die alle Wiederholungen überdauert, und speichert zugleich die Anfragekennung aus den Response-Headern sowie die request_id aus dem Antwortkörper unverändert. Wurde nichts protokolliert, lässt sich in den Modell-Monitoring-Logs der Konsole suchen, sofern Inferenz-Logs aktiviert sind.

Ein Log enthält mindestens: Zeitpunkt, trace_id, Base-URL, Region, Modellname, HTTP-Statuscode, Fehlercode, Fehlermeldung, request_id, Dauer, Anzahl der Wiederholungen und ob gestreamt wurde. Vom Key nur die ersten Zeichen oder einen Hash speichern; Nutzertexte und vollständige Antworten nicht abschnittsweise auf die Festplatte schreiben. Bei der Kontaktaufnahme mit dem Support ist ein Datensatz mit diesen Feldern deutlich hilfreicher als „gelegentliche Fehler“.

7. Retry und Backoff: Beispielcode

Der folgende Code deaktiviert die automatischen Retries des SDK, wiederholt nur behebbare 429- und 5xx-Fehler und gibt Statuscode, Fehlercode und request_id gemeinsam aus. Zahlungsrückstand, erschöpftes kostenloses Kontingent und Budgetüberschreitung fallen nicht unter die Wiederholung.

import os
import random
import time
import uuid

import httpx
from openai import OpenAI, APIConnectionError, APIStatusError, APITimeoutError

client = OpenAI(
    api_key=os.environ["DASHSCOPE_API_KEY"],
    base_url=os.environ.get(
        "DASHSCOPE_BASE_URL",
        "https://dashscope.aliyuncs.com/compatible-mode/v1",
    ),
    timeout=httpx.Timeout(connect=5.0, read=180.0, write=30.0, pool=10.0),
    max_retries=0,  # SDK-Retries deaktiviert; die Logik unten steuert sie zentral
)

RETRYABLE_429 = {
    "Throttling",
    "Throttling.RateQuota",
    "Throttling.AllocationQuota",
    "Throttling.BurstRate",
    "Throttling.Concurrency",
    "LimitRequests",
    "limit_requests",
    "ResourceExhausted",
}

def unpack_error(exc: APIStatusError):
    body = {}
    try:
        body = exc.response.json()
    except Exception:
        pass
    err = body.get("error", body) if isinstance(body, dict) else {}
    code = err.get("code") if isinstance(err, dict) else None
    request_id = None
    if isinstance(body, dict):
        request_id = body.get("request_id")
    request_id = (
        request_id
        or exc.response.headers.get("x-request-id")
        or exc.response.headers.get("x-dashscope-request-id")
    )
    return code, request_id, exc.response.text[:500]

def ask(prompt: str, model: str, max_attempts: int = 4) -> str:
    trace_id = uuid.uuid4().hex[:12]
    for attempt in range(1, max_attempts + 1):
        try:
            resp = client.chat.completions.create(
                model=model,
                messages=[{"role": "user", "content": prompt}],
            )
            return resp.choices[0].message.content
        except APIStatusError as exc:
            code, request_id, body = unpack_error(exc)
            print(
                f"trace={trace_id} attempt={attempt} "
                f"http={exc.status_code} code={code} "
                f"request_id={request_id} body={body}"
            )
            retryable = exc.status_code >= 500 or (
                exc.status_code == 429 and code in RETRYABLE_429
            )
            if not retryable or attempt == max_attempts:
                raise
        except (APITimeoutError, APIConnectionError) as exc:
            print(f"trace={trace_id} attempt={attempt} err={type(exc).__name__}")
            if attempt == max_attempts:
                raise
        wait = min(2 ** (attempt - 1), 30) + random.uniform(0, 1)
        time.sleep(wait)
    raise RuntimeError("Wiederholungsversuche erschöpft")

Drei ergänzende Regeln: Wenn der Server Retry-After zurückgibt, ist dieser Vorrang einzuräumen; das Retry-Budget global steuern, damit nicht mehrere Dienste gleichzeitig den Verkehr vervielfachen; bei Anfragen mit Nebenwirkungen zuerst prüfen, ob sie bereits ausgeführt wurden, und erst dann über eine erneute Sendung entscheiden.

8. Parallelitätssteuerung: wirksamer als größere Retry-Zahlen

Drosselungsprobleme werden meist nicht durch Retries gelöst, sondern durch Steuerung am Eingang:

  • Keys nach Geschäftsbereich trennen und jeweils Obergrenzen für die Parallelität setzen, damit ein Batch-Job den Online-Dienst nicht lahmlegt.
  • Batch-Aufgaben aufteilen und zeitlich versetzen, um Lastspitzen zur vollen Stunde zu vermeiden.
  • Warteschlangen zur Spitzenkappung einsetzen; fehlgeschlagene Aufgaben in eine Verzögerungswarteschlange legen statt im Kreis zu wiederholen.
  • Anteil der 429-Fehler und p95-Latenz überwachen; bei einem Sprung zuerst die Parallelität senken.
  • Offline-Aufgaben bevorzugt über die Batch-Schnittstelle abwickeln, um Echtzeit-Drosselung zu umgehen.
  • Ersatzmodell oder Ersatzzugang bereithalten und vor dem Wechsel die Parameterkompatibilität prüfen.

Drosselungsgrenzen werden pro Modell und Konto konfiguriert; eine Aufladung erhöht RPM oder TPM nicht automatisch. Für höhere Quoten den geschäftlichen Antragsweg nutzen und fremde Zahlen nicht ungeprüft übernehmen.

9. Checkliste vor der Kontaktaufnahme mit dem Support

  1. Zeitpunkt, Zeitzone und ob der Fehler geballt auftritt.
  2. Base-URL, Region, Schnittstellenpfad, Modellname und Anfragemethode.
  3. HTTP-Statuscode, Fehlercode und vollständige Fehlermeldung.
  4. request_id; falls nicht vorhanden, die selbst erzeugte trace_id.
  5. Eine reproduzierbare minimale curl-Anfrage mit anonymisiertem Key.
  6. Ob gestreamt wurde, ob langer Kontext vorlag und ob die Konfiguration gerade geändert wurde.
  7. Auswirkungsbereich: einzelner Key, einzelner Workspace oder alle Dienste.

10. Häufig gestellte Fragen (FAQ)

1. Bedeutet 429 immer Drosselung?

Nicht unbedingt. 429 kann auch bedeuten, dass das kostenlose Kontingent erschöpft oder das Budget überschritten ist; ein Zahlungsrückstand kann 400 mit Arrearage liefern, ein nicht freigeschalteter Dienst 403. Zuerst den Fehlercode lesen und dann entscheiden, ob Backoff, Aufladung oder Konfigurationsänderung nötig ist.

2. Was tun, wenn 401 auch mit einem neuen Key auftritt?

Vor allem Region und Key-Typ prüfen. Qwen-Keys sind regionsgebunden; ein Peking-Key mit Singapur-Adresse liefert 401, ebenso eine paketspezifische Adresse mit normalem Key. Danach Header, Umgebungsvariablen und prüfen, ob ein Reverse-Proxy die Authentifizierungsinformation verwirft.

3. Wie mit einer Kontextüberschreitung umgehen?

Zuerst den Nachrichtenverlauf kürzen und irrelevante Anhänge sowie doppelte Absätze entfernen; dann lange Dokumente blockweise zusammenfassen oder per Retrieval reduzieren; reicht das nicht, ein Modell mit längerem Kontext wählen. Eine Eingabeüberschreitung lässt sich nicht durch höhere max_tokens lösen.

4. Sollten Timeouts wiederholt werden?

Nur bei Verbindungsfehlern und Lese-Timeouts, mit begrenzter Anzahl, exponentiellem Backoff und Obergrenze. Bei Geschäftsvorgängen mit Nebenwirkungen zuerst prüfen, ob sie bereits ausgeführt wurden, um doppelte Bestellungen oder Schreibvorgänge zu vermeiden.

5. Wo findet man die request_id?

Zuerst in den Response-Headern und im Antwortkörper; das Feld richtet sich nach der tatsächlichen Schnittstelle. Wurde nichts erfasst, in den Modell-Monitoring-Logs der Konsole suchen, sofern Inferenz-Logs aktiviert sind. Bei der Support-Anfrage trace_id und eine minimale Reproduktion mitsenden.

Nächster Schritt

Erstellen Sie zunächst im ZSQH AI Gateway einen Test-Key und proben Sie 401, 404, 429, Kontextüberschreitung und Timeout jeweils einmal, bevor Sie die Produktionsüberwachung anbinden. Verfügbare Modelle und Abrechnungsarten finden Sie unter Modellpreise.

Weiterführende Beiträge