Skip to main content
LibreChat is joining ClickHouse to power the open-source Agentic Data Stack 🎉 Learn more
LibreChat

再開可能なストリーム

接続が切断された後のAI応答の復旧、タブやデバイス間でのチャットの同期、およびスケールアウトされたインスタンス間でのストリームの維持を行います。

再開可能なストリーム(Resumable streams)により、AIの応答中に接続が切断されても、進行中の応答を維持できます。ネットワークが切断されたり、ブラウザが更新されたり、タブやデバイスを切り替えたりした場合でも、LibreChatはすでにストリームされたコンテンツを再構築し、中断した箇所から継続します。同じ仕組みによって、1つの会話を複数の閲覧者で同期させることも可能です。

得られるもの

  • 応答が失われることはありません。 ネットワークの切断、ブラウザの更新、サーバーの再起動が発生しても、ストリーミングされたコンテンツが破棄されることはありません。
  • タブは同期されます。 1つの会話を2つのブラウザタブで開くと、両方のタブでリアルタイムに同じ更新が反映されます。
  • デバイスを途中で切り替える。 デスクトップで生成を開始し、スマートフォンでその結果の続きを確認できます。
  • バックグラウンド生成。 長い応答を開始し、別のタブやアプリに移動しても、戻ってきたときには応答がすべて完了しています。
  • 共有された会話。 共有されたチャットの閲覧者は全員、同時にコンテンツがストリーミングされる様子を確認できます。

仕組み

メッセージを送信すると、LibreChatはストリーミングされたすべてのデルタを記録する生成ジョブを作成します。接続が切断された場合:

  1. クライアントが切断を検知します。
  2. 再接続時、サーバーはジョブの記録されたデルタから、これまでにストリーミングされたコンテンツを再構築します。
  3. 欠落しているコンテンツは、単一の同期イベントで配信されます。
  4. 現在の位置からストリーミングを継続します。

これは自動的に実行されるため、ユーザーによる操作は必要ありません。

デプロイメントモード

LibreChatには、再開可能なストリームのための2つのバックエンドが付属しています。

シングルインスタンスモード (デフォルト)

ストリームの状態をメモリ内に保持し、パブ/サブ(pub/sub)にはNode.jsの EventEmitter を使用します。これはデフォルトの設定であり、追加の設定は不要です。ローカル開発、単一サーバーへのデプロイ、および Docker Compose セットアップに対応しています。

Redis モード (本番環境)

Redis StreamsおよびPub/Subを使用しているため、ストリームの状態はインスタンス間で共有されます。Kubernetesクラスターを含む、水平スケーリング、負荷分散、または高可用性が求められるデプロイメントで利用してください。Redisを使用することで、あるインスタンスで開始された生成を別のインスタンスで再開できるため、ローリングデプロイメントやオートスケーリング中もアクティブなストリームを維持できます。

シングルインスタンスですか?その場合、Redisは不要である可能性が高いです

In-memoryモードは、単一のLibreChatインスタンスに関するすべてを処理します。ロードバランサーの背後で複数のインスタンスを実行する場合、Redisが必要になります。Redisは単一インスタンスのデプロイメントにおいてもキャッシュやセッションストレージとして有用ですが、再開可能なストリーム(resumable streams)のためだけに必須というわけではありません。

設定

Redis Streams を有効にする

USE_REDIS=true を設定すると、再開可能なストリームで自動的に Redis が使用されるようになります。明示的に制御するには USE_REDIS_STREAMS を使用してください。

USE_REDIS=true
REDIS_URI=redis://localhost:6379
# Resumable streams use Redis automatically when USE_REDIS=true.
# Set USE_REDIS_STREAMS to control it explicitly:
USE_REDIS_STREAMS=true

Redis Cluster

Redis Clusterの場合は、クラスターモードを有効にし、REDIS_URIにノードをリストしてください。

USE_REDIS_STREAMS=true
USE_REDIS_CLUSTER=true
REDIS_URI=redis://node1:7001,redis://node2:7002,redis://node3:7003

LibreChatは、マルチキー操作が同じクラスタスロットに割り当てられるように、ハッシュタグ付きのキーを使用します。

再構築されるもの

再接続時に、LibreChatは記録されたデルタイベントを集約して以下を再構築します:

  • メッセージコンテンツ(テキスト、ツール呼び出し、引用)
  • エージェントの実行ステップと中間推論
  • メタデータと状態情報

ストレージのメカニズムは、デプロイモードによって異なります:

コンポーネントストレージメカニズム
ChunksRedis Streams (XADD/XRANGE)
Job metadataRedis Hash structures
Real-time eventsRedis Pub/Sub channels
ExpirationAutomatic TTL after stream completion

LibreChatは、これを低コストに抑えるためにいくつかの最適化を適用しています:

  • メモリファーストのリカバリ。 同じインスタンスに再接続する際、ローカルキャッシュから読み込まれるため、Redisへのラウンドトリップを回避します。
  • アクセス時のクリーンアップ。 古いジョブエントリはクエリ実行時に削除され、完了したストリームは自動的に期限切れとなります。
  • ガベージコレクションによるストレージ。 インメモリモードでは、ストリームグラフを WeakRef で保持するため、会話が終了すると自動的に収集されます。

テスト

機能が動作していることを確認するには、任意のモデルでストリーミング会話を開始し、以下のいずれかを試してください:

  • タブ。 同じチャットを2つ目のタブで開くと、両方が同期されるはずです。
  • 切断。 ネットワークを一時的に切断してから、再接続してください。
  • ナビゲーション。 ストリームの途中で別のページに移動し、その後戻ります。

各ケースにおいて、コンテンツの欠落なく完全なレスポンスが生成される必要があります。

トラブルシューティング

ストリームが再開されません。 Redisに接続可能であること、および USE_REDIS_STREAMS が設定されていることを確認してください。

docker exec -it librechat-redis redis-cli ping
# Expected: PONG
 
echo $USE_REDIS_STREAMS

コンテンツが重複して表示される場合。これは通常、クライアントのバージョン不一致が原因です。LibreChatを最新バージョンにアップデートしてください。

シングルインスタンスモードでのメモリ使用量が高い場合。 完了したストリームはガベージコレクションされます。メモリ使用量が高いままの場合は、完了しない非常に長時間実行されているストリームや、クリーンアップされずにエラーが発生したストリームがないか確認してください。

  • Redis Configuration: キャッシュおよび水平スケーリングのためのRedis設定
  • Agents: ツールを使用するAIエージェント
  • Docker Deployment: コンテナベースのデプロイメント

実装の詳細については、PR #10926 を参照してください。

このガイドはいかがでしたか?