Couldn't load this page.

← ブログ
Engineering

Redisを使ったAIエージェントのメモリ: セッションをまたいでユーザーを記憶する

Yura Oak

Redisを使ったAIエージェントのメモリにより、アプリケーションはモデル呼び出し間のコンテキストを保存し、同じユーザーが戻ってきたときにそれを読み込むことができます。モデルは次のリクエストでそのコンテキストを参照します。Redisはデータを保持し、アプリケーションは何を保持し、取得し、忘れるかを決定します。

このガイドでは、小さなPythonアシスタントが、Aliceがベジタリアン料理を好むことを記憶します。1つのPythonプロセスを停止し、新しいセッションIDで別のプロセスを開始して、彼女の好みを思い出すように求めます。Bobには別のプロファイルが用意されます。忘却コマンドは、AliceのRedis上のレコードを削除します。

この例をローカルで実行してから、同じコードをLizardのManaged Redisに接続できます。標準のRedis HashおよびListコマンドを使用するため、このチュートリアルではベクトルインデックス、RedisJSON、またはエージェントフレームワークは必要ありません。

2026年9月25日にテスト済み: Python 3.12.10、Redis 8.8.0、redis-py==5.2.1、およびOpenRouterを経由したopenai/gpt-4.1-miniへの4回のライブ呼び出し。16個のチェックすべてに合格しました。テストは、ローカルのRedisインスタンス上の個別のアプリケーションプロセスとセッションを対象としました。ホストされたインスタンス、同時リクエスト、またはRedisのクラッシュからの回復は対象としていません。

AIエージェントは何を記憶すべきか?

2種類のデータから始めます。これらには異なるキーと保持ルールが必要です。

メモリ含まれる内容Redisタイプこの例での保持期間
ユーザープロファイルユーザーが明示的に保存した好みHash最後のプロファイル書き込みから30日
セッション履歴最近のユーザーメッセージとアシスタントの返答List最新の20メッセージ。最後に完了したターンの24時間後に期限切れ

プロファイルはユーザーに属しているため、新しいセッションで読み取ることができます。会話履歴は、1人のユーザーと1つのセッションに属します。2番目のセッションを開始しても、最初のセッションの記録はコピーされません。

Redis Hashは2つのセッションにわたってAliceの好みを保持し、個別のListは各セッションの最近のメッセージを保持します。

この区別は、エージェントが「私について何を知っていますか?」という質問に答えるときに重要です。最近のメッセージは、制限された履歴リストから消える可能性があります。保存された好みには独自の保持期間があります。どちらもモデルのコンテキストに永遠に留まる必要はありません。

Redisは、個別のRedis Agent Memoryも提供しています。このチュートリアルでは、Redis接続を使用してアプリケーションコード内に小さなメモリ層を構築します。そのサービスや自動抽出機能は使用しません。

1. デモのセットアップ

Python 3.10以降、使い捨てのRedisインスタンス、およびOpenRouter APIキーが必要です。テスト中は架空の好みを使用してください。保存されたプロファイルと選択されたチャットメッセージは、呼び出しのたびにモデルプロバイダーに送信されます。

テスト済みの完全なプログラムをダウンロードし、1つのPython依存関係をインストールします。

mkdir redis-memory-demo
cd redis-memory-demo
python3 -m venv .venv
. .venv/bin/activate
python -m pip install redis==5.2.1
curl -fsSLo memory_agent.py \
  https://lizard.build/blog-examples/redis-agent-memory/memory_agent.py

ローカルテストの場合は、別のターミナルでRedisを実行します。このコマンドは、ポート6387のループバックにバインドします。そのターミナルを実行したままにしてください。

redis-server --bind 127.0.0.1 --port 6387 --save "" --appendonly no

このローカルのRedisプロセスは意図的に使い捨てにしています。Pythonアプリケーションが終了してもデータは利用可能ですが、Redisを停止するとそのデータは失われます。以下のテストでは、データベースではなくアプリケーションを再起動します。

エディターを使用して、デモディレクトリにプライベートな.envファイルを作成します。

REDIS_URL=redis://127.0.0.1:6387/0
OPENROUTER_API_KEY=replace-with-your-key
OPENROUTER_MODEL=openai/gpt-4.1-mini

.envをGitに含めないでください。アクセスを制限し、現在のシェルに読み込みます。

chmod 600 .env
set -a
. ./.env
set +a

この例では、OpenRouter Chat Completions APIを呼び出します。モデルの呼び出しを別のプロバイダーに置き換えても、Redisは同じメモリの読み書きを処理します。

2. 各ユーザーとセッションに独自のキーを割り当てる

プログラムは次のようなキーを作成します。

agentmem:v1:{alice}:profile
agentmem:v1:{alice}:session:session-1
agentmem:v1:{alice}:session:session-2
agentmem:v1:{bob}:profile

バージョンのプレフィックスは、将来のデータ形式に個別の名前空間を提供します。ユーザーIDはプロファイルを分離します。セッションIDは会話を分離します。中括弧はRedisハッシュタグです。後でRedis Clusterを使用する場合に、1人のユーザーのキーを同じハッシュスロットに保持します。このガイドでは、単一のRedisインスタンスをテストします。

デモでは、キーを作成する前にIDを検証します。Webアプリケーションでは、認証されたサーバーセッションからユーザーIDを導出します。リクエスト本文から別のユーザーのIDを受け取り、それを身元の証明として扱わないでください。Redisのキー名だけでは、誰がユーザーのデータにアクセスできるかを強制することはできません。

3. 明示的な好みを保存する

Aliceの選択を保存します。

python memory_agent.py remember --user alice --preference vegetarian

コマンドはPreference saved.を出力します。内部的には、フィールドをRedis Hashに書き込み、トランザクション内でプロファイルの有効期限を設定します。

with client.pipeline(transaction=True) as tx:
    tx.hset(profile, mapping={"dietary_preference": preference})
    tx.expire(profile, 30 * 24 * 60 * 60)
    tx.execute()

許可される値はvegetarian、vegan、およびno_preferenceのみです。この小さなスキーマにより、保存内容を確認しやすくなります。モデルはプロファイルに任意の主張を書き込むことはできません。実際の製品では、「これを記憶する」コントロールを使用して、ユーザーが確認した後に同じ検証済みの書き込みを行うことができます。

このガイドでは、すべてのチャットメッセージから好みを推測することはありません。好みの変更や修正には同じ明示的なコマンドを使用し、そのフィールドを上書きして30日間のTTLを更新します。

4. モデルを呼び出す前にメモリを読み込む

保存された選択を思い出すようにアシスタントに依頼します。

python memory_agent.py chat --user alice --session session-1 \
  --message "What dietary preference have I saved?"

テストでは、モデルは次のように返答しました。

Your saved dietary preference is vegetarian.

呼び出しごとに、アプリケーションはユーザーのプロファイルと現在のセッションの最近のメッセージを読み取ります。次の順序でモデルリクエストを構築します。

  1. アシスタントのタスクを定義する指示。
  2. 許可された保存済みの好みを含むデータメッセージ。
  3. このセッションの最近のユーザーとアシスタントのメッセージ。
  4. 新しいユーザーの質問。

モデルには、直接のRedis認証情報や一般的なデータベースツールはありません。選択されたコンテキストのみを受け取ります。返答が成功した後、アプリは新しいユーザーとアシスタントのメッセージを一緒に保存します。

with client.pipeline(transaction=True) as tx:
    tx.rpush(history, *rows)
    tx.ltrim(history, -20, -1)
    tx.expire(history, 24 * 60 * 60)
    tx.execute()

各ターンで2つのメッセージが追加されるため、リストには最後の10回の完全なターンが保持されます。アプリはまた、各メッセージを2,000文字に制限します。1つのメッセージに本全体が含まれる可能性がある場合、メッセージ数だけではコンテキストサイズを制限できません。

この例では、メモリを読み取っても有効期限は更新されません。プロファイルの書き込みはプロファイルのTTLを更新し、完了したチャットターンはセッションのTTLを更新します。有効期限が更新とどのように相互作用するかについては、Redis EXPIREリファレンスを参照してください。

5. 新しいプロセスと新しいセッションを開始する

各CLIコマンドは、独自のPythonプロセスを開始して終了します。別のセッションIDを使用して2番目のチャットコマンドを実行します。

python memory_agent.py chat --user alice --session session-2 \
  --message "What dietary preference have I saved?"

モデルは再びYour saved dietary preference is vegetarian.を返しました。新しいセッションは、最初の会話のメッセージなしで開始されました。そのリクエストには共有ユーザープロファイルが含まれており、答えるにはそれで十分でした。

アプリの再起動後、モデル呼び出しの前にAliceの保存された好みを読み込み、新しいセッションに返答を書き込みます。

アプリケーションが読み取るレコードを検査します。

python memory_agent.py inspect --user alice --session session-2

dietary_preferenceを含むプロファイルと、そのセッションのユーザーの質問とアシスタントの回答を含む履歴が表示されるはずです。モデルは新しい重みを学習したり、永続的な内部メモリを獲得したりしていません。アプリケーションは、リクエストごとに保存されたコンテキストを提供します。

6. ユーザーの分離と忘却を確認する

まず、別のユーザーのコンテキストを検査します。

python memory_agent.py inspect --user bob --session session-1

新しいBobのプロファイルの場合、結果は次のようになります。

{
  "profile": {},
  "history": []
}

Bobのアシスタントに同じ好みの質問をしたところ、テストではYour dietary preference is unknown.が生成されました。空のコンテキストは決定論的な分離チェックです。モデルの表現は異なる場合があります。

次に、Aliceに対するリクエストを停止し、彼女のRedis上のメモリを削除します。

python memory_agent.py forget-user --user alice
python memory_agent.py inspect --user alice --session session-1
python memory_agent.py inspect --user alice --session session-2

どちらの検査でも、空のプロファイルと履歴が返されるはずです。このコマンドは、Aliceの検証済みキープレフィックスのみをスキャンし、一致するキーのリンクを解除します。Bobのキーはそのまま残します。

デプロイされたアプリの場合、削除の実行中は該当ユーザーの新しい書き込みをブロックします。そうしないと、スキャン中に完了した返答によってセッションが再作成される可能性があります。また、Redisキーを削除しても、プロバイダーのログ、バックアップ、または別のデータベースのレコードは削除されません。これらのストアには独自の保持および削除ルールが必要です。

テストした内容

検証スクリプトは、利用可能なループバックポートで新しいRedisプロセスを開始します。既存のデータベースには決して接続しません。その保存された結果には、バージョン、スコープ、および4つのモデルの返答が記録されています。

チェック結果
保存された好みが個別のPythonプロセス間で維持される合格
新しいセッションが古い記録なしでプロファイルを読み込む合格
別のユーザーが空のコンテキストで開始する合格
期限切れのプロファイルとセッションキーが消える合格
履歴が20メッセージ以内に収まり、完全なターンを保持する合格
忘却によりセッションとプロファイルの両方が削除され、別のユーザーはそのまま残る合格
ライブモデル呼び出しが削除前に好みを思い出し、その後は不明と報告する合格

テストハーネスは合計16個のチェックを実行しました。これらの結果は、例の読み書きが説明どおりに機能することを示しています。これらは、本番環境の可用性やデータ復旧を保証するものではありません。

例をManaged Redisに接続する

ローカルテストの後、プロジェクト用に個別のRedisインスタンスを作成します。リンクされたLizardプロジェクトで、次を実行します。

lizard add redis

apiという名前のデプロイ済みサービスの場合、接続参照を設定して再デプロイします。

lizard secrets set REDIS_URL='${{redis.REDIS_URL}}' --service api
lizard redeploy --service api

これらのコマンドは、サービスがすでに存在し、モデルAPIキーが構成されていることを前提としています。これらはそのサービスをRedisに接続します。CLIデモ自体はHTTPサーバーではありません。環境変数とコンピューターからのアクセスについては、Managed Redis接続ガイドに従ってください。

ダッシュボードのRedisブラウザでデモのキーを検査できます。Redisの認証情報はサーバー上に保持し、プロバイダーが提供している場合はプライベート接続または検証済みのTLSを使用してください。プレーンなredis:// URLでは、トランスポート暗号化は追加されません。

失ってはいけない情報の保存先を決める

アプリケーションの再起動後もメモリが残るからといって、すべてのRedisの障害から生き残るわけではありません。有効期限、キーの削除(エビクション)、永続化設定、およびバックアップのすべてが重要です。

Managed Redisは現在、allkeys-lruエビクションポリシーを文書化しています。メモリの圧迫により、TTLが経過していないプロファイルを含む任意のキーが削除される可能性があります。失うわけにはいかない好みについては、ソースレコードをManaged Postgresに保持し、最近のコンテキストや再読み込み可能なコピーにRedisを使用してください。保持ポリシーを選択する前に、ストレージと復旧ガイドを確認してください。

これをWeb APIの背後に配置する前に

CLIにより、例は小規模に保たれています。共有アプリケーションには次のものも必要です。

  • 認証と所有権のチェック。 サーバー上でユーザーIDを導出し、各セッションがそのユーザーに属していることを確認します。
  • セッションごとに1つのアクティブなターン。 読み取り → モデル呼び出し → 書き込みの完全なシーケンスをキューに入れるかロックします。最後のRedisトランザクションだけでは、2つのモデル呼び出しが同じ古いコンテキストを読み取るのを防ぐことはできません。
  • メモリ使用量の上限。 プロファイルフィールド、メッセージサイズ、履歴の長さ、およびセッション数を制限します。Redisのメモリ使用量とエビクションを監視します。
  • Redisの障害ポリシー。 リクエストを明確に失敗させるか、明示的にステートレスなモードを提供します。書き込みに失敗したときに好みが保存されたと主張しないでください。
  • 記憶されたテキストから権限を分離する。 保存されたメッセージには悪意のある指示が含まれる可能性があります。権限とツールの決定はアプリケーションコード内に保持してください。システムプロンプトはアクセス制御の境界ではありません。

よくある質問

AIエージェントのメモリにベクトルデータベースは必要ですか?

この例のように、既知のユーザーの明示的な好みと最近のメッセージをキーで読み込むことができます。ベクトル検索は、アプリケーションがはるかに大きなメモリのセットから関連する事実を見つける必要がある場合に役立ちます。これにより、埋め込み、インデックス構成、および検索テストが追加されます。

Redisを使用すると、エージェントは永遠に記憶しますか?

保持期間は、TTL、エビクション、永続化、およびアプリケーションの書き込みに依存します。この例では、意図的にデータを期限切れにしています。データを失うと製品が壊れる場合は、耐久性のあるレコードを別の場所に保持してください。

これはRAGですか、それともセマンティックキャッシュですか?

この例では、1人のユーザーの保存されたコンテキストを取得します。RAGは通常、質問に答えるのに役立つ関連するソース資料を取得します。セマンティックキャッシュは、類似のクエリに対して以前の回答を再利用します。これらはRedisインフラストラクチャを共有できますが、異なるデータモデルとテストが必要です。

後でLangGraphを使用できますか?

はい。LangGraphは、会話状態のチェックポイントと、スレッド間でメモリを保存するストアを提供します。そのRedis統合には独自の要件があります。このシンプルなクライアントをフレームワークのバックエンドに置き換える前に、LangGraph Redisパッケージのドキュメントを確認してください。

内容を確認できるメモリをエージェントに追加する

1つの明示的な事実、個別のセッション履歴、およびプロセスの境界を越えるテストから始めます。自動抽出やベクトル検索を追加する前に、有効期限、所有権のチェック、および忘れる方法を追加してください。

アプリケーションの共有コンテキスト用にManaged Redisを作成します。エージェントが構造化されたプロジェクトデータをクエリする必要もある場合は、Postgres MCPガイドで、個別のデータベースリーダーロールを使用したその接続について説明しています。

AI で構築。Lizard で公開。

本番公開にプラットフォームチームは必要ありません。クラウド全体が、1 つの CLI コマンドですぐ使えます。

無料で試す
ワークスペース
—
サービス
—
アドオン
—
デプロイ
—

当サイトでは、基本機能と分析のために Cookie を使用しています。詳しくはCookie ポリシーをご覧ください。