Gere memórias

O banco de memória permite-lhe criar memórias a longo prazo a partir de conversas entre o utilizador e o seu agente. Esta página descreve como funciona a geração de memórias, como pode personalizar a forma como as memórias são extraídas e como acionar a geração de memórias.

Para concluir os passos demonstrados neste guia, primeiro, tem de seguir os passos em Configuração do banco de memória.

Compreender a geração de memórias

O banco de memórias extrai memórias de dados de origem e organiza automaticamente memórias para uma coleção específica de memórias (definida por um scope) adicionando, atualizando e removendo memórias ao longo do tempo.

Quando aciona a geração de memórias, o banco de memórias realiza as seguintes operações:

  • Extração: extrai informações sobre o utilizador das respetivas conversas com o agente. Apenas as informações que correspondem a, pelo menos, um dos tópicos de memória da sua instância são mantidas.

  • Consolidação: identifica se as memórias existentes com o mesmo âmbito devem ser eliminadas ou atualizadas com base nas informações extraídas. O banco de memória verifica se as novas memórias não são duplicadas nem contraditórias antes de as unir às memórias existentes. Se as memórias existentes não se sobrepuserem à nova informação, é criada uma nova memória.

Tópicos de memórias

Os "Tópicos de memória" identificam as informações que o banco de memória considera significativas e que, por isso, devem ser mantidas como memórias geradas. O banco de memórias suporta dois tipos de tópicos de memórias:

  • Tópicos geridos: a etiqueta e as instruções são definidas pelo banco de memória. Só tem de indicar o nome do tópico gerido. Por exemplo:

    Dicionário

    memory_topic = {
        "managed_memory_topic": {
            "managed_topic_enum": "USER_PERSONAL_INFO"
        }
    }
    

    Com base em classes

    from vertexai.types import ManagedTopicEnum
    from vertexai.types import MemoryBankCustomizationConfigMemoryTopic as MemoryTopic
    from vertexai.types import MemoryBankCustomizationConfigMemoryTopicManagedMemoryTopic as ManagedMemoryTopic
    
    memory_topic = MemoryTopic(
        managed_memory_topic=ManagedMemoryTopic(
            managed_topic_enum=ManagedTopicEnum.USER_PERSONAL_INFO
        )
    )
    
  • Tópicos personalizados: a etiqueta e as instruções são definidas por si quando configura a sua instância do banco de memória. Vão ser usadas no comando para o passo de extração do banco de memória. Por exemplo:

    Dicionário

    memory_topic = {
        "custom_memory_topic": {
            "label": "business_feedback",
            "description": """Specific user feedback about their experience at
    the coffee shop. This includes opinions on drinks, food, pastries, ambiance,
    staff friendliness, service speed, cleanliness, and any suggestions for
    improvement."""
        }
    }
    

    Com base em classes

    from vertexai.types import MemoryBankCustomizationConfigMemoryTopic as MemoryTopic
    from vertexai.types import MemoryBankCustomizationConfigMemoryTopicCustomMemoryTopic as CustomMemoryTopic
    
    memory_topic = MemoryTopic(
        custom_memory_topic=CustomMemoryTopic(
            label="business_feedback",
            description="""Specific user feedback about their experience at
    the coffee shop. This includes opinions on drinks, food, pastries, ambiance,
    staff friendliness, service speed, cleanliness, and any suggestions for
    improvement."""
        )
    )
    

    Quando usar tópicos personalizados, é recomendável fornecer também exemplos de poucos disparos para demonstrar como as memórias devem ser extraídas da sua conversa.

Por predefinição, o banco de memória mantém todos os seguintes tópicos geridos:

  • Informações pessoais (USER_PERSONAL_INFO): informações pessoais significativas sobre o utilizador, como nomes, relações, passatempos e datas importantes. Por exemplo, "Trabalho no Google" ou "O meu aniversário de casamento é a 31 de dezembro".
  • Preferências do utilizador (USER_PREFERENCES): gostos, não gostos, estilos ou padrões preferidos declarados ou implícitos. Por exemplo, "Prefiro o lugar do meio."
  • Eventos de conversa principais e resultados de tarefas (KEY_CONVERSATION_DETAILS): marcos ou conclusões importantes no diálogo. Por exemplo, "Reservei bilhetes de avião para uma viagem de ida e volta entre JFK e SFO. Parto a 1 de junho de 2025 e regresso a 7 de junho de 2025."
  • Instruções explícitas para lembrar / esquecer (EXPLICIT_INSTRUCTIONS): informações que o utilizador pede explicitamente ao agente para lembrar ou esquecer. Por exemplo, se o utilizador disser "Memoriza que uso principalmente Python", o banco de memória gera uma memória como "Uso principalmente Python".

Isto é equivalente a usar o seguinte conjunto de tópicos de memória gerida:

Dicionário

  memory_topics = [
      {"managed_memory_topic": {"managed_topic_enum": "USER_PERSONAL_INFO"}},
      {"managed_memory_topic": {"managed_topic_enum": "USER_PREFERENCES"}},
      {"managed_memory_topic": {"managed_topic_enum": "KEY_CONVERSATION_DETAILS"}},
      {"managed_memory_topic": {"managed_topic_enum": "EXPLICIT_INSTRUCTIONS"}},
  ]

Com base em classes

from vertexai.types import ManagedTopicEnum
from vertexai.types import MemoryBankCustomizationConfigMemoryTopic as MemoryTopic
from vertexai.types import MemoryBankCustomizationConfigMemoryTopicManagedMemoryTopic as ManagedMemoryTopic

memory_topics = [
  MemoryTopic(
      managed_memory_topic=ManagedMemoryTopic(
          managed_topic_enum=ManagedTopicEnum.USER_PERSONAL_INFO)),
  MemoryTopic(
      managed_memory_topic=ManagedMemoryTopic(
          managed_topic_enum=ManagedTopicEnum.USER_PREFERENCES)),
  MemoryTopic(
      managed_memory_topic=ManagedMemoryTopic(
          managed_topic_enum=ManagedTopicEnum.KEY_CONVERSATION_DETAILS)),
  MemoryTopic(
      managed_memory_topic=ManagedMemoryTopic(
          managed_topic_enum=ManagedTopicEnum.EXPLICIT_INSTRUCTIONS)),
]

Se quiser personalizar os tópicos que o banco de memórias mantém, defina os tópicos de memória na sua configuração de personalização quando configurar o banco de memórias.

Acionar a geração de memórias

Pode acionar a geração de memórias através do comando GenerateMemories no final de uma sessão ou a intervalos regulares durante uma sessão. A geração de memória extrai o contexto principal das conversas de origem e combina-o com as memórias existentes para o mesmo âmbito. Por exemplo, pode criar memórias ao nível da sessão usando um âmbito como {"user_id": "123", "session_id": "456"}. As memórias com o mesmo âmbito podem ser consolidadas e obtidas em conjunto.

GenerateMemories é uma operação de longa duração. Quando a operação estiver concluída, o elemento AgentEngineGenerateMemoriesOperation contém uma lista de memórias geradas, se tiverem sido geradas:

AgentEngineGenerateMemoriesOperation(
  name="projects/.../locations/.../reasoningEngines/.../operations/...",
  done=True,
  response=GenerateMemoriesResponse(
    generatedMemories=[
      GenerateMemoriesResponseGeneratedMemory(
        memory=Memory(
          "name": "projects/.../locations/.../reasoningEngines/.../memories/..."
        ),
        action="CREATED",
      ),
      GenerateMemoriesResponseGeneratedMemory(
        memory=Memory(
          "name": "projects/.../locations/.../reasoningEngines/.../memories/..."
        ),
        action="UPDATED",
      ),
      GenerateMemoriesResponseGeneratedMemory(
        memory=Memory(
          "name": "projects/.../locations/.../reasoningEngines/.../memories/..."
        ),
        action="DELETED",
      ),
    ]
  )
)

Cada memória gerada inclui a action que foi realizada nessa memória:

  • CREATED: indica que foi adicionada uma nova memória, representando um conceito novo que não foi capturado pelas memórias existentes.
  • UPDATED: indica que uma memória existente foi atualizada, o que acontece se a memória abranger conceitos semelhantes aos das informações recém-extraídas. O facto da memória pode ser atualizado com novas informações ou permanecer igual.
  • DELETED: indica que a memória existente foi eliminada porque as respetivas informações eram contraditórias com as novas informações extraídas da conversa.

Para memórias CREATED ou UPDATED, pode usar GetMemories para aceder ao conteúdo completo da memória. A obtenção de DELETED memórias resulta num erro 404.

A gerar memórias em segundo plano

GenerateMemories é uma operação de longa duração. Por predefinição, client.agent_engines.generate_memories é uma função de bloqueio que consulta a operação até que esta seja concluída. A execução da geração de memórias como uma operação de bloqueio é útil quando quer inspecionar manualmente as memórias geradas ou notificar os utilizadores finais sobre as memórias que foram geradas.

No entanto, para agentes de produção, geralmente, quer executar a geração de memória em segundo plano como um processo assíncrono. Na maioria dos casos, o cliente não precisa de usar o resultado para a execução atual, pelo que não é necessário incorrer em latência adicional à espera de uma resposta. Se quiser que a geração de memórias seja executada em segundo plano, defina wait_for_completion como False:

client.agent_engines.memories.generate(
    ...,
    config={
        "wait_for_completion": False
    }
)

Origens de dados

Existem várias formas de fornecer dados de origem para a geração de memórias:

Quando fornece eventos diretamente no payload ou usa sessões do Vertex AI Agent Engine, as informações são extraídas da conversa e consolidadas com as memórias existentes. Se quiser apenas extrair informações destas origens de dados, pode desativar a consolidação:

client.agent_engines.memories.generate(
    ...
    config={
        "disable_consolidation": True
    }
)

Usar eventos no payload como origem de dados

Use direct_contents_source quando quiser gerar memórias com eventos fornecidos diretamente no payload. As informações significativas são extraídas destes eventos e consolidadas com as informações existentes para o mesmo âmbito. Pode usar esta abordagem se estiver a usar um armazenamento de sessões diferente das sessões do Vertex AI Agent Engine.

Dicionário

Os eventos devem incluir dicionários Content.

events =  [
  {
    "content": {
      "role": "user",
      "parts": [
        {"text": "I work with LLM agents!"}
      ]
    }
  }
]

client.agent_engines.memories.generate(
    name=agent_engine.api_resource.name,
    direct_contents_source={
      "events": EVENTS
    },
    # For example, `scope={"user_id": "123"}`.
    scope=SCOPE,
    config={
        "wait_for_completion": True
    }
)

Substitua o seguinte:

  • SCOPE: um dicionário que representa o âmbito das memórias geradas. Por exemplo, {"session_id": "MY_SESSION"}. Apenas as memórias com o mesmo âmbito são consideradas para consolidação.

Com base em classes

Os eventos devem incluir objetos Content.

from google import genai
import vertexai

events = [
  vertexai.types.GenerateMemoriesRequestDirectContentsSourceEvent(
    content=genai.types.Content(
      role="user",
      parts=[
        genai.types.Part.from_text(text="I work with LLM agents!")
      ]
    )
  )
]

client.agent_engines.memories.generate(
    name=agent_engine.api_resource.name,
    direct_contents_source={
      "events": events
    },
    # For example, `scope={"user_id": "123"}`.
    scope=SCOPE,
    config={
        "wait_for_completion": True
    }
)

Substitua o seguinte:

  • SCOPE: um dicionário que representa o âmbito das memórias geradas. Por exemplo, {"session_id": "MY_SESSION"}. Apenas as memórias com o mesmo âmbito são consideradas para consolidação.

Usar as sessões do Vertex AI Agent Engine como origem de dados

Com as sessões do Agent Engine, o banco de memória usa eventos de sessão como a conversa de origem para a geração de memória.

Para restringir o âmbito das memórias geradas, o banco de memórias extrai e usa o ID do utilizador da sessão por predefinição. Por exemplo, o âmbito das memórias é armazenado como {"user_id": "123"} se o user_id da sessão for "123". Também pode fornecer um scope diretamente, o que substitui a utilização do user_id da sessão como âmbito.

Dicionário

client.agent_engines.memories.generate(
  name=agent_engine.api_resource.name,
  vertex_session_source={
      # For example, projects/.../locations/.../reasoningEngines/.../sessions/...
      "session": "SESSION_NAME"
  },
  # Optional when using Agent Engine Sessions. Defaults to {"user_id": session.user_id}.
  scope=SCOPE,
  config={
      "wait_for_completion": True
  }
)

Substitua o seguinte:

  • SESSION_NAME: o nome da sessão totalmente qualificado.

  • (Opcional) SCOPE: um dicionário que representa o âmbito das memórias geradas. Por exemplo, {"session_id": "MY_SESSION"}. Apenas as memórias com o mesmo âmbito são consideradas para consolidação. Se não for fornecido, é usado o valor {"user_id": session.user_id}.

Com base em classes

client.agent_engines.memories.generate(
  name=agent_engine.api_resource.name,
  vertex_session_source=vertexai.types.GenerateMemoriesRequestVertexSessionSource(
      # For example, projects/.../locations/.../reasoningEngines/.../sessions/...
      session="SESSION_NAME"
  ),
  # Optional when using Agent Engine Sessions. Defaults to {"user_id": session.user_id}.
  scope=SCOPE,
  config={
      "wait_for_completion": True
  }
)

Opcionalmente, pode indicar um intervalo de tempo que indique que eventos na sessão devem ser incluídos. Se não for indicado, todos os eventos na sessão são incluídos.

Dicionário

import datetime

client.agent_engines.memories.generate(
  name=agent_engine.api_resource.name,
  vertex_session_source={
      "session": "SESSION_NAME",
      # Extract memories from the last hour of events.
      "start_time": datetime.datetime.now(tz=datetime.timezone.utc) - datetime.timedelta(seconds=24 * 60),
      "end_time": datetime.datetime.now(tz=datetime.timezone.utc)
  },
  scope=SCOPE
)

Com base em classes

import datetime

client.agent_engines.memories.generate(
  name=agent_engine.api_resource.name,
  vertex_session_source=vertexai.types.GenerateMemoriesRequestVertexSessionSource(
      session="SESSION_NAME",
      # Extract memories from the last hour of events.
      start_time=datetime.datetime.now(tz=datetime.timezone.utc) - datetime.timedelta(seconds=24 * 60),
      end_time=datetime.datetime.now(tz=datetime.timezone.utc)
  ),
  scope=SCOPE
)

Consolidação de memórias pré-extraídas

Em alternativa à utilização do processo de extração automática do banco de memórias, pode fornecer diretamente memórias pré-extraídas. As memórias de origem direta vão ser consolidadas com as memórias existentes para o mesmo âmbito. Isto pode ser útil quando quer que o seu agente ou um humano no circuito seja responsável por extrair memórias, mas ainda quer tirar partido da consolidação do banco de memórias para garantir que não existem memórias duplicadas ou contraditórias.

client.agent_engines.memories.generate(
    name=agent_engine.api_resource.name,
    direct_memories_source={"direct_memories": [{"fact": "FACT"}]},
    scope=SCOPE
)

Substitua o seguinte:

  • FACT: o facto pré-extraído que deve ser consolidado com as memórias existentes. Pode fornecer até 5 factos pré-extraídos numa lista como a seguinte:

    {"direct_memories": [{"fact": "fact 1"}, {"fact": "fact 2"}]}
    
  • SCOPE: um dicionário que representa o âmbito das memórias geradas. Por exemplo, {"session_id": "MY_SESSION"}. Apenas as memórias com o mesmo âmbito são consideradas para consolidação.

Usar a entrada multimodal

Pode extrair memórias a partir de entradas multimodais. No entanto, as memórias só são extraídas de texto, ficheiros inline e dados de ficheiros no conteúdo de origem. Todo o outro conteúdo, incluindo chamadas de funções e respostas, é ignorado quando são geradas memórias.

As memórias podem ser extraídas de imagens, vídeos e áudio fornecidos pelo utilizador. Se o contexto fornecido pela entrada multimodal for considerado significativo pelo banco de memória para interações futuras, pode ser criada uma memória textual que inclua informações extraídas da entrada. Por exemplo, se o utilizador fornecer uma imagem de um golden retriever com o texto "Este é o meu cão", o banco de memórias gera uma memória como "O meu cão é um golden retriever".

Por exemplo, pode fornecer uma imagem e contexto para a imagem no payload:

Dicionário

with open(file_name, "rb") as f:
    inline_data = f.read()

events =  [
  {
    "content": {
      "role": "user",
      "parts": [
        {"text": "This is my dog"},
        {
          "inline_data": {
            "mime_type": "image/jpeg",
            "data": inline_data
          }
        },
        {
          "file_data": {
            "file_uri": "gs://cloud-samples-data/generative-ai/image/dog.jpg",
            "mime_type": "image/jpeg"
          }
        },
      ]
    }
  }
]

Com base em classes

from google import genai
import vertexai

with open(file_name, "rb") as f:
    inline_data = f.read()

events = [
  vertexai.types.GenerateMemoriesRequestDirectContentsSourceEvent(
    content=genai.types.Content(
      role="user",
      parts=[
        genai.types.Part.from_text(text="This is my dog"),
        genai.types.Part.from_bytes(
          data=inline_data,
          mime_type="image/jpeg",
        ),
        genai.types.Part.from_uri(
          file_uri="gs://cloud-samples-data/generative-ai/image/dog.jpg",
          mime_type="image/jpeg",
        )
      ]
    )
  )
]

Quando usa as sessões do Vertex AI Agent Engine como origem de dados, o conteúdo multimodal é fornecido diretamente nos eventos da sessão.

O que se segue?