Foundry Agent Service でのメモリの作成と使用 (プレビュー)

重要

Foundry Agent Service のメモリ (プレビュー) および Memory Store API (プレビュー) は、Azure サブスクリプションの一部としてお客様にライセンスされ、Microsoft 製品条項Microsoft 製品およびサービス データ保護補遺、および Microsoft Azure プレビューの使用に関する補足条件における「プレビュー」に適用される条件に従うものとします。

最新のプレビューでは、次のような新機能と拡張機能が提供されます。

  • 個々のメモリ レコードを作成、読み取り、更新、一覧表示、削除するためのメモリ項目操作。
  • 新しく作成されたメモリ ストアの既定の TTL を含む、ストア レベルの既定の保持制御。
  • 同期メモリの記憶/忘却コマンドの直接的な動作。

Foundry Agent Service のメモリは、マネージドの長期メモリ ソリューションです。 これにより、セッション、デバイス、ワークフロー間でエージェントの継続性を実現できます。 メモリ ストアを作成および管理することで、ユーザー設定を保持し、会話履歴を維持し、パーソナライズされたエクスペリエンスを提供するエージェントを構築できます。

メモリ ストアは永続的ストレージとして機能し、各エージェントに関連する情報の種類を定義します。 scope パラメーターを使用してアクセスを制御します。これにより、ユーザー間でメモリがセグメント化され、セキュリティで保護された分離されたエクスペリエンスが確保されます。

この記事では、メモリ ストアを作成、管理、使用する方法について説明します。 概念に関しては、「Foundry Agent Service のメモリ」を参照してください。

最初のエンド ツー エンドの成功には、次のパスに従います。

  1. エージェントのメモリ ストアを作成します。
  2. メモリ検索ツールを エージェントにアタッチします。
  3. 会話を作成し、優先設定を送信し、構成された更新の遅延を待機して、サービスがそれを記憶できるようにします。
  4. 同じ例で新しい会話を開始し、関連する質問をして、エージェントが優先設定を取り消していることを確認します。

メモリを直接制御する必要がある方法に基づいてワークフローを選択します。

Scenario 次から開始 これを使用して、
管理 メモリ ストアを作成する ストアとリテンション期間の設定を構成、更新、一覧表示、または削除します。
コマンド 直接の記憶または忘れ動作を適用する 情報をすぐに記憶または忘れる明示的なユーザー要求を受け入れる。
項目 メモリ項目の管理 個々のレコードを直接作成、検査、更新、または削除します。

カバレッジの例

チェックマークは、この記事にその言語の例が含まれていることを意味します。 ダッシュは、例が現在含まれていないことを意味します。SDK が操作をサポートしているかどうかは示されません。

能力 Python SDK C# SDK JavaScript SDK Java SDK REST API
メモリ ストアの作成、更新、一覧表示、削除 ✔️ ✔️ ✔️ ✔️ ✔️
プロンプト エージェントにメモリをアタッチする ✔️ ✔️ ✔️ ✔️ ✔️
メモリの更新と検索 ✔️ ✔️ ✔️ ✔️ ✔️
直接の記憶または忘れコマンドを適用する ✔️ ✔️ ✔️ ✔️
メモリ項目の作成、読み取り、更新、一覧表示、削除 ✔️ ✔️ ✔️ ✔️

前提 条件

承認とアクセス許可

運用環境 のデプロイにはロールベースのアクセス制御 を使用します。 ロールが実現できない場合は、このセクションをスキップし、代わりにキーベースの認証を使用してください。

ロールベースのアクセスを構成するには:

  1. Azure ポータルにサインインします。

  2. プロジェクトで次の手順を実行します。

    1. 左側のウィンドウで、 リソース管理>Identity を選択します。
    2. トグルを使用して、システム割り当てマネージド ID を有効にします。
  3. プロジェクトを含むリソースで、次の手順を実行します。

    1. 左側のウィンドウで、[ アクセス制御 (IAM)] を選択します。

    2. [ 追加]>[ロールの割り当ての追加] を選択します。

    3. Foundry ユーザーをプロジェクトのマネージド ID に割り当てます。

      重要

      Foundry RBAC ロールの名前が最近変更されました。 Foundry User, Foundry Owner, Foundry Account Owner、および Foundry Project Manager は、以前は、AZURE AI ユーザー、Azure AI 所有者、Azure AI アカウント所有者、および AZURE AI Project Manager という名前でした。 名前の変更がロールアウトされている間、以前の名前が表示される場合があります。ロール ID とコア アクセス許可は、名前の変更によって変更されません。

環境を設定する

必要なパッケージをインストールします。

pip install "azure-ai-projects>=2.3.0" azure-identity

必要なパッケージをインストールします。

dotnet add package Azure.AI.Projects --version 2.1.0-beta.4
dotnet add package Azure.AI.Projects.Agents --version 2.1.0-beta.4
dotnet add package Azure.AI.Extensions.OpenAI --version 2.1.0-beta.4
dotnet add package Azure.Identity

必要なパッケージをインストールします。

npm install @azure/ai-projects @azure/identity

@azure/ai-projects 2.4.0 で Node.js 22 以降を使用します。

必要なパッケージをインストールします。

<dependency>
  <groupId>com.azure</groupId>
  <artifactId>azure-ai-agents</artifactId>
</dependency>
<dependency>
  <groupId>com.azure</groupId>
  <artifactId>azure-identity</artifactId>
</dependency>

プロジェクト エンドポイントとモデルのデプロイ名の環境変数を設定します。

export FOUNDRY_PROJECT_ENDPOINT="https://{your-ai-services-account}.services.ai.azure.com/api/projects/{project-name}"
export MEMORY_STORE_CHAT_MODEL_DEPLOYMENT_NAME="<chat-model-deployment-name>"
export MEMORY_STORE_EMBEDDING_MODEL_DEPLOYMENT_NAME="<embedding-model-deployment-name>"

プロジェクト エンドポイント、モデル デプロイ、API バージョン、アクセス トークンの環境変数を設定します。

FOUNDRY_PROJECT_ENDPOINT="https://{your-ai-services-account}.services.ai.azure.com/api/projects/{project-name}"
MEMORY_STORE_CHAT_MODEL_DEPLOYMENT_NAME="<chat-model-deployment-name>" # For example, gpt-5.2
MEMORY_STORE_EMBEDDING_MODEL_DEPLOYMENT_NAME="<embedding-model-deployment-name>" # For example, text-embedding-3-small
API_VERSION="2025-11-15-preview"

# Get a short-lived access token using Azure CLI
ACCESS_TOKEN="$(az account get-access-token --resource https://ai.azure.com/ --query accessToken -o tsv)"

スコープを理解する

scope パラメーターは、メモリのパーティション分割方法を制御します。 メモリ ストア内の各スコープは、メモリ項目の分離されたコレクションを保持します。 たとえば、メモリを使用してカスタマー サポート エージェントを作成する場合、各顧客は独自のメモリを持つ必要があります。

開発者は、メモリ項目の格納と取得に使用するキーを選択します。 適切な方法は、メモリへのアクセス方法によって異なります。

メモリ検索ツールを使用する

メモリ検索ツールをエージェントにアタッチする場合は、scope{{$userId}} に設定して、ハード コーディング識別子なしでユーザーごとのメモリ分離を有効にします。 システムは、次の 2 つのソースのいずれかからの各応答呼び出しでエンド ユーザーの ID を自動的に解決します。

  • x-memory-user-id 要求ヘッダー: 存在する場合は、ヘッダー値がユーザー ID として使用されます。 これは、サービスがエンド ユーザーに代わって API を呼び出すプロキシまたはバックエンドのシナリオで使用します。

  • Microsoft Entra認証トークン: ヘッダーが設定されていない場合、システムは呼び出し元のテナント ID (TID) とオブジェクト ID (OID) にフォールバックします。 これは、ユーザーが Microsoft Entra で直接認証するフロントエンド シナリオの既定値です。

ユーザーごとの分離が必要ない場合は、代わりに静的な scope 値を使用します。

低レベルのメモリ API を使用する

メモリ API を直接呼び出す場合は、各要求でscopeを明示的に指定します。 静的な値を渡すことができます。例えば、ユニバーサル一意識別子(UUID)やシステムからの他の安定した識別子などです。 これらの操作では、ID の自動抽出はサポートされていません。

メモリ ストアを作成する

各エージェント用の専用メモリ ストアを作成して、メモリ アクセスと最適化の明確な境界を確立します。 メモリ ストアを作成するときに、メモリ コンテンツを処理するチャット モデルと埋め込みモデルのデプロイを指定します。

メモリ ストア オプションを使用して、抽出動作とリテンション期間の既定値を制御します。 最新のプレビューでは、手続き型メモリを有効にし、新しく作成されたメモリ エントリの既定の TTL (秒) を設定できます。

import os
from datetime import timedelta
from azure.ai.projects import AIProjectClient
from azure.ai.projects.models import MemoryStoreDefaultDefinition, MemoryStoreDefaultOptions
from azure.identity import DefaultAzureCredential

project_client = AIProjectClient(
    endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
    credential=DefaultAzureCredential(),
)

memory_store_name = "my_memory_store"

# Specify memory store options
options = MemoryStoreDefaultOptions(
    chat_summary_enabled=True,
    user_profile_enabled=True,
    procedural_memory_enabled=True,
    default_ttl_seconds=timedelta(days=30),
    user_profile_details="Avoid irrelevant or sensitive data, such as age, financials, precise location, and credentials"
)

# Create memory store
chat_model = os.environ["MEMORY_STORE_CHAT_MODEL_DEPLOYMENT_NAME"]
embedding_model = os.environ["MEMORY_STORE_EMBEDDING_MODEL_DEPLOYMENT_NAME"]

definition = MemoryStoreDefaultDefinition(
    chat_model=chat_model,
    embedding_model=embedding_model,
    options=options
)

memory_store = project_client.beta.memory_stores.create(
    name=memory_store_name,
    definition=definition,
    description="Memory store with procedural memory and 30-day default TTL",
)

print(f"Created memory store: {memory_store.name}")
using System;
using Azure.AI.Projects;
using Azure.AI.Projects.Memory;
using Azure.Identity;

#pragma warning disable AAIP001

var projectEndpoint = Environment.GetEnvironmentVariable(
    "FOUNDRY_PROJECT_ENDPOINT");
var chatModel = Environment.GetEnvironmentVariable(
    "MEMORY_STORE_CHAT_MODEL_DEPLOYMENT_NAME");
var embeddingModel = Environment.GetEnvironmentVariable(
    "MEMORY_STORE_EMBEDDING_MODEL_DEPLOYMENT_NAME");

AIProjectClient projectClient = new(
    new Uri(projectEndpoint),
    new DefaultAzureCredential());

var memoryStoreName = "my_memory_store";

// Specify memory store options
MemoryStoreDefaultDefinition memoryStoreDefinition = new(
    chatModel: chatModel,
    embeddingModel: embeddingModel
);
memoryStoreDefinition.Options = new(
    isUserProfileEnabled: true,
    isChatSummaryEnabled: true);
memoryStoreDefinition.Options.UserProfileDetails =
    "Avoid irrelevant or sensitive data, such as age, "
    + "financials, precise location, and credentials";

// Create memory store
MemoryStore memoryStore = projectClient.MemoryStores.CreateMemoryStore(
    name: memoryStoreName,
    definition: memoryStoreDefinition,
    description: "Memory store for customer support agent"
);

Console.WriteLine($"Created memory store: {memoryStore.Name}");
import { DefaultAzureCredential } from "@azure/identity";
import type {
  MemoryStoreDefaultDefinition,
  MemoryStoreDefaultOptions,
} from "@azure/ai-projects";
import { AIProjectClient } from "@azure/ai-projects";

const projectEndpoint =
  process.env["FOUNDRY_PROJECT_ENDPOINT"] ||
  "<project endpoint>";
const chatModelDeployment =
  process.env["MEMORY_STORE_CHAT_MODEL_DEPLOYMENT_NAME"] ||
  "<chat model deployment name>";
const embeddingModelDeployment =
  process.env["MEMORY_STORE_EMBEDDING_MODEL_DEPLOYMENT_NAME"] ||
  "<embedding model deployment name>";

const memoryStoreName = "my_memory_store";

const project = new AIProjectClient(
  projectEndpoint,
  new DefaultAzureCredential(),
);

const memoryOptions: MemoryStoreDefaultOptions = {
  user_profile_enabled: true,
  chat_summary_enabled: true,
  procedural_memory_enabled: true,
  default_ttl_seconds: 30 * 24 * 60 * 60,
  user_profile_details:
    "Avoid irrelevant or sensitive data, such as age, " +
    "financials, precise location, and credentials",
};

const definition: MemoryStoreDefaultDefinition = {
  kind: "default",
  chat_model: chatModelDeployment,
  embedding_model: embeddingModelDeployment,
  options: memoryOptions,
};

const memoryStore = await project.beta.memoryStores.create(
  memoryStoreName,
  definition,
  {
    description: "Memory store with procedural memory and 30-day default TTL",
  },
);

console.log(
  `Created memory store: ${memoryStore.name} (${memoryStore.id})`,
);
import com.azure.ai.agents.AgentsClientBuilder;
import com.azure.ai.agents.BetaMemoryStoresClient;
import com.azure.ai.agents.models.MemoryStoreDefaultDefinition;
import com.azure.ai.agents.models.MemoryStoreDefaultOptions;
import com.azure.ai.agents.models.MemoryStoreDetails;
import com.azure.identity.DefaultAzureCredentialBuilder;

String projectEndpoint = System.getenv("FOUNDRY_PROJECT_ENDPOINT");
String chatModel = System.getenv("MEMORY_STORE_CHAT_MODEL_DEPLOYMENT_NAME");
String embeddingModel =
  System.getenv("MEMORY_STORE_EMBEDDING_MODEL_DEPLOYMENT_NAME");

BetaMemoryStoresClient memoryStoresClient = new AgentsClientBuilder()
  .credential(new DefaultAzureCredentialBuilder().build())
  .endpoint(projectEndpoint)
  .beta()
  .buildBetaMemoryStoresClient();

String memoryStoreName = "my_memory_store";

MemoryStoreDefaultDefinition definition =
  new MemoryStoreDefaultDefinition(chatModel, embeddingModel)
    .setOptions(new MemoryStoreDefaultOptions(true, true));

MemoryStoreDetails memoryStore = memoryStoresClient.createMemoryStore(
  memoryStoreName,
  definition,
  "Memory store for customer support agent",
  null);

System.out.println("Created memory store: " + memoryStore.getName());
curl -X POST "${FOUNDRY_PROJECT_ENDPOINT}/memory_stores?api-version=${API_VERSION}" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "my_memory_store",
    "description": "Memory store with procedural memory and 30-day default TTL",
    "definition": {
      "kind": "default",
      "chat_model": "'"${MEMORY_STORE_CHAT_MODEL_DEPLOYMENT_NAME}"'",
      "embedding_model": "'"${MEMORY_STORE_EMBEDDING_MODEL_DEPLOYMENT_NAME}"'",
      "options": {
        "chat_summary_enabled": true,
        "user_profile_enabled": true,
        "procedural_memory_enabled": true,
        "default_ttl_seconds": 2592000,
        "user_profile_details": "Avoid irrelevant or sensitive data, such as age, financials, precise location, and credentials"
      }
    }
  }'

ヒント

  • 残りのPython、C#、TypeScript、およびJava スニペットは、クライアントと「メモリ ストアの作成」で定義されている変数に基づいて構築されます。 これらのコード スニペットを個別に実行する場合は、このセクションのインポートコードとクライアント初期化コードを含めます。

  • この記事の C# スニペットでは、同期メソッドを使用します。 非同期の使用については、memory 検索ツール および memory store サンプルを参照してください。

メモリをカスタマイズする

エージェントが格納する情報をカスタマイズして、メモリの効率、関連性、プライバシーに配慮した状態を維持します。 user_profile_details パラメーターを使用して、エージェントの関数に不可欠なデータの種類を指定します。

たとえば、 user_profile_details を設定して、旅行代理店の "フライト キャリアの優先順位と食事制限" に優先順位を付けます。 この重点的なアプローチは、メモリシステムが、どの詳細を抽出、要約し、どのように長期記憶に保存するかを把握するのに役立ちます。

また、このパラメーターを使用して、特定の種類のデータを除外し、メモリの無駄を維持し、プライバシー要件に準拠することもできます。 たとえば、 user_profile_details を設定して、"年齢、財務、正確な場所、資格情報など、無関係なデータや機密データを避ける" ようにします。

TTL と保持ポリシーを設定する

TTL は、直接メモリ コマンド、抽出と統合、または項目レベルの CRUD 操作からのすべてのメモリに適用されます。 メモリが更新および統合されると、サービスは最後に更新された時刻をリセットします。

TTL は、TTL サポートが導入された後に作成されたメモリ ストアにのみ適用されます。 既存のメモリ ストアには影響しません。

default_ttl_seconds0値は、有効期限がないことを示します。 コンプライアンスとユーザー データのライフサイクル要件に一致する保持期間を選択します。

メモリ ストアを更新する

メモリ ストアの管理を強化するために、 descriptionmetadataなどのメモリ ストアのプロパティを更新します。

# Update memory store properties
updated_store = project_client.beta.memory_stores.update(
    name=memory_store_name,
    description="Updated description"
)

print(f"Updated: {updated_store.description}")
// Update memory store properties
MemoryStore updatedStore = projectClient.MemoryStores.UpdateMemoryStore(
    name: memoryStoreName,
    description: "Updated description"
);

Console.WriteLine($"Updated: {updatedStore.Description}");
const updatedStore = await project.beta.memoryStores.update(
  memoryStoreName,
  {
    description: "Updated description",
  },
);

console.log(`Updated: ${updatedStore.description}`);
import com.azure.ai.agents.models.MemoryStoreDetails;

MemoryStoreDetails updatedStore = memoryStoresClient.updateMemoryStore(
  memoryStoreName,
  "Updated description",
  null);

System.out.println("Updated: " + updatedStore.getDescription());
MEMORY_STORE_NAME="my_memory_store"

curl -X POST "${FOUNDRY_PROJECT_ENDPOINT}/memory_stores/${MEMORY_STORE_NAME}?api-version=${API_VERSION}" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "description": "Updated description"
  }'

メモリ ストアを一覧表示する

メモリ インフラストラクチャを管理および監視するために、プロジェクト内のメモリ ストアの一覧を取得します。

# List all memory stores
stores_list = list(project_client.beta.memory_stores.list())

print(f"Found {len(stores_list)} memory stores")
for store in stores_list:
    print(f"- {store.name} ({store.description})")
// List all memory stores
foreach (MemoryStore store in projectClient.MemoryStores.GetMemoryStores())
{
    Console.WriteLine(
        $"Memory store: {store.Name} ({store.Description})");
}
const storeList = project.beta.memoryStores.list();

console.log("Listing all memory stores...");
for await (const store of storeList) {
  console.log(`  - Memory Store: ${store.name} (${store.id})`);
}
import com.azure.ai.agents.models.MemoryStoreDetails;

System.out.println("Listing all memory stores...");
for (MemoryStoreDetails store : memoryStoresClient.listMemoryStores()) {
    System.out.println(
        "  - Memory Store: " + store.getName() + " (" + store.getId() + ")");
}
curl -X GET "${FOUNDRY_PROJECT_ENDPOINT}/memory_stores?api-version=${API_VERSION}" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}"

エージェント ツールを使用してメモリを使用する

メモリ ストアを作成したら、メモリ検索ツールをプロンプト エージェントにアタッチできます。 このツールを使用すると、エージェントは会話中にメモリ ストアの読み取りと書き込みを行うことができます。 メモリの更新方法とタイミングを制御するために、適切な scopeupdate_delay を使用してツールを構成します。

ヒント

メモリのスコープを個々のエンド ユーザーに設定するには、 scope をツール定義で "{{$userId}}" に設定し、各応答呼び出しでヘッダーとして x-memory-user-id: <user-id> を渡します。 システムは、スコープをそのユーザーの ID に解決します。 ヘッダーがない場合、スコープは呼び出し元のMicrosoft Entra ID (TID と OID) にフォールバックします。 詳細については、「 スコープについて」を参照してください。

from azure.ai.projects.models import MemorySearchPreviewTool, PromptAgentDefinition

# Set scope to associate the memories with
scope = "user_123"

openai_client = project_client.get_openai_client()

# Create memory search tool
tool = MemorySearchPreviewTool(
    memory_store_name=memory_store_name,
    scope=scope,
    update_delay=1, # Wait 1 second of inactivity before updating memories
    # In a real application, set this to a higher value like 300 (5 minutes, default)
)

# Create a prompt agent with memory search tool
agent = project_client.agents.create_version(
    agent_name="MyAgent",
    definition=PromptAgentDefinition(
        model=os.environ["MEMORY_STORE_CHAT_MODEL_DEPLOYMENT_NAME"],
        instructions="You are a helpful assistant that answers general questions",
        tools=[tool],
    )
)

print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.version})")
using Azure.AI.Projects.Agents;
using Azure.AI.Extensions.OpenAI;
using OpenAI.Responses;

#pragma warning disable OPENAI001

// Set scope to associate the memories with
string scope = "user_123";

// Create a prompt agent with memory search tool
DeclarativeAgentDefinition agentDefinition = new(model: chatModel)
{
    Instructions = "You are a helpful assistant that answers "
        + "general questions",
};
agentDefinition.Tools.Add(new MemorySearchPreviewTool(
    memoryStoreName: memoryStore.Name,
    scope: scope)
{
    UpdateDelayInSecs = 1, // Wait 1 second of inactivity before updating memories
    // In a real application, set this to a higher value
    // like 300 (5 minutes, default)
});

ProjectsAgentVersion agent =
    projectClient.AgentAdministrationClient.CreateAgentVersion(
        agentName: "MyAgent",
        options: new(agentDefinition));

Console.WriteLine(
    $"Agent created (id: {agent.Id}, name: {agent.Name}, "
    + $"version: {agent.Version})");
// Set scope to associate the memories with
const scope = "user_123";

const agent = await project.agents.createVersion(
  "memory-search-agent",
  {
    kind: "prompt",
    model: chatModelDeployment,
    instructions:
      "You are a helpful assistant that retrieves relevant " +
      "information from the user's memory store to answer their questions.",
    tools: [
      {
        type: "memory_search_preview",
        memory_store_name: memoryStoreName,
        scope: scope,
        update_delay: 1,
      },
    ],
  },
);

console.log(
  `Created agent with memory search tool, agent ID: ${agent.id}, ` +
    `name: ${agent.name}, version: ${agent.version}`,
);
import com.azure.ai.agents.AgentsClient;
import com.azure.ai.agents.AgentsClientBuilder;
import com.azure.ai.agents.models.AgentVersionDetails;
import com.azure.ai.agents.models.MemorySearchPreviewTool;
import com.azure.ai.agents.models.PromptAgentDefinition;
import com.azure.identity.DefaultAzureCredentialBuilder;

String scope = "user_123";

AgentsClient agentsClient = new AgentsClientBuilder()
  .credential(new DefaultAzureCredentialBuilder().build())
  .endpoint(projectEndpoint)
  .buildAgentsClient();

MemorySearchPreviewTool memoryTool = new MemorySearchPreviewTool(
  memoryStoreName,
  scope).setUpdateDelaySeconds(1);

PromptAgentDefinition agentDefinition = new PromptAgentDefinition(chatModel)
  .setInstructions("You are a helpful assistant that answers general questions")
  .setTools(java.util.Collections.singletonList(memoryTool));

AgentVersionDetails agent =
  agentsClient.createAgentVersion("MyAgent", agentDefinition);

System.out.println(
  "Agent created (id: " + agent.getId() + ", name: " + agent.getName()
    + ", version: " + agent.getVersion() + ")");
# The agents API uses api-version=v1, which differs from the memory store API version
curl -X POST "${FOUNDRY_PROJECT_ENDPOINT}/agents?api-version=v1" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "MyAgent",
    "definition": {
        "kind": "prompt",
        "model": "gpt-5.2",
        "instructions": "You are a helpful assistant that answers general questions",
        "tools": [
            {
              "type": "memory_search_preview",
              "memory_store_name": "my_memory_store",
              "scope": "user_123",
              "update_delay": 1
            }
        ]
    }
}'

会話を作成する

会話を作成し、エージェントの応答を要求できるようになりました。 各会話の開始時に静的メモリが挿入され、エージェントは即時の永続的なコンテキストを持ちます。 コンテキスト メモリは、各応答に通知する最新のメッセージに基づいてターンごとに取得されます。

各エージェント応答の後、サービスは内部的に update_memoriesを呼び出します。 ただし、長期メモリへの実際の書き込みは、 update_delay 設定によってデバウンスされます。 更新プログラムはスケジュールされ、構成された非アクティブ期間の後にのみ完了します。

Note

更新されたプレビュー スキーマでは、メモリ検索ツールの出力では、レガシ memories フィールドではなく、results コレクションが使用されます。 生出力ペイロードを処理する場合は、それに応じてパーサーを更新します。

import time

# Create a conversation with the agent with memory tool enabled
conversation = openai_client.conversations.create()
print(f"Created conversation (id: {conversation.id})")

# Create an agent response to initial user message
response = openai_client.responses.create(
    input="I prefer dark roast coffee",
    conversation=conversation.id,
    extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}},
    # To scope memories to an end user, uncomment:
    # extra_headers={"x-memory-user-id": "<user-id>"},
)

print(f"Response output: {response.output_text}")

# After an inactivity in the conversation, memories will be extracted from the conversation and stored
print("Waiting for memories to be stored...")
time.sleep(65)

# Create a new conversation
new_conversation = openai_client.conversations.create()
print(f"Created new conversation (id: {new_conversation.id})")

# Create an agent response with stored memories
new_response = openai_client.responses.create(
    input="Please order my usual coffee",
    conversation=new_conversation.id,
    extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}},
)

print(f"Response output: {new_response.output_text}")
using System.Threading;

#pragma warning disable OPENAI001

// Get a response client scoped to the agent
ProjectResponsesClient responseClient =
    projectClient.ProjectOpenAIClient
        .GetProjectResponsesClientForAgent(agent.Name);

// Create an agent response to initial user message
ResponseItem request = ResponseItem.CreateUserMessageItem(
    "I prefer dark roast coffee");
ResponseResult response = responseClient.CreateResponse([request]);
// To scope memories to an end user, uncomment:
// var options = new CreateResponseOptions();
// options.InputItems.Add(request);
// var requestOptions = new RequestOptions();
// requestOptions.AddHeader("x-memory-user-id", "<user-id>");
// ClientResult result = responseClient.CreateResponse(
//     BinaryContent.Create(options), requestOptions);
// ResponseResult response = ModelReaderWriter.Read<ResponseResult>(
//     result.GetRawResponse().Content);

Console.WriteLine($"Response output: {response.GetOutputText()}");

// After inactivity, memories are extracted and stored
Console.WriteLine("Waiting for memories to be stored...");
Thread.Sleep(65_000);

// Create a new response to demonstrate cross-session recall
ResponseItem newRequest = ResponseItem.CreateUserMessageItem(
    "Please order my usual coffee");
ResponseResult newResponse = responseClient.CreateResponse(
    [newRequest]);

Console.WriteLine(
    $"Response output: {newResponse.GetOutputText()}");
import { setTimeout } from "timers/promises";

const openai = project.getOpenAIClient();

// Create a conversation with the agent with memory tool enabled
const conversation = await openai.conversations.create();
console.log(`Created conversation (id: ${conversation.id})`);

// Create an agent response to initial user message
const response = await openai.responses.create(
  {
    conversation: conversation.id,
    input: "I prefer dark roast coffee",
  },
  {
    body: {
      agent_reference: { name: agent.name, type: "agent_reference" },
    },
    // To scope memories to an end user, uncomment:
    // headers: { "x-memory-user-id": "<user-id>" },
  },
);

console.log(`Response output: ${response.output_text}`);

// After inactivity, memories are extracted and stored
console.log("Waiting for memories to be stored...");
await setTimeout(65_000);

// Create a new conversation to demonstrate cross-session recall
const newConversation = await openai.conversations.create();
console.log(`Created new conversation (id: ${newConversation.id})`);

// Create an agent response with stored memories
const newResponse = await openai.responses.create(
  {
    conversation: newConversation.id,
    input: "Please order my usual coffee",
  },
  {
    body: {
      agent_reference: { name: agent.name, type: "agent_reference" },
    },
  },
);

console.log(`Response output: ${newResponse.output_text}`);
import com.azure.ai.agents.ResponsesClient;
import com.azure.ai.agents.AgentsClientBuilder;
import com.azure.ai.agents.models.AgentReference;
import com.azure.ai.agents.models.AzureCreateResponseOptions;
import com.azure.identity.DefaultAzureCredentialBuilder;
import com.openai.models.responses.Response;
import com.openai.models.responses.ResponseCreateParams;

ResponsesClient responsesClient = new AgentsClientBuilder()
  .credential(new DefaultAzureCredentialBuilder().build())
  .endpoint(projectEndpoint)
  .buildResponsesClient();

AgentReference agentReference = new AgentReference(agent.getName())
  .setVersion(agent.getVersion());

Response response = responsesClient.createAzureResponse(
  new AzureCreateResponseOptions().setAgentReference(agentReference),
  ResponseCreateParams.builder()
    .input("I prefer dark roast coffee"));

System.out.println("Response output: " + response.output());

System.out.println("Waiting for memories to be stored...");
Thread.sleep(65_000);

Response newResponse = responsesClient.createAzureResponse(
  new AzureCreateResponseOptions().setAgentReference(agentReference),
  ResponseCreateParams.builder()
    .input("Please order my usual coffee"));

System.out.println("Response output: " + newResponse.output());
curl -X POST "${FOUNDRY_PROJECT_ENDPOINT}/openai/v1/conversations" \
    -H "Authorization: Bearer ${ACCESS_TOKEN}" \
    -H "Content-Type: application/json" \
    -d '{}'

# Copy the "id" field from the previous response
# To scope memories to an end user, add -H "x-memory-user-id: <user-id>" to the following request
curl -X POST "${FOUNDRY_PROJECT_ENDPOINT}/openai/v1/responses" \
    -H "Authorization: Bearer ${ACCESS_TOKEN}" \
    -H "Content-Type: application/json" \
    -d '{
      "input": "I prefer dark roast coffee",
      "conversation": "{conversation-id}",
      "agent_reference": {
        "type": "agent_reference",
        "name": "MyAgent"
      }
    }'

直接の記憶または忘れ動作を適用する

ユーザーがエージェントに情報の記憶または忘れについて明示的に要求すると、 tools 配列内のメモリ検索ツールは操作を直ちに適用し、結果を応答出力のメモリ コマンド項目として返します。 追加のツール構成は必要ありません。

Note

ダイレクト メモリ コマンドでは、メモリ TTL はオーバーライドされません。 メモリ ストアに TTL が構成されている場合、メモリ項目は remember コマンドによって追加された場合でも、有効期限が切れる可能性があります。

openai_client = project_client.get_openai_client()

# Configure the memory search tool
tools = [
    {
        "type": "memory_search_preview",
        "memory_store_name": memory_store_name,
        "scope": scope,
    }
]

# Ask the agent to remember information
remember_response = openai_client.responses.create(
    model=os.environ["MEMORY_STORE_CHAT_MODEL_DEPLOYMENT_NAME"],
    tools=tools,
    input="Remember that my preferred seat is aisle.",
)

for item in remember_response.output:
    if getattr(item, "type", None) == "memory_command_call":
        print(item.type)       # memory_command_call
        print(item.arguments)  # {"action": "remember", "content": "..."}
        print(item.status)     # completed

# Ask the agent to forget information
forget_response = openai_client.responses.create(
    model=os.environ["MEMORY_STORE_CHAT_MODEL_DEPLOYMENT_NAME"],
    tools=tools,
    input="Forget my preferred seat.",
)

for item in forget_response.output:
    if getattr(item, "type", None) == "memory_command_call":
        print(item.type)
        print(item.arguments)  # {"action": "forget", "content": "..."}
        print(item.status)

次の使用例は、「会話の作成」で作成したresponseClientを再利用します

using Azure.AI.Extensions.OpenAI;
using OpenAI.Responses;

#pragma warning disable AAIP001
#pragma warning disable OPENAI001

static void PrintMemoryCommands(ResponseResult response)
{
    foreach (ResponseItem item in response.OutputItems)
    {
        switch (item.AsAgentResponseItem())
        {
            case MemoryCommandToolCall command:
                Console.WriteLine($"Arguments: {command.Arguments}");
                Console.WriteLine($"Status: {command.Status}");
                break;
            case MemoryCommandToolCallOutput output:
                Console.WriteLine($"Status: {output.Status}");
                break;
        }
    }
}

// Ask the agent to remember information
ResponseResult rememberResponse = responseClient.CreateResponse(
    [ResponseItem.CreateUserMessageItem(
        "Remember that my preferred seat is aisle.")]);
PrintMemoryCommands(rememberResponse);

// Ask the agent to forget information
ResponseResult forgetResponse = responseClient.CreateResponse(
    [ResponseItem.CreateUserMessageItem(
        "Forget my preferred seat.")]);
PrintMemoryCommands(forgetResponse);
const openai = project.getOpenAIClient();

// Configure the memory search tool
const tools = [
  {
    type: "memory_search_preview",
    memory_store_name: memoryStoreName,
    scope: scope,
  },
];

// Ask the agent to remember information
const rememberResponse = await openai.responses.create({
  model: chatModelDeployment,
  input: "Remember that my preferred seat is aisle.",
  tools: tools as any,
});

for (const item of rememberResponse.output) {
  const outputItem = item as Record<string, unknown>;
  if (outputItem["type"] === "memory_command_call") {
    console.log(outputItem["type"]);       // memory_command_call
    console.log(outputItem["arguments"]);
    // {"action": "remember", "content": "..."}
    console.log(outputItem["status"]);     // completed
  }
}

// Ask the agent to forget information
const forgetResponse = await openai.responses.create({
  model: chatModelDeployment,
  input: "Forget my preferred seat.",
  tools: tools as any,
});

for (const item of forgetResponse.output) {
  const outputItem = item as Record<string, unknown>;
  if (outputItem["type"] === "memory_command_call") {
    console.log(outputItem["type"]);
    console.log(outputItem["arguments"]);
    // {"action": "forget", "content": "..."}
    console.log(outputItem["status"]);
  }
}
import com.openai.models.responses.Response;
import com.openai.models.responses.ResponseCreateParams;

Response rememberResponse = responsesClient.createAzureResponse(
  new AzureCreateResponseOptions().setAgentReference(agentReference),
  ResponseCreateParams.builder()
    .input("Remember that my preferred seat is aisle."));

System.out.println(rememberResponse.output());

Response forgetResponse = responsesClient.createAzureResponse(
  new AzureCreateResponseOptions().setAgentReference(agentReference),
  ResponseCreateParams.builder()
    .input("Forget my preferred seat."));

System.out.println(forgetResponse.output());
# Reuse the {conversation-id} from the previous section
# To scope memories to an end user, set x-memory-user-id in each request
curl -X POST "${FOUNDRY_PROJECT_ENDPOINT}/openai/v1/responses" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}" \
  -H "Content-Type: application/json" \
  -H "x-memory-user-id: <user-id>" \
  -d '{
    "input": "Remember that my preferred seat is aisle.",
    "conversation": "{conversation-id}",
    "agent_reference": {
      "type": "agent_reference",
      "name": "MyAgent"
    }
  }'

curl -X POST "${FOUNDRY_PROJECT_ENDPOINT}/openai/v1/responses" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}" \
  -H "Content-Type: application/json" \
  -H "x-memory-user-id: <user-id>" \
  -d '{
    "input": "Forget my preferred seat.",
    "conversation": "{conversation-id}",
    "agent_reference": {
      "type": "agent_reference",
      "name": "MyAgent"
    }
  }'

API 経由でメモリを使用する

メモリ ストア API を使用して、メモリ ストアを直接操作できます。 まず、会話コンテンツからメモリ ストアにメモリを追加し、関連するメモリを検索してエージェントの対話のコンテキストを提供します。

メモリ ストアにメモリを追加する

メモリ ストアに会話コンテンツを提供して、メモリを追加します。 システムは、エージェントのメモリを最適化するために、メモリの抽出や統合など、データを前処理して後処理します。 この実行時間の長い操作には約 1 分かかる場合があります。

scope パラメーターを指定して、ユーザー間でメモリをセグメント化する方法を決定します。 特定のエンド ユーザー、チーム、または別の識別子にメモリのスコープを設定できます。

複数の会話ターンのコンテンツを使用してメモリ ストアを更新したり、前の更新操作 ID を使用して各ターンとチェーンの更新後に更新したりできます。

# Set scope to associate the memories with
scope = "user_123"

user_message = {
  "role": "user",
  "content": "I prefer dark roast coffee and usually drink it in the morning",
   "type": "message"
}

update_poller = project_client.beta.memory_stores.begin_update_memories(
    name=memory_store_name,
    scope=scope,
    items=[user_message], # Pass conversation items that you want to add to memory
    update_delay=0, # Trigger update immediately without waiting for inactivity
)

# Wait for the update operation to complete, but can also fire and forget
update_result = update_poller.result()
print(f"Updated with {len(update_result.memory_operations)} memory operations")
for operation in update_result.memory_operations:
    print(
        f"  - Operation: {operation.kind}, Memory ID: {operation.memory_item.memory_id}, Content: {operation.memory_item.content}"
    )

# Extend the previous update with another update and more messages
new_message = {
    "role":"user", 
    "content":"I also like cappuccinos in the afternoon", 
    "type":"message"}

new_update_poller = project_client.beta.memory_stores.begin_update_memories(
    name=memory_store_name,
    scope=scope,
    items=[new_message],
    previous_update_id=update_poller.update_id, # Extend from previous update ID
    update_delay=0, # Trigger update immediately without waiting for inactivity
)
new_update_result = new_update_poller.result()
for operation in new_update_result.memory_operations:
    print(
        f"  - Operation: {operation.kind}, Memory ID: {operation.memory_item.memory_id}, Content: {operation.memory_item.content}"
    )
#pragma warning disable OPENAI001

// Set scope to associate the memories with
string scope = "user_123";

MemoryUpdateOptions memoryOptions = new(scope)
{
    UpdateDelay = 0, // Trigger update immediately without waiting for inactivity
};
memoryOptions.Items.Add(ResponseItem.CreateUserMessageItem(
    "I prefer dark roast coffee and usually drink it "
    + "in the morning"));

// Wait for the update operation to complete
MemoryUpdateResult updateResult =
    projectClient.MemoryStores.WaitForMemoriesUpdate(
        memoryStoreName: memoryStore.Name,
        options: memoryOptions,
        pollingInterval: 500);

if (updateResult.Status == MemoryStoreUpdateStatus.Failed)
{
    throw new InvalidOperationException(
        updateResult.ErrorDetails);
}
Console.WriteLine(
    $"Updated with {updateResult.Details.MemoryOperations.Count} "
    + "memory operations");
foreach (var operation in updateResult.Details.MemoryOperations)
{
    Console.WriteLine(
        $"  - Operation: {operation.Kind}, "
        + $"Memory ID: {operation.MemoryItem.MemoryId}, "
        + $"Content: {operation.MemoryItem.Content}");
}

// Extend the previous update with another message
MemoryUpdateOptions newMemoryOptions = new(scope)
{
    PreviousUpdateId = updateResult.UpdateId,
    UpdateDelay = 0, // Trigger update immediately without waiting for inactivity
};
newMemoryOptions.Items.Add(ResponseItem.CreateUserMessageItem(
    "I also like cappuccinos in the afternoon"));

MemoryUpdateResult newUpdateResult =
    projectClient.MemoryStores.WaitForMemoriesUpdate(
        memoryStoreName: memoryStore.Name,
        options: newMemoryOptions,
        pollingInterval: 500);

if (newUpdateResult.Status == MemoryStoreUpdateStatus.Failed)
{
    throw new InvalidOperationException(
        newUpdateResult.ErrorDetails);
}
foreach (var operation in newUpdateResult.Details.MemoryOperations)
{
    Console.WriteLine(
        $"  - Operation: {operation.Kind}, "
        + $"Memory ID: {operation.MemoryItem.MemoryId}, "
        + $"Content: {operation.MemoryItem.Content}");
}
const scope = "user_123";

const userMessage: Record<string, unknown> = {
  type: "message",
  role: "user",
  content: [
    {
      type: "input_text",
      text: "I prefer dark roast coffee and usually drink it in the morning",
    },
  ],
};

console.log("\nSubmitting memory update request...");
const updatePoller = project.beta.memoryStores.updateMemories(
  memoryStoreName,
  scope,
  {
    items: [userMessage],
    updateDelayInSecs: 0,
  },
);

const updateResult = await updatePoller.pollUntilDone();
console.log(
  `Updated with ${updateResult.memory_operations.length} ` +
    `memory operation(s)`,
);
for (const operation of updateResult.memory_operations) {
  console.log(
    `  - Operation: ${operation.kind}, ` +
      `Memory ID: ${operation.memory_item.memory_id}, ` +
      `Content: ${operation.memory_item.content}`,
  );
}

// Extend the previous update with another message
const newMessage = {
  role: "user",
  content: "I also like cappuccinos in the afternoon",
  type: "message",
};

const newUpdatePoller = project.beta.memoryStores.updateMemories(
  memoryStoreName,
  scope,
  {
    items: [newMessage],
    updateDelayInSecs: 0,
  },
);

const newUpdateResult = await newUpdatePoller.pollUntilDone();
console.log(
  `Updated with ${newUpdateResult.memory_operations.length} ` +
    `memory operation(s)`,
);
for (const operation of newUpdateResult.memory_operations) {
  console.log(
    `  - Operation: ${operation.kind}, ` +
      `Memory ID: ${operation.memory_item.memory_id}, ` +
      `Content: ${operation.memory_item.content}`,
  );
}
import com.azure.ai.agents.models.MemoryStoreUpdateCompletedResult;
import com.azure.ai.agents.models.MemoryStoreUpdateResponse;
import com.azure.core.util.polling.SyncPoller;
import com.openai.models.responses.EasyInputMessage;
import com.openai.models.responses.ResponseInputItem;
import java.util.Arrays;

ResponseInputItem userMessage = ResponseInputItem.ofEasyInputMessage(
  EasyInputMessage.builder()
    .role(EasyInputMessage.Role.USER)
    .content("I prefer dark roast coffee and usually drink it in the morning")
    .build());

SyncPoller<MemoryStoreUpdateResponse, MemoryStoreUpdateCompletedResult> updatePoller =
  memoryStoresClient.beginUpdateMemories(
    memoryStoreName,
    scope,
    Arrays.asList(userMessage),
    null,
    0);

updatePoller.waitForCompletion();
MemoryStoreUpdateCompletedResult updateResult = updatePoller.getFinalResult();
System.out.println(
  "Updated with " + updateResult.getMemoryOperations().size()
    + " memory operation(s)");
for (var operation : updateResult.getMemoryOperations()) {
  System.out.println(
    "  - Operation: " + operation.getKind() + ", Memory ID: "
      + operation.getMemoryItem().getMemoryId() + ", Content: "
      + operation.getMemoryItem().getContent());
}

ResponseInputItem newMessage = ResponseInputItem.ofEasyInputMessage(
  EasyInputMessage.builder()
    .role(EasyInputMessage.Role.USER)
    .content("I also like cappuccinos in the afternoon")
    .build());

// Pass null for previousUpdateId to start a fresh independent update.
// To chain from the previous update, pass the update ID from the
// intermediate poller response instead.
SyncPoller<MemoryStoreUpdateResponse, MemoryStoreUpdateCompletedResult> newUpdatePoller =
  memoryStoresClient.beginUpdateMemories(
    memoryStoreName,
    scope,
    Arrays.asList(newMessage),
    null,
    0);

newUpdatePoller.waitForCompletion();
MemoryStoreUpdateCompletedResult newUpdateResult = newUpdatePoller.getFinalResult();
for (var newOperation : newUpdateResult.getMemoryOperations()) {
  System.out.println(
    "  - Operation: " + newOperation.getKind() + ", Memory ID: "
      + newOperation.getMemoryItem().getMemoryId() + ", Content: "
      + newOperation.getMemoryItem().getContent());
}
curl -X POST "${FOUNDRY_PROJECT_ENDPOINT}/memory_stores/my_memory_store:update_memories?api-version=${API_VERSION}" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "scope": "user_123",
    "items": [
      {
        "type": "message",
        "role": "user",
        "content": [
          {
            "type": "input_text",
            "text": "I prefer dark roast coffee and usually drink it in the morning"
          }
        ]
      }
    ],
    "update_delay": 0
  }'

# Get add memory status by polling the update_id
# Use the "update_id" from previous response
UPDATE_ID=<your_update_id>
curl -X GET "${FOUNDRY_PROJECT_ENDPOINT}/memory_stores/my_memory_store/updates/${UPDATE_ID}?api-version=${API_VERSION}" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}"

メモリ ストア内の記憶を検索する

メモリを検索して、エージェントの対話に関連するコンテキストを取得します。 検索を絞り込むためのメモリ ストア名とスコープを指定します。

from azure.ai.projects.models import MemorySearchOptions

# Search memories by a query
query_message = {"role": "user", "content": "What are my coffee preferences?", "type": "message"}

search_response = project_client.beta.memory_stores.search_memories(
    name=memory_store_name,
    scope=scope,
    items=[query_message],
    options=MemorySearchOptions(max_memories=5)
)
print(f"Found {len(search_response.memories)} memories")
for memory in search_response.memories:
    print(f"  - Memory ID: {memory.memory_item.memory_id}, Content: {memory.memory_item.content}")
#pragma warning disable OPENAI001

// Search memories by a query
MemorySearchOptions searchOptions = new(scope)
{
    Items =
    {
        ResponseItem.CreateUserMessageItem(
            "What are my coffee preferences?")
    },
    ResultOptions = new() { MaxMemories = 5 },
};

MemoryStoreSearchResponse searchResponse =
    projectClient.MemoryStores.SearchMemories(
        memoryStoreName: memoryStore.Name,
        options: searchOptions);

Console.WriteLine(
    $"Found {searchResponse.Memories.Count} memories");
foreach (MemorySearchItem item in searchResponse.Memories)
{
    Console.WriteLine(
        $"  - Content: {item.MemoryItem.Content}");
}
const queryMessage: Record<string, unknown> = {
  type: "message",
  role: "user",
  content: [
    { type: "input_text", text: "What are my coffee preferences?" },
  ],
};

console.log("\nSearching memories for stored preferences...");
const searchResponse =
  await project.beta.memoryStores.searchMemories(
    memoryStoreName,
    scope,
    {
      items: [queryMessage],
      options: { max_memories: 5 },
    },
  );

console.log(`Found ${searchResponse.memories.length} memory item(s)`);
for (const memory of searchResponse.memories) {
  console.log(
    `  - Memory ID: ${memory.memory_item.memory_id}, ` +
      `Content: ${memory.memory_item.content}`,
  );
}
import com.azure.ai.agents.models.MemorySearchItem;
import com.azure.ai.agents.models.MemorySearchOptions;
import com.azure.ai.agents.models.MemoryStoreSearchResponse;
import com.openai.models.responses.EasyInputMessage;
import com.openai.models.responses.ResponseInputItem;
import java.util.Arrays;

ResponseInputItem queryMessage = ResponseInputItem.ofEasyInputMessage(
  EasyInputMessage.builder()
    .role(EasyInputMessage.Role.USER)
    .content("What are my coffee preferences?")
    .build());

MemorySearchOptions searchOptions = new MemorySearchOptions()
  .setMaxMemories(5);

MemoryStoreSearchResponse searchResponse = memoryStoresClient.searchMemories(
  memoryStoreName,
  scope,
  Arrays.asList(queryMessage),
  null,
  searchOptions);

System.out.println("Found " + searchResponse.getMemories().size() + " memories");
for (MemorySearchItem item : searchResponse.getMemories()) {
  System.out.println(
    "  - Memory ID: " + item.getMemoryItem().getMemoryId() + ", Content: "
      + item.getMemoryItem().getContent());
}
curl -X POST "${FOUNDRY_PROJECT_ENDPOINT}/memory_stores/my_memory_store:search_memories?api-version=${API_VERSION}" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "scope": "user_123",
    "items": [
      {
        "type": "message",
        "role": "user",
        "content": [
          {
            "type": "input_text",
            "text": "What are my coffee preferences?"
          }
        ]
      }
    ],
    "options": {
      "max_memories": 5
    }
  }'

静的メモリまたはコンテキスト メモリを取得する

多くの場合、ユーザーのメッセージに対するセマンティック類似性に基づいてユーザー プロファイルメモリを取得することはできません。 各会話の先頭に静的メモリを挿入し、コンテキスト メモリを使用して各エージェントの応答を生成します。

  • 静的メモリを取得するには、search_memoriesscopeを使用せずに、itemsを使用してprevious_search_idを呼び出します。 これにより、スコープに関連付けられているユーザー プロファイル メモリが返されます。

  • コンテキスト メモリを取得するには、search_memoriesを最新のメッセージに設定してitemsを呼び出します。 これにより、指定されたアイテムに最も関連するユーザー プロファイルとチャットの概要メモリの両方を返すことができます。

ユーザー プロファイルとチャットの概要メモリの詳細については、「 メモリの種類」を参照してください。

メモリ項目の管理

項目レベルの操作を使用して、個々のメモリ レコードを直接作成、検査、更新、削除します。 スコープ レベルまたはストア レベルの削除については、「メモリの 削除」を参照してください。

メモリ項目を作成する

# Create a memory item directly
created = project_client.beta.memory_stores.create_memory(
    name=memory_store_name,
    scope="defaultUser",
    content="User prefers concise changelogs with impact-first summaries.",
    kind="user_profile",
)

print(f"Memory ID: {created.memory_id}")
print(f"Content: {created.content}")
print(f"Kind: {created.kind}")
using Azure.AI.Projects.Memory;

#pragma warning disable AAIP001

// Create a memory item directly
MemoryItem created = projectClient.MemoryStores.CreateMemory(
    name: memoryStoreName,
    scope: "defaultUser",
    content: "User prefers concise changelogs with impact-first summaries.",
    kind: MemoryItemKind.UserProfile);

Console.WriteLine($"Memory ID: {created.MemoryId}");
Console.WriteLine($"Content: {created.Content}");
Console.WriteLine($"Scope: {created.Scope}");
// Create a memory item directly
const created = await project.beta.memoryStores.createMemory(
  memoryStoreName,
  "defaultUser",
  "User prefers concise changelogs with impact-first summaries.",
  "user_profile",
);

console.log(`Memory ID: ${created.memory_id}`);
console.log(`Content: ${created.content}`);
console.log(`Kind: ${created.kind}`);
import com.azure.ai.agents.models.MemoryItem;
import com.azure.ai.agents.models.MemoryItemKind;

MemoryItem created = memoryStoresClient.createMemory(
  memoryStoreName,
  "defaultUser",
  "User prefers concise changelogs with impact-first summaries.",
  MemoryItemKind.USER_PROFILE);

System.out.println("Memory ID: " + created.getMemoryId());
System.out.println("Content: " + created.getContent());
System.out.println("Kind: " + created.getKind());
curl -X POST "${FOUNDRY_PROJECT_ENDPOINT}/memory_stores/my_memory_store/items?api-version=${API_VERSION}" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "scope": "defaultUser",
    "content": "User prefers concise changelogs with impact-first summaries.",
    "kind": "user_profile"
  }'

メモリ項目を取得する

# Retrieve a memory item by ID
item = project_client.beta.memory_stores.get_memory(
    name=memory_store_name,
    memory_id="<memory-item-id>",
)

print(f"Memory ID: {item.memory_id}")
print(f"Content: {item.content}")
print(f"Kind: {item.kind}")
using Azure.AI.Projects.Memory;

#pragma warning disable AAIP001

// Retrieve a memory item by ID
MemoryItem item = projectClient.MemoryStores.GetMemory(
    name: memoryStoreName,
    memoryId: "<memory-item-id>");

Console.WriteLine($"Memory ID: {item.MemoryId}");
Console.WriteLine($"Content: {item.Content}");
Console.WriteLine($"Scope: {item.Scope}");
// Retrieve a memory item by ID
const item = await project.beta.memoryStores.getMemory(
  memoryStoreName,
  "<memory-item-id>",
);

console.log(`Memory ID: ${item.memory_id}`);
console.log(`Content: ${item.content}`);
console.log(`Kind: ${item.kind}`);
import com.azure.ai.agents.models.MemoryItem;

MemoryItem memItem = memoryStoresClient.getMemory(
  memoryStoreName,
  "<memory-item-id>");

System.out.println("Memory ID: " + memItem.getMemoryId());
System.out.println("Content: " + memItem.getContent());
System.out.println("Kind: " + memItem.getKind());
curl -X GET "${FOUNDRY_PROJECT_ENDPOINT}/memory_stores/my_memory_store/items/<memory-item-id>?api-version=${API_VERSION}" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}"

メモリ項目を一覧表示する

# List all memory items in the store
memories = project_client.beta.memory_stores.list_memories(
    name=memory_store_name,
    scope="defaultUser",
)

count = 0
for item in memories:
    count += 1
    print(f"- {item.memory_id} [{item.kind}]: {item.content}")

print(f"Total memories: {count}")
using Azure.AI.Projects.Memory;

#pragma warning disable AAIP001

// List all memory items in the store
int count = 0;
foreach (MemoryItem item in projectClient.MemoryStores.GetMemories(
    name: memoryStoreName,
    scope: "defaultUser"))
{
    count++;
    Console.WriteLine(
  $"- {item.MemoryId} [{item.Scope}]: {item.Content}");
}

Console.WriteLine($"Total memories: {count}");
// List all memory items in the store
const memoriesList = project.beta.memoryStores.listMemories(
  memoryStoreName,
  "defaultUser",
);

let count = 0;
for await (const item of memoriesList) {
  count += 1;
  console.log(`- ${item.memory_id} [${item.kind}]: ${item.content}`);
}
console.log(`Total memories: ${count}`);
import com.azure.ai.agents.models.ListMemoriesOptions;
import com.azure.ai.agents.models.MemoryItem;

ListMemoriesOptions options = new ListMemoriesOptions(
  memoryStoreName,
  "defaultUser");

int count = 0;
for (MemoryItem memoryEntry : memoryStoresClient.listMemories(options)) {
  count++;
  System.out.println(
    "- " + memoryEntry.getMemoryId() + " [" + memoryEntry.getKind() + "]: "
      + memoryEntry.getContent());
}

System.out.println("Total memories: " + count);
curl -X GET "${FOUNDRY_PROJECT_ENDPOINT}/memory_stores/my_memory_store/items:list?scope=user_123&api-version=${API_VERSION}" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}"

メモリ項目を更新する

# Update a memory item by ID
updated = project_client.beta.memory_stores.update_memory(
    name=memory_store_name,
    memory_id="<memory-item-id>",
    content="User prefers detailed technical explanations with examples.",
)

print(f"Updated: {updated.content}")
using Azure.AI.Projects.Memory;

#pragma warning disable AAIP001

// Update a memory item by ID
MemoryItem updated = projectClient.MemoryStores.UpdateMemory(
    name: memoryStoreName,
    memoryId: "<memory-item-id>",
    content: "User prefers detailed technical explanations with examples.");

Console.WriteLine($"Updated: {updated.Content}");
// Update a memory item by ID
const updated = await project.beta.memoryStores.updateMemory(
  memoryStoreName,
  "<memory-item-id>",
  "User prefers detailed technical explanations with examples.",
);

console.log(`Updated: ${updated.content}`);
import com.azure.ai.agents.models.MemoryItem;

MemoryItem updated = memoryStoresClient.updateMemory(
  memoryStoreName,
  "<memory-item-id>",
  "User prefers detailed technical explanations with examples.");

System.out.println("Updated: " + updated.getContent());
curl -X POST "${FOUNDRY_PROJECT_ENDPOINT}/memory_stores/my_memory_store/items/<memory-item-id>?api-version=${API_VERSION}" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{"content": "User prefers detailed technical explanations with examples."}'

メモリ項目を削除する

# Delete a memory item by ID
project_client.beta.memory_stores.delete_memory(
    name=memory_store_name,
    memory_id="<memory-item-id>",
)

print("Memory item deleted successfully")
using Azure.AI.Projects.Memory;

#pragma warning disable AAIP001

// Delete a memory item by ID
MemoryDeletionResult result = projectClient.MemoryStores.DeleteMemory(
    name: memoryStoreName,
    memoryId: "<memory-item-id>");

Console.WriteLine(
    $"Memory item {result.MemoryId} deleted: {result.Deleted}");
// Delete a memory item by ID
await project.beta.memoryStores.deleteMemory(
  memoryStoreName,
  "<memory-item-id>",
);

console.log("Memory item deleted successfully");
memoryStoresClient.deleteMemory(memoryStoreName, "<memory-item-id>");

System.out.println("Memory item deleted successfully");
curl -X DELETE "${FOUNDRY_PROJECT_ENDPOINT}/memory_stores/my_memory_store/items/<memory-item-id>?api-version=${API_VERSION}" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}"

メモリを削除する

警告

メモリ ストアを削除する前に、依存エージェントへの影響を考慮してください。 メモリ ストアがアタッチされているエージェントは、履歴コンテキストにアクセスできなくなる可能性があります。

メモリは、メモリ ストア内のスコープ別に整理されます。 特定のスコープのメモリを削除してユーザー固有のデータを削除することも、メモリ ストア全体を削除してすべてのスコープのすべてのメモリを削除することもできます。

スコープ別にメモリを削除する

メモリ ストア構造を維持しながら、特定のユーザーまたはグループ スコープに関連付けられているすべてのメモリを削除します。 この操作を使用して、ユーザー データ削除要求を処理するか、特定のユーザーのメモリをリセットします。

# Delete memories for a specific scope
project_client.beta.memory_stores.delete_scope(
    name=memory_store_name,
    scope="user_123"
)

print(f"Deleted memories for scope: user_123")
// Delete memories for a specific scope
MemoryStoreDeleteScopeResponse deleteScopeResponse =
    projectClient.MemoryStores.DeleteScope(
        name: memoryStore.Name,
        scope: "user_123");

Console.WriteLine(
    $"Deleted scope: {deleteScopeResponse.Name}, "
    + $"success: {deleteScopeResponse.IsDeleted}");
console.log("\nDeleting memories for scope...");
await project.beta.memoryStores.deleteScope(memoryStoreName, scope);
memoryStoresClient.deleteScope(memoryStoreName, "user_123");

System.out.println("Deleted memories for scope: user_123");
curl -X POST "${FOUNDRY_PROJECT_ENDPOINT}/memory_stores/my_memory_store:delete_scope?api-version=${API_VERSION}" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "scope": "user_123"
  }'

メモリ ストアを削除する

すべてのスコープで、メモリ ストア全体と関連するすべてのメモリを削除します。 この操作は元に戻すことができません。

# Delete the entire memory store
delete_response = project_client.beta.memory_stores.delete(memory_store_name)
print(f"Deleted memory store: {delete_response.deleted}")
// Delete the entire memory store
DeleteMemoryStoreResponse deleteResponse =
    projectClient.MemoryStores.DeleteMemoryStore(
        name: memoryStore.Name);

Console.WriteLine(
    $"Deleted memory store: {deleteResponse.Name}, "
    + $"success: {deleteResponse.IsDeleted}");
console.log("Deleting memory store...");
await project.beta.memoryStores.delete(memoryStoreName);
memoryStoresClient.deleteMemoryStore(memoryStoreName);

System.out.println("Deleted memory store: " + memoryStoreName);
curl -X DELETE "${FOUNDRY_PROJECT_ENDPOINT}/memory_stores/my_memory_store?api-version=${API_VERSION}" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}"

ベスト プラクティス

  • ユーザーごとのアクセス制御を実装します。 すべてのユーザー間で共有されているメモリへのアクセス権をエージェントに付与しないようにします。 scope プロパティを使用して、ユーザー別にメモリ ストアをパーティション分割します。 ユーザー間で scope を共有する場合は、 user_profile_details を使用して、個人情報を格納しないようにメモリ システムに指示します。

  • エンド ユーザーにスコープをマップします。メモリ検索ツールを使用する場合は、scopeをツール定義で{{$userId}}するように設定します。 システムは、 x-memory-user-id 要求ヘッダー (存在する場合) からユーザー ID を解決します。 それ以外の場合は、呼び出し元のMicrosoft Entra トークン ({tid}_{oid}) にフォールバックします。

  • 機密データを最小限に抑え、保護する: ユース ケースに必要なものだけを保存します。 個人データ、健康データ、機密ビジネス情報などの機密データを格納する必要がある場合は、個人を特定できる他の情報をマスキングまたは削除してください。

  • プライバシーとコンプライアンスをサポートする: データにアクセスして削除するオプションなど、ユーザーに透明性を提供します。 改ざんを防止する監査証跡にすべての削除を記録します。 システムがローカルのコンプライアンス要件と規制基準に準拠していることを確認します。

  • データをセグメント化し、メモリを分離する: マルチエージェント システムでは、メモリを論理的および運用的にセグメント化します。 お客様が独自のメモリ フットプリントを定義、分離、検査、削除できるようにします。

  • メモリ使用量の監視: トークンの使用状況とメモリ操作を追跡して、コストを把握し、パフォーマンスを最適化します。

  • ユーザー向けのメモリ コントロールを公開する: 信頼とデータ権限のワークフローをサポートするために、アイテム レベルの編集アクションと削除アクションを提供します。

  • 明示的な保持の既定値を設定します。 ポリシー要件に一致する TTL 設定を使用します。 製品 UX での保持動作を文書化します。

トラブルシューティング

問題 原因 解決方法
要求は認証または承認エラーで失敗します。 あなたの ID またはプロジェクト管理 ID に必要なロールが付与されていません。 [承認] と [アクセス許可] でロールを確認します。 REST 呼び出しの場合は、新しいアクセス トークンを生成して再試行します。
会話の後に思い出が表示されません。 メモリ更新はデバウンスされるか、まだ処理されています。 待機時間を長くするか、 update_delay0 に設定して更新 API を呼び出して、すぐに処理をトリガーします。
メモリ検索は結果を返しません。 scope値は、メモリの格納時に使用されるスコープと一致しません。 更新と検索には同じスコープを使用します。 スコープをユーザーにマップする場合は、安定したユーザー識別子を使用します。
エージェントの応答では、格納されているメモリは使用されません。 エージェントがメモリ検索ツールで構成されていないか、メモリ ストア名が正しくありません。 エージェント定義に memory_search_preview ツールが含まれていることを確認し、正しいメモリ ストア名を参照します。
手続き型メモリまたは既定の TTL 設定は、更新後に有効になりませんでした。 最新のプレビューでは、メモリ ストアの作成時にのみ既定のオプションを設定できます。 目的の既定値でメモリ ストアを再作成するか、API バージョンで作成後オプションの更新がサポートされているかどうかを確認します。
明示的な記憶または忘れ要求は、応答でメモリ コマンド項目を返しませんでした。 メモリ ツールが正しく構成されていないか、入力が remember-or-forget コマンドとして認識されませんでした。 メモリ ツールの構成を確認し、直接の記憶または忘れフレージングを使用してテストします。