GLM API のエラーには 2 層あります。外層は HTTP ステータスコード、内層はレスポンス本文の業務コードです。外層だけを見ると誤判定しやすく、たとえば口座の未払いも 429 で返ります。切り分けの順序は、まず業務コードとエラーメッセージを読み、次にリクエスト ID またはエラー ID を探し、最小リクエストで再現し、最後にパラメータを変えるかモデルを替えることです。
本記事では 401、403、404、429、5xx、タイムアウトに分け、業務コードの対照表、エラー処理のコード、サポートに連絡する前のチェックリストを示します。モデルと価格はサイト内のモデル価格を基準とします。
注記:智谱、GLM、BigModel は関連する権利者の商標です。本記事は技術的な説明のみを目的とし、智谱とは提携・代理関係にありません。エラーコード、レート制限の基準、インターフェースの挙動はバージョンによって調整される可能性があり、最終的には公式ドキュメントと実際のレスポンスを基準とします。
一、まず 2 層のエラーを区別する
HTTP ステータスコードはプロトコル層の結果を示し、業務コードは具体的な原因を示します。同じ 401 でも、認証ヘッダーの欠落、Token の期限切れ、二要素認証の可能性があります。同じ 429 でも、レート制限、モデルの混雑、未払い、プラン上限の可能性があります。業務コードをログに記録することが、最も効率的な切り分けの第一歩です。
| HTTP | よくある業務コード | 意味 | 再試行に適するか |
|---|---|---|---|
| 401 | 1000 / 1001 / 1003 / 1005 | 認証失敗、認証ヘッダー欠落、Token 期限切れ、二要素認証 | いいえ。まず認証情報を修正 |
| 403 | 1220 | その API またはモデルへのアクセス権限がない | いいえ。プランと権限を確認 |
| 400 | 1210 / 1211 / 1221 / 1222 / 1261 | パラメータ誤り、モデル不存在、API 終了または不存在、Prompt 長すぎ | いいえ。リクエストを修正 |
| 429 | 1113 | 口座の未払い | いいえ。まずチャージ |
| 429 | 1302 / 1305 | 速度制限、モデルのアクセス量過大 | はい。バックオフ後に再試行 |
| 429 | 1308 / 1310 | 周期上限。next_flush_time でリセット | リセットを待ち、無理に再試行しない |
| 429 | 1311 / 1313 / 1315 | プランにモデル権限なし、公正使用制限、キー種別の不一致 | いいえ。プランとキーを確認 |
| 500 | 1200 / 1230 / 1234 | 内部エラー、フローエラー、ネットワークエラー(エラー ID を含む) | はい。バックオフし、エラー ID を保持 |
表は最も一般的な対応関係で、完全な一覧は公式ドキュメントを基準とします。ストリーミングの中断には業務コードがなく、原因が finish_reason や最後のデータ断片に現れる場合があります。
二、401:4 種類の認証失敗
401 は身元の検証に通らなかったことを示し、モデル能力や残高とは通常関係ありません。公式エラーコードはよくある原因を比較的細かく分けています。
- 1000 認証失敗:キーの誤り、コピー不完全、または削除済み。
- 1001 リクエストヘッダーに認証パラメータがない:
Authorization: Bearer <key>がない、またはプロキシに破棄された。 - 1003 Token の期限切れ:キーに有効期限がある、またはコンソールでローテーション済み。
- 1005 二要素認証が有効:プラットフォームの要求に従って検証を完了する。
確認は次の順序で行います。
- リクエストヘッダーの形式を確認する。コロンの後に空白 1 つ、キーの前後に引用符や改行がないこと。
- 環境変数の先頭部分を出力し、空値や古い値でないことを確認する。
- キーの種類を確認する。標準モデル API、Coding Plan、チームまたは企業キーは別々に管理し、混用しない。
- Base URL とキーの帰属が一致するか確認する。公式キーには公式アドレス、ゲートウェイキーにはゲートウェイアドレス。
- 新しいキーで最小リクエストを行い、キー自体の問題か、プロキシやゲートウェイの設定問題かを切り分ける。
チャット画面からキーをコピーすると、空白や改行が最も入りやすいです。まず 1 語だけ出力するリクエストを行えば、大半の初歩的なミスを排除できます。
三、403 と 404:権限、パス、モデル名
403 の一般的な業務コードは 1220 で、現在のアカウントにその API またはモデルへのアクセス権限がないことを示します。まずプランに対象モデルが含まれるか、キーが対応する製品種別か、開通していないインターフェースを呼んでいないかを確認します。この種のエラーは再試行しても無駄で、権限を変えるかキーを替えます。
404 の多くは「サービス停止」ではなく、アドレスの誤りです。Base URL の /v1 が余分または不足している、SDK が自動連結するのに完全なパスを手書きでもう一度連結した、リバースプロキシの書き換え規則がパスを壊した、などです。GLM のモデル名誤りは通常 400 の 1211 を返し、API の終了または不存在は 1221 と 1222 に対応します。したがって 404 を見たらまずアドレス、1211 を見たらモデル名を確認します。
モデル名は公式ドキュメントとサイト内の価格ページを基準とし、記憶でバージョン番号を書かないでください。モデルをアップグレードする前に、テスト環境でパラメータの互換性を確認します。
四、429:まず業務コードを読み、再試行するか決める
429 は最も誤って処理されやすいエラーです。少なくとも 5 種類の状況を含みます。
- 1113 口座の未払い:チャージ前に再試行しても意味がありません。
- 1302 速度制限に到達:同時実行を下げるかバックオフします。
- 1305 モデルの現在のアクセス量が過大:通常はピークに関係し、バックオフ後に再試行し、必要なら予備モデルに切り替えます。
- 1308、1310 周期使用上限に到達:エラーメッセージにリセット時刻があるので、クォータの回復を待ちます。
- 1309、1311、1313、1315:プラン期限切れ、モデル未開放、公正使用制限、キー種別の不一致。設定を変えなければ意味がありません。
自動再試行に適するのは 1302、1305 のような一時的なレート制限だけです。それ以外の場合、再試行は障害時間を延ばすだけです。レート制限の基準(同時実行、毎分リクエスト数、Token 速度)はプランとモデルによって変わり、コンソールと公式ドキュメントを基準とします。
五、5xx とタイムアウト:分けて特定する
500 系には 1200 内部エラー、1230 フローエラー、1234 ネットワークエラーがあります。1234 は通常エラー ID を伴うため、サポートに連絡する際は忘れずに保持してください。5xx が継続する場合はまずバックオフし、次にサービス状態や提供者の通知を確認します。高頻度の再試行はしないでください。
タイムアウトは 3 段階に分けて見ます。接続タイムアウトは DNS、出口、プロキシに到達できない状態です。初回 Token の遅さは通常、上流の待ち行列か入力が長すぎることが原因です。読み取りタイムアウトは多くが出力が長いか推論時間が長いことによります。3 者の対応方法は異なり、タイムアウト値を大きくするだけでは済みません。
ストリーミングリクエストが中断した場合、HTTP エラーコードも業務コードもないことがあります。まず受信済み内容と最後のデータ断片を記録し、finish_reason を確認してから、ネットワークの揺らぎ、プロキシの切断、上流のタイムアウトのどれかを判断します。途中までの内容を完全な結果としてそのまま保存しないでください。
六、リクエスト ID とログ:切り分けの証拠
公式レスポンスがすべてのインターフェースで同名のリクエスト ID を提供するとは限らず、フィールド名は実際のレスポンスとドキュメントを基準とします。エンジニアリング上より安全なのは二重記録です。クライアント側で trace_id を生成してすべての再試行を通し、同時に上流が返すエラー本文と、その中の request id、error id フィールドをそのまま保存します。
ログには少なくとも、時刻、trace_id、Base URL、モデル名、HTTP ステータスコード、業務コード、エラーメッセージ、所要時間、再試行回数、ストリーミングかどうかを含めます。キーは先頭数文字またはハッシュのみを記録し、ユーザーの原文と完全なレスポンスを丸ごとディスクに保存しないでください。
これらのフィールドは自分のためだけのものではありません。サポートに連絡するとき、trace_id、業務コード、最小再現リクエストを添えた記録は、「ときどきエラーが出ます」という一言よりはるかに有用です。
七、再試行とバックオフ:コード例
次のコードは SDK の自動再試行を無効にし、業務コードに応じて再試行するかを決め、trace_id、ステータスコード、業務コードをまとめて出力します。ネットワークタイムアウトは別に処理し、再試行には上限を設けます。
import os
import random
import time
import uuid
import httpx
from openai import OpenAI, APIConnectionError, APIStatusError, APITimeoutError
client = OpenAI(
api_key=os.environ["GLM_API_KEY"],
base_url=os.environ.get(
"GLM_BASE_URL", "https://open.bigmodel.cn/api/paas/v4"
),
timeout=httpx.Timeout(connect=5.0, read=120.0, write=30.0, pool=10.0),
max_retries=0, # SDK の自動再試行を切り、以下のロジックで一元管理する
)
RETRYABLE_CODES = {1302, 1305} # 速度制限、モデル混雑。未払いとプラン上限は含まない
def ask(prompt: 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=os.environ["GLM_MODEL"],
messages=[{"role": "user", "content": prompt}],
max_tokens=1024,
)
return resp.choices[0].message.content
except APIStatusError as exc:
code = None
try:
code = int(exc.response.json().get("code"))
except Exception:
pass
print(
f"trace={trace_id} attempt={attempt} "
f"http={exc.status_code} code={code} "
f"body={exc.response.text[:500]}"
)
retryable = exc.status_code >= 500 or (
exc.status_code == 429 and code in RETRYABLE_CODES
)
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), 20) + random.uniform(0, 1)
time.sleep(wait)
raise RuntimeError("再試行回数を使い切りました")
補足の規則が 3 つあります。サーバーが返す Retry-After があれば優先して尊重すること。再試行の予算は全体で管理し、複数サービスの分が重ならないようにすること。副作用のあるリクエストは冪等キーで状態を確認してから再送すること。
八、同時実行の管理:再試行回数を増やすより効果的
レート制限の問題は通常、再試行ではなく入口の管理で解決します。
- サービスごとに独立したキーと同時実行上限を設定する。
- バッチ処理を分割し、時間帯をずらし、正時のトラフィックパルスを避ける。
- キューでピークを平準化し、失敗したタスクは遅延キューに入れ、その場で繰り返さない。
- 429 の割合と P95 遅延を監視し、急増時はまず同時実行を下げる。
- 予備モデルまたは予備入口を用意するが、切り替え前にパラメータの互換性を確認する。
同時実行上限、毎分リクエスト数、Token 速度の具体的な基準はプランとモデルによって変わり、コンソールと公式ドキュメントを基準とします。他人の数値をそのまま使わず、自分の実測結果で設定してください。
九、サポートに連絡する前のチェックリスト
- 発生日時とタイムゾーン、障害が集中的に発生したか。
- Base URL、インターフェースパス、モデル名、リクエスト方式。
- HTTP ステータスコード、業務コード、完全なエラーメッセージ。
- エラー ID またはリクエスト ID。なければ自分で生成した
trace_idを提供する。 - 再現可能な最小 curl リクエスト(キーはマスキングする)。
- ストリーミングか、長コンテキストか、直前に設定を変更したか。
- 影響範囲:単一キー、単一プロジェクト、または全サービス。
これらをそろえておけば、サポートチームは情報のやり取りを繰り返さずに直接特定できます。障害のたびに監視とアラートを追加し、ユーザーからの指摘で初めて気づく事態を避けてください。
十、よくある質問(FAQ)
1. 429 は常にレート制限ですか?
いいえ。429 は未払い(1113)、周期上限(1308、1310)、プランにモデル権限なし(1311)、公正使用制限(1313)の場合もあります。まず業務コードを読み、バックオフ、チャージ、設定変更のどれが必要か決めます。
2. 401 で新しいキーに替えても失敗する場合は?
リクエストヘッダーが Authorization: Bearer <key> か、環境変数が読み込まれているか、キー種別とインターフェースが一致しているか、Base URL とキーの帰属が一致しているか、リバースプロキシが認証ヘッダーを破棄していないかを確認します。
3. タイムアウトは再試行すべきですか?
接続失敗と読み取りタイムアウトのみ、回数を限定して指数バックオフで再試行します。副作用のある業務は、実行済みかどうかを確認してから再送し、二重注文や重複書き込みを避けます。
4. ストリーミング出力が途中で切れた場合、どう切り分けますか?
受信済み内容、最後のデータ断片、finish_reason を記録し、ネットワークの揺らぎ、プロキシの切断、上流のタイムアウトを区別します。クライアントは再接続と重複排除に対応し、途中までの内容を保存しないようにします。
5. エラーメッセージにステータスコードしかなく業務コードがない場合は?
完全なレスポンス本文とレスポンスヘッダーを保存し、trace_id、Base URL、モデル名、最小再現リクエストを記録してからサービス提供者に連絡します。ゲートウェイ経由の場合は、ゲートウェイ側にも同じ情報を提供し、上流ログとの照合を容易にします。
次のステップ
まず ZSQH AI Gateway でテスト用キーを作成し、401、403、429、5xx、タイムアウトをそれぞれ一度ずつ演習してから、本番の監視に組み込んでください。利用可能なモデルと課金方式はモデル価格を参照してください。
