Generar recuerdos

Agent Platform Memory Bank te permite crear recuerdos a largo plazo a partir de conversaciones entre el usuario y tu agente. Este proceso se realiza automáticamente cuando se activa y extrae información valiosa para interacciones futuras.

En este documento, se explica cómo funciona la generación de memoria, cómo personalizar la extracción de memoria con temas y cómo activar las solicitudes de generación de memoria.

Para obtener información sobre cómo configurar tu entorno, consulta Configura Memory Bank.

Comprende la generación de memoria

Memory Bank extrae recuerdos de los datos de origen y los organiza automáticamente para una colección específica de recuerdos (definida por un scope) agregando, actualizando y quitando recuerdos con el tiempo.

Cuando activas la generación de memoria, Memory Bank realiza las siguientes operaciones:

  • Extracción: Extrae información sobre el usuario de sus conversaciones con el agente. Solo se conservará la información que coincida con al menos uno de los temas de memoria de tu instancia.

  • Consolidación: Identifica si se deben borrar o actualizar los recuerdos existentes con el mismo alcance en función de la información extraída. Memory Bank verifica que los recuerdos nuevos no sean duplicados ni contradictorios antes de combinarlos con los existentes. Si los recuerdos existentes no se superponen con la información nueva, se creará un recuerdo nuevo.

Algoritmo de generación de memoria

Puedes inspeccionar los pasos intermedios de la generación de memoria y ver cómo cambia un recuerdo en varias solicitudes con las revisiones de memoria. Cada revisión incluye el resultado intermedio del paso de extracción (extracted_memories) y el paso de consolidación final (fact) para cada solicitud de generación de memoria.

list(client.agent_engines.memories.revisions.list(
  name="projects/.../locations/.../reasoningEngines/.../memories/.../revisions/..."))

"""
[
  MemoryRevision(
    name="projects/123/locations/us-central1/reasoningEngines/456/memories/789/revision/456",
    fact="This is my updated fact",
    extracted_memories=[
      IntermediateExtractedMemory(
        fact='This is the output of extraction for a single request.'
      ),
    ],
    ...
  ),
  MemoryRevision(
    name="projects/123/locations/us-central1/reasoningEngines/456/memories/789/revision/123",
    fact="This is my original fact",
    extracted_memories=[
      IntermediateExtractedMemory(
        fact='This is my original fact.'
      ),
    ],
    ...
  )
]
"""

Temas de memoria

Los "temas de memoria" identifican qué información considera Memory Bank que es significativa y, por lo tanto, debe conservarse como recuerdos generados. Memory Bank admite dos tipos de temas de memoria:

  • Temas administrados: Memory Bank define la etiqueta y las instrucciones. Solo debes proporcionar el nombre del tema administrado. Por ejemplo:

    Diccionario

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

    Basado en clases

    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
        )
    )
    
  • Temas personalizados: Tú defines la etiqueta y las instrucciones cuando configuras tu instancia de Memory Bank. Se usarán en la instrucción para el paso de extracción de Memory Bank. Por ejemplo:

    Diccionario

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

    Basado en clases

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

    Cuando usas temas personalizados, se recomienda proporcionar ejemplos de pocas tomas para demostrar cómo se deben extraer los recuerdos de tu conversación.

De forma predeterminada, Memory Bank conserva todos los siguientes temas administrados:

  • Información del usuario (USER_PERSONAL_INFO): Información importante sobre el usuario, como nombres, relaciones, pasatiempos y fechas importantes. Por ejemplo, "Trabajo en Google" o "Mi aniversario de bodas es el 31 de diciembre".

  • Preferencias del usuario (USER_PREFERENCES): Gustos, disgustos, estilos o patrones preferidos, ya sean explícitos o implícitos. Por ejemplo, "Prefiero el asiento del medio".

  • Eventos clave de la conversación y resultados de tareas (KEY_CONVERSATION_DETAILS): Hitos o conclusiones importantes dentro del diálogo. Por ejemplo, "Reservé boletos de avión para un viaje de ida y vuelta entre JFK y SFO. Salgo el 1 de junio de 2025 y regreso el 7 de junio de 2025".

  • Instrucciones explícitas para recordar o olvidar (EXPLICIT_INSTRUCTIONS): Información que el usuario le pide explícitamente al agente que recuerde o olvide. Por ejemplo, si el usuario dice "Recuerda que uso principalmente Python", Memory Bank genera un recuerdo como "Uso principalmente Python".

Esto equivale a usar el siguiente conjunto de temas de memoria administrados:

Diccionario

  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"}},
  ]

Basado en clases

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)),
]

Si deseas personalizar qué temas conserva Memory Bank, establece los temas de memoria en tu configuración de personalización cuando configures Memory Bank.

Usa metadatos durante la consolidación

Puedes adjuntar metadatos a los recuerdos generados. Los metadatos te permiten almacenar información estructurada (cadenas, dobles, booleanos o marcas de tiempo) junto con un hecho de memoria. Esto es útil para filtrar o administrar los ciclos de vida de los recuerdos.

Diccionario

import datetime

client.agent_engines.memories.generate(
    ...,
    config={
        "metadata": {
            "my_string_key": {"string_value": "my_string_value"},
            "my_double_key": {"double_value": 123.456},
            "my_boolean_key": {"bool_value": True},
            "my_timestamp_key": {
                "timestamp_value": datetime.datetime(
                    2027, 1, 1, 12, 30, 00, tzinfo=datetime.timezone.utc
                )
            }
        },
        "metadata_merge_strategy": "MERGE"
    },
)

Basado en clases

import datetime

from vertexai import types

client.agent_engines.memories.generate(
    ...,
    config=types.GenerateAgentEngineMemoriesConfig(
        metadata={
            "my_string_key": types.MemoryMetadataValue(string_value="my_string_value"),
            "my_double_key": types.MemoryMetadataValue(double_value=123.456),
            "my_boolean_key": types.MemoryMetadataValue(bool_value=True),
            "my_timestamp_key": types.MemoryMetadataValue(
                timestamp_value=datetime.datetime(
                    2027, 1, 1, 12, 30, 00, tzinfo=datetime.timezone.utc
                )
            ),
        },
        metadata_merge_strategy=types.MemoryMetadataMergeStrategy.MERGE,
    )
)

Si usas una metadata_merge_strategy, puedes controlar cómo interactúan los metadatos nuevos con los recuerdos existentes durante la consolidación:

  • MERGE: (Predeterminado) Combina los metadatos nuevos con los existentes. Si ya existe una clave, el valor nuevo reemplaza al anterior.

  • OVERWRITE: Reemplaza los metadatos de los recuerdos actualizados por los metadatos nuevos.

  • REQUIRE_EXACT_MATCH: Restringe la consolidación a los recuerdos que tienen exactamente los mismos metadatos que la solicitud. Si un recuerdo no tiene los mismos metadatos, no es apto para la consolidación y no se actualizará.

Genera recuerdos para un subconjunto de temas

De forma predeterminada, la generación de memoria extrae datos para todos los temas de memoria que configuraste cuando configuraste tu instancia de Memory Bank. Para una solicitud GenerateMemories específica, puedes restringir la extracción a un subconjunto de temas configurados. Para configurar los temas permitidos, usa el campo allowed_topics.

Diccionario

client.agent_engines.memories.generate(
    ...,
    config={
        "allowed_topics": [
            {"managed_memory_topic": "USER_PERSONAL_INFO"},
            {"custom_memory_topic_label": "business_feedback"}
        ]
    },
)

Basado en clases

from vertexai import types

client.agent_engines.memories.generate(
    ...,
    config=types.GenerateAgentEngineMemoriesConfig(
        allowed_topics=[
            types.MemoryTopicId(
                managed_memory_topic=types.ManagedTopicEnum.USER_PERSONAL_INFO
            ),
            types.MemoryTopicId(
                custom_memory_topic_label="business_feedback"
            )
        ]
    )
)

Activa la generación de memoria

Puedes activar la generación de memoria con uno de los siguientes métodos:

  • GenerateMemories: Incorpora datos a Memory Bank y activa la generación de memoria de inmediato. Este método es útil cuando deseas generar recuerdos en un momento específico, como al final de una sesión o a intervalos regulares dentro de una sesión.
  • IngestEvents: Incorpora datos a Memory Bank de forma continua y permite que Memory Bank los procese cuando se cumplan tus criterios de activación. Este método es útil cuando tienes un flujo continuo de eventos y deseas que Memory Bank controle automáticamente el almacenamiento en búfer y active la generación de memoria según el volumen o el tiempo. Para obtener más información, consulta Incorpora eventos.

La generación de memoria extrae el contexto clave de las conversaciones de origen y lo combina con los recuerdos existentes para el mismo alcance. Por ejemplo, puedes crear recuerdos a nivel de la sesión con un alcance como {"user_id": "123", "session_id": "456"}. Los recuerdos con el mismo alcance se pueden consolidar y recuperar juntos.

GenerateMemories es una operación de larga duración. Una vez que se realiza la operación, AgentEngineGenerateMemoriesOperation contiene una lista de recuerdos generados, si se generó alguno:

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 recuerdo generado incluye la action que se realizó en ese recuerdo:

  • CREATED: Indica que se agregó un recuerdo nuevo, lo que representa un concepto nuevo que no se capturó en los recuerdos existentes.

  • UPDATED: Indica que se actualizó un recuerdo existente, lo que sucede si el recuerdo abarca conceptos similares a la información recién extraída. Es posible que el hecho del recuerdo se actualice con información nueva o permanezca igual.

  • DELETED: Indica que se borró el recuerdo existente porque su información era contradictoria con la información nueva extraída de la conversación.

Para los recuerdos CREATED o UPDATED, puedes usar GetMemories para recuperar el contenido completo del recuerdo. La recuperación de recuerdos DELETED genera un error 404.

Genera recuerdos en segundo plano

GenerateMemories es una operación de larga duración. De forma predeterminada, client.agent_engines.generate_memories es una función de bloqueo que sondea la operación hasta que se completa. Ejecutar la generación de memoria como una operación de bloqueo es útil cuando deseas inspeccionar manualmente los recuerdos generados o notificar a los usuarios finales qué recuerdos se generaron.

Sin embargo, para los agentes de producción, por lo general, deseas ejecutar la generación de memoria en segundo plano como un proceso asíncrono. En la mayoría de los casos, el cliente no necesita usar el resultado de la ejecución actual, por lo que no es necesario incurrir en una latencia adicional esperando una respuesta. Si deseas que la generación de memoria se ejecute en segundo plano, establece wait_for_completion en False:

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

Como alternativa a llamar a GenerateMemories de forma asíncrona, puedes usar IngestEvents, que desacopla la incorporación de eventos de la generación de memoria y procesa los eventos en segundo plano de forma predeterminada.

Fuentes de datos

Existen varias formas de proporcionar datos de origen para la generación de memoria:

Cuando proporcionas eventos directamente en la carga útil o usas sesiones de Agent Runtime, se extrae información de la conversación y se consolida con los recuerdos existentes. Si solo deseas extraer información de estas fuentes de datos, puedes inhabilitar la consolidación:

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

Usa eventos en la carga útil como fuente de datos

Usa direct_contents_source cuando quieras generar recuerdos con eventos proporcionados directamente en la carga útil. Se extrae información significativa de estos eventos y se consolida con la información existente para el mismo alcance. Este enfoque se puede usar si usas un almacenamiento de sesión diferente de las sesiones de Agent Platform.

Diccionario

Los eventos deben incluir Content diccionarios.

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

Reemplaza lo siguiente:

  • SCOPE: Un diccionario que representa el alcance de los recuerdos generados. Por ejemplo, {"session_id": "MY_SESSION"}. Solo se consideran los recuerdos con el mismo alcance para la consolidación.

Basado en clases

Los eventos deben incluir Content objetos.

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

Reemplaza lo siguiente:

  • SCOPE: Un diccionario que representa el alcance de los recuerdos generados. Por ejemplo, {"session_id": "MY_SESSION"}. Solo se consideran los recuerdos con el mismo alcance para la consolidación.

Usa sesiones de Agent Runtime como fuente de datos

Con las sesiones, Memory Bank usa eventos de sesión como la conversación de origen para la generación de memoria.

Para definir el alcance de los recuerdos generados, Memory Bank extrae y usa el ID de usuario de la sesión de forma predeterminada. Por ejemplo, el alcance de los recuerdos se almacena como {"user_id": "123"} si el de la sesión user_id es "123". También puedes proporcionar un scope directamente, lo que anula el uso del user_id de la sesión como alcance.

Diccionario

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 Sessions. Defaults to {"user_id": session.user_id}.
  scope=SCOPE,
  config={
      "wait_for_completion": True
  }
)

Reemplaza lo siguiente:

  • SESSION_NAME: El nombre de sesión completamente calificado.

  • SCOPE (opcional): Un diccionario que representa el alcance de los recuerdos generados. Por ejemplo, {"session_id": "MY_SESSION"}. Solo se consideran los recuerdos con el mismo alcance para la consolidación. Si no se proporciona, se usa {"user_id": session.user_id}.

Basado en clases

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 Sessions. Defaults to {"user_id": session.user_id}.
  scope=SCOPE,
  config={
      "wait_for_completion": True
  }
)

De manera opcional, puedes proporcionar un intervalo de tiempo que indique qué eventos de la sesión se deben incluir. Si no se proporciona, se incluyen todos los eventos de la sesión.

Diccionario

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
)

Basado en clases

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 recuerdos extraídos previamente

Como alternativa a usar el proceso de extracción automática de Memory Bank, puedes proporcionar directamente recuerdos extraídos previamente. Los recuerdos de origen directo se consolidarán con los recuerdos existentes para el mismo alcance. Esto puede ser útil cuando deseas que tu agente o un humano en el circuito se encargue de extraer recuerdos, pero aún deseas aprovechar la consolidación de Memory Bank para asegurarte de que no haya recuerdos duplicados o contradictorios.

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

Reemplaza lo siguiente:

  • FACT: El hecho extraído previamente que se debe consolidar con los recuerdos existentes. Puedes proporcionar hasta 5 hechos extraídos previamente en una lista como la siguiente:

    {"direct_memories": [{"fact": "fact 1"}, {"fact": "fact 2"}]}
    
  • SCOPE: Un diccionario que representa el alcance de los recuerdos generados. Por ejemplo, {"session_id": "MY_SESSION"}. Solo se consideran los recuerdos con el mismo alcance para la consolidación.

Usa la entrada multimodal

Puedes extraer recuerdos de la entrada multimodal. Sin embargo, los recuerdos solo se extraen del texto, los archivos intercalados y los datos de archivos en el contenido de origen. Todo el contenido restante, incluidas las llamadas y respuestas de funciones, se ignora cuando se generan recuerdos.

Los recuerdos se pueden extraer de imágenes, videos, y audio proporcionados por el usuario. Si Memory Bank considera que el contexto proporcionado por la entrada multimodal es significativo para interacciones futuras, se puede crear un recuerdo textual que incluya información extraída de la entrada. Por ejemplo, si el usuario proporciona una imagen de un golden retriever con el texto "Este es mi perro", Memory Bank genera un recuerdo como "Mi perro es un golden retriever".

Por ejemplo, puedes proporcionar una imagen y el contexto de la imagen en la carga útil:

Diccionario

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"
          }
        },
      ]
    }
  }
]

Basado en clases

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

Cuando usas sesiones de Agent Runtime como fuente de datos, el contenido multimodal se proporciona directamente en los eventos de la sesión.

¿Qué sigue?

Guía

Obtén información para recuperar recuerdos generados y subidos.

Guía

Obtén información para configurar Memory Bank.

Guía

Obtén información para inspeccionar las revisiones de memoria.