De protótipos a agentes com o ADK

1. Visão geral

Onde começa a criação com IA hoje? Para a maioria das pessoas, tudo começa com uma pergunta simples: "O modelo pode ajudar a resolver o problema em que estou pensando?". É exatamente aí que entra o Google AI Studio. É um lugar onde você pode criar protótipos rapidamente. Quero reformar minha cozinha e acho que o Gemini pode ajudar, mas sou engenheiro, não um empreiteiro geral. Não sei nem o que pedir. Há muita coisa a considerar: regulamentações, acessórios etc. Então, vamos dividir isso e pedir para o Gemini gerar um comando superdetalhado para nós, depois um plano de reforma completo e também visualizar a remodelação. Mas espere. Como posso ajudar as empresas a crescer a partir de agora? ENTREM AGENTES!!!

Um agente é um programa autônomo que conversa com um modelo de IA para realizar uma operação baseada em metas usando as ferramentas e o contexto disponíveis. Ele também é capaz de tomar decisões autônomas com base na verdade.

Kit de Desenvolvimento de Agente (ADK)

O Kit de Desenvolvimento de Agente (ADK) é um framework flexível e modular para desenvolver e implantar agentes de IA. O ADK permite criar aplicativos sofisticados ao compor várias instâncias de agentes distintos em um sistema multiagente (MAS, na sigla em inglês).

No ADK, um sistema multiagente é um aplicativo em que diferentes agentes, geralmente formando uma hierarquia, colaboram ou se coordenam para alcançar um objetivo maior. Estruturar seu aplicativo dessa forma oferece vantagens significativas, incluindo modularidade, especialização, reutilização, capacidade de manutenção aprimoradas e a capacidade de definir fluxos de controle estruturados usando agentes de fluxo de trabalho dedicados.

O que você vai criar

Tudo pronto para passar do nosso PROMPT de protótipo para "Como criar um agente"? Vamos criar um agente para ajudar a gerar o documento de proposta do projeto de reforma da cozinha. Neste laboratório, você vai:

  1. Criar um agente simples para gerar um documento de proposta de reforma com o ADK
  2. Armazenar o documento de proposta de reforma gerado em um bucket do Cloud Storage
  3. Testar o agente no Cloud Shell e na saída da Web do agente

Requisitos

  • Use um navegador, como o Chrome ou o Firefox.
  • Ter um projeto do Google Cloud com o faturamento ativado.

2. Antes de começar

Criar um projeto

  1. No console do Google Cloud, na página de seletor de projetos, selecione ou crie um projeto 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 .
  3. Se você está lendo este artigo e quer receber alguns créditos para começar a usar o Google Cloud e o ADK, use este link para resgatar créditos.
  4. Siga as instruçõesaqui para resgatar. Esse link é válido apenas até 15 de julho de 2025 para resgate.
  5. Ative o Cloud Shell clicando neste link. É possível alternar entre o terminal do Cloud Shell (para executar comandos da nuvem) e o editor (para criar projetos) clicando no botão correspondente no Cloud Shell.
  6. Depois de se conectar ao Cloud Shell, verifique se sua conta já está autenticada e se o projeto está configurado com seu ID do projeto usando o seguinte comando:
gcloud auth list
  1. Execute o comando a seguir no Cloud Shell para confirmar se o comando gcloud sabe sobre seu projeto.
gcloud config list project
  1. Se o projeto não estiver definido, use este comando:
gcloud config set project <YOUR_PROJECT_ID>
  1. Verifique se você tem o Python 3.9 ou uma versão mais recente.

Consulte a documentação para ver outros comandos e usos do gcloud.

3. Protótipo

Acesse o Google AI Studio. Comece a digitar seu comando. Este é meu comando:

I want to renovate my kitchen, basically just remodel it. I don't know where to start. So I want to use Gemini to generate a plan. For that I need a good prompt. Give me a short yet detailed prompt that I can use.

Ajuste e configure os parâmetros à direita para receber a resposta ideal.

Com base nessa descrição simples, o Gemini criou um comando incrivelmente detalhado para iniciar minha reforma. Na prática, estamos usando o Gemini para receber respostas ainda melhores do AI Studio e dos nossos modelos. Você também pode selecionar modelos diferentes para usar, com base no seu caso de uso.

Escolhemos o Gemini 2.5 Pro. Esse é um modelo de pensamento, o que significa que recebemos ainda mais tokens de saída, neste caso, até 65 mil tokens, para análises longas e documentos detalhados. A caixa de raciocínio do Gemini aparece quando você ativa o Gemini 2.5 Pro, que tem recursos de raciocínio nativos e pode receber solicitações de contexto longo.

Confira o snippet da resposta abaixo:

4e4361663df80964.png

O AI Studio analisou meus dados e produziu todos esses itens, como armários, bancadas, revestimento, piso, pia, coesão, paleta de cores e seleção de materiais. O Gemini está até citando fontes!

Agora tente ver a ideia ganhar vida com um comando diferente.

  1. Copie e cole este comando no editor de comandos:
Add flat and circular light accessories above the island area for my current kitchen in the attached image.
  1. Anexe uma imagem da sua cozinha atual ou use a imagem de exemplo.
  2. Mude o modelo para "Geração de imagens de prévia do Gemini 2.0 Flash" para ter acesso à geração de imagens.

Recebi esta saída:

fb33e7b1f6560a0c.png

Esse é o potencial do Gemini!

Desde entender vídeos até gerar imagens nativas e embasar informações reais com a Pesquisa Google, há coisas que só podem ser criadas com o Gemini.

No AI Studio, é possível pegar esse protótipo, extrair a chave de API e dimensioná-lo para um aplicativo de agente completo usando o poder do ADK da Vertex AI.

4. Configuração do ADK

Agora, vamos para o terminal do Cloud Shell que ativamos na seção "Antes de começar":

  1. Criar e ativar o ambiente virtual (recomendado)

No terminal do Cloud Shell, crie um ambiente virtual:

python -m venv .venv

Ative o ambiente virtual:

source .venv/bin/activate
  1. Instale o ADK
pip install google-adk

5. Estrutura do projeto

  1. No terminal do Cloud Shell, crie um diretório raiz para seus apps generativos no local desejado do projeto:
mkdir agentic-apps
  1. No diretório principal, crie uma pasta específica para o projeto atual:
mkdir renovation-agent
  1. Acesse o editor do Cloud Shell e crie a seguinte estrutura de projeto criando os arquivos (vazios para começar):
renovation-agent/
        __init__.py
        agent.py
        requirements.txt
        .env

6. Código-fonte

  1. Acesse "init.py" e atualize com o seguinte conteúdo:
from . import agent
  1. Acesse agent.py e atualize o arquivo com o seguinte conteúdo do caminho abaixo:

Em agent.py, importamos as dependências necessárias, recuperamos os parâmetros de configuração do arquivo .env e definimos o root_agent, que gera um documento de proposta e o armazena em um bucket do Cloud Storage. Para fazer a etapa do Cloud Storage, usamos uma ferramenta chamada store_pdf.

OBSERVAÇÃO: no momento, o PDF NÃO ESTÁ FORMATADO! Com base no PR da comunidade de desenvolvimento, o snippet a seguir foi incluído aqui [não testado]. Fique à vontade para acomodar isso no método store_pdf:

doc = SimpleDocTemplate(
        pdf_buffer,
        pagesize=letter,
        rightMargin=0.75 * inch,
        leftMargin=0.75 * inch,
        topMargin=0.75 * inch,
        bottomMargin=0.75 * inch
    )

    styles = getSampleStyleSheet()
    story = []

    # --- CUSTOM STYLES FOR HEADERS ---
    # Define a new style for section headers
    styles.add(ParagraphStyle(name='SectionHeader',
                              parent=styles['Normal'],
                              fontName='Helvetica-Bold', # Make it bolder
                              fontSize=14,               # Make it slightly larger
                              leading=16,                # Line spacing
                              spaceAfter=0.15 * inch,    # Space after the header
                              spaceBefore=0.25 * inch,   # Space before the header
                              textColor=black            # Ensure color is bright/black (default is usually black, but explicit is good)
                             ))

    # Define a style for the main document title
    styles.add(ParagraphStyle(name='DocumentTitle',
                              parent=styles['Normal'],
                              fontName='Helvetica-Bold',
                              fontSize=20,
                              leading=24,
                              spaceAfter=0.25 * inch,
                              alignment=TA_CENTER, # Center align the title
                              textColor=black
                             ))
    # ---------------------------------

    paragraphs_raw = pdf_text.split('\n\n')

    # Heuristic for the garbled line issue (as before, temporary)
    if paragraphs_raw and len(paragraphs_raw[-1]) < 50 and any(char in paragraphs_raw[-1] for char in ['io', 'og', 'al', 'op']):
         logger.warning("Detected potentially garbled last paragraph. Attempting to trim/omit.")
         paragraphs_raw[-1] = "11. Entire Agreement:\nThis proposal constitutes the entire agreement between the parties and supersedes all prior discussions and agreements."


    for i, para_text in enumerate(paragraphs_raw):
        para_text = para_text.strip()
        if not para_text:
            continue

        # Special handling for the main document title (PROPOSAL DOCUMENT)
        if i == 0 and "PROPOSAL DOCUMENT" in para_text.upper():
            p = Paragraph("PROPOSAL DOCUMENT", styles['DocumentTitle'])
            story.append(p)
            story.append(Spacer(1, 0.15 * inch)) # Add space after the title
            # Skip the rest of this initial block if it's just the title
            remaining_text_lines = para_text.splitlines()[1:]
            if remaining_text_lines:
                formatted_text = "<br/>".join(remaining_text_lines)
                p = Paragraph(formatted_text, styles['Normal'])
                story.append(p)
                story.append(Spacer(1, 0.1 * inch))
            continue # Move to the next paragraph

        # Check if the paragraph looks like a section header (e.g., starts with a number and dot or just bold text)
        # This is a heuristic and might need fine-tuning based on actual proposal content variability.
        is_section_header = False
        # Check for numbered sections (e.g., "1. Scope of Work:")
        if para_text.startswith(('1.', '2.', '3.', '4.', '5.', '6.', '7.', '8.', '9.', '10.', '11.')):
            is_section_header = True
        # Check for Exhibit headers (e.g., "Exhibit A: Cabinet Design") or Roman numeral headings
        elif para_text.startswith(('Exhibit ', 'I.', 'II.', 'III.', 'IV.', 'V.', 'VI.', 'VII.')):
            is_section_header = True
        # Check for specific known headers
        elif para_text.strip().upper() in ["IN WITNESS WHEREOF,", "EXHIBITS:"]:
            is_section_header = True


        if is_section_header:
            p = Paragraph(para_text, styles['SectionHeader'])
            story.append(p)
            # No additional Spacer here, as SectionHeader style has spaceAfter
        else:
            formatted_text = para_text.replace('\n', '<br/>')
            p = Paragraph(formatted_text, styles['Normal'])
            story.append(p)
            story.append(Spacer(1, 0.1 * inch)) # Standard space after body paragraphs

    doc.build(story)

    pdf_buffer.seek(0)

    # Upload the PDF to GCS
    storage_client = storage.Client()
    bucket = storage_client.bucket(STORAGE_BUCKET)
    blob = bucket.blob(PROPOSAL_DOCUMENT_FILE_NAME)

    blob.upload_from_file(pdf_buffer, content_type="application/pdf")

    logger.info(f"Successfully uploaded PDF to gs://{STORAGE_BUCKET}/{PROPOSAL_DOCUMENT_FILE_NAME}")

except Exception as e:
    logger.error(f"Error writing text to PDF and uploading: {e}")
    raise
finally:
    if 'pdf_buffer' in locals():
        pdf_buffer.close()
return "Successfully uploaded PDF to GCS!!"
  1. Verifique se você tem o bucket do Cloud Storage

Isso é para armazenar o documento de proposta gerado pelo agente. Crie e provisione o acesso para que o sistema agêntico criado com a Vertex AI possa acessá-lo. Confira como fazer isso:

https://cloud.google.com/storage/docs/creating-buckets#console

Nomeie o bucket como "next-demo-store". Se você der outro nome, atualize o valor de STORAGE_BUCKET no arquivo .env (na etapa "Configuração de variáveis de ambiente").

  1. Para configurar o acesso ao bucket, acesse o console do Cloud Storage e seu bucket de armazenamento. No nosso caso, o nome do bucket é "next-demo-storage": https://console.cloud.google.com/storage/browser/next-demo-storage.

Navegue até "Permissões" -> "Ver principais" -> "Permitir acesso". Selecione "allUsers" como principais e "Usuário de objetos do Storage" como papel.

Make sure to not enable "prevent public access". Since this is a demo/study application we are going with a public bucket. Remember to configure permission settings appropriately when you are building your application.
  1. Criar lista de dependências

Liste todas as dependências em requirements.txt. Você pode copiar isso do repositório.

Explicação do código-fonte do sistema de um único agente

O arquivo agent.py define a estrutura e o comportamento do nosso sistema multiagente de reforma da cozinha usando o Kit de Desenvolvimento de Agente (ADK). Vamos entender melhor cada componente:

Definição do agente

Agente raiz (Orchestrator): proposal_agent

O root_agent atua como o orquestrador desse sistema de agente único. Ele recebe a solicitação inicial de reforma e determina quais ferramentas invocar com base nas necessidades da solicitação.

Em seguida, o root_agent coleta as respostas das ferramentas e as combina para fornecer uma resposta abrangente ao usuário. Neste caso, temos apenas uma ferramenta, "store_pdf".

7. Fluxo de dados e conceitos principais

O usuário inicia uma solicitação pela interface do ADK (terminal ou interface da Web).

  1. A solicitação é recebida pelo root_agent.
  2. O root_agent analisa a solicitação e a encaminha para a ferramenta conforme e quando necessário.
  3. A ferramenta "store_pdf" foi projetada para gravar o conteúdo de texto renovado em um arquivo PDF e fazer upload dele no Google Cloud Storage.
  4. Em seguida, isso retorna a resposta para o root_agent.
  5. O root_agent combina as respostas e fornece uma saída final ao usuário.

LLMs (modelos de linguagem grandes)

Os agentes dependem muito dos LLMs para gerar texto, responder a perguntas e realizar tarefas de raciocínio. Os LLMs são os "cérebros" por trás da capacidade dos agentes de entender e responder às solicitações dos usuários. Estamos usando o Gemini 2.5 neste aplicativo.

Google Cloud Storage

Usado para armazenar os documentos de proposta de reforma gerados. Você precisa criar um bucket e conceder as permissões necessárias para que os agentes acessem o bucket.

Cloud Run (opcional)

O OrderingAgent usa uma função do Cloud Run para interagir com o AlloyDB. O Cloud Run oferece um ambiente sem servidor para executar código em resposta a solicitações HTTP.

AlloyDB

Se você estiver usando o OrderingAgent, precisará configurar um banco de dados do AlloyDB para armazenar informações de pedidos.

Arquivo.env

O arquivo .env armazena informações sensíveis, como chaves de API, credenciais de banco de dados e nomes de buckets. É fundamental manter esse arquivo seguro e não confirmá-lo no repositório. Ele também armazena configurações para os agentes e seu projeto do Google Cloud. Normalmente, o root_agent ou as funções de suporte leem valores desse arquivo. Verifique se todas as variáveis necessárias estão definidas corretamente no arquivo .env. Isso inclui o nome do bucket do Cloud Storage

8. Configuração do modelo

A capacidade do seu agente de entender solicitações do usuário e gerar respostas é alimentada por um modelo de linguagem grande (LLM). Seu agente precisa fazer chamadas seguras para esse serviço de LLM externo, o que exige credenciais de autenticação. Sem uma autenticação válida, o serviço de LLM vai negar as solicitações do agente, e ele não vai funcionar.

  1. Receba uma chave de API do Google AI Studio.
  2. Na próxima etapa, em que você configura o arquivo .env, substitua <<your API KEY>> pelo valor real da sua chave de API.

9. Configuração de variáveis de ambiente

  1. Configure os valores dos parâmetros no arquivo .env do modelo neste repositório. No meu caso, o .env tem estas variáveis:
GOOGLE_GENAI_USE_VERTEXAI=FALSE
GOOGLE_API_KEY=<<your API KEY>>
GOOGLE_CLOUD_LOCATION = us-central1 <<or your region>>
GOOGLE_CLOUD_PROJECT = <<your project id>>
PROJECT_ID = <<your project id>>
GOOGLE_CLOUD_REGION=us-central1 <<or your region>>
STORAGE_BUCKET = next-demo-store <<or your storage bucket name>>

Substitua os marcadores pelos seus valores.

10. Executar o agente

  1. Usando o terminal, navegue até o diretório pai do projeto do agente:
cd agentic-apps/renovation-agent
  1. Instale todas as dependências
pip install -r requirements.txt
  1. Execute o comando a seguir no terminal do Cloud Shell para executar o agente:
adk run .
  1. Execute o seguinte comando para executar em uma interface da Web provisionada pelo ADK:

Observação: execute esse comando FORA da pasta do projeto do agente. Saia dela e execute o comando:

adk web
  1. Teste com os seguintes comandos:
user>> 

Hello. Generate Proposal Document for the kitchen remodel requirement in a proper format that applies to a renovation contract. Remember this text will eventually be stored as a pdf file so make sure to have the formatting appropriate. I have no other specification.

11. Resultado

Para o comando adk run . result is as follows"

2703603a907329ae.png

ae56b38cc6da9afe.png

91452a4de933a75b.png

Você pode validar se o documento de proposta de reforma foi criado no bucket do Cloud Storage.

12. Implantar no Cloud Run

  1. Crie um arquivo chamado Dockerfile na pasta raiz do projeto:
cd agentic-apps/renovation-agent
  1. Copie o conteúdo do repositório do GitHub.
https://github.com/AbiramiSukumaran/adk-renovation-single-agent/blob/main/Dockerfile

neste arquivo Dockerfile.

  1. Implante no Cloud Run usando o seguinte comando:
adk deploy cloud_run --project=abis-345004 --region=us-central1 --service_name=renovation-agent --app_name=renovation-app --with_ui .

É isso. Depois da implantação, o endpoint vai aparecer no terminal e estará pronto para uso.

13. Limpar

Para evitar cobranças na sua conta do Google Cloud pelos recursos usados nesta postagem, siga estas etapas:

  1. No console do Google Cloud, acesse a página Gerenciar recursos.
  2. Na lista de projetos, selecione o projeto que você quer excluir e clique em Excluir.
  3. Na caixa de diálogo, digite o ID do projeto e clique em Encerrar para excluí-lo.

14. Parabéns

Parabéns! Você criou e interagiu com seu app multiagente usando o ADK. O sistema multiagente foi projetado para simplificar o processo de reforma da cozinha, automatizando tarefas como geração de propostas, verificação de permissões e rastreamento do status do pedido. Cada agente tem uma função específica, e o root_agent coordena as atividades deles para oferecer uma solução abrangente. O sistema usa LLMs, serviços do Google Cloud e APIs externas para oferecer sua funcionalidade. Aqui está um link para a documentação do produto.