DeepSeek API のエラーは大きく 4 種類に分かれます。認証、パスとモデル名、レート制限、タイムアウトです。正しい切り分け順序は、まず HTTP ステータスコードとエラー種別を見て、次にリクエスト ID と最小再現を確認し、最後にプロンプトを変えたりモデルを替えたりすることです。順序を逆にすると、設定の問題をモデル能力の問題と誤認しやすくなります。
本記事では 401、404、429、タイムアウトの 4 種類に分け、原因、確認手順、再利用できるバックオフのコードを示します。モデルと価格はサイト内のモデル価格を基準にしてください。
注記:DeepSeek はその権利者の商標です。エラー種別、レート制限の基準、インターフェースの挙動はバージョンによって調整される可能性があります。本記事は 2026 年 10 月時点の一般的な状況を例にしており、最終的には公式ドキュメントを基準とします。
一、まず 4 種類のエラーを区別する
| ステータスまたは現象 | 一般的な意味 | 典型的な原因 | 対応順序 |
|---|---|---|---|
| 401 | 認証失敗 | キーの誤り、Bearer の欠落、キーの失効 | まず認証情報を修正 |
| 404 | パスまたはモデルが存在しない | Base URL の誤り、古いモデル名、パスの二重連結 | アドレスとモデル名を確認 |
| 429 | レート制限またはクォータ制限 | 同時実行の急増、キーの共用、再試行の嵐 | バックオフ、同時実行を削減 |
| タイムアウト | 接続または読み取りのタイムアウト | ネットワーク、長い出力、推論モデル、プロキシ | 層ごとに切り分け |
| 400 | リクエストパラメータまたはコンテキストの問題 | コンテキスト超過、形式エラー | 計量化して分割 |
| 5xx | 上流サービスのエラー | サーバー障害または過負荷 | バックオフ、経路を変更 |
ログには少なくとも時刻、ステータスコード、エラー種別、モデル名、所要時間、リクエスト ID を記録します。キー全体を記録したり、ユーザーの原文をそのままログに出力したりしないでください。
二、401:まずリクエストヘッダー、次にキー
401 は身元の検証に通らなかったことを示し、モデル能力や残高とは通常関係ありません。次の順序で確認します。
- リクエストヘッダーが
Authorization: Bearer <key>になっているか、他の認証方式になっていないか。 - キーの前後に空白、改行、余分な引用符が入っていないか。チャット画面からのコピーで最も混入しやすいです。
- 環境変数が実際に読み込まれているか。先頭部分だけ出力して確認します。
- キーが削除、ローテーション、無効化されていないか。
- Base URL とキーが同じプラットフォームのものか。公式キーにゲートウェイのアドレスを組み合わせると 401 になります。
- リバースプロキシが
Authorizationヘッダーを上書きまたは破棄していないか。
export DEEPSEEK_API_KEY="sk-あなたのキー"
curl "https://api.deepseek.com/chat/completions" \
-H "Authorization: Bearer $DEEPSEEK_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "deepseek-chat",
"messages": [{"role": "user", "content": "OK とだけ返してください"}],
"max_tokens": 16
}'
このコマンドが 200 を返せば、キー、Base URL、モデル名の 3 つは通っています。それでも 401 になる場合は、新しいキーで最小リクエストを実行し、キー自体の問題か、プロキシやゲートウェイの設定問題かを切り分けます。
三、404:アドレスとモデル名の誤りが最も多い
404 は通常「API が停止した」のではなく、存在しないパスやモデルにリクエストが到達したことを意味します。よくある原因は次のとおりです。
- Base URL に他ベンダーのアドレスを書いた、または
/v1を余分に書いた/書き忘れた。 - SDK が
/chat/completionsを自動で連結するのに、手書きのパスでもう一度連結した。 - 廃止された旧バージョンのモデル名を使った、または大文字小文字や接尾辞が一致していない。
- ゲートウェイのアドレスと公式アドレスを混用し、パス規則が異なっている。
- リバースプロキシの書き換え規則がパスを壊した。
確認時はまず curl で完全なアドレスを叩き、レスポンス本文のエラー情報を確認します。そのうえで Base URL とモデル名をサイト内の価格ページと項目ごとに照合してください。コード内に複数のアドレスをハードコードせず、環境ごとに設定し、テスト環境のアドレスが本番に持ち込まれないようにします。
四、429:レート制限であり残高不足ではない
429 は、リクエストがレート、同時実行、またはクォータの制限を超えたことを示します。DeepSeek はピーク時にリクエストを制限したりキューに入れたりする場合があり、具体的な基準は公式ドキュメントを基準とします。よくある発生場面は次のとおりです。
- 複数のサービスが 1 つのキーを共用し、互いの枠を圧迫している。
- バッチ処理が正時に一斉に開始され、トラフィックのパルスが発生している。
- 再試行にバックオフがなく、失敗するほど大量に送信して再試行の嵐になる。
- 長い出力や推論タスクが多くのリソースを占有し、同時実行に回せる余裕が小さくなる。
| 現象 | 考えられる原因 | 対応 |
|---|---|---|
| ピーク時に 429 が集中 | 上流の負荷またはトラフィックのパルス | キュー、送信の平準化、時間帯の分散 |
| 単一キーを複数サービスで使用して 429 | クォータの共有 | プロジェクトごとにキーを分割 |
| 再試行後に悪化 | バックオフなしの再試行 | 指数バックオフとランダムな揺らぎ |
| 長いリクエストで先に 429 | 出力 Token の占有が多い | max_tokens または同時実行を削減 |
import random
import time
from openai import OpenAI, RateLimitError, APITimeoutError, APIStatusError
client = OpenAI(
api_key="sk-あなたのキー",
base_url="https://api.deepseek.com",
max_retries=0, # SDK の自動再試行を切り、独自の再試行との二重実行を避ける
)
def ask(prompt: str, retries: int = 4) -> str:
for attempt in range(retries):
try:
resp = client.chat.completions.create(
model="deepseek-chat",
messages=[{"role": "user", "content": prompt}],
max_tokens=1024,
timeout=60,
)
return resp.choices[0].message.content
except (RateLimitError, APITimeoutError):
wait = min(2 ** attempt, 20) + random.random()
print(f"{attempt + 1} 回目失敗、{wait:.1f} 秒待機")
time.sleep(wait)
except APIStatusError as exc:
if exc.status_code >= 500:
wait = min(2 ** attempt, 20) + random.random()
time.sleep(wait)
continue
raise
raise RuntimeError("再試行回数を使い切りました")
print(ask("レート制限とは何かを 1 文で説明してください"))
再試行が適するのは一時的なエラーだけです。すでに副作用が発生した業務では、冪等キーまたは状態確認で実行済みかどうかを確かめてから、再送するか決めます。
五、タイムアウト:接続、読み取り、ストリーミングを分けて考える
タイムアウトはサービス停止とは限りません。まずどこで止まっているかを特定します。
| 現象 | 考えられる原因 | 対応 |
|---|---|---|
| 接続タイムアウト | DNS、ネットワーク出口、プロキシに到達不能 | ネットワークとプロキシを確認し、回線を変更 |
| 初回 Token が遅い | 上流の待ち行列、プロンプトが長すぎる | 入力を短縮、時間帯を分散、軽量モデルに変更 |
| 読み取りタイムアウト | 出力が長い、推論モデルの思考が長い | 読み取りタイムアウトを延長、出力を制限 |
| ストリーミング中断 | ネットワークの揺らぎ、プロキシの切断 | 再接続に対応、受信済み内容を記録 |
| サイト全体で同時にタイムアウト | ローカル出口または上流の障害 | 予備経路に切り替え、サービス状態を確認 |
import httpx
from openai import OpenAI
client = OpenAI(
api_key="sk-あなたのキー",
base_url="https://api.deepseek.com",
timeout=httpx.Timeout(connect=5.0, read=120.0, write=30.0, pool=10.0),
)
接続タイムアウトと読み取りタイムアウトは別々に設定します。すべてのタイムアウトを非常に大きな値にすると、障害時にスレッドプールを占有し続けます。逆に小さすぎると、正常な長いタスクを誤って打ち切ります。タスク種別ごとに設定するのがより安全です。
六、切り分け順序の一覧表
- ステータスコード、エラー種別、リクエスト ID、モデル名、発生時刻を記録する。
- 401 はキー、リクエストヘッダー、環境変数、プラットフォームの一致を確認する。
- 404 は Base URL、パスの連結、モデル名を確認する。
- 400 はパラメータ、コンテキスト長、画像やファイルの形式を確認する。
- 429 は同時実行、キーの共用、再試行戦略、ピーク時間帯を確認する。
- タイムアウトは DNS、プロキシ、出力長、読み取りタイムアウト設定を確認する。
- 5xx はまずバックオフして再試行し、継続する場合はリクエスト ID を添えてサービス提供者に連絡する。
- 障害のたびに監視とアラートを追加し、ユーザーからの指摘で初めて気づく事態を避ける。
七、監視とログ
| フィールド | 用途 |
|---|---|
| 時刻とプロジェクト | ピークと影響範囲の特定 |
| ステータスコードとエラー種別 | 認証、レート制限、上流エラーの区別 |
| リクエスト ID | サービス提供者への調査依頼の鍵 |
| モデル名とバージョン | モデル変更後に発生したかの判断 |
| 入力・出力 Token | コストと長いリクエストの分析 |
| 所要時間と再試行回数 | テール遅延と再試行の嵐の発見 |
監視では少なくとも 1 時間単位で 401、404、429、タイムアウト、5xx の件数を集計します。エラー率が急増したときは、特定のプロジェクト、キー、モデルに集中していないかを先に見てから、同時実行の削減、経路の切り替え、バージョンのロールバックを決めます。
よくある質問
429 は残高不足ですか?
いいえ。429 はリクエストがレート、同時実行、クォータの制限を超えたことを示します。残高不足は通常、別のエラーを返すか、レスポンス本文で説明されます。まず同時実行とキーの共用を確認し、その後に口座残高を確認します。
404 の最も多い原因は何ですか?
Base URL の誤り、パスの二重連結、モデル名の期限切れです。まず curl で完全なアドレスを叩き、次にサイト内の価格ページでモデル名を確認すれば、通常は数分で特定できます。
タイムアウトは無限に再試行すべきですか?
すべきではありません。再試行には上限、バックオフ、アラートが必要です。タイムアウトは、リクエストがすでに上流で実行されたことを意味する場合もあります。副作用のある業務は状態を確認してから再送を決めます。
ストリーミング出力が中断したらどうしますか?
まず受信済みの内容と中断位置を記録し、ネットワークの揺らぎ、プロキシの切断、上流のタイムアウトのどれかを判断します。クライアントは再接続と重複排除に対応し、途中までの内容を完全な結果としてそのまま保存しないようにします。
ゲートウェイのエラーと公式のエラーをどう区別しますか?
リクエスト ID とエラー種別を残し、同じリクエストを公式入口とゲートウェイ入口の両方に送ります。キー、ネットワーク、ゲートウェイ設定、上流サービスのどれが問題かを素早く切り分けられます。
次のステップ
まず ZSQH AI Gateway でテスト用キーを作成し、401、404、429、タイムアウトをそれぞれ一度ずつ演習してから、本番の監視に組み込んでください。モデルの可用性と価格はモデル価格を基準とします。
関連記事:
