Compartilhar via


Criar e usar memória no Serviço do Foundry Agent (versão prévia)

Importante

A memória (visualização) no Serviço de Agente da Fábrica e na API do Repositório de Memória (visualização) são licenciadas para você como parte de sua assinatura do Azure e estão sujeitas aos termos aplicáveis a "Visualizações" nos Termos de Produto da Microsoft, e no Adendo de Proteção de Dados de Produtos e Serviços da Microsoft, bem como nos termos de Versões Prévias dos Serviços de IA Generativa da Microsoft nos Termos Complementares de Uso para Visualizações do Microsoft Azure.

A memória no Serviço do Foundry Agent é uma solução de memória gerenciada e de longo prazo. Ele permite a continuidade do agente entre sessões, dispositivos e fluxos de trabalho. Ao criar e gerenciar repositórios de memória, você pode criar agentes que retêm as preferências do usuário, mantêm o histórico de conversas e oferecem experiências personalizadas.

Os repositórios de memória atuam como armazenamento persistente, definindo quais tipos de informações são relevantes para cada agente. Você controla o acesso usando o scope parâmetro, que segmenta a memória entre os usuários para garantir experiências seguras e isoladas.

Este artigo explica como criar, gerenciar e usar repositórios de memória. Para obter informações conceituais, consulte Memória no Foundry Agent Service.

Suporte de uso

Capability SDK do Python SDK do C# SDK JavaScript API REST
Criar, atualizar, listar e excluir repositórios de memória ✔️ ✔️ ✔️ ✔️
Atualizar e pesquisar memórias ✔️ ✔️ ✔️ ✔️
Anexar memória a um agente de solicitação ✔️ ✔️ ✔️ ✔️

Pré-requisitos

Autorização e permissões

Recomendamos o controle de acesso baseado em função para implantações de produção. Se as funções não forem viáveis, ignore esta seção e use a autenticação baseada em chave.

Para configurar o acesso baseado em função:

  1. Entre no portal do Azure.

  2. Em seu projeto:

    1. No painel esquerdo, selecione Gerenciamento de Recursos>Identidade.
    2. Use o alternador para habilitar uma identidade gerenciada do sistema.
  3. No recurso que contém seu projeto:

    1. No painel esquerdo, selecione Controle de acesso (IAM).
    2. Selecione Adicionar>Adicionar atribuição de função.
    3. Atribua o usuário de IA do Azure à identidade gerenciada do seu projeto.

Configure seu ambiente

Instale os pacotes necessários:

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

Instale os pacotes necessários:

dotnet add package Azure.AI.Projects
dotnet add package Azure.AI.Projects.Agents
dotnet add package Azure.AI.Extensions.OpenAI
dotnet add package Azure.Identity

Instale os pacotes necessários:

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

Defina variáveis de ambiente para o endpoint do projeto e os nomes de implantação de modelo.

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>"

Defina variáveis de ambiente para o ponto de extremidade do projeto, implantações de modelo, versão da API e token de acesso:

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)"

Compreender o escopo

O scope parâmetro controla como a memória é particionada. Cada escopo no repositório de memória mantém uma coleção isolada de itens de memória. Por exemplo, se você criar um agente de suporte ao cliente com memória, cada cliente deverá ter sua própria memória individual.

Como desenvolvedor, você escolhe a chave usada para armazenar e recuperar itens de memória. A abordagem certa depende de como você acessa a memória.

Por meio da ferramenta de pesquisa de memória

Ao anexar a ferramenta de pesquisa de memória a um agente, configure scope para {{$userId}} para habilitar o isolamento de memória por usuário sem identificadores de codificação rígida. O sistema resolve automaticamente a identidade do usuário final em cada chamada de resposta de uma das duas fontes:

  • x-memory-user-id cabeçalho de solicitação: se presente, o valor do cabeçalho é usado como a ID do usuário. Use isso em cenários de proxy ou back-end em que seu serviço chama a API em nome de um usuário final.

  • Token de autenticação do Microsoft Entra: Se o cabeçalho não estiver definido, o sistema retornará à ID do locatário (TID) do chamador e à ID do objeto (OID). Esse é o padrão em cenários de front-end em que os usuários se autenticam diretamente com o Microsoft Entra.

Se você não precisar de isolamento por usuário, use um valor estático scope .

Por meio de APIs de memória de baixo nível

Ao chamar as APIs de memória diretamente, especifique scope explicitamente em cada solicitação. Você pode passar um valor estático, como um UUID (identificador universal exclusivo) ou outro identificador estável do sistema. Não há suporte para extração automática de identidade para essas operações.

Criar um repositório de memória

Crie um repositório de memória dedicado para cada agente estabelecer limites claros para acesso e otimização de memória. Ao criar um repositório de memória, especifique o modelo de chat e as implantações de modelo de inserção que processam o conteúdo da memória.

import os
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,
    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 for customer support agent",
)

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,
  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 for customer support agent",
  },
);

console.log(
  `Created memory store: ${memoryStore.name} (${memoryStore.id})`,
);
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 for customer support agent",
    "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,
        "user_profile_details": "Avoid irrelevant or sensitive data, such as age, financials, precise location, and credentials"
      }
    }
  }'

Dica

  • Os snippets de código Python, C#e TypeScript restantes se baseiam no cliente e nas variáveis definidas em Criar um repositório de memória. Se você executar esses snippets de código de forma independente, inclua o código de importação e inicialização do cliente desta seção.
  • Os snippets de C# neste artigo usam métodos síncronos. Para uso assíncrono, consulte a ferramenta de pesquisa de memória e os exemplos do repositório de memória .

Personalizar memória

Personalize quais informações o agente armazena para manter a memória eficiente, relevante e que respeita a privacidade. Use o user_profile_details parâmetro para especificar os tipos de dados que são críticos para a função do agente.

Por exemplo, defina user_profile_details para priorizar "preferência por companhia aérea e restrições alimentares" para um agente de viagens. Essa abordagem focada ajuda o sistema de memória a saber quais detalhes extrair, resumir e confirmar na memória de longo prazo.

Você também pode usar esse parâmetro para excluir determinados tipos de dados, mantendo a memória enxuta e em conformidade com os requisitos de privacidade. Por exemplo, defina user_profile_details como "evitar dados irrelevantes ou confidenciais, como idade, finanças, localização precisa e credenciais".

Atualizar um repositório de memória

Atualize as propriedades do repositório de memória, como description ou metadata, para gerenciar melhor os repositórios de memória.

# 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}`);
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"
  }'

Listar repositórios de memória

Recupere uma lista de repositórios de memória em seu projeto para gerenciar e monitorar sua infraestrutura de memória.

# 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})`);
}
curl -X GET "${FOUNDRY_PROJECT_ENDPOINT}/memory_stores?api-version=${API_VERSION}" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}"

Usar memórias por meio de uma ferramenta de agente

Depois de criar um repositório de memória, você pode anexar a ferramenta de pesquisa de memória a um agente de prompt. Essa ferramenta permite que o agente leia e escreva no repositório de memória durante as conversas. Configure a ferramenta com o scope e update_delay apropriados para controlar como e quando as memórias são atualizadas.

Dica

Para associar memórias a um usuário final individual, defina scope para "{{$userId}}" na definição da ferramenta e passe x-memory-user-id: <user-id> como cabeçalho em cada chamada de resposta. O sistema resolve o escopo para a identidade desse usuário. Sem o cabeçalho, o escopo volta para a identidade do Microsoft Entra (TID e OID) do chamador. Para obter mais informações, veja Compreender o escopo.

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}`,
);
# 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
            }
        ]
    }
}'

Criar uma conversa

Agora você pode criar conversas e solicitar respostas do agente. No início de cada conversa, as memórias estáticas são injetadas para que o agente tenha contexto imediato e persistente. As memórias contextuais são recuperadas por turno com base nas mensagens mais recentes para informar cada resposta.

Após cada resposta do agente, o serviço internamente chama update_memories. No entanto, as gravações reais na memória de longo prazo são amortecidas pela configuração update_delay. A atualização é agendada e só é concluída após o período configurado de inatividade.

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 openaiClient = project.getOpenAIClient();

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

// Create an agent response to initial user message
const response = await openaiClient.responses.create(
  {
    conversation: conversation.id,
    input: "I prefer dark roast coffee",
  },
  {
    body: {
      agent: { 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 openaiClient.conversations.create();
console.log(`Created new conversation (id: ${newConversation.id})`);

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

console.log(`Response output: ${newResponse.output_text}`);
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"
      }
    }'

Usar memórias por meio de APIs

Você pode interagir com um repositório de memória diretamente usando as APIs do repositório de memória. Comece adicionando memórias do conteúdo da conversa ao repositório de memória e procure memórias relevantes para fornecer contexto para interações do agente.

Adicionar memórias a um repositório de memória

Adicione memórias fornecendo conteúdo de conversa ao repositório de memória. O sistema pré-processa e pós-processa os dados, incluindo extração e consolidação de memória, para otimizar a memória do agente. Essa operação de longa execução pode levar cerca de um minuto.

Decida como segmentar a memória entre os usuários especificando o scope parâmetro. Você pode definir o escopo da memória para um usuário final específico, uma equipe ou outro identificador.

Você pode atualizar um repositório de memória com conteúdo de vários turnos de conversas, ou atualizar após cada turno e encadear as atualizações usando a ID da operação de atualização anterior.

# 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}`,
  );
}
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}"

Pesquisar memórias em um repositório de memória

Pesquise memórias para recuperar o contexto relevante para interações de agente. Especifique o nome e o escopo do repositório de memória para restringir a pesquisa.

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}`,
  );
}
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
    }
  }'

Recuperar memórias estáticas ou contextuais

Muitas vezes, as memórias de perfil do usuário não podem ser recuperadas com base na similaridade semântica com a mensagem de um usuário. Recomendamos injetar memórias estáticas no início de cada conversa e usar memórias contextuais para gerar cada resposta do agente.

  • Para recuperar memórias estáticas, chame search_memories com um scope mas sem items ou previous_search_id. Isso retorna memórias de perfil do usuário associadas ao escopo.

  • Para recuperar memórias contextuais, chame search_memories com items definido como as mensagens mais recentes. Isso pode retornar memórias de resumo de chat e perfil de usuário mais relevantes para os itens especificados.

Para obter mais informações sobre o perfil do usuário e as memórias de resumo de chat, consulte os tipos de memória.

Excluir memórias

Aviso

Antes de excluir um repositório de memória, considere o impacto nos agentes dependentes. Agentes com repositórios de memória anexados podem perder o acesso ao contexto histórico.

As memórias são organizadas por escopo em um repositório de memória. Você pode excluir memórias de um escopo específico para remover dados específicos do usuário ou excluir todo o repositório de memória para remover todas as memórias em todos os escopos.

Excluir memórias por escopo

Remova todas as memórias associadas a um determinado escopo de usuário ou grupo, preservando a estrutura do repositório de memória. Use esta operação para lidar com solicitações de exclusão de dados do usuário ou redefinir memória para usuários específicos.

# 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);
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"
  }'

Excluir um repositório de memória

Remova todo o repositório de memória e todas as memórias associadas em todos os escopos. essa operação é irreversível.

# 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);
curl -X DELETE "${FOUNDRY_PROJECT_ENDPOINT}/memory_stores/my_memory_store?api-version=${API_VERSION}" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}"

Práticas recomendadas

  • Implementar controles de acesso por usuário: Evite dar aos agentes acesso a memórias compartilhadas entre todos os usuários. Use a scope propriedade para particionar o repositório de memória pelo usuário. Ao compartilhar scope entre usuários, use user_profile_details para instruir o sistema de memória a não armazenar informações pessoais.

  • Atribuir escopo ao usuário final: Ao usar a ferramenta de pesquisa de memória, defina scope como {{$userId}} na definição da ferramenta. O sistema determina a identidade do usuário do cabeçalho da solicitação x-memory-user-id, se presente. Caso contrário, ele retornará ao token do Microsoft Entra do chamador ({tid}_{oid}).

  • Minimizar e proteger dados confidenciais: Armazene apenas o que é necessário para seu caso de uso. Se você precisar armazenar dados confidenciais, como dados pessoais, dados de integridade ou entradas comerciais confidenciais, rediga ou remova outros conteúdos que possam ser usados para rastrear um indivíduo.

  • Suporte à privacidade e à conformidade: Forneça aos usuários transparência, incluindo opções para acessar e excluir seus dados. Registre todas as deleções em uma trilha de auditoria inviolável. Verifique se o sistema adere aos requisitos de conformidade local e aos padrões regulatórios.

  • Segmentar dados e isolar memória: Em sistemas de vários agentes, segmente a memória logicamente e operacionalmente. Permitir que os clientes definam, isolem, inspecionem e excluam sua própria pegada de memória.

  • Monitorar o uso de memória: Acompanhe o uso de token e as operações de memória para entender os custos e otimizar o desempenho.

Resolução de problemas

Questão Motivo Resolução
As solicitações falham com um erro de autenticação ou autorização. Sua identidade ou a identidade gerenciada do projeto não tem as funções necessárias. Verifique as funções em Autorização e permissões. Para chamadas REST, gere um novo token de acesso e tente novamente.
As memórias não aparecem depois de uma conversa. As atualizações de memória são amortecidas ou ainda estão sendo processadas. Aumente o tempo de espera ou chame a API de atualização com update_delay definido como 0 para disparar o processamento imediatamente.
A pesquisa de memória não retorna resultados. O scope valor não corresponde ao escopo usado quando as memórias foram armazenadas. Use o mesmo escopo para atualização e pesquisa. Se você mapear o escopo para os usuários, use um identificador de usuário estável.
A resposta do agente não usa memória armazenada. O agente não está configurado com a ferramenta de pesquisa de memória ou o nome do repositório de memória está incorreto. Confirme se a definição do agente inclui a memory_search_preview ferramenta e referencia o nome correto do repositório de memória.