Closed4

[メモ] Memobaseのバッファ・キャッシュの仕組み

kun432kun432

バッファ

長期メモリを生成するための会話データを登録する際のレスポンス速度に影響する。

Memobaseのバッファの仕組み

Memobaseはバッファシステムを使用して、ユーザーのインタラクションを一時的に保存し、バッチ処理することでコストとパフォーマンスを最適化しています。

バッファの基本動作

ユーザーがデータ(チャットメッセージなど)を挿入すると、それは即座に処理されるのではなく、まずBufferZoneテーブルに保存されます。各バッファエントリには以下の情報が含まれます:

  • user_id: ユーザーID
  • blob_id: データのID
  • blob_type: データの種類(chat、summaryなど)
  • token_size: トークン数
  • status: 処理状態(idle、processing、done、failed)

フラッシュのトリガー条件

バッファは以下の条件で自動的にフラッシュ(処理)されます:

  1. トークン数の上限: バッファ内のトークン数がCONFIG.max_chat_blob_buffer_token_size(デフォルトは512トークン)を超えた場合
  2. アイドル時間: バッファが一定期間アイドル状態の場合

手動でフラッシュをトリガーすることも可能です:

u.flush()  # 非同期
u.flush(sync=True)  # 同期(処理完了を待つ)

フラッシュ処理の流れ

フラッシュが実行されると、以下の処理が行われます:

  1. バッファの取得: idle状態のバッファエントリを取得
  2. ステータス更新: バッファのステータスをprocessingに変更
  3. LLM処理: BLOBS_PROCESS[blob_type]を使用してデータを処理(プロファイル抽出、イベント生成など)
  4. 完了処理: 成功時はステータスをdoneに更新し、設定に応じて元のblobを削除

バックグラウンド処理

非同期フラッシュの場合、処理はバックグラウンドで実行されます。バックグラウンド処理では:

  • Redisキューを使用してバッファIDを管理
  • ロック機構により同時実行を防止
  • 最大15分間、最大200タスクまで処理

Notes

バッファシステムの主な利点は、LLM処理のコストを削減し、レスポンス速度を向上させることです。メッセージごとにフラッシュすると、トークン消費量が大幅に増加するため、自動処理に任せることが推奨されます。ただし、テスト時やセッション終了時など、即座にメモリ更新が必要な場合は手動フラッシュを使用できます。

関連する設定は以下

  • max_chat_blob_buffer_token_size
    • バッファの最大トークンサイズ(デフォルト: 1024)
    • この値を超えるとバッファが自動的にフラッシュされる。
    • 値を大きくするとLLM処理コストは下がるが、プロファイル更新が遅延する。
  • buffer_flush_interval
    • バッファのフラッシュ間隔秒(デフォルト: 3600)
    • アイドル状態のバッファがある場合、この時間が経過すると自動でフラッシュされる
  • max_chat_blob_buffer_process_token_size
    • バッファ処理時の最大トークンサイズ(デフォルト: 16384)
kun432kun432

キャッシュ

登録された長期メモリを参照する際のレスポンス速度に影響する。

プロファイルのキャッシュの仕組み

Memobaseでは、ユーザープロファイルの取得パフォーマンスを向上させるため、Redisを使用したキャッシュシステムを実装しています。

キャッシュの動作フロー

プロファイルを取得する際、システムは以下の順序で動作します:

  1. Redisキャッシュの確認: まずuser_profiles::{project_id}::{user_id}というキーでRedisからキャッシュを取得しようとします。

  2. キャッシュヒット時: キャッシュが存在する場合、JSONをパースして即座に返します。

  3. キャッシュミス時: キャッシュが存在しない場合、PostgreSQLデータベースからUserProfileテーブルをクエリします。

  4. キャッシュの保存: データベースから取得したプロファイルをRedisに保存します。TTL(有効期限)はCONFIG.cache_user_profiles_ttlで設定されます。

キャッシュの無効化

プロファイルが更新される際、キャッシュは自動的に無効化されます。以下の操作時にrefresh_user_profile_cache()が呼び出されます:

  • プロファイルの追加時
  • プロファイルの更新時
  • プロファイルの削除時
  • ユーザーの削除時

refresh_user_profile_cache()関数は、Redisから該当するキーを削除することでキャッシュを無効化します。

パフォーマンスへの影響

このキャッシュ機構により、プロファイルクエリは100ms以下のレイテンシで実行できます。キャッシュされたプロファイルは事前にコンパイルされているため、リアルタイムでの分析が不要になります。

Notes

Doubao LLMプロバイダー用の別のキャッシュシステム(src/server/api/memobase_server/llms/doubao_cache_llm.py)も存在しますが、これはプロンプトのコンテキストをキャッシュするもので、ユーザープロファイルのキャッシュとは異なる目的で使用されます。

関連する設定は以下

  • cache_user_profiles_ttl
    • プロファイルキャッシュの有効期限秒(デフォルトは1200)
    • Redisにプロファイルを保存する際のexパラメータとして使用される
kun432kun432

知りたかったのはキャッシュ生成のところ。

生成されたプロフィール情報はキャッシュされて高速に取得できる(100ms以下を謳っている)が、タイミングによっては、

  • プロフィールキャッシュの有効期限が切れている
  • 長期メモリが更新される→プロフィールキャッシュが削除される

ということで、レスポンス速度が遅い場合があるって感じかな。

このスクラップは5日前にクローズされました