Integrar agentes da Vertex AI ao Google Workspace

1. Antes de começar

99afae2505f696fb.png

O que é a Vertex AI?

A Vertex AI é a plataforma de desenvolvimento unificada do Google Cloud para criar, implantar e escalonar agentes e aplicativos de IA de nível empresarial. Ele oferece aos desenvolvedores e cientistas de dados as ferramentas sofisticadas necessárias para arquitetar fluxos de trabalho agênticos personalizados que são profundamente integrados à infraestrutura de escala global.

  • Acessar o Model Garden:escolha entre mais de 150 modelos de fundação, incluindo toda a família Gemini, modelos de terceiros e modelos especializados de código aberto para encontrar a opção certa para tarefas específicas do agente.
  • Arquitetar orquestrações complexas:a Vertex AI oferece o framework para projetar agentes autônomos que usam o raciocínio para planejar, executar tarefas de várias etapas e chamar APIs externas.
  • Embasamento de nível empresarial:conecte agentes a dados comerciais em tempo real, incluindo RAG (geração aumentada por recuperação) de alta performance para eliminar alucinações e garantir a precisão factual.
  • DevOps:integre o desenvolvimento de agentes aos pipelines de CI/CD atuais com SDKs, APIs e ferramentas de avaliação robustos para medir o desempenho e a segurança dos agentes em grande escala.
  • Segurança de nível industrial:a Vertex AI garante que os dados do cliente usados para treinamento ou embasamento permaneçam particulares, criptografados e em conformidade com os requisitos globais de residência.
  • Infraestrutura otimizada:dimensione cargas de trabalho de agentes sem esforço nos clusters de TPU e GPU de nível mundial do Google, garantindo desempenho de baixa latência mesmo para os aplicativos globais mais exigentes.

127f2ed7d484722c.png

O que é o Google Workspace?

O Google Workspace é um conjunto de soluções de produtividade e colaboração baseadas na nuvem projetadas para pessoas, escolas e empresas:

  • Comunicação:serviços de e-mail profissional (Gmail), videoconferências (Meet) e mensagens em grupo (Chat).
  • Criação de conteúdo:ferramentas para escrever documentos (Documentos), criar planilhas (Planilhas) e design de apresentações (Apresentações).
  • Organização:agendas compartilhadas (Agenda) e anotações digitais (Keep).
  • Armazenamento:espaço centralizado na nuvem para salvar e compartilhar arquivos com segurança (Drive).
  • Gerenciamento:controles administrativos para gerenciar usuários e configurações de segurança (Admin Console do Workspace).

Que tipo de integrações personalizadas?

O Google Workspace e a Vertex AI criam um ciclo de feedback eficiente em que o Workspace fornece dados em tempo real e contexto de colaboração, enquanto a Vertex AI oferece os modelos, o raciocínio de agentes e a orquestração necessários para automatizar fluxos de trabalho inteligentes.

  • Conectividade inteligente:os repositórios de dados, as APIs e os servidores MCP gerenciados pelo Google (gerenciados pelo Google e personalizados) permitem que os agentes acessem os dados do Workspace com segurança e facilidade e realizem ações em nome dos usuários.
  • Agentes personalizados:usando designers sem código ou estruturas de programação, as equipes podem criar agentes especializados com base em dados e ações do Workspace gerenciados pelo administrador.
  • Integração nativa:os complementos do Workspace preenchem a lacuna entre os sistemas de IA e aplicativos como o Chat e o Gmail, seja por componentes dedicados da interface ou por processos em segundo plano. Assim, os atendentes podem ajudar os usuários de forma instantânea e contextualizada.

Ao combinar o robusto ecossistema de produtividade do Google Workspace com o poder avançado da Vertex AI, as organizações podem transformar as operações com agentes de IA personalizados e baseados em dados que automatizam fluxos de trabalho complexos diretamente nas ferramentas que as equipes já usam todos os dias.

Pré-requisitos

Se quiser seguir todas as etapas no seu próprio ambiente, você vai precisar do seguinte:

O que você criará

Neste codelab, vamos criar três soluções com agentes da Vertex AI integrados ao Google Workspace. Eles vão demonstrar padrões arquitetônicos que podem ser usados para interagir com dados, ações e interfaces.

App Vertex AI para Pesquisa

Com ele, os usuários podem pesquisar dados e realizar ações no Workspace em linguagem natural. Ele depende dos seguintes elementos:

  • Modelo:Gemini.
  • Dados e ações:repositórios de dados da Vertex AI para o Google Workspace (Agenda, Gmail, Drive).
  • Host do agente:Vertex AI para Pesquisa.
  • Interface: widget da Web da Vertex AI para Pesquisa.

d276ff8e2b9d0ddf.png

Agente personalizado

Com ele, os usuários podem pesquisar dados e realizar ações no Workspace em linguagem natural usando ferramentas e regras personalizadas. Ele depende dos seguintes elementos:

  • Modelo:Gemini.
  • Dados e ações:repositórios de dados da Vertex AI para Google Workspace (Agenda, Gmail, Drive), servidor do Protocolo de Contexto de Modelo (MCP, na sigla em inglês) da Vertex AI para Pesquisa gerenciado pelo Google, função de ferramenta personalizada para enviar mensagens do Google Chat (pela API do Google Chat).
  • Ferramentas de criação de agentes:Kit de Desenvolvimento de Agente (ADK).
  • Host do agente:Vertex AI Agent Engine.
  • Interface:ADK Web.

145f47f45332e6be.png

293ec4d3e2bb6a0.png

Um agente como complemento do Google Workspace

Com ele, os usuários podem pesquisar dados do Workspace em linguagem natural no contexto das interfaces dos apps do Workspace. Ele depende dos seguintes elementos:

  • Modelo:Gemini.
  • Dados e ações:repositórios de dados da Vertex AI para Google Workspace (Agenda, Gmail, Drive), servidor do Protocolo de Contexto de Modelo (MCP, na sigla em inglês) da Vertex AI para Pesquisa gerenciado pelo Google, função de ferramenta personalizada para enviar mensagens do Google Chat (pela API do Google Chat).
  • Ferramentas de criação de agentes:Kit de Desenvolvimento de Agente (ADK).
  • Host do agente:Vertex AI Agent Engine.
  • Interface:complemento do Google Workspace para Chat e Gmail (facilmente extensível para Agenda, Drive, Documentos, Planilhas e Apresentações).
  • Complemento do Google Workspace:Apps Script, APIs do Agent Engine da Vertex AI, contextual (mensagem selecionada do Gmail).

172da43f310a0579.png

840b494aa5eaa1ef.png

O que você vai aprender

  • Os pontos de integração entre a Vertex AI para Pesquisa e o Google Workspace que permitem dados e ações.
  • As opções para criar agentes personalizados hospedados na Vertex AI.
  • As formas como os usuários podem acessar agentes, como o widget da Web da Vertex AI para Pesquisa e os aplicativos do Google Workspace.

2. Configurar

Antes de criar soluções, precisamos inicializar as configurações de aplicativos da Vertex AI do projeto, ativar as APIs necessárias e criar os repositórios de dados do Vertex AI Workspace.

Revisar conceitos

Aplicativo da Vertex AI

Um aplicativo da Vertex AI é uma solução gerenciada de ponta a ponta no Google Cloud que integra modelos de machine learning (como agentes de IA generativa ou mecanismos de pesquisa) com dados empresariais e ferramentas especializadas para realizar tarefas complexas, como pesquisa semântica, geração de conteúdo ou interação automatizada com o cliente.

Data store da Vertex AI

Um repositório de dados da Vertex AI é uma entidade que contém os dados ingeridos de uma fonte de dados própria, como o Google Workspace, ou de aplicativos de terceiros, como o Jira ou o Shopify. Os repositórios de dados que contêm dados de aplicativos de terceiros também são chamados de conectores de dados.

Iniciar as configurações dos aplicativos da Vertex AI

Abra o console do Google Cloud em uma nova guia e siga estas etapas:

  1. Selecione o projeto.
  2. No campo de pesquisa do Google Cloud, acesse Aplicativos de IA.

  1. Clique em Continuar e ativar a API depois de ler e aceitar os termos.
  2. Acesse Settings.
  3. Na guia Authentication, edite global.

93b0cc6ed63fba0c.png

  1. Selecione Google Identity e clique em Salvar.

5c01b4cbeebaa93b.png

Ativar APIs

Os repositórios de dados do Workspace da Vertex AI exigem a ativação das seguintes APIs:

  1. No console do Google Cloud, ative as APIs Calendar, Gmail e People:

3877dcaa56624d0b.png

  1. Clique em Menu ☰ > APIs e serviços > APIs e serviços ativados e confirme se a API Google Agenda, a API Gmail e a API People estão na lista.

Criar repositórios de dados

Crie o repositório de dados do Google Drive:

  1. No console do Google Cloud, acesse Aplicativos de IA e navegue até Repositórios de dados.

  1. Clique em + Criar repositório de dados.
  2. Em Origem, em Google Drive, clique em Selecionar.

6939363368bde36d.png

  1. Em Dados, selecione Todos e clique em Continuar.

5044243322acec9e.png

  1. Em Configuração, defina o Nome do conector de dados como drive e clique em Continuar depois de revisar e concordar com as cobranças que podem ser aplicadas.

1f5deb1aeecee983.png

  1. Em Preços, selecione o modelo de preços que você prefere e clique em Criar. Preços gerais são recomendados no contexto deste codelab.
  2. Você vai ser redirecionado automaticamente para Repositórios de dados, onde poderá ver o repositório recém-adicionado.

Crie o repositório de dados do Google Agenda:

  1. Clique em + Criar repositório de dados.
  2. Em Origem, pesquise Google Agenda e clique em Selecionar.
  3. Na seção Ações, clique em Pular.
  4. Na seção Configuração, defina o Nome do conector de dados como calendar.
  5. Clique em Criar.
  6. Você vai ser redirecionado automaticamente para Repositórios de dados, onde poderá ver o repositório recém-adicionado.

Crie o repositório de dados do Google Gmail:

  1. Clique em + Novo repositório de dados.
  2. Em Origem, pesquise Google Gmail e clique em Selecionar.
  3. Na seção Ações, clique em Pular.
  4. Na seção Configuração, defina o Nome do conector de dados como gmail.
  5. Clique em Criar.
  6. Você vai ser redirecionado automaticamente para Repositórios de dados, onde poderá ver o repositório recém-adicionado.

3. App Vertex AI para Pesquisa

Com ele, os usuários podem pesquisar dados e realizar ações no Workspace em linguagem natural. Ele depende dos seguintes elementos:

  • Modelo:Gemini.
  • Dados e ações:repositórios de dados da Vertex AI para o Google Workspace (Agenda, Gmail, Drive).
  • Host do agente:Vertex AI para Pesquisa.
  • Interface: widget da Web da Vertex AI para Pesquisa.

Revisar conceitos

App Vertex AI para Pesquisa

Um app da Vertex AI para Pesquisa fornece resultados de pesquisa, ações e agentes para seus usuários finais. O termo "app" pode ser usado de forma intercambiável com o termo "engine" no contexto das APIs. Um app precisa estar conectado a um repositório de dados para usar as informações dele e veicular resultados da pesquisa, respostas ou ações.

Widget da Web da Vertex AI para Pesquisa

O widget da Web da Vertex AI para Pesquisa é um componente de interface pré-criado e personalizável que permite aos desenvolvedores incorporar uma barra de pesquisa e uma interface de resultados com tecnologia de IA diretamente em um site com programação mínima.

Prévia da Vertex AI para Pesquisa

A prévia da Vertex AI para Pesquisa é um ambiente de teste integrado no console do Google Cloud que permite aos desenvolvedores validar configurações de pesquisa e respostas generativas antes de implantar essas mesmas configurações em um widget da Web da Vertex AI para Pesquisa pronto para produção.

Analisar a arquitetura da solução

1f337dc91da74391.png

Criar app

Abra Aplicativos de IA > Apps no console do Cloud e siga estas etapas:

  1. Clique em + Criar app.
  2. Em Tipo, em Pesquisa personalizada (geral), clique em Criar.

9714a5fff49b5e1b.png

  1. Em Configuração, marque Recursos da edição Enterprise e Respostas generativas depois de revisar e concordar com os preços.
  2. Defina o Nome do app como codelab.
  3. Um ID é gerado com base no nome e exibido abaixo do campo. Copie-o.
  4. Defina o Nome da empresa como Codelab.
  5. Defina a Multirregião como global (Global).
  6. Clique em Continuar.

327702cd837cbb18.png

  1. Em Dados, selecione os repositórios drive, gmail e calendar e clique em Continuar.

5745607f3c43d5c0.png

  1. Em Preços, selecione o modelo de preços que você prefere e clique em Criar. Preços gerais são recomendados no contexto deste codelab.
  2. O app é criado, e você é redirecionado automaticamente para Aplicativos de IA > Apps > codelab > Visão geral do app.
  3. Acesse Repositórios de dados conectados.
  4. Depois de alguns minutos, todos os status dos repositórios de dados conectados devem ser Ativo.

d53ed9d9d1ced955.png

Configurar o widget da Web

  1. Acesse Configurações.
  2. Na guia Interface, defina o Tipo de pesquisa como Pesquisar com acompanhamentos e clique em Salvar e publicar.

af1ca3bd78e1cb4f.png

Testar o app

  1. Navegue até Visualizar. O widget da Web vai aparecer.
  2. No chat, digite Do I have any meetings today? e pressione enter.
  3. No chat, digite Did I receive an email on March 1st 2026? e pressione enter.
  4. No chat, digite Give me the title of the latest Drive file I created e pressione enter.

d276ff8e2b9d0ddf.png

4. Agente personalizado

Com ele, os usuários podem pesquisar dados e realizar ações no Workspace em linguagem natural usando ferramentas e regras personalizadas. Ele depende dos seguintes elementos:

  • Modelo:Gemini.
  • Dados e ações:repositórios de dados da Vertex AI para Google Workspace (Agenda, Gmail, Drive), servidor do Protocolo de Contexto de Modelo (MCP, na sigla em inglês) da Vertex AI para Pesquisa gerenciado pelo Google, função de ferramenta personalizada para enviar mensagens do Google Chat (pela API do Google Chat).
  • Ferramentas de criação de agentes:Kit de Desenvolvimento de Agente (ADK).
  • Host do agente:Vertex AI Agent Engine.
  • Interface:ADK Web.

Revisar conceitos

Kit de Desenvolvimento de Agente (ADK)

O Kit de Desenvolvimento de Agente (ADK) é um conjunto especializado de ferramentas e frameworks projetados para simplificar a criação de agentes autônomos de IA. Ele oferece módulos pré-criados para raciocínio, gerenciamento de memória e integração de ferramentas.

Protocolo de Contexto de Modelo (MCP)

O Protocolo de Contexto de Modelo (MCP) é um padrão aberto criado para permitir a integração perfeita e segura entre aplicativos de IA e várias fontes de dados ou ferramentas por meio de uma interface universal "plug-and-play".

Ferramenta de função

Uma ferramenta de função é uma rotina executável predefinida que um modelo de IA pode acionar para realizar ações específicas ou recuperar dados em tempo real de sistemas externos, estendendo suas capacidades além da simples geração de texto.

ADK Web

A Web do ADK é a interface de desenvolvimento integrada que vem com o SDK do ADK para facilitar o desenvolvimento e a depuração.

Analisar a arquitetura da solução

f14251cca6a19b1f.png

Revisar o código-fonte

agent.py

...
MODEL = "gemini-2.5-flash"

# Access token for authentication
ACCESS_TOKEN = os.environ.get("ACCESS_TOKEN")
if not ACCESS_TOKEN:
    raise ValueError("ACCESS_TOKEN environment variable must be set")

VERTEXAI_SEARCH_TIMEOUT = 15.0

def get_project_id():
    """Fetches the consumer project ID from the environment natively."""
    _, project = google.auth.default()
    if project:
        return project
    raise Exception(f"Failed to resolve GCP Project ID from environment.")

def find_serving_config_path():
    """Dynamically finds the default serving config in the engine."""
    project_id = get_project_id()
    engines = discoveryengine_v1.EngineServiceClient().list_engines(
        parent=f"projects/{project_id}/locations/global/collections/default_collection"
    )
    for engine in engines:
        # engine.name natively contains the numeric Project Number
        return f"{engine.name}/servingConfigs/default_serving_config"
    raise Exception(f"No Discovery Engines found in project {project_id}")

def send_direct_message(email: str, message: str) -> dict:
    """Sends a Google Chat Direct Message (DM) to a specific user by email address."""
    chat_client = chat_v1.ChatServiceClient(
        credentials=Credentials(token=ACCESS_TOKEN)
    )

    # 1. Setup the DM space or find existing one
    person = chat_v1.User(
        name=f"users/{email}",
        type_=chat_v1.User.Type.HUMAN
    )
    membership = chat_v1.Membership(member=person)
    space_req = chat_v1.Space(space_type=chat_v1.Space.SpaceType.DIRECT_MESSAGE)
    setup_request = chat_v1.SetUpSpaceRequest(
        space=space_req,
        memberships=[membership]
    )
    space_response = chat_client.set_up_space(request=setup_request)
    space_name = space_response.name
    
    # 2. Send the message
    msg = chat_v1.Message(text=message)
    message_request = chat_v1.CreateMessageRequest(
        parent=space_name,
        message=msg
    )
    message_response = chat_client.create_message(request=message_request)
    
    return {"status": "success", "message_id": message_response.name, "space": space_name}

vertexai_mcp = McpToolset(
    connection_params=StreamableHTTPConnectionParams(
        url="https://discoveryengine.googleapis.com/mcp",
        timeout=VERTEXAI_SEARCH_TIMEOUT,
        sse_read_timeout=VERTEXAI_SEARCH_TIMEOUT,
        headers={"Authorization": f"Bearer {ACCESS_TOKEN}"}
    ),
    tool_filter=['search']
)

# Answer nicely the following user queries:
#  - Please find my meetings for today, I need their titles and links
#  - What is the latest Drive file I created?
#  - What is the latest Gmail message I received?
#  - Please send the following message to someone@example.com: Hello, this is a test message.

root_agent = LlmAgent(
    model=MODEL,
    name='enterprise_ai',
    instruction=f"""
        You are a helpful assistant that always uses the Vertex AI MCP search tool to answer the user's message, unless the user asks you to send a message to someone.
        If the user asks you to send a message to someone, use the send_direct_message tool to send the message.
        You MUST unconditionally use the Vertex AI MCP search tool to find answer, even if you believe you already know the answer or believe the Vertex AI MCP search tool does not contain the data.
        The Vertex AI MCP search tool accesses the user's data through datastores including Google Drive, Google Calendar, and Gmail.
        Only use the Vertex AI MCP search tool with servingConfig and query parameters, do not use any other parameters.
        Always use the servingConfig {find_serving_config_path()} while using the Vertex AI MCP search tool.
    """,
    tools=[vertexai_mcp, FunctionTool(send_direct_message)]
)

Baixar o código-fonte

  1. Faça o download deste repositório do GitHub.

  1. Em um terminal, abra o diretório solutions/enterprise-ai-agent-local.

Ativar APIs

A solução exige a ativação de outras APIs:

  1. No console do Google Cloud, ative as APIs Vertex AI, Cloud Resource Manager e Google Chat:

60bae4065338c5bf.png

  1. Clique em Menu ☰ > APIs e serviços > APIs e serviços ativados e confirme se a API Vertex AI, a API Cloud Resource Manager e a API Google Chat estão na lista.

A solução exige uma configuração de tela de consentimento:

  1. No console do Google Cloud, clique em Menu ☰ > Plataforma de autenticação do Google > Branding.

  1. Clique em Primeiros passos.
  2. Em Informações do app, defina o Nome do app como Codelab .
  3. Em E-mail para suporte do usuário, escolha um endereço de e-mail para que os usuários possam entrar em contato com você se tiverem dúvidas sobre o consentimento deles.
  4. Clique em Próxima.
  5. Em Público-alvo, selecione Interno.
  6. Clique em Próxima.
  7. Em Informações de contato, insira um Endereço de e-mail para receber notificações sobre mudanças no seu projeto.
  8. Clique em Próxima.
  9. Em Concluir, leia a Política de dados do usuário dos serviços de API do Google e, se concordar, selecione Concordo com a Política de dados do usuário dos serviços de API do Google.
  10. Clique em Continuar e em Criar.

bb53eeb45c51d301.png

  1. A configuração é salva, e você é redirecionado automaticamente para Plataforma de autenticação do Google > Visão geral.

Para saber mais, consulte o guia completo Configurar a permissão OAuth.

Criar credenciais de cliente OAuth

Crie um cliente OAuth de app para computador para autenticar o usuário em um ambiente local:

  1. No console do Google Cloud, clique em Menu ☰ > Plataforma de autenticação do Google > Clientes.

  1. Clique em + Criar cliente.
  2. Em Tipo de aplicativo, selecione App para computador.
  3. Defina o Nome como codelab.
  4. Clique em Criar. A credencial recém-criada aparece.
  5. Clique em Baixar JSON e salve o arquivo como client_secret.json no diretório solutions/enterprise-ai-agent-local.

c1c9bc2f8c14dd6c.png

Ativar o MCP da Vertex AI para Pesquisa

  1. Em um terminal, execute:
gcloud beta services mcp enable discoveryengine.googleapis.com \
     --project=$(gcloud config get-value project)

Configurar o app Chat

  1. No console do Google Cloud, pesquise Google Chat API no campo de pesquisa do Google Cloud, clique em API Google Chat, em Gerenciar e em Configuração.

  1. Defina o Nome do app e a Descrição como Vertex AI.
  2. Defina o URL do avatar como https://developers.google.com/workspace/add-ons/images/quickstart-app-avatar.png.
  3. Desmarque a opção Ativar recursos interativos e clique em Desativar na caixa de diálogo modal que aparece.
  4. Selecione Registrar erros no Logging.
  5. Clique em Salvar.

952e7ebcb945f1b2.png

Executar o agente na Web do ADK

  1. Em um terminal, abra o diretório solutions/enterprise-ai-agent-local e execute:
# 1. Authenticate with all the required scopes
gcloud auth application-default login \
  --client-id-file=client_secret.json \
   --scopes=https://www.googleapis.com/auth/cloud-platform,https://www.googleapis.com/auth/chat.spaces,https://www.googleapis.com/auth/chat.messages

# 2. Configure environment
export ACCESS_TOKEN=$(gcloud auth application-default print-access-token)
export GOOGLE_GENAI_USE_VERTEXAI=1
export GOOGLE_CLOUD_PROJECT=$(gcloud config get-value project)
export GOOGLE_CLOUD_LOCATION=us-central1

# 3. Create and activate a new virtual environment
python3 -m venv .venv
source .venv/bin/activate

# 4. Install poetry and project dependencies
pip install poetry
poetry install

# 5. Start ADK Web
adk web

95fc30883ce3d56f.png

Testar agente

  1. No navegador da Internet, abra o site do ADK.
  2. No chat, digite Please find my meetings for today, I need their titles and links e pressione enter.
  3. O agente responde com uma lista de eventos da Agenda (dependendo da conta do usuário).
  4. No chat, digite Please send a Chat message to someone@example.com with the following text: Hello! e pressione enter.
  5. O agente responde com uma mensagem de confirmação.

145f47f45332e6be.png

293ec4d3e2bb6a0.png

5. Agente como complemento do Google Workspace

Com ele, os usuários podem pesquisar dados do Workspace em linguagem natural no contexto das interfaces dos apps do Workspace. Ele depende dos seguintes elementos:

  • Modelo:Gemini.
  • Dados e ações:repositórios de dados da Vertex AI para Google Workspace (Agenda, Gmail, Drive), servidor do Protocolo de Contexto de Modelo (MCP, na sigla em inglês) da Vertex AI para Pesquisa gerenciado pelo Google, função de ferramenta personalizada para enviar mensagens do Google Chat (pela API do Google Chat).
  • Ferramentas de criação de agentes:Kit de Desenvolvimento de Agente (ADK).
  • Host do agente:Vertex AI Agent Engine.
  • Interface:complemento do Google Workspace para Chat e Gmail (facilmente extensível para Agenda, Drive, Documentos, Planilhas e Apresentações).
  • Complemento do Google Workspace:Apps Script, APIs do Agent Engine da Vertex AI, contextual (mensagem selecionada do Gmail).

Revisar conceitos

Complemento do Google Workspace

Um complemento do Google Workspace é um aplicativo personalizado que estende um ou mais apps do Google Workspace (Gmail, Chat, Agenda, Documentos, Drive, Meet, Planilhas e Apresentações).

Apps Script

O Apps Script é uma plataforma JavaScript baseada na nuvem com tecnologia do Google Drive que permite integrar e automatizar tarefas em vários produtos do Google.

Estrutura de cards do Google Workspace

O framework de card no Google Workspace permite que os desenvolvedores criem interfaces de usuário interativas e avançadas. Ele permite a construção de cards organizados e visualmente atraentes que podem incluir texto, imagens, botões e outros widgets. Esses cards melhoram a experiência do usuário ao fornecer informações estruturadas e permitir ações rápidas diretamente nos aplicativos do Workspace.

Analisar a arquitetura da solução

f2fd048ba298f431.png

Revisar o código-fonte

Agente

agent.py

...
MODEL = "gemini-2.5-flash"

# Client injects a bearer token into the ToolContext state.
# The key pattern is "CLIENT_AUTH_NAME_<random_digits>".
# We dynamically parse this token to authenticate our MCP and API calls.
CLIENT_AUTH_NAME = "enterprise-ai"

VERTEXAI_SEARCH_TIMEOUT = 15.0

def get_project_id():
    """Fetches the consumer project ID from the environment natively."""
    _, project = google.auth.default()
    if project:
        return project
    raise Exception(f"Failed to resolve GCP Project ID from environment.")

def find_serving_config_path():
    """Dynamically finds the default serving config in the engine."""
    project_id = get_project_id()
    engines = discoveryengine_v1.EngineServiceClient().list_engines(
        parent=f"projects/{project_id}/locations/global/collections/default_collection"
    )
    for engine in engines:
        # engine.name natively contains the numeric Project Number
        return f"{engine.name}/servingConfigs/default_serving_config"
    raise Exception(f"No Discovery Engines found in project {project_id}")

def _get_access_token_from_context(tool_context: ToolContext) -> str:
    """Helper method to dynamically parse the intercepted bearer token from the context state."""
    escaped_name = re.escape(CLIENT_AUTH_NAME)
    pattern = re.compile(fr"^{escaped_name}_\d+$")
    # Handle ADK varying state object types (Raw Dict vs ADK State)
    state_dict = tool_context.state.to_dict() if hasattr(tool_context.state, 'to_dict') else tool_context.state
    matching_keys = [k for k in state_dict.keys() if pattern.match(k)]
    if matching_keys:
        return state_dict.get(matching_keys[0])
    raise Exception(f"No bearer token found in ToolContext state matching pattern {pattern.pattern}")

def auth_header_provider(tool_context: ToolContext) -> dict[str, str]:
    token = _get_access_token_from_context(tool_context)
    return {"Authorization": f"Bearer {token}"}

def send_direct_message(email: str, message: str, tool_context: ToolContext) -> dict:
    """Sends a Google Chat Direct Message (DM) to a specific user by email address."""
    chat_client = chat_v1.ChatServiceClient(
        credentials=Credentials(token=_get_access_token_from_context(tool_context))
    )

    # 1. Setup the DM space or find existing one
    person = chat_v1.User(
        name=f"users/{email}",
        type_=chat_v1.User.Type.HUMAN
    )
    membership = chat_v1.Membership(member=person)
    space_req = chat_v1.Space(space_type=chat_v1.Space.SpaceType.DIRECT_MESSAGE)
    setup_request = chat_v1.SetUpSpaceRequest(
        space=space_req,
        memberships=[membership]
    )
    space_response = chat_client.set_up_space(request=setup_request)
    space_name = space_response.name
    
    # 2. Send the message
    msg = chat_v1.Message(text=message)
    message_request = chat_v1.CreateMessageRequest(
        parent=space_name,
        message=msg
    )
    message_response = chat_client.create_message(request=message_request)
    
    return {"status": "success", "message_id": message_response.name, "space": space_name}

vertexai_mcp = McpToolset(
    connection_params=StreamableHTTPConnectionParams(
        url="https://discoveryengine.googleapis.com/mcp",
        timeout=VERTEXAI_SEARCH_TIMEOUT,
        sse_read_timeout=VERTEXAI_SEARCH_TIMEOUT
    ),
    tool_filter=['search'],
    # The auth_header_provider dynamically injects the bearer token from the ToolContext
    # into the MCP call for authentication.
    header_provider=auth_header_provider
)

# Answer nicely the following user queries:
#  - Please find my meetings for today, I need their titles and links
#  - What is the latest Drive file I created?
#  - What is the latest Gmail message I received?
#  - Please send the following message to someone@example.com: Hello, this is a test message.

root_agent = LlmAgent(
    model=MODEL,
    name='enterprise_ai',
    instruction=f"""
        You are a helpful assistant that always uses the Vertex AI MCP search tool to answer the user's message, unless the user asks you to send a message to someone.
        If the user asks you to send a message to someone, use the send_direct_message tool to send the message.
        You MUST unconditionally use the Vertex AI MCP search tool to find answer, even if you believe you already know the answer or believe the Vertex AI MCP search tool does not contain the data.
        The Vertex AI MCP search tool accesses the user's data through datastores including Google Drive, Google Calendar, and Gmail.
        Only use the Vertex AI MCP search tool with servingConfig and query parameters, do not use any other parameters.
        Always use the servingConfig {find_serving_config_path()} while using the Vertex AI MCP search tool.
    """,
    tools=[vertexai_mcp, FunctionTool(send_direct_message)]
)

Cliente

appsscript.json

...
"addOns": {
    "common": {
      "name": "Vertex AI",
      "logoUrl": "https://developers.google.com/workspace/add-ons/images/quickstart-app-avatar.png"
    },
    "chat": {},
    "gmail": {
      "contextualTriggers": [
        {
          "unconditional": {},
          "onTriggerFunction": "onAddonEvent"
        }
      ]
    }
  },
  "oauthScopes": [
   "https://www.googleapis.com/auth/script.external_request",
   "https://www.googleapis.com/auth/cloud-platform",
   "https://www.googleapis.com/auth/gmail.addons.execute",
   "https://www.googleapis.com/auth/gmail.addons.current.message.readonly"
 ]
...

Chat.gs

...
// Service that handles Google Chat operations.

// Handle incoming Google Chat message events, actions will be taken via Google Chat API calls
function onMessage(event) {
  if (isInDebugMode()) {
    console.log(`MESSAGE event received (Chat): ${JSON.stringify(event)}`);
  }
  // Extract data from the event.
  const chatEvent = event.chat;
  setChatConfig(chatEvent.messagePayload.space.name);

  // Request AI agent to answer the message
  requestAgent(chatEvent.messagePayload.message);
  // Respond with an empty response to the Google Chat platform to acknowledge execution
  return null; 
}

// --- Utility functions ---

// The Chat direct message (DM) space associated with the user
const SPACE_NAME_PROPERTY = "DM_SPACE_NAME"

// Sets the Chat DM space name for subsequent operations.
function setChatConfig(spaceName) {
  const userProperties = PropertiesService.getUserProperties();
  userProperties.setProperty(SPACE_NAME_PROPERTY, spaceName);
  console.log(`Space is set to ${spaceName}`);
}

// Retrieved the Chat DM space name to sent messages to.
function getConfiguredChat() {
  const userProperties = PropertiesService.getUserProperties();
  return userProperties.getProperty(SPACE_NAME_PROPERTY);
}

// Finds the Chat DM space name between the Chat app and the given user.
function findChatAppDm(userName) {
  return Chat.Spaces.findDirectMessage(
    { 'name': userName },
    {'Authorization': `Bearer ${getAddonCredentials().getAccessToken()}`}
  ).name;
}

// Creates a Chat message in the configured space.
function createMessage(message) {
  const spaceName = getConfiguredChat();
  console.log(`Creating message in space ${spaceName}...`);
  return Chat.Spaces.Messages.create(
    message,
    spaceName,
    {},
    {'Authorization': `Bearer ${getAddonCredentials().getAccessToken()}`}
  ).name;
}

Sidebar.gs

...
// Service that handles Gmail operations.

// Triggered when the user opens the Gmail Add-on or selects an email.
function onAddonEvent(event) {
  // If this was triggered by a button click, handle it
  if (event.parameters && event.parameters.action === 'send') {
    return handleSendMessage(event);
  }

  // Otherwise, just render the default initial sidebar
  return createSidebarCard();
}

// Creates the standard Gmail sidebar card consisting of a text input and send button.
// Optionally includes an answer section if a response was generated.
function createSidebarCard(optionalAnswerSection) {
  const card = CardService.newCardBuilder();
  const actionSection = CardService.newCardSection();

  // Create text input for the user's message
  const messageInput = CardService.newTextInput()
    .setFieldName("message")
    .setTitle("Message")
    .setMultiline(true);

  // Create action for sending the message
  const sendAction = CardService.newAction()
    .setFunctionName('onAddonEvent')
    .setParameters({ 'action': 'send' });

  const sendButton = CardService.newTextButton()
    .setText("Send message")
    .setTextButtonStyle(CardService.TextButtonStyle.FILLED)
    .setOnClickAction(sendAction);

  actionSection.addWidget(messageInput);
  actionSection.addWidget(CardService.newButtonSet().addButton(sendButton));

  card.addSection(actionSection);

  // Attach the response at the bottom if we have one
  if (optionalAnswerSection) {
    card.addSection(optionalAnswerSection);
  }

  return card.build();
}

// Handles clicks from the Send message button.
function handleSendMessage(event) {
  const commonEventObject = event.commonEventObject || {};
  const formInputs = commonEventObject.formInputs || {};
  const messageInput = formInputs.message;

  let userMessage = "";
  if (messageInput && messageInput.stringInputs && messageInput.stringInputs.value.length > 0) {
    userMessage = messageInput.stringInputs.value[0];
  }

  if (!userMessage || userMessage.trim().length === 0) {
    return CardService.newActionResponseBuilder()
      .setNotification(CardService.newNotification().setText("Please enter a message."))
      .build();
  }

  let finalQueryText = `USER MESSAGE TO ANSWER: ${userMessage}`;

  // If we have an email selected in Gmail, append its content as context
  if (event.gmail && event.gmail.messageId) {
    try {
      GmailApp.setCurrentMessageAccessToken(event.gmail.accessToken);
      const message = GmailApp.getMessageById(event.gmail.messageId);

      const subject = message.getSubject();
      const bodyText = message.getPlainBody() || message.getBody();

      finalQueryText += `\n\nEMAIL THE USER HAS OPENED ON SCREEN:\nSubject: ${subject}\nBody:\n---\n${bodyText}\n---`;
    } catch (e) {
      console.error("Could not fetch Gmail context: " + e);
      // Invalidate the token explicitly so the next prompt requests the missing scopes
      ScriptApp.invalidateAuth();

      CardService.newAuthorizationException()
        .setResourceDisplayName("Enterprise AI")
        .setAuthorizationUrl(ScriptApp.getAuthorizationUrl())
        .throwException();
    }
  }

  try {
    const response = queryAgent({ text: finalQueryText });

    // We leverage the 'showdown' library to parse the LLM's Markdown output into HTML
    // We also substitute markdown listings with arrows and adjust newlines for clearer rendering in the sidebar
    let displayedText = substituteListingsFromMarkdown(response.text);
    displayedText = new showdown.Converter().makeHtml(displayedText).replace(/\n/g, '\n\n');

    const textParagraph = CardService.newTextParagraph();
    textParagraph.setText(displayedText);

    const answerSection = CardService.newCardSection()
      .addWidget(textParagraph);

    const updatedCard = createSidebarCard(answerSection);

    return CardService.newActionResponseBuilder()
      .setNavigation(CardService.newNavigation().updateCard(updatedCard))
      .build();

  } catch (err) {
    return CardService.newActionResponseBuilder()
      .setNotification(CardService.newNotification().setText("Error fetching response: " + err.message))
      .build();
  }
}
...

AgentHandler.gs

...
// Service that handles Vertex AI Agent operations.

// Submits a query to the AI agent and returns the response string synchronously
function queryAgent(input) {
 let systemPrompt = "SYSTEM PROMPT START Do not respond with tables but use bullet points instead." +
   " Do not ask the user follow-up questions or converse with them as history is not kept in this interface." +
   " SYSTEM PROMPT END\n\n";

 const requestPayload = {
   "class_method": "async_stream_query",
   "input": {
     "user_id": "vertex_ai_add_on",
     "message": { "role": "user", "parts": [{ "text": systemPrompt + input.text }] },
     "state_delta": {
       "enterprise-ai_999": `${ScriptApp.getOAuthToken()}`
     }
   }
 };

 const responseContentText = UrlFetchApp.fetch(
   `https://${getLocation()}-aiplatform.googleapis.com/v1/${getReasoningEngine()}:streamQuery?alt=sse`,
   {
     method: 'post',
     headers: { 'Authorization': `Bearer ${ScriptApp.getOAuthToken()}` },
     contentType: 'application/json',
     payload: JSON.stringify(requestPayload),
     muteHttpExceptions: true
   }
 ).getContentText();
  if (isInDebugMode()) {
   console.log(`Response: ${responseContentText}`);
 }

 const events = responseContentText.split('\n').map(s => s.replace(/^data:\s*/, '')).filter(s => s.trim().length > 0);
 console.log(`Received ${events.length} agent events.`);

 let author = "default";
 let answerText = "";
 for (const eventJson of events) {
   if (isInDebugMode()) {
     console.log("Event: " + eventJson);
   }
   const event = JSON.parse(eventJson);

   // Retrieve the agent responsible for generating the content
   author = event.author;
  
   // Ignore events that are not useful for the end-user
   if (!event.content) {
     console.log(`${author}: internal event`);
     continue;
   }

   // Handle text answers
   const parts = event.content.parts || [];
   const textPart = parts.find(p => p.text);
   if (textPart) {
     answerText += textPart.text;
   }
 }
 return { author: author, text: answerText };
}
...

Implantar o agente no Vertex AI Agent Engine

  1. Em um terminal, abra o diretório solutions/enterprise-ai-agent das fontes baixadas nas etapas anteriores e execute:
# 1. Create and activate a new virtual environment
deactivate
python3 -m venv .venv
source .venv/bin/activate

# 2. Install poetry and project dependencies
pip install poetry
poetry install

# 3. Deploy the agent
adk deploy agent_engine \
  --project=$(gcloud config get-value project) \
  --region=us-central1 \
  --display_name="Enterprise AI" \
  enterprise_ai

eafd2f9c4fbf305.png

  1. Quando a linha Deploying to agent engine... aparecer nos registros, abra um novo terminal e execute o comando a seguir para adicionar as permissões necessárias ao agente de serviço do Reasoning Engine da Vertex AI:
# 1. Get the current Project ID
PROJECT_ID=$(gcloud config get-value project)

# 2. Extract the Project Number for that ID
PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format='value(projectNumber)')

# 3. Construct the Service Account name
SERVICE_ACCOUNT="service-${PROJECT_NUMBER}@gcp-sa-aiplatform-re.iam.gserviceaccount.com"

# 4. Apply the IAM policy binding
gcloud projects add-iam-policy-binding $PROJECT_ID \
     --member="serviceAccount:$SERVICE_ACCOUNT" \
     --role="roles/discoveryengine.viewer"
  1. Aguarde a conclusão do comando adk deploy e copie o nome do recurso do agente recém-implantado da saída do comando em verde.

d098fe1347d6581b.png

Iniciar conta de serviço

No console do Google Cloud, siga estas etapas:

  1. Clique em Menu ☰ > IAM e administrador > Contas de serviço > + Criar conta de serviço.

  1. Defina o Nome da conta de serviço como vertexai-add-on.

46be0eb53f416c59.png

  1. Clique em Concluído. O sistema vai redirecionar você para a página Contas de serviço, onde é possível conferir a conta de serviço que criou.

f002fef61c71ed8.png

  1. Selecione a conta de serviço recém-criada e clique na guia Chaves.
  2. Clique em Adicionar chave e em Criar nova chave.
  3. Selecione JSON e clique em Criar.

7b140535d9e1af44.png

  1. A caixa de diálogo é fechada, e o par de chaves pública/privada recém-criado é automaticamente transferido por download para o ambiente local como um arquivo JSON.

Criar e configurar um projeto do Apps Script

  1. Clique no botão a seguir para abrir o projeto do Apps Script do complemento de IA empresarial:

  1. Clique em Visão geral > Fazer uma cópia.
  2. No projeto do Apps Script, clique em Configurações do projeto > Editar propriedades do script > Adicionar propriedade do script.
  3. Defina REASONING_ENGINE_RESOURCE_NAME como o nome do recurso do agente da Vertex AI copiado nas etapas anteriores. Ele tem o seguinte formato:
projects/<PROJECT_NUMBER>/locations/us-central1/reasoningEngines/<AGENT_ID>
  1. Defina APP_SERVICE_ACCOUNT_KEY como a chave JSON do arquivo da conta de serviço baixado nas etapas anteriores.
  2. Clique em Salvar propriedades do script.

Implantar no Gmail e no Chat

No seu projeto do Apps Script, siga estas etapas:

  1. Clique em Implantar > Testar implantações e em Instalar. Agora ele está disponível no Gmail.
  2. Clique em Copiar em ID da implantação principal.

b0cba69eef271850.png

No console do Google Cloud, siga estas etapas:

  1. Pesquise Google Chat API no campo de pesquisa do Google Cloud, clique em API Google Chat, em Gerenciar e em Configuração.

  1. Selecione Ativar recursos interativos.
  2. Desmarque a opção Participar de espaços e conversas em grupo.
  3. Em Configurações de conexão, selecione Apps Script.
  4. Defina o ID da implantação como o ID da implantação principal copiado nas etapas anteriores.
  5. Em Visibilidade, selecione Disponibilize o app de chat para pessoas e grupos específicos no seu domínio do Workspace e digite seu endereço de e-mail.
  6. Clique em Salvar.

6ea187ccb90a0e49.png

Testar o complemento

Abra o Google Chat em uma nova guia e siga estas etapas:

  1. Abra um espaço de mensagem direta com o app Chat Vertex AI.

495632314dec5a5d.png

  1. Clique em Configurar e siga o fluxo de autenticação.
  2. Digite What are my meetings for today? e pressione enter. O app de chat da Vertex AI vai responder com os resultados.

172da43f310a0579.png

Abra o Gmail em uma nova guia e siga estas etapas:

  1. Envie um e-mail para você mesmo com o Assunto definido como We need to talk e o Corpo definido como Are you available today between 8 and 9 AM?.
  2. Abra o e-mail que você acabou de receber.
  3. Abra a barra lateral do complemento Vertex AI.
  4. Defina a Mensagem como Do I have any meeting conflicts?.
  5. Clique em Enviar mensagem.
  6. A resposta aparece depois do botão.

840b494aa5eaa1ef.png

6. Limpar

Excluir projeto do Google Cloud

Para evitar cobranças na conta do Google Cloud pelos recursos usados neste codelab, é recomendável excluir o projeto do Google Cloud.

No console do Google Cloud, siga estas etapas:

  1. Clique em Menu ☰ > IAM e administrador > Configurações.

  1. Clique em Encerrar.
  2. Digite o ID do projeto.
  3. Clique em Encerrar mesmo assim.

3b9492d97f771b2c.png

7. Parabéns

Parabéns! Você criou soluções que aproveitam o poder de aproximar a Vertex AI e o Google Workspace para os trabalhadores.

A seguir

Mostramos apenas os casos de uso mais típicos neste codelab, mas existem muitas áreas de expansão que você pode querer considerar nas suas soluções, como estas:

  • Use ferramentas de desenvolvedor com tecnologia de IA, como a CLI do Gemini e a Antigravity.
  • Integração com outros frameworks e ferramentas de agentes, como MCPs personalizados, chamadas de função personalizadas e UIs generativas.
  • Integrar com outros modelos de IA, incluindo os personalizados, hospedados em plataformas dedicadas, como a Vertex AI.
  • Integração com outros agentes hospedados em plataformas dedicadas, como o Dialogflow, ou por terceiros via Cloud Marketplace.
  • Publique agentes no Cloud Marketplace para capacitar equipes, organizações ou usuários públicos.

Saiba mais

Existem muitos recursos disponíveis para desenvolvedores, como vídeos do YouTube, sites de documentação, exemplos de código e tutoriais: