マネージドエージェントメモリ
ベータ版
この機能はベータ版です。ワークスペース管理者は、 プレビュー ページからこの機能へのアクセスを制御できます。Databricksのプレビューを管理するを参照してください。
マネージドエージェントメモリは、会話全体でエージェントに長期メモリを提供します。Databricksはインフラストラクチャを運用し、各スコープのメモリを分離するため、お客様自身でストレージやパーティションを管理する必要はありません。
マネージド メモリを使用すると、エージェントは次のことができます。
- ユーザー設定、過去の決定、および会話全体で蓄積されたコンテキストを記憶します。
- その知識を Unity Catalog のガバナンスで保護します。
- エージェントとプロジェクト間でメモリを共有します。
- 時間をかけて、その精度と効率を向上させます。
要件
- Unity Catalogが有効になっているDatabricksワークスペース。
- メモリストアを作成するための親スキーマに対する
CREATE MEMORY STORE権限。
マネージドメモリの仕組み
マネージドメモリには 2 つのレベルがあります:
- メモリ ストア は、メモリ エントリのコンテナとして機能する Unity Catalog のセキュリティ保護可能なオブジェクトです。メモリ ストアは、他の Unity Catalog アセットと同様に、同じガバナンス、アクセス制御、およびリネージを継承します。
- メモリ入力とは、メモリストア内に保存される個々のコンテンツです。各入力は、スコープとパスによって識別されます。スコープは入力がどのメモリに属するかを決定し、パスはファイルパス(例:
/memories/preferences.md)と同様にスコープ内の入力を整理します。
範囲
スコープとは、メモリを1人のユーザー専用にするか、グループ全体で共有するかを決定する方法です。アプリケーションは読み取りおよび書き込みのたびにスコープを設定し、検索では一致するスコープを持つエントリのみが返されます。エージェントが記憶する必要がある内容に一致する戦略を選択してください:
-
ユーザーごとのプライベートメモリ: スコープを検証済みのエンドユーザー ID に設定します。各ユーザーは独自のパーティションを取得し、自身の項目のみを表示します。値
user_clientは、エンドユーザーの ID を解決します。- 例: サポートエージェントは、ユーザーの通信設定と過去のチケットを記憶します。
-
グループの共有メモリ: 組織、チーム、プロジェクトIDなど、選択した固定キーにスコープを設定します。すべてのユーザーが同じメモリを読み取り、書き込みます。
- 例: チームエージェントは、会社用語と社内ポリシーの共有用語集を記憶します。
-
メモリが他の要素によって分割されている場合: テナントIDや
user_id:project複合値など、独自の値を基にスコープを構築します。- 例: マルチテナントアプリは各顧客のメモリを個別に保持するか、単一ユーザーのメモリをプロジェクトごとに分離します。
単一のエージェントは、1つの会話の中で複数の戦略を組み合わせることができます。たとえば、同じリクエスト内でユーザーのプライベートメモリと共有チームメモリを読み取ることができます。
リクエストが改ざんできない信頼された呼び出し元コンテキストから、アプリケーションコード内でスコープを設定します。ユーザーごとのメモリにはOBOトークンから検証されたエンドユーザーIDを、共有メモリには信頼されたテナント、チーム、またはプロジェクトキーを使用します。モデルに選択させないでください。スコープ戦略がエンドユーザーIDに依存している場合は、共有スコープにフォールバックするのではなく、IDを持たないリクエストを拒否してください。managed-memory スキルが、このセットアップの手順を案内します。
スコープはメモリを分離しますが、ストアへのアクセス権を付与するものではありません。呼び出し元がこれを開くには、依然としてREAD MEMORY STOREまたはWRITE MEMORY STOREの権限が必要です。「メモリのアクセス制御」を参照してください。
スコープはユーザー間の分離境界ですが、アクセス制御ではありません。アプリの Databricks Service Principal はすべてのスコープを読み取ることができるため、その資格情報は適切に保護してください。
エージェントが保存および呼び出す内容
マネージドメモリは、メモリストアと、エントリーの読み取りおよび書き込みを行うためのAPIsを提供します。アプリケーションは、エージェントが何を保存し、いつメモリを取得し、結果をどのように使用するかを制御します。
エージェントのシステムプロンプトでこの動作を定義します。どのような永続的な情報を保存し、いつそれを取得するかをエージェントに指示してください。The managed-memory skill and Template keep this system prompt in a constant named MEMORY_INSTRUCTIONS.スコープは信頼されたアプリケーションコード内で個別に構成され、モデルによって選択されることはありません。
スコープ戦略に合わせて表現を調整してください。以下は、ユーザーごとの戦略の例です。
You have durable, cross-session memory about whoever (or whatever) this conversation is scoped to. Use it deliberately, not by reflex.
Recall whenever the answer is about the user or calls for personalized information — anything that might draw on preferences, decisions, or workflows they've shared before — and you don't already have it from this conversation; also list once before saving, to find the right existing topic. Don't tell the user you don't know their preferences without checking — list_memories first. Skip memory only when the answer truly doesn't depend on who's asking (general knowledge, math, coding) or you already have what you need. A `[has_contents]` entry has a body to get_memory; one without is fully captured by its description. Open a memory with get_memory before you state its specifics, and never assert a fact that isn't stored — if nothing relevant is stored, just answer without it. Don't re-list what you've already seen this turn.
Save only what will still matter in a future, unrelated conversation — a stable preference, fact, decision, or ongoing project the user actually stated or decided. Don't save your own suggestions or guesses, passing chatter, secrets, or anything scoped to this chat ("for now", a one-off label).
- Write each memory so it stands on its own out of context, under one broad, stable /memories/... topic per subject with the specifics inside it.
- Check the list first and update_memory an existing topic instead of minting a near-duplicate.
- For a very broad question that touches many memories, summarize from the list's descriptions; reserve get_memory for the specific entry you actually need.
- If the user's info changes or contradicts what's stored, update or replace it rather than keeping both — but don't rewrite a memory that already says the same thing.
- delete_memory what's stale.
- Briefly tell the user whenever you save, update, or delete.
マネージドメモリスキルの利用を開始する
エージェントにマネージドメモリを追加する最も簡単な方法は、managed-memory Claude Codeスキルです。このスキルは、すべてのセットアップを自動的に行い、OpenAI Agents SDK と LangGraph の両方で動作します。
スキルをプロジェクトに組み込む方法は2つあります。
- Start from a template
- Add the skill to an existing project
このスキルは、Databricks アプリテンプレートに含まれています。エージェントテンプレートのいずれかから新しいエージェントをスキャフォールドし、スキルは .claude/skills/managed-memory/ の下にあります。
-
テンプレートリポジトリをクローンします。
Bashgit clone https://github.com/databricks/app-templates.git -
app-templatesを参照し、開始するエージェントテンプレートを選択します。たとえば、OpenAI Agents SDK テンプレートを使用するには:Bashcd app-templates/agent-openai-agents-sdk
「advanced」アプリテンプレートの場合、デプロイ後に、アプリのサービスプリンシパルにLakebase Postgresの特権を付与する必要があります。そうしないと、セッション設定で502エラーが返されます。
- スキルがプロジェクトに配置されたら、やりたいことを記述すると、コーディングアシスタントが残りの処理を行います:
Add Databricks managed long-term memory to my agent.
エージェントプロジェクトを既に持っている場合は、それにスキルを追加してください。
-
スキル ディレクトリが存在しない場合は作成します。
Bashmkdir -p .claude/skills/managed-memory -
SKILL.mdmanaged-memoryスキルディレクトリ から ファイルをダウンロードし、.claude/skills/managed-memory/に保存します。 -
スキルがプロジェクトに配置されたら、やりたいことを記述すると、コーディングアシスタントが残りの処理を行います:
Add Databricks managed long-term memory to my agent.
メモリストアを手動で作成して使用する
このセクションでは、managed-memory Claude Code スキルなしで、メモリストアを作成して使用する方法を示します。
以下の例では、顧客サポートエージェント向けにマネージドメモリを設定します。これにより、ユーザーの好み(設定)を保存し、後の会話でそれらを取得できます。
-
Databricks CLIを使用してAPIを呼び出すOAuthトークンを生成します:
Bashdatabricks auth login --host ${DATABRICKS_HOST}
databricks auth token -
エージェントのメモリを保持するためのメモリ ストアを作成します。
Bashcurl -X POST "https://${DATABRICKS_HOST}/api/2.1/unity-catalog/memory-stores" \
-H "Authorization: Bearer ${DATABRICKS_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"name": "support_agent_memory",
"catalog_name": "main",
"schema_name": "default",
"description": "Long-term memory for the customer support agent"
}' -
エージェントがユーザーについて何かを学習した後、メモリ エントリを書き込みます。
scopeはエントリを単一のユーザーにパーティション分割します。contentsフィールドを完全なメモリテキストに使用し、descriptionを検索(取得)を改善する短い要約として使用します:Bashcurl -X POST \
"https://${DATABRICKS_HOST}/api/2.1/unity-catalog/memory-stores/main.default.support_agent_memory/entries?scope=user-123" \
-H "Authorization: Bearer ${DATABRICKS_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"path": "/memories/preferences.md",
"contents": "Prefers email communication. Timezone: PST. Has an Enterprise subscription.",
"description": "User 123 communication preferences and account details"
}' -
後続の会話でそのユーザーのメモリ エントリを検索し、エージェントが学習した内容を取得します。
Bashcurl -X POST \
"https://${DATABRICKS_HOST}/api/2.1/unity-catalog/memory-stores/main.default.support_agent_memory/entries:search" \
-H "Authorization: Bearer ${DATABRICKS_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"scope": "user-123",
"query": "communication preferences"
}'
エンドポイント、リクエストフィールド、レスポンスフィールドを含む完全なREST APIについては、Memory APIリファレンスを参照してください。
会話を使用してエージェントにメモリを追加
上記の REST ワークフローは、メモリストアおよび APIs を直接呼び出します。Databricks モデルサービングエンドポイント上でエージェントを構築する場合、代わりに SDKdatabricks-openai内の OpenAI 互換クライアントを使用して、メモリストアを「会話」に接続します。
会話とは、メモリストアによってバックアップされ、単一のスコープにピン留めされた、OpenAI互換の会話状態、つまりメッセージとツール呼び出しの実行履歴です。エージェントに以前のターンのメモリを持たせるために、同じ会話をリクエスト間で再利用します。
-
既存のメモリストアとスコープを新しい会話にバインドします。
memory_store.nameはストアの 3 レベル名であり、scopeは通常エンドユーザーによって会話の状態をパーティション分割します:Pythonfrom databricks.sdk import WorkspaceClient
from databricks_openai import DatabricksOpenAI
workspace_client = WorkspaceClient()
user_id = str(workspace_client.current_user.me().id)
client = DatabricksOpenAI(workspace_client=workspace_client, use_ai_gateway=True)
conversation = client.conversations.create(
extra_body={
"memory_store": {"name": "main.default.support_agent_memory"},
"scope": {"kind": "user", "value": user_id},
},
) -
会話IDを
responses.createに渡します。エージェントは、そのスコープの下にあるバインドされたメモリストアで会話の状態を読み書きします。Pythonresponse = client.responses.create(
model="databricks-gpt-5-2",
conversation=conversation.id,
input=[{"type": "message", "role": "user", "content": "What is the average NYC taxi price?"}],
stream=True,
)
for event in response:
if event.type == "response.output_text.delta":
print(event.delta, end="", flush=True) -
後のリクエストで 同じ 会話 ID を再利用します。これにより、エージェントが以前のターンを記憶します。ターンごとに新しい会話を作成しないでください:
Pythonfollowup = client.responses.create(
model="databricks-gpt-5-2",
conversation=conversation.id,
input=[{"type": "message", "role": "user", "content": "Restate the average taxi price you found, and how it was calculated."}],
stream=True,
)
for event in followup:
if event.type == "response.output_text.delta":
print(event.delta, end="", flush=True)
会話エンドポイントとリクエスト フィールドについては、Conversation APIs を参照してください。
メモリのアクセス制御
メモリストアはUnity Catalogのセキュリティ保護可能なオブジェクトです。次の権限がアクセスを制御します。
権限 | 適用対象 | 説明 |
|---|---|---|
| 親スキーマ | スキーマの下に新しいメモリストアを作成します。 |
| メモリストア | メモリストアのメタデータとそのエントリを読み取ります。 |
| メモリストア | ストアでメモリのエントリを作成、更新、削除します。 |
| メモリストア | メモリ ストア自体を更新または削除します。他のユーザーに権限を付与します。 |
| 親スキーマ | スキーマ内のメモリストアを一覧表示します。 |
短期メモリを実装する
メモリエントリーAPIsは、エージェントが使用するツールとして長期メモリを提供します。セッションでエージェントにマネージドの短期メモリを提供するために、Databricksはメモリストアを会話にバインドすることを推奨しています。また、以下も可能です。
- OpenAI
session=パラメーターやLangGraphチェックポインターなど、エージェントフレームワークのセッションメモリを保持します。 - 会話履歴ストアには、セルフマネージドエージェントメモリを使用してください。
セキュリティの推奨事項
Databricks は、ガバナンスストア、暗号化、分離プリミティブ、および監査証跡を提供しています。アプリ開発者として、Databricks は次のことを推奨しています。
- 意図的に異なる方法でパーティション分割する理由がない限り、ユーザーごとのスコープのdefault (
user_client) を使用してください(例:プロジェクトごと、またはアカウントごとのメモリなど)。 - 最小限の特権を付与します:エージェントのDatabricks Service Principalのみが
WRITE MEMORY STOREを必要とします。READ MEMORY STOREを限定的に付与し、人間のユーザーや大規模なグループへの広範な付与は避けてください。 - アプリのDatabricks Service Principal資格情報を保護してください:これはストアのデータプレーンへの鍵です。機密性の高いサービス資格情報と同様に扱ってください。有効期間の短いトークンを使用し、ログに記録することは避け、アプリにSSRF防御を追加してください。
制限事項
- メモリ エントリは長期メモリのみを提供します。短期メモリと長期メモリの違いについては、短期メモリと長期メモリを参照してください。
- メモリストアとエントリは、Unity Catalog REST API を介してのみ作成および管理されます。これらの API 用の Python SDK はありません。エージェントからメモリストアを使用するには、OpenAI 互換クライアントを使用して会話に接続します。会話を使用してエージェントにメモリを追加するを参照してください。