Palestra de abertura dos desenvolvedores do Next ‘26: como melhorar os agentes com memória

1. Introdução

Neste codelab, você vai levar seus agentes do ADK para o próximo nível adicionando conhecimento persistente e especializado. Você vai aprender a gerenciar o estado da conversa com as sessões da plataforma de agentes, ativar o aprendizado de longo prazo com o Memory Bank e integrar dados complexos de regras da cidade usando o Spark e o AlloyDB para RAG (geração aumentada por recuperação).

Atividades deste laboratório

  • Configure Sessões da plataforma do agente para persistência de conversas.
  • Implemente um Memory Bank para permitir que os agentes aprendam com interações anteriores.
  • Use o Spark Lightning Engine para ingerir e processar a documentação das regras da cidade.
  • Crie um sistema RAG usando AlloyDB e pesquisa vetorial.
  • Implante o agente aprimorado na plataforma de agentes.

O que é necessário

  • Um navegador da web, como o Chrome
  • Ter um projeto do Google Cloud com o faturamento ativado.
  • Conhecimento básico de Python e SQL

Duração estimada: 60 minutos

Os recursos criados neste codelab custam menos de US $5.

2. Antes de começar

Criar um projeto do Google Cloud

  1. No console do Google Cloud, na página do seletor de projetos, selecione ou crie um projeto na nuvem do Google Cloud.
  2. Verifique se o faturamento está ativado para seu projeto do Cloud. Saiba como verificar se o faturamento está ativado em um projeto.

Iniciar o Cloud Shell

O Cloud Shell é um ambiente de linha de comando executado no Google Cloud que vem pré-carregado com as ferramentas necessárias.

  1. Clique em Ativar o Cloud Shell na parte de cima do console do Google Cloud.
  2. Depois de se conectar ao Cloud Shell, verifique sua autenticação:
    gcloud auth list
    
  3. Confirme se o projeto está configurado:
    gcloud config get project
    
  4. Se o projeto não estiver definido como esperado, faça o seguinte:
    export PROJECT_ID=<YOUR_PROJECT_ID>
    gcloud config set project $PROJECT_ID
    

Verificar a autenticação:

gcloud auth list

Confirme seu projeto:

gcloud config get project

Defina, se necessário:

export PROJECT_ID=<YOUR_PROJECT_ID>
gcloud config set project $PROJECT_ID

Ativar APIs

Execute este comando para ativar todas as APIs necessárias para gerenciamento de sessões, processamento do Spark e AlloyDB:

gcloud services enable \
  aiplatform.googleapis.com \
  run.googleapis.com \
  alloydb.googleapis.com \
  dataproc.googleapis.com \
  documentai.googleapis.com \
  storage.googleapis.com \
  secretmanager.googleapis.com

3. Configurar o ambiente

Neste codelab, você vai usar o ambiente pré-configurado no repositório de keynote.

  1. Clone o repositório e acesse a pasta do projeto:
git clone https://github.com/GoogleCloudPlatform/next-26-keynotes
cd next-26-keynotes/devkey/enhancing-agents-with-memory
  1. Configure um ambiente virtual do Python e instale os pacotes do ADK necessários:
uv venv
source .venv/bin/activate
uv sync

Configurar variáveis de ambiente

O agente requer uma configuração específica para se conectar à plataforma de agentes e ao AlloyDB.

  1. Copie o arquivo de ambiente de exemplo:
cp .env.example .env
  1. Abra .env e atualize os seguintes campos:
    • GOOGLE_CLOUD_PROJECT: o ID do projeto
    • GOOGLE_CLOUD_LOCATION: us-central1.
    • ALLOYDB_CLUSTER_ID: rules-db.
GOOGLE_CLOUD_PROJECT=<YOUR_PROJECT_ID>
GOOGLE_CLOUD_LOCATION=global
GOOGLE_GENAI_USE_VERTEXAI=TRUE
GOOGLE_CLOUD_REGION=us-central1
ALLOYDB_CLUSTER_ID=rules-db
  1. Execute o script auxiliar a seguir para criar uma instância do Agent Engine que será usada em sessões de conversa e memória de longo prazo. Isso vai preencher automaticamente o AGENT_ENGINE_ID no arquivo .env:
uv run utils/setup_agent_engine.py

Se tudo der certo, você vai ver:

Creating Agent Engine instance...
Successfully created Agent Engine. ID: 1234567890
Updated .env with AGENT_ENGINE_ID=1234567890

4. Criar um agente com o gerenciamento de sessões

Nesta etapa, você vai inicializar um agente de planejamento de maratona que pode manter o histórico de conversas em vários turnos. Isso é feito usando a classe App do ADK e as sessões da plataforma de agente.

Inicializar o agente e o serviço de sessão

Abra planner_agent/agent.py. Você vai ver como estamos adicionando uma classe do ADK para integrar as sessões da plataforma de agente. Isso nos permite tornar nossos agentes com estado ao longo do tempo e modificar o contexto conforme necessário.

from google.adk.agents import LlmAgent
from google.adk.sessions import VertexAiSessionService
from vertexai.agent_engines import AdkApp

PROJECT_ID = os.environ.get("GOOGLE_CLOUD_PROJECT")
REGION = os.environ.get("GOOGLE_CLOUD_REGION", "us-central1")

# Initialize Vertex AI for regional services
if PROJECT_ID:
    vertexai.init(project=PROJECT_ID, location=REGION)

# Define the agent logic
root_agent = LlmAgent(
    name="planner_agent",
    model="gemini-3-flash-preview",
    instruction="You are a helpful marathon planning assistant...",
    tools=[] # We will add tools in the next steps
)

def session_service_builder():
    """Builder for Agent Platform Sessions."""
    return VertexAiSessionService(project=PROJECT_ID, location=REGION)

# Wrap the agent in an AdkApp to manage stateful context
app = AdkApp(
    agent=root_agent,
    session_service_builder=session_service_builder
)

5. Ativar o aprendizado de longo prazo com o Memory Bank

O gerenciamento de sessões rastreia conversas individuais, mas você pode fazer o mesmo com a memória de longo prazo. Nesta etapa, você vai anexar o agente ao Memory Bank da plataforma de agentes, um serviço de memória totalmente gerenciado e pronto para empresas.

Inicializar o serviço Memory Bank

O Memory Bank permite que o agente recupere o contexto em diferentes sessões. Atualize planner_agent/agent.py para incluir o serviço de memória:

from google.adk.memory import VertexAiMemoryBankService

def memory_service_builder():
    """Builder for Agent Platform Memory Bank."""
    return VertexAiMemoryBankService(
        project=PROJECT_ID,
        location=REGION,
        agent_engine_id=AGENT_ENGINE_ID
    )

Implementar a ingestão automática de memória

Para garantir que o agente aprenda com cada interação, adicionamos um after_agent_callback. Essa função é acionada depois que o agente conclui uma resposta, permitindo que ele "digira" a sessão e salve memórias relevantes no banco.

  1. Defina a função de callback:
async def auto_save_memories(callback_context):
    """Callback to ingest the session into the memory bank after the turn."""
    # In AdkApp, the memory service is available via the invocation context
    if hasattr(callback_context._invocation_context, 'memory_service') and callback_context._invocation_context.memory_service:
        await callback_context._invocation_context.memory_service.add_session_to_memory(
            callback_context._invocation_context.session
        )
  1. Anexe o callback ao LlmAgent:
root_agent = LlmAgent(
    # ... other params
    after_agent_callback=[auto_save_memories],
)

6. Configurar o AlloyDB para RAG

Antes de ingerir dados de regras da cidade, precisamos de um banco de dados de alto desempenho para armazená-los. Nesta etapa, você vai criar um cluster do AlloyDB e inicializar o esquema do banco de dados para a pesquisa vetorial.

1. Criar o cluster e a instância principal do AlloyDB

Execute estes comandos no Cloud Shell para criar o cluster e a instância principal dele:

# Create the cluster
gcloud alloydb clusters create rules-db \
  --password=postgres \
  --region=us-central1

# Create the primary instance with IAM authentication enabled
gcloud alloydb instances create rules-db-primary \
  --instance-type=PRIMARY \
  --cpu-count=2 \
  --region=us-central1 \
  --cluster=rules-db \
  --database-flags=alloydb.iam_authentication=on

2. Conceder os papéis do IAM necessários

Para usar o servidor MCP gerenciado do AlloyDB, sua identidade precisa de permissões específicas. Execute estes comandos para conceder os papéis necessários:

export USER_EMAIL=$(gcloud config get-value account)

# Role to use MCP tools
gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="user:$USER_EMAIL" \
  --role="roles/mcp.toolUser"

# Role to execute SQL in AlloyDB
gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="user:$USER_EMAIL" \
  --role="roles/alloydb.admin"

# Role for IAM database authentication
gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="user:$USER_EMAIL" \
  --role="roles/alloydb.databaseUser"

# Create the IAM-based database user
gcloud alloydb users create "$USER_EMAIL" \
  --cluster=rules-db \
  --region=us-central1 \
  --type=IAM_BASED

3. Criar banco de dados e tabelas com o AlloyDB Studio

Como os bancos de dados e as tabelas do AlloyDB são gerenciados por SQL, vamos usar o AlloyDB Studio no console do Google Cloud para finalizar o esquema.

  1. Acesse AlloyDB > Clusters e clique em rules-db.
  2. No menu de navegação à esquerda, clique em AlloyDB Studio.
  3. Faça login usando o usuário postgres e a senha definida (postgres).
  4. Execute o seguinte SQL para criar o banco de dados:
    CREATE DATABASE city_rules;
    
  5. Mude a conexão do banco de dados para city_rules no AlloyDB Studio e execute o seguinte SQL para instalar extensões e criar a tabela rules:
    -- Install extensions for vector search and ML
    CREATE EXTENSION IF NOT EXISTS vector;
    CREATE EXTENSION IF NOT EXISTS google_ml_integration CASCADE;
    
    -- Create the rules table
    CREATE TABLE IF NOT EXISTS rules (
        id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
        text TEXT NOT NULL,
        city TEXT NOT NULL,
        embedding vector(3072) DEFAULT NULL
    );
    
    -- Grant your IAM user access to the table (replace with your email)
    GRANT ALL PRIVILEGES ON TABLE rules TO "YOUR_EMAIL_ADDRESS";
    

7. Ingestão de dados de regras da cidade com o Spark Lightning Engine

Para oferecer um planejamento realmente preciso, um agente precisa de mais do que apenas um comando bem elaborado: ele precisa de embasamento em dados e contexto organizacional. Nesta etapa, você vai usar o Spark Lightning Engine no Dataproc sem servidor para processar PDFs de regras de grandes cidades e ingerir esses dados no AlloyDB.

Por que usar o Spark Lightning Engine?

Para embasar agentes em grande escala, é necessário processar grandes quantidades de dados não estruturados. O Spark Lightning Engine é um mecanismo de execução de alto desempenho para o Spark que acelera significativamente essas cargas de trabalho. Usamos esse recurso para realizar o chunking semântico em documentos usando a Document AI do Google.

Analisar o pipeline do Spark

A lógica de ingestão é definida em spark-setup/spark_alloydb_processor.py. O pipeline segue estas etapas:

  1. Listar PDFs: recupera URIs de documentos de um bucket do Cloud Storage.
  2. Extração semântica: usa uma UDF (função definida pelo usuário) para chamar a API Document AI.
  3. Gravar no AlloyDB: salva os trechos de texto extraídos na tabela do AlloyDB chamada rules.
# Extract from spark_alloydb_processor.py
def process_document(gcs_uri: str):
    # ... calls Document AI to parse PDF ...
    return chunks

# Parallel processing with Spark Lightning Engine
process_udf = udf(process_document, chunk_schema)
chunked_df = uri_df.withColumn("chunks", process_udf(col("gcs_uri"))) \
                   .select(explode(col("chunks")).alias("chunk")) \
                   .select("chunk.*")

# Save to AlloyDB for Vector Search
chunked_df.write.format("jdbc") \
    .option("url", jdbc_url) \
    .option("dbtable", "rules") \
    .mode("append") \
    .save()

Executar o job de ingestão

Acione o processo de ingestão usando o script fornecido:

./spark-setup/run_dataproc.sh

8. RAG com o AlloyDB

Agora que os dados das regras da cidade estão no AlloyDB, o agente pode usá-los para realizar a geração aumentada por recuperação (RAG). Isso garante que o plano da maratona siga códigos de cidades específicos.

A eficiência do AlloyDB para RAG

O AlloyDB é excelente em pesquisa vetorial, permitindo armazenar dados estruturados e embeddings de vetor no mesmo lugar. O agente pode usar a função embedding integrada no AlloyDB para encontrar as informações de regras mais relevantes.

Para dar ao agente acesso a esses dados, fornecemos uma ferramenta que consulta o AlloyDB usando a similaridade vetorial. É possível conferir essa lógica em hybrid_recall.sql, que demonstra como calcular a distância entre uma consulta e nossas regras armazenadas:

SELECT
    text,
    (embedding <=> 
     embedding('gemini-embedding-001', 
               'Restrictions for running a race on the Las Vegas strip')::vector) 
    as distance
FROM
    rules
WHERE city = 'Las Vegas'
ORDER BY
    distance ASC
LIMIT 5;

Embasar o agente em regras locais com uma ferramenta RAG

Para disponibilizar a ferramenta ao agente, defina-a em planner_agent/tools.py e registre-a em planner_agent/agent.py. Vamos usar o servidor MCP remoto gerenciado do AlloyDB do Google Cloud para nos conectar ao banco de dados.

  1. Defina a ferramenta em planner_agent/tools.py usando o padrão "Hybrid Recall". Vamos usar o protocolo streamable_http para nos conectar ao servidor MCP gerenciado do AlloyDB:
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client

async def get_local_and_traffic_rules(query: str) -> str:
    """Uses vector search in AlloyDB via managed MCP server."""
    # Vector search query using built-in AlloyDB embedding functions
    sql = f"SELECT text FROM rules WHERE city = 'Las Vegas' ORDER BY embedding <=> google_ml.embedding('gemini-embedding-001', '{query}')::vector ASC LIMIT 5;"
    
    # Establish a streamable HTTP connection to the MCP server
    async with streamablehttp_client(url, headers=get_auth_headers()) as (read_stream, write_stream, _):
        async with ClientSession(read_stream, write_stream) as session:
            await session.initialize()
            result = await session.call_tool(
                "execute_sql",
                arguments={
                    "instance": full_instance_name,
                    "database": "city_rules",
                    "sqlStatement": sql
                }
            )
            return "\n".join([c.text for c in result.content if hasattr(c, 'text')])
  1. Registre a ferramenta e finalize planner_agent/agent.py:
# ... imports ...

# Assemble the Agent
root_agent = LlmAgent(
    name="planner_agent",
    model="gemini-3-flash-preview",
    instruction="You are a helpful marathon planning assistant...",
    tools=[
        get_local_and_traffic_rules,
    ],
    after_agent_callback=[auto_save_memories],
)

# 2. Wrap the agent in an AdkApp to manage the stateful lifecycle
app = AdkApp(
    agent=root_agent,
    session_service_builder=session_service_builder,
    memory_service_builder=memory_service_builder
)

9. Orientação de especialistas com habilidades do agente

As habilidades do agente são módulos independentes que oferecem instruções, orientações e recursos específicos para ajudar os agentes a realizar tarefas com mais eficiência. Em vez de poluir o comando do sistema com instruções complexas para cada ferramenta, você pode encapsular essa experiência em uma Skill que é carregada apenas quando necessário.

O Google oferece habilidades pré-criadas para produtos do Google (como AlloyDB e BigQuery) para garantir que seus agentes sigam as práticas recomendadas do setor para consultar dados e gerenciar recursos. Você pode conferir esses e outros padrões especializados no Google Skills Depot. Confira as habilidades básicas do AlloyDB aqui.

1. Conheça o arquivo de habilidade

Abra o arquivo de habilidade pré-configurado em planner_agent/skills/get-local-and-traffic-rules/SKILL.md. Veja como ele aparece:

---
name: get-local-and-traffic-rules
description: Retrieve local rules and traffic information for a specific jurisdiction.
---
# get_local_and_traffic_rules Skill

This skill provides guidelines on how to effectively use the `get_local_and_traffic_rules` tool.

## Overview
The `get_local_and_traffic_rules` tool interfaces with an AlloyDB database to perform vector similarity searches on a corpus of rules and traffic information using a provided natural language query.

## Usage Guidelines
1. **Query Specificity**: When calling the tool, provide specific details in the `query` argument. For example, instead of querying "food rules", use "rules regarding food vendors during public events".
2. **Contextual Use**: Use the tool when planning events or activities that require adherence to local municipal or state rules (e.g., street closures, noise ordinances, environmental rules).
3. **Handling Results**: The tool returns a string containing the text of the top 5 most relevant rules. If no error occurs, parse the returned string to inform your planning tasks.
4. **Error Handling**: If an error string is returned (e.g., "Error querying rules: ..."), you must report this failure or attempt an alternative approach if applicable.

## Underlying Mechanism
- The tool uses `google_ml.embedding` to convert the query into a vector representation.
- It calculates distance (`<=>`) against the `embedding` column in the `rules` table on an AlloyDB instance.
- Results are fetched in descending order of similarity, limited to 5 results.

2. Como a habilidade é registrada

Em planner_agent/agent.py, a habilidade é carregada do diretório e adicionada às ferramentas do agente. Veja como o código fica:

import pathlib
from google.adk.skills import load_skill_from_dir
from google.adk.tools import skill_toolset

# Load the AlloyDB skill from its directory
alloydb_skill = load_skill_from_dir(pathlib.Path(__file__).parent / "skills" / "get-local-and-traffic-rules")

# Assemble the Agent with the Skill Toolset
root_agent = LlmAgent(
    name="planner_agent",
    model="gemini-3-flash-preview",
    instruction="You are a helpful marathon planning assistant...",
    tools=[
        get_local_and_traffic_rules,
        skill_toolset.SkillToolset(skills=[alloydb_skill])
    ],
    after_agent_callback=[auto_save_memories],
)

10. Testar o agente

  1. Inicie o agente localmente:
uv run adk run planner_agent
  1. Pergunte sobre as regras da cidade: [user]: What are the rules for running a race on the Las Vegas strip?

O agente vai chamar a ferramenta get_local_and_traffic_rules, realizar uma pesquisa vetorial no AlloyDB e retornar uma resposta com base nos blocos de regras oficiais processados pelo Spark.

11. Implante o agente

Implantar na plataforma de agentes

uv run adk deploy agent_engine \
  --env_file .env \
  planner_agent

12. Limpar

Para evitar cobranças contínuas, exclua os recursos criados durante este codelab.

Excluir o cluster do AlloyDB

# Delete the AlloyDB Cluster
gcloud alloydb clusters delete rules-db --region=us-central1 --force

Excluir o app do Agent Runtime

É possível excluir a instância do Reasoning Engine pelo console ou usando o comando gcloud (se você tiver o nome do recurso). Para simplificar, use o console:

  1. Acesse a página Agent Runtime.
  2. Selecione planner_agent –> clique no botão de três pontos no lado direito.
  3. Clique em Excluir.

13. Parabéns

Parabéns! Você melhorou um agente do ADK com recursos avançados de memória e embasamento de dados.

O que você aprendeu

  • Agentes com estado: integração das sessões da plataforma de agentes para manter o contexto da conversa.
  • Aprendizado de longo prazo: anexar um Memory Bank da plataforma do agente para permitir que o agente aprenda com as interações do usuário.
  • Ingestão de dados: uso do Spark Lightning Engine e da Document AI para processar documentos não estruturados.
  • RAG: criação de um sistema de pesquisa vetorial no AlloyDB para fundamentar o agente em regras do mundo real.

Próximas etapas