コンテンツにスキップ

4. 記憶するエージェント

セッションは基本的に使い捨てで、終了すると会話の内容は次のセッションに引き継がれません。メモリストアを使うと、エージェントがセッションを跨いで記憶を持てるようになります。このページでは、あなたのことを覚えてくれるパーソナルアシスタントを作ります。

このページでは、Managed Agentsの次の要素を新しく使います。

要素役割
メモリストアセッションを跨いで永続する、エージェント用のテキストファイル置き場
メモリストアのリソース紐付けセッション作成時にresourcesでストアをサンドボックスにマウントする仕組み

プロジェクトを作成し、そのフォルダーに移動して、Claude SDKをインストールします。

Terminal window
uv init memory-agent
cd memory-agent
uv add anthropic
  1. プロジェクトのフォルダーにsetup_memory.pyを作成し、以下の内容を保存します。

    setup_memory.py
    import json
    from anthropic import Anthropic
    client = Anthropic()
    ###############################
    # 1. メモリストアを作成(descriptionはエージェントに渡される)
    ###############################
    store = client.beta.memory_stores.create(
    name="personal-memory",
    description="ユーザーに関する記憶。名前、好み、仕事の文脈、過去の依頼内容などを保存する。",
    )
    print(f"memory_store: {store.id}")
    ###############################
    # 2. 環境を作成(MCPもパッケージも不要な最小構成)
    ###############################
    environment = client.beta.environments.create(
    name="Memory-environment",
    config={"type": "cloud"},
    )
    print(f"environment: {environment.id}")
    ###############################
    # 3. エージェントを作成(メモリの読み書きにはビルトインツールが必要)
    ###############################
    agent = client.beta.agents.create(
    name="Memory Agent",
    model={"id": "claude-haiku-4-5", "speed": "standard"},
    description="ユーザーのことを覚えるパーソナルアシスタント。",
    system=(
    "あなたはユーザー専属のパーソナルアシスタントです。"
    "会話の中でユーザーに関する情報(名前、好み、仕事の文脈、依頼の傾向など)を知ったら、"
    "指示されなくても、writeツールを使ってメモリディレクトリ(/mnt/memory/ 配下)に"
    "Markdownファイルとして保存してください。ファイルに書き込むまでは「記録した」ことになりません。"
    "また、依頼に取り組む前には必ずメモリディレクトリの中身を読み、ユーザーに合わせた対応をしてください。"
    "日本語で応答してください。"
    ),
    tools=[{"type": "agent_toolset_20260401", "default_config": {"enabled": True}}],
    )
    print(f"agent: {agent.id}")
    with open("ids_memory.json", "w") as f:
    json.dump(
    {
    "memory_store_id": store.id,
    "environment_id": environment.id,
    "agent_id": agent.id,
    },
    f,
    indent=2,
    )
    print("IDをids_memory.jsonに保存しました")

    ポイントは3つです。

    • メモリストアのdescriptionはエージェントに渡されます。「何のための記憶か」を人間向けではなくエージェント向けに書きます
    • メモリはサンドボックスにファイルとしてマウントされるため、読み書きにはビルトインツール(agent_toolset)が必要です
    • 環境はネットワーク設定もパッケージもない最小構成です。メモリに外部アクセスは不要です
  2. スクリプトを実行します。

    Terminal window
    uv run setup_memory.py
  1. プロジェクトのフォルダーにchat_memory.pyを作成し、以下の内容を保存します。

    chat_memory.py
    import json
    from anthropic import Anthropic
    client = Anthropic()
    with open("ids_memory.json") as f:
    ids = json.load(f)
    ###############################
    # 1. セッションを作成(メモリストアをリソースとして紐付ける)
    ###############################
    session = client.beta.sessions.create(
    agent=ids["agent_id"],
    environment_id=ids["environment_id"],
    resources=[
    {
    "type": "memory_store",
    "memory_store_id": ids["memory_store_id"],
    "access": "read_write",
    "instructions": "ユーザーに関する記憶。会話で知った事実や好みは、指示がなくても記録すること。依頼に取り組む前に必ず確認すること。",
    }
    ],
    )
    print(f"session: {session.id}")
    print("エージェントと対話します。exit と入力すると終了します。\n")
    ###############################
    # 2. 1ターン分の送信と受信
    ###############################
    def run_turn(text: str) -> None:
    stream = client.beta.sessions.events.stream(session_id=session.id)
    client.beta.sessions.events.send(
    session.id,
    events=[{"type": "user.message", "content": [{"type": "text", "text": text}]}],
    )
    for event in stream:
    if event.type == "agent.tool_use":
    print(f"[ツール: {event.name}]")
    elif event.type == "agent.message":
    for block in event.content:
    if block.type == "text":
    print(block.text)
    elif event.type == "session.status_idle":
    if event.stop_reason.type != "requires_action":
    break
    elif event.type == "session.status_terminated":
    break
    stream.close()
    ###############################
    # 3. 対話ループ
    ###############################
    while True:
    user_input = input("あなた> ").strip()
    if user_input == "exit":
    break
    if not user_input:
    continue
    run_turn(user_input)
    print()
    print("完了しました")

    メモリストアは、セッション作成時にresourcesで紐付けます。accessread_write(読み書き)とread_only(参照のみ)から選べ、instructionsでこのセッションでの使い方を指示できます。紐付けたストアはサンドボックスの/mnt/memory/ストア名/にマウントされ、マウント情報はシステムプロンプトに自動で追加されます。

  2. スクリプトを実行し、「覚えて」とは言わずに自己紹介をしてみます。[ツール: write]が表示されれば、エージェントが自発的にメモリへ書き込んだ証拠です。

    Terminal window
    uv run chat_memory.py
    session: sesn_01V6uP82wu7cjWHdghEyiCH2
    エージェントと対話します。exit と入力すると終了します。
    あなた> 私は山田です。大阪でエンジニアをしています。文章を頼むときは、箇条書きで簡潔なものが好みです。
    [ツール: write]
    山田さんですね。ご紹介いただきありがとうございます!
    大阪でエンジニアとして活動されているのですね。文章依頼時は箇条書きで簡潔な形式をご希望とのこと、
    了解しました。今後のご依頼では、その点を意識して対応させていただきます。
    あなた> exit
    完了しました

4. 新しいセッションで確認する

Section titled “4. 新しいセッションで確認する”
  1. chat_memory.pyもう一度実行します。まったく新しいセッション(会話履歴なし)ですが、エージェントはメモリを読んでから応答します。

    Terminal window
    uv run chat_memory.py
    session: sesn_016XtdU3RLZB34ydhRnZkrAD
    エージェントと対話します。exit と入力すると終了します。
    あなた> 私の好みに合う形式で、社内勉強会の告知文を作ってください。
    メモリを確認して、あなたの好みを把握してから告知文を作成させていただきます。
    [ツール: bash]
    [ツール: read]
    ありがとうございます。箇条書きで簡潔な形式をご希望とのことですね。社内勉強会の告知文を、
    いくつかのバージョンでご提案します。
    ## 案1:シンプル版
    **【社内勉強会開催のお知らせ】**
    - **テーマ**:(テーマを入力してください)
    - **開催日時**:○年○月○日(○)○時~○時
    ...

    前のセッションで伝えた「箇条書きで簡潔」という好みを覚えていて、その形式で出力してくれます。会話の履歴はセッションごとに独立していますが、メモリはストアに永続化されているのでセッションを跨いで引き継がれる、というのがポイントです。

エージェントが何を覚えたのかは、ホスト側からAPIで確認できます。

  1. プロジェクトのフォルダーにpeek_memory.pyを作成し、実行します。

    peek_memory.py
    import json
    from anthropic import Anthropic
    client = Anthropic()
    with open("ids_memory.json") as f:
    ids = json.load(f)
    store_id = ids["memory_store_id"]
    # ストア内のメモリを一覧し、それぞれの中身を表示する
    for item in client.beta.memory_stores.memories.list(store_id, path_prefix="/"):
    if item.type != "memory":
    continue
    memory = client.beta.memory_stores.memories.retrieve(item.id, memory_store_id=store_id)
    print(f"===== {memory.path} =====")
    print(memory.content)
    print()
    Terminal window
    uv run peek_memory.py
    ===== /user_profile.md =====
    # ユーザープロフィール
    ## 基本情報
    - 名前:山田
    - 職業:エンジニア
    - 勤務地:大阪
    ## 好み・スタイル
    - 文章依頼時:箇条書きで簡潔な形式を希望

    エージェントの「記憶」の正体は、ただのMarkdownファイルです。ホスト側からはmemories.updateで修正したり、memories.deleteで削除したりもできます。また、メモリへのすべての変更にはバージョンが記録されるので、いつ・どのセッションが何を書いたかを監査できます。

  • メモリストアをセッションのresourcesで紐付けると、/mnt/memory/にファイルとしてマウントされ、エージェントがビルトインツールで読み書きします。書いた内容はストアに永続化され、次のセッションに引き継がれます
  • 自発的に記録させるには、「ファイルに書き込むまでは記録にならない」ことをプロンプトで明示するのが確実です。
  • 記憶の実体はMarkdownファイルで、ホスト側からAPIで閲覧・修正・削除でき、変更履歴(バージョン)も監査できます。

おつかれさまでした!ここまでの感想を、ぜひXにポストしてください。

感想をXにポストする