APIを使ったリアルタイム応答(ストリーミング)を使っているとき、突然接続が切れてしまう経験はありませんか?私は最初、この問題を全く理解しておらず、「応答が途中で止まってしまう」と嘆いていました。しかし、ストリーミングの中断は避けられないケースとして適切に処理する必要があるのです。本記事では、HolySheep AIのAPIを使って、ストリーミング中断時の接続管理とデータ完全性を確保する方法をゼロから解説します。
なぜストリーミング中断は发生するのか
ネットワークの問題、サーバーの過負荷、タイムアウトなど、ストリーミングは様々な理由で中断する可能性があります。重要なのは「中断してもデータが壊れない仕組み」を作ることです。HolySheep AIの<50msレイテンシなら中断リスクも大幅に軽減されますが、それでも備えた設計が大切です。
必要な准备
始める前に、以下の準備をお願いします:
- 今すぐ登録して無料クレジットを取得
- APIキーを確認(ダッシュボードの「API Keys」セクションで確認できます)
- Python 3.8以上をインストール
💡 スクリーンショットヒント: HolySheep AIダッシュボード左側のメニューから「API Keys」をクリックすると、認証用のキーをコピーできます。キーは他人と共有しないでください。
基本的なストリーミング実装(中断対応なし)
まずはシンプルなストリーミングの書き方を見てみましょう。以下のコードはHolySheep AIのGPT-5にストリーミングでリクエストを送る基本形です:
import requests
import json
def basic_streaming():
"""基本的なストリーミング実装(中断 обработкаなし)"""
url = "https://api.holysheep.ai/v1/chat/completions"
headers = {
"Authorization": "Bearer YOUR_HOLYSHEEP_API_KEY",
"Content-Type": "application/json"
}
data = {
"model": "gpt-5",
"messages": [{"role": "user", "content": "日本の四季について教えてください"}],
"stream": True
}
response = requests.post(url, headers=headers, json=data, stream=True)
full_response = ""
for line in response.iter_lines():
if line:
# SSE形式: data: {...} を解析
decoded = line.decode('utf-8')
if decoded.startswith('data: '):
json_str = decoded[6:] # "data: " を除去
if json_str == "[DONE]":
break
chunk = json.loads(json_str)
if 'choices' in chunk and len(chunk['choices']) > 0:
delta = chunk['choices'][0].get('delta', {})
if 'content' in delta:
full_response += delta['content']
print(delta['content'], end='', flush=True)
print("\n\n=== 完了 ===")
print(f"合計文字数: {len(full_response)}")
return full_response
if __name__ == "__main__":
basic_streaming()
💡 ポイント: stream=Trueにすることで、応答が逐次届きます。APIキーは必ず自分のものに置き換えてください。HolySheep AIなら、レートが¥1=$1と非常にコストパフォーマンスに優れています。
中断に対応丈夫なストリーミング実装
ここからが本番です。ネットワーク中断、网络切断に対応しながらも、既に受け取ったデータを失わないようにする実装を見てみましょう:
import requests
import json
import time
from typing import Optional, Callable
class ResilientStreamingHandler:
"""中断に対応丈夫なストリーミングハンドラー"""
def __init__(self, api_key: str, base_url: str = "https://api.holysheep.ai/v1"):
self.api_key = api_key
self.base_url = base_url
self.max_retries = 3
self.retry_delay = 2 # 秒
def stream_with_recovery(
self,
messages: list,
model: str = "gpt-5",
on_chunk: Optional[Callable] = None
) -> dict:
"""
中断からの回復機能付きストリーミング
- 部分的な応答を保持
- 自動再接続
- 進捗コールバック
"""
url = f"{self.base_url}/chat/completions"
headers = {
"Authorization": f"Bearer {self.api_key}",
"Content-Type": "application/json"
}
data = {
"model": model,
"messages": messages,
"stream": True
}
accumulated_content = ""
last_id = None
retry_count = 0
while retry_count < self.max_retries:
try:
response = requests.post(
url,
headers=headers,
json=data,
stream=True,
timeout=60
)
if response.status_code == 429:
# レート制限の場合
wait_time = int(response.headers.get('Retry-After', 60))
print(f"レート制限: {wait_time}秒待機...")
time.sleep(wait_time)
retry_count += 1
continue
response.raise_for_status()
for line in response.iter_lines():
if line:
decoded = line.decode('utf-8')
if decoded.startswith('data: '):
json_str = decoded[6:]
if json_str == "[DONE]":
break
try:
chunk = json.loads(json_str)
if 'choices' in chunk and len(chunk['choices']) > 0:
delta = chunk['choices'][0].get('delta', {})
if 'content' in delta:
content = delta['content']
accumulated_content += content
last_id = chunk.get('id')
if on_chunk:
on_chunk(content)
# 正常完了
return {
"status": "completed",
"content": accumulated_content,
"total_chars": len(accumulated_content),
"stream_id": last_id
}
except requests.exceptions.Timeout:
print(f"タイムアウト (試行 {retry_count + 1}/{self.max_retries})")
retry_count += 1
time.sleep(self.retry_delay * retry_count)
except requests.exceptions.ConnectionError as e:
print(f"接続エラー: {e}")
print("再接続を試みます...")
retry_count += 1
time.sleep(self.retry_delay * retry_count)
except Exception as e:
print(f"予期しないエラー: {e}")
return {
"status": "error",
"content": accumulated_content, # 部分的でも返す
"error": str(e),
"partial_chars": len(accumulated_content)
}
# 最大リトライ超過
return {
"status": "max_retries_exceeded",
"content": accumulated_content,
"total_chars": len(accumulated_content)
}
使用例
if __name__ == "__main__":
handler = ResilientStreamingHandler("YOUR_HOLYSHEEP_API_KEY")
def progress_callback(chunk):
"""各チャンク受信時に呼ばれる"""
print(chunk, end='', flush=True)
messages = [
{"role": "system", "content": "あなたは помощникです。"},
{"role": "user", "content": "自己紹介してください"}
]
result = handler.stream_with_recovery(
messages,
model="gpt-5",
on_chunk=progress_callback
)
print("\n\n=== 結果サマリー ===")
print(f"ステータス: {result['status']}")
print(f"受信文字数: {result.get('total_chars', result.get('partial_chars', 0))}")
データ完全性を确保するためのベストプラクティス
ストリーミング中断時にデータを失わないためには、以下のポイントを押さえておきましょう:
- 增量保存: 各チャンクを受け取るたびにデータを保存する
- チェックサム検証: 完了後にデータ整合性を確認する
- 部分応答の活用: 中断しても少なくとも部分的な応答は得られる設計にする
- セッション管理: stream_idを記録して中断位置を特定可能にする
💡 ヒント: HolySheep AIではWeChat PayやAlipayにも対応しているので、日本語圏以外的ユーザーも簡単に決済できます。DeepSeek V3.2なら$0.42/MTokという破格の安さで試すことも可能です。
よくあるエラーと対処法
エラー1: 「Connection reset by peer」(接続が相手にリセットされた)
# ❌ 错误な写法
response = requests.post(url, headers=headers, json=data, stream=True)
for line in response.iter_lines(): # 接続が切れるとここでクラッシュ
process(line)
✅ 正しい写法(接続エラー捕獲付き)
try:
response = requests.post(url, headers=headers, json=data, stream=True)
response.raise_for_status()
for line in response.iter_lines():
if line:
process(line)
except requests.exceptions.ConnectionError:
print("接続が切れました。部分的データを保存して終了します。")
save_partial_data(accumulated)
except Exception as e:
print(f"エラー: {e}")
# 既に蓄積したデータを必ず保存
save_partial_data(accumulated)
エラー2: 「JSON decode error at position 0」(JSON解析エラー)
# ❌ エラーを考虑しない写法
for line in response.iter_lines():
decoded = line.decode('utf-8')
if decoded.startswith('data: '):
chunk = json.loads(decoded[6:]) # 空行や不正なJSONでクラッシュ
✅ JSONエラーに対応した写法
for line in response.iter_lines():
if not line:
continue
try:
decoded = line.decode('utf-8')
if decoded.startswith('data: '):
json_str = decoded[6:]
if json_str and json_str != "[DONE]":
chunk = json.loads(json_str)
process(chunk)
except json.JSONDecodeError as e:
print(f"JSON解析エラー: {e} - スキップして継続")
continue
エラー3: 「TimeoutError」(タイムアウトエラー)
# ❌ タイムアウト无しの写法(永久に待つ可能性)
response = requests.post(url, headers=headers, json=data, stream=True)
✅ 適切なタイムアウト設定
from requests.exceptions import ReadTimeout, ConnectTimeout
try:
response = requests.post(
url,
headers=headers,
json=data,
stream=True,
timeout=(10, 30) # (接続タイムアウト, 読み取りタイムアウト)
)
except ConnectTimeout:
print("接続がタイムアウトしました。ネットワークを確認してください。")
except ReadTimeout:
print("読み取りがタイムアウトしました。応答データを保存して終了します。")
save_partial(accumulated)
エラー4: 「Rate limit exceeded」(レート制限超過)
# ✅ レート制限への適切な対応
if response.status_code == 429:
retry_after = int(response.headers.get('Retry-After', 60))
print(f"リクエスト過多です。{retry_after}秒後に再試行します。")
time.sleep(retry_after)
# 再リクエスト処理にジャンプ
elif response.status_code == 400:
error_data = response.json()
print(f"リクエストエラー: {error_data.get('error', {}).get('message')}")
まとめ:中断を意識した設計が成功のコツ
ストリーミングAPIを使う場合、中断は「起こりうる正常なケース」として設計に組み込むべきです。HolySheep AIの<50msという低レイテンシなら中断リスクは最小限,但你それでも本記事のような対策を入れておくことで、より堅牢なアプリケーションが作れます。
特に重要なポイント:
- части的なデータでも必ず保存する
- リトライ、回退机制を実装する
- タイムアウト時間は适当に設定する
- エラーログを必ず残す
HolySheep AIなら、GPT-4.1が$8/MTok、Claude Sonnet 4.5が$15/MTokという選択肢もあり、あなたの用途に合わせて最適なモデルを選べます。まずは今すぐ登録して無料クレジットで試してみましょう!
👉 HolySheep AI に登録して無料クレジットを獲得