📝

[Python-Agno] ユーザ情報をMemoryに蓄積するAgentをつくる (基本編)

に公開

はじめに

MoatになりうるAIエージェントのメモリデザインパターン でも示されているように、LLMが組み込まれたAgenticなプロダクトを構築するにあたって、ユーザのパーソナルデータを蓄積することは非常に重要です。

Moatとはビジネスにおいて競合他社と差別化して競合優位性を築くためのものです。
他の類似プロダクトが収集・蓄積していないユーザのパーソナル情報を元にユーザ体験を向上させることができれば、プロダクトを利用してもらう強力な理由になります。

今回は、Agnoのメモリ機能に焦点を当て、ユーザ情報をメモリに保存する方法を見ていきます。今回紹介するようなメモリ機能を発展させることで、エージェントは過去の会話や情報を記憶し、ユーザ体験を向上させるための種として活用できるはずです。

Agnoとは

Agnoは、メモリ、知識、ツール、推論機能を備えたAgentを構築するための軽量Pythonライブラリです。近年、AI Agent開発が進む中で、記憶(Memory)機能は重要な役割を果たしています。

Agnoは以下の主要な特徴を持っています:

  • モデル非依存: 複数のモデルプロバイダーに接続可能で、特定のモデルに縛られない
  • マルチモーダル対応: テキスト、画像、音声、動画の入出力に対応
  • 長期記憶とセッションストレージ: Agentに長期記憶とセッションストレージを提供するプラグアンドプレイのストレージとメモリドライバを搭載

実装例

基本的なメモリの保存

まずは、基本的なメモリの保存方法を見てみましょう。以下のコードは、ユーザの名前をメモリに保存する例です。
この例では、メモリに保存する内容をハードコーディングしています。

# SQLiteデータベースを使用してメモリを保存
memory_db = SqliteMemoryDb(table_name="memory", db_file="tmp/memory.db")
memory = Memory(db=memory_db)

# ユーザIDを設定
john_doe_id = "john_doe@example.com"

# ユーザのメモリを追加
memory.add_user_memory(
    memory=UserMemory(memory="The user's name is John Doe", topics=["name"]),
    user_id=john_doe_id,
)

# 保存されたメモリを読み取り
memories: list[MemoryRow] = memory_db.read_memories()
print("All the DB memories:")
for i, m in enumerate(memories):
    print(f"{i}: {m.memory['memory']} ({m.last_updated})")

このコードでは、以下の手順でメモリを保存しています:

  1. SqliteMemoryDbクラスを使用してSQLiteデータベースを作成
  2. Memoryクラスを初期化して、データベースと連携
  3. add_user_memoryメソッドを使用して、ユーザの名前を「name」というトピックとともに保存
  4. read_memoriesメソッドを使用して、保存されたメモリを読み取り

エージェントによるメモリの自動生成

先ほどはハードコーディングされたテキストを与えていましたが、より高度な使い方として、LLMモデルによる自動的メモリ生成の例を紹介します。

# SQLiteデータベースを設定
memory_db = SqliteMemoryDb(table_name="memory", db_file="tmp/memory.db")
memory_db.clear()  # このサンプルのためにデータベースをクリア

# OpenAIのモデルを使用してメモリを生成
memory = Memory(model=OpenAIChat(id="gpt-4o"), db=memory_db)

# ユーザID
john_doe_id = "john_doe@example.com"

# ユーザのメッセージからメモリを自動生成(例1)
memory.create_user_memories(
    message="""
    I enjoy hiking in the mountains on weekends,
    reading science fiction novels before bed,
    cooking new recipes from different cultures,
    playing chess with friends.
    """,
    user_id=john_doe_id,
)

# 生成されたメモリを取得して表示
memories = memory.get_user_memories(user_id=john_doe_id)
print("John Doe's memories:")
for i, m in enumerate(memories):
    print(f"{i}: {m.memory} - {m.topics}")

print("---")

# 追加のメモリを自動生成(例2)
conversation_data = """
    I like to play mahjong with friends,
    and attending live music concerts whenever possible.
    Photography has become a recent passion of mine, especially capturing landscapes and street scenes.
    I also like to meditate in the mornings and practice yoga to stay centered.
"""
memory.create_user_memories(
    message=conversation_data,
    user_id=john_doe_id,
)

# 更新後のメモリを表示
memories = memory.get_user_memories(user_id=john_doe_id)
print("John Doe's memories:")
for i, m in enumerate(memories):
    print(f"{i}: {m.memory} - {m.topics}")

このコードでは、より高度なメモリ管理を行っています:

  1. LLMモデルを使用してメモリを自動生成
  2. create_user_memoriesメソッドに、ユーザとの会話テキストを渡して、適切なメモリとトピックを自動抽出
  3. 新しい情報が追加されると、既存のメモリに統合される

この例では利用していませんが、modelにsystem_promptを渡すことも可能です。

出力結果

実行すると、以下のような出力が得られます(実際の出力はモデルの生成結果によって異なる場合があります):

  1. 基本的なメモリ保存の例:
All the DB memories:
0: The user's name is John Doe (2025-04-27 04:31:44)
  1. エージェントによるメモリ自動生成の例:
John Doe's memories:
0: User enjoys hiking in the mountains on weekends. - ['hobbies', 'interests']
1: User reads science fiction novels before bed. - ['hobbies', 'preferences']
2: User enjoys cooking new recipes from different cultures. - ['hobbies', 'interests']
3: User likes playing chess with friends. - ['hobbies', 'social']
---
John Doe's memories:
0: User likes to play mahjong with friends. - ['hobbies', 'social activities']
1: User enjoys attending live music concerts whenever possible. - ['interests', 'entertainment']
2: User has a recent passion for photography, especially capturing landscapes and street scenes. - ['hobbies', 'interests']
3: User likes to meditate in the mornings. - ['health', 'wellness']
4: User practices yoga to stay centered. - ['health', 'wellness']
5: User enjoys hiking in the mountains on weekends. - ['hobbies', 'interests']
6: User reads science fiction novels before bed. - ['hobbies', 'preferences']
7: User enjoys cooking new recipes from different cultures. - ['hobbies', 'interests']
8: User likes playing chess with friends. - ['hobbies', 'social']

まとめ

Agentのメモリ機能は、冒頭で述べたようにビジネスにおけるMoat(競合優位性)を構築するための重要な要素となります。
今回は以下の点を中心に、基本的なMemoryの保存方法を見てきました。

  1. 基本的なメモリ保存: 特定の情報をトピックとともに手動で保存する方法
  2. 自動メモリ生成: LLMを活用して会話からメモリとトピックを自動的に抽出する方法
  3. メモリの取得と管理: 保存されたメモリを効率的に取得・表示する方法

今回引用したコードは、 https://github.com/t-nakatani/agno-memory-example から確認・localで動作確認することができます。

Discussion