メインコンテンツへスキップ

概要

Shannonは、Server-Sent Events (SSE)およびWebSocketプロトコルを通じてリアルタイムのイベントストリーミングを提供します。ストリーミングを使用して、タスクの実行を監視し、進捗を表示し、生成される結果を受け取ります。
認証: ストリーミングエンドポイントは、他のAPIと同じヘッダーを必要とします。 ブラウザはEventSourceでカスタムヘッダーを送信できません。
  • 開発: GATEWAY_SKIP_AUTH=1を設定します。
  • 本番: バックエンドを介してSSEをプロキシし、X-API-KeyまたはBearerヘッダーを注入します。 SSEエンドポイントでは、フォールバックとして api_key クエリパラメータがサポートされています(例: ?api_key=sk_...)。その他のエンドポイントではヘッダーを使用してください。
ストリーミング制限:
  • タイムアウト: 5分間の非アクティブ後にストリームは自動的に閉じます
  • バッファサイズ: 接続ごとに最大1MBのバッファデータ
  • 使用メタデータ: すべてのLLMプロバイダー(OpenAI、Anthropic、Google、Groq、xAI)に対してトークン数とコストが利用可能になりました

エンドポイント

統一された送信 + ストリーム(推奨)

POST /api/v1/tasks/stream

タスクを送信し、そのイベントのストリーミングを即座に開始する最も簡単な方法です。このエンドポイントは、タスクの送信とストリーミングの設定を1回の呼び出しで組み合わせています。
フロントエンドアプリケーションに最適: このエンドポイントは、タスクを送信した直後に進捗を表示したいリアルタイムUIに最適です。

認証

必要: はい
または:

リクエストボディ

レスポンス

ステータス: 201 Created ボディ:

レスポンスフィールド

例: JavaScript/TypeScript

例: React Hook

例: Vue 3 Composition API

例: Python

このエンドポイントを使用する理由は? 統一されたエンドポイントにより、送信後すぐにストリーミングを開始でき、別々に送信して接続する際に発生する可能性のあるイベントの見逃しを防ぎます。

サーバー送信イベント (SSE)

GET /api/v1/stream/sse

サーバー送信イベントを使用したリアルタイムイベントストリーミング。

認証

必要: はい

クエリパラメータ

イベントフォーマット

各イベントはSSE仕様に従います:

リクエストの例

レスポンスの例

イベントIDの形式: idフィールドはRedisストリームID(例: 1719000000000-0)を使用しており、単純な整数ではありませんlast_event_idで再接続する際は、これらの正確なIDを使用する必要があります。詳しくは下記の再接続を参照してください。

WebSocket

GET /api/v1/stream/ws

WebSocketを介した双方向ストリーミング。

認証

ゲートウェイは、ヘッダーのみ(X-API-KeyまたはAuthorization)を使用してWebSocket接続を認証します。ブラウザはWebSocketハンドシェイク中にカスタムヘッダーを設定できません。ブラウザでの使用方法:
  • GATEWAY_SKIP_AUTH=1でローカル実行するか、
  • ヘッダーを挿入してからゲートウェイに転送するリバースプロキシを使用します。
サーバー環境向けのヘッダーを使用した例: Node (ws):
Python (websockets):
接続後にクエリ文字列または「auth」メッセージを介してAPIキーを渡すことは、ゲートウェイではサポートされていません。

メッセージタイプ

クライアント → サーバー:
サーバー → クライアント:

OpenAI互換ストリーミング

Shannonは/v1/chat/completionsでOpenAI互換のストリーミングエンドポイントも提供しており、ShannonイベントをOpenAI標準のchat.completion.chunk形式に変換します。これにより、OpenAI SDKを直接Shannonで使用できます。 OpenAI互換APIの完全なドキュメント(リクエスト/レスポンススキーマ、利用可能なモデル、Shannon固有の拡張(shannon_events)、SDK使用例を含む)については、OpenAI互換APIリファレンスを参照してください。

イベントタイプ

コアイベント

エージェントイベント

ツールイベント

LLMイベント

ほとんどの統合ではLLM_PARTIAL/LLM_OUTPUTではなく、thread.message.delta(ストリーミングテキスト)とthread.message.completed(使用メタデータ付きの最終結果)をリッスンしてください。

進捗およびシステムイベント

ストリームライフサイクルイベント

SSE経由では、STREAM_ENDライフサイクルイベントはdoneという名前のSSEイベントとしてdata: [DONE](プレーンテキスト、JSONではない)で配信されます。WebSocket経由では、通常のJSONイベントとして"type": "STREAM_END"として現れます。

チームと承認

コード例

Python with httpx (SSE)

Python - イベントフィルタリング付きストリーム

JavaScript/Node.js (SSE)

JavaScript/Node.js - WebSocket (ws)

Go (SSE)

Bash/curl (SSE)

使用例

1. リアルタイム進捗表示

2. すべてのイベントをファイルにログ

3. ツール使用メトリクスの収集

4. React UI 統合

ディープリサーチストリーミング

ディープリサーチタスクは2〜10分かかります。Task APIを通じてディープリサーチをトリガーするにはcontext.force_researchを使用します:
context.research_strategyでリサーチの深さを制御できます:
ディープリサーチにおけるChat API vs Task API: Chat API(/v1/chat/completionsmodel: "shannon-deep-research"を指定)でもディープリサーチをトリガーできますが、そのストリーミング形式にはSSEイベントIDが含まれません。そのため再接続は不可能です。プラットフォームに接続時間制限がある場合(例: Vercelの5分制限)やページリフレッシュに対応する必要がある場合は、Task APIを使用してください

ハートビート

サーバーはプロキシやロードバランサーを介した接続を維持するために、10秒ごとに: ping SSEコメントを送信します:
これはSSEコメントであり(JSONメッセージではありません)。pingの受信が停止した場合、接続が切断されています。直ちに再接続してください。

再接続

SSE接続は、ネットワークの問題、プロキシのタイムアウト、またはプラットフォームの制限(例: Vercel hobbyプラン: 5分の接続制限)により切断される可能性があります。Shannonは中断したところからの再開をサポートしています。 仕組み:
  1. 受信した各SSEイベントのidフィールドを記録する
  2. 切断時にlast_event_idパラメータを付けて再接続する
  3. サーバーはそのID以降のすべてのイベントをリプレイする(約256イベントをバッファ、24時間TTL)

プロアクティブ再接続(推奨)

接続時間制限のあるプラットフォームでは、制限前にプロアクティブに切断します:

ページリフレッシュ / フォールバック

ユーザーがページをリフレッシュし、workflow_idがまだある場合:
  1. タスクのステータスを確認: GET /api/v1/tasks/{workflow_id}
  2. TASK_STATUS_RUNNINGの場合 → SSEに再接続
  3. TASK_STATUS_COMPLETEDの場合 → レスポンスから結果を表示
  4. TASK_STATUS_FAILEDの場合 → エラーを表示

Pythonでの再接続

ベストプラクティス

2. タイムアウトの実装

3. クライアントサイドでのイベントフィルタリング

4. 最後のイベントから再開

注意: last_event_id は、Redis ストリーム ID(例: 1700000000000-0)または数値シーケンス(例: 42)のいずれかを受け入れます。数値の場合、リプレイには seq > last_event_id のイベントが含まれます。

比較: SSE vs WebSocket vs ポーリング

それぞれの使用時期

  • SSE: ほとんどのユースケース、リアルタイムモニタリング、進捗表示
  • WebSocket: インタラクティブアプリケーション、双方向通信が必要
  • ポーリング (GET /api/v1/tasks/): レガシーシステム、ストリーミングサポートなし

関連エンドポイント

タスクの提出

POST /api/v1/tasks

ステータス取得

GET /api/v1/tasks/

Python SDK

client.stream() を使用

ノート

イベント保持:
  • Redis: すべてのイベントは24時間保存(リアルタイムストリーミング)
  • PostgreSQL: 重要なイベントは90日間保存(履歴クエリ)
  • 接続が切れた場合は last_event_id を使用してストリーミングを再開
接続制限:
  • APIキーごとに最大100の同時ストリーミング接続
  • 5分間の非アクティブタイムアウト(自動接続切断)
  • 接続ごとのバッファサイズ制限は1MB
  • 単一のWebSocket上で複数のワークフローを多重化することを検討