重要
Foundry Agent Service 中的 Memory(預覽)和 Memory Store API(預覽)係作為您 Azure 訂用帳戶的一部分授權給您,並受 Microsoft 產品條款、Microsoft 產品與服務資料保護附錄 以及 Microsoft Azure 預覽版補充使用條款 中適用於「預覽」的條款約束。
最新預覽版提供了新功能與增強功能,包括:
- 記憶體項目操作用於建立、讀取、更新、列出及刪除個別記憶體記錄。
- 儲存區層級預設保留控制項,包括新建立記憶體儲存區的預設 TTL。
- 直接控制記住或遺忘同步記憶體命令的行為。
Foundry Agent Service 中的記憶體是一種可管理的長期記憶解決方案。 它能確保代理人員在會話、裝置與工作流程間的連續性。 透過建立和管理記憶體儲存,你可以建立能保留使用者偏好、維持對話紀錄並提供個人化體驗的代理。
記憶體儲存作為持久儲存,定義與每個代理相關的資訊類型。 你透過參數 scope 來控制存取,該參數會將記憶體分割給使用者,以確保安全且隔離的體驗。
本文說明如何建立、管理及使用記憶體儲存。 對於概念性資訊,請參閱 Foundry Agent Service 中的記憶體。
若要首次從頭到尾成功,請遵循以下路徑:
- 為代理建立一個記憶體儲存 。
- 把記憶體搜尋工具綁定 到代理上。
- 建立對話,傳送偏好設定,等待設定好的更新延遲,讓服務記住它。
- 在同一範例中重新開啟對話,並提出相關問題以確認客服是否記得該偏好。
根據你需要多直接控制記憶體來選擇工作流程:
| Scenario | 從...開始 | 用它來做 |
|---|---|---|
| 管理 | 建立記憶體儲存 | 設定、更新、列出或刪除儲存與保留設定。 |
| 命令 | 直接應用「記憶或忘記」行為 | 尊重明確的使用者要求,立即記住或忘記資訊。 |
| Items | 管理記憶體項目 | 可直接建立、檢查、更新或刪除個別紀錄。 |
範例報導
勾選代表本文包含該語言的範例。 破折號表示範例目前未包含;它不會顯示 SDK 是否支援該操作。
| 能力 | Python SDK | C# SDK | JavaScript SDK | Java 開發套件 | REST API |
|---|---|---|---|---|---|
| 建立、更新、列出及刪除記憶體儲存 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
| 將記憶體附加到提示代理上 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
| 更新與搜尋記憶 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
| 直接套用「記住或忘記」指令 | ✔️ | — | ✔️ | ✔️ | ✔️ |
| 建立、讀取、更新、列出及刪除記憶體項目 | ✔️ | — | ✔️ | ✔️ | ✔️ |
先決條件
- 一個 Azure 訂閱。 免費創建一個。
- 一個Microsoft Foundry 專案,具備設定的 授權與權限。
- 例如,在你的專案中部署聊天模型
gpt-5.2。 - 把 嵌入模型 部署到你的專案中,例如
text-embedding-3-small。 - 一個 配置好的本地環境 ,包含所需的套件和環境變數。
授權與許可
在生產部署中使用 基於角色的存取控制 。 如果角色不可行,跳過這部分,改用基於金鑰的認證。
要配置基於角色的存取:
登入 Azure 入口網站。
關於你的專案:
- 從左側窗格選擇 資源管理>身份。
- 使用切換鍵啟用系統指派的管理身份。
關於包含你專案的資源:
從左側窗格選擇存取控制(IAM)。
選擇 新增>角色分配。
將 Foundry 使用者指派給您專案的受控識別。
重要
Foundry RBAC 角色最近已重新命名。 Foundry 用戶、Foundry 擁有者、Foundry Account Owner 以及 Foundry Project Manager 先前分別被稱為 Azure AI 使用者、Azure AI 擁有者、Azure AI 帳戶擁有者及 Azure AI Project 管理者。 在更名期間,你可能還會在某些地方看到之前的名字。角色 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
使用 Node.js 22 或更新版本,搭配 @azure/ai-projects 2.4.0。
安裝所需的套件:
<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}} 啟用每使用者的記憶體隔離,且不會使用硬編碼識別碼。 系統會在每個來自兩個來源之一的回應呼叫中自動解析最終使用者的身份:
x-memory-user-id請求標頭: 若存在,標頭值作為使用者 ID。 在您的服務代表終端使用者呼叫 API 的 Proxy 或後端情境中使用此功能。Microsoft Entra 認證憑證: 若標頭未設定,系統會回退至呼叫者的租戶 ID(TID)與物件 ID(OID)。 在使用者直接使用 Microsoft Entra 認證的前端場景中,這是預設設定。
如果你不需要每個使用者隔離,就用靜態 scope 值。
透過低階記憶體 API
當你直接呼叫 記憶體 API ,請在每個請求中明確指定 scope 。 你可以傳遞靜態值,例如通用唯一識別碼(UUID)或其他穩定識別碼。 這些操作不支援自動身份擷取。
建立記憶體儲存
為每個代理建立專屬的記憶體儲存,以建立明確的記憶體存取與優化邊界。 當你建立記憶體儲存體時,指定處理記憶體內容的聊天模型和嵌入模型的部署。
使用記憶體儲存選項來控制擷取行為和保留預設值。 在最新的預覽中,你可以啟用程序式記憶體,並為新建立的記憶體條目設定預設的 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"
}
}
}'
提示
自訂記憶體
自訂代理所儲存的資訊,以保持記憶體高效、相關且尊重隱私。 使用參數 user_profile_details 來指定對代理功能至關重要的資料類型。
例如,設定 user_profile_details 為旅行社優先設定「航空公司偏好與飲食限制」。 這種聚焦的方法幫助記憶系統知道哪些細節該提取、摘要並投入長期記憶。
你也可以利用此參數排除某些類型的資料,保持記憶體精簡並符合隱私要求。 例如,設定 user_profile_details 為「避免無關或敏感資料,例如年齡、財務狀況、精確位置及憑證」。
設定 TTL 與保留政策
TTL 適用於所有記憶體,無論是直接記憶體指令、擷取與整合,或是項目層級的 CRUD 操作。 如果記憶體被更新並整合,服務會重置其最後更新的時間。
TTL 僅適用於在 TTL 支援引入後建立的記憶體儲存。 它不會影響現有的記憶體儲存。
default_ttl_seconds值為0表示不會過期。 選擇符合您合規性及使用者資料生命週期需求的保留期限。
更新記憶體儲存
更新記憶體儲存屬性,如 description 或 metadata,以更好地管理記憶體儲存。
# 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}"
透過代理工具使用記憶體
建立記憶體儲存後,你可以將記憶體搜尋工具附加到提示代理程式上。 此工具使代理在對話中能讀取並寫入你的記憶體儲存。 請透過合適的scope和update_delay來設定工具,以控制記憶體更新的時間與方式。
提示
若要將記憶體範圍設定給個別終端使用者,請在工具定義中設定 scope 為 , "{{$userId}}" 並在每次回應呼叫中以標頭方式傳遞 x-memory-user-id: <user-id> 。 系統會將範圍映射到該使用者的身份。 若無標頭,範圍會退回到呼叫者的 Microsoft Entra 身份(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 與記憶體儲存互動。 首先將對話內容中的記憶加入記憶儲存,然後搜尋相關記憶,以提供代理人互動的背景。
將資料加入記憶體儲存系統
透過將對話內容加入記憶儲存庫來新增回憶。 系統會對資料進行預處理與後處理,包括記憶體擷取與整合,以優化代理記憶體。 此長時間執行作業可能需要約一分鐘。
決定如何透過指定 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_memories,使用scope,但不使用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(若有)。 否則,它會回復至呼叫端的 Microsoft Entra 權杖 ({tid}_{oid})。減少並保護敏感資料: 只儲存符合你使用情境所需的資料。 若必須儲存敏感資料,如個人資料、健康資料或機密商業資料,請遮蔽或移除其他可能被用來追蹤個人的內容。
支持隱私與合規: 提供使用者透明性,包括存取與刪除資料的選項。 將所有刪除記錄在防篡改的稽核追蹤中。 確保系統符合當地的合規要求與法規標準。
區段資料與隔離記憶體: 在多代理系統中,記憶體在邏輯與操作上進行分段。 讓客戶能夠定義、隔離、檢查並刪除自己的記憶體佔用空間。
監控記憶體使用: 追蹤代幣使用與記憶體操作,以了解成本並優化效能。
揭露面向使用者的記憶體控制: 提供項目層級的編輯與刪除操作,以支援信任與資料權限工作流程。
設定明確的保留預設: 使用符合政策要求的 TTL 設定。 在產品使用者體驗中記錄留任行為。
故障排除
| 問題 | 成因 | 解決方法 |
|---|---|---|
| 請求失敗時會發生認證或授權錯誤。 | 您的身分或專案受控識別未具備所需的角色。 | 確認授權和權限中的角色。 對於 REST 呼叫,產生一個全新的存取權杖並重試。 |
| 記憶不會在對話後出現。 | 記憶更新已去彈跳或仍在處理中。 | 增加等待時間或設定update_delay 為0來呼叫更新 API,以立即觸發處理。 |
| 記憶體搜尋沒有結果。 | 這個 scope 數值和記憶儲存時使用的範圍不符。 |
更新和搜尋時用同一個範圍。 如果你將範圍映射到使用者,請使用穩定的使用者識別碼。 |
| 代理回應不會使用儲存的記憶體。 | 代理程式沒有設定記憶體搜尋工具,或者記憶體儲存名稱錯誤。 | 確認代理定義中包含memory_search_preview工具,並且引用了正確的記憶體儲存名稱。 |
| 程序式記憶體或預設的 TTL 設定在更新後都沒有生效。 | 在最新的預覽中,你只能在記憶體儲存建立時設定預設選項。 | 請用想要的預設值重新建立記憶體儲存,或檢查你的 API 版本是否支援建立後的選項更新。 |
| 明確的「記住」或「遺忘」請求未在回應中回傳記憶指令項目。 | 記憶體工具設定不正確,或輸入未被識別為「記憶或忘記」指令。 | 確認記憶體工具的設定,並用直接的「記住或忘記」措辭來測試。 |