A Google colocou o Gemini 3.7 Flash em disponibilidade geral (GA) a 13 de agosto de 2026, apenas três semanas depois do Gemini 3.6 Flash. O ritmo de lançamentos da Google acelerou tanto que a maior parte das equipas de engenharia nem chega a testar um modelo em profundidade antes do seguinte aparecer. Isso é um problema quando o modelo em causa passou a controlar agentes que executam código, chamam ferramentas externas e tomam decisões autónomas em produção.

Este tutorial mostra como configurar a Gemini API do zero e, mais importante, como testar essa configuração antes de a expor a utilizadores reais. Vais criar a chave de acesso, construir um agente simples com function calling e depois atacá-lo com três ferramentas open source de red-teaming: promptfoo, garak e PyRIT. No final, terás um projeto funcional com um harness de testes que corre automaticamente sempre que alteras o código do agente.

Isto não é um exercício académico. A Google descreve o Gemini 3.7 Flash como o modelo “mais inteligente” da família Flash até agora, otimizado para engenharia de software, desenvolvimento web e fluxos agentic. Um agente que executa código ou acede a APIs externas é, por definição, uma superfície de ataque maior do que um chatbot que só devolve texto. Se o teu agente aceita input de utilizadores ou de documentos externos, precisas de saber como reage a um prompt malicioso antes que um atacante o descubra por ti.

Porque testar a segurança da API Gemini agora

Três fatores tornam este o momento certo para montar um processo de testes de segurança à volta da API Gemini. Primeiro, o ciclo de lançamentos ficou curto de mais para confiar em testes manuais pontuais: se a Google lança uma versão nova a cada três semanas, o comportamento do modelo perante prompts adversariais também pode mudar a cada três semanas. Segundo, o preço de lançamento do Gemini 3.7 Flash mantém-se válido até 31 de dezembro de 2026, o que cria um incentivo real para migrar aplicações antigas para o modelo novo sem repetir todo o trabalho de validação de segurança do zero.

Terceiro, a concorrência não parou. A OpenAI atualizou o ChatGPT com os modelos GPT-5.6 Sol e GPT-5.6 Luna no início de agosto de 2026, com o Luna a tornar-se o modelo predefinido para utilizadores gratuitos. Equipas que gerem vários fornecedores de LLM em paralelo precisam de um processo de teste que funcione da mesma forma em qualquer modelo, não de um script ad-hoc por fornecedor. É exatamente isso que promptfoo e garak resolvem: correm o mesmo conjunto de testes contra a Gemini API, a API da OpenAI ou um modelo local, e devolvem um relatório comparável.

Vale ainda notar que o modelo gemini-3.7-flash não tem, até à data, uma data de descontinuação anunciada na documentação oficial de depreciações da Google, o que o torna uma base estável para construir e testar sem receio de o código ficar obsoleto em poucas semanas.

Pré-requisitos e versões usadas neste guia

Antes de avançar, confirma que tens estas ferramentas instaladas. As versões abaixo foram verificadas nos repositórios oficiais no momento da escrita deste artigo, mas o comando --version de cada ferramenta dir-te-á sempre a versão exata que tens instalada.

FerramentaVersão usada neste guiaFunção no fluxo de trabalho
Python3.11 ou superior (testado em 3.12)Executar o SDK e os scripts do agente
google-genai (PyPI)2.18.1SDK oficial Python para a Gemini API
Node.js22.22.0 ou superiorRequisito mínimo do promptfoo
promptfoo (npm)0.122.0Testes automatizados e red-teaming de prompts
garak (PyPI)0.16.0Scanner de vulnerabilidades para LLMs
PyRITúltima versão do repositório Azure/PyRIT no GitHubFramework de red-teaming da Microsoft para IA generativa
Conta Google AI Studiogratuita, com chave de APIAcesso à Gemini API

Também precisas de um cartão de crédito válido caso queiras ultrapassar o tier gratuito da Gemini API (o tutorial funciona inteiramente dentro do tier gratuito), e de acesso a um terminal Linux, macOS ou WSL no Windows. Todo o código abaixo foi escrito para correr em qualquer um destes três ambientes sem alterações.

Gemini API vs. outras APIs de LLM: o que muda para quem testa segurança

Se já usaste a API da OpenAI ou a API da Anthropic, a Gemini API vai parecer-te familiar em termos gerais: envias uma lista de mensagens, defines um prompt de sistema e podes declarar funções que o modelo pode chamar. As diferenças que mais importam para quem testa segurança estão nos detalhes de implementação, não na filosofia geral.

A Gemini API separa explicitamente as “safety settings” da configuração de geração, permitindo ajustar o limiar de bloqueio para categorias como conteúdo de ódio, assédio ou conteúdo sexual de forma independente da configuração de temperatura ou do número máximo de tokens. Isto é útil em testes de red-teaming porque permite isolar se uma falha vem do prompt de sistema ou das definições de segurança da própria chamada. Outra diferença prática é a forma como a API estrutura o “function calling”: o Gemini devolve um objeto de chamada de função separado do texto, o que obriga o teu código a validar explicitamente essa chamada antes de a executar, em vez de teres de interpretar a intenção a partir de texto livre.

Do ponto de vista de red-teaming, isto significa que os plugins do promptfoo e as probes do garak que testam “system-prompt-override” ou “excessive-agency” continuam válidos entre fornecedores, mas os resultados não são diretamente comparáveis número a número: um agente Gemini e um agente equivalente construído sobre outra API podem ter taxas de falha diferentes mesmo com o mesmo prompt de sistema, simplesmente porque cada fornecedor treina e ajusta o seu modelo de forma diferente. Corre sempre a tua própria bateria de testes por fornecedor, em vez de assumir que um resultado de segurança se transfere de um modelo para outro.

Passo 1 – Criar a conta e gerar a chave da Gemini API

Acede ao Google AI Studio com a tua conta Google e escolhe a opção “Get API key” no menu lateral. Cria um projeto novo no Google Cloud se ainda não tiveres nenhum associado à tua conta, e gera a chave. Guarda-a de imediato num gestor de senhas: a chave dá acesso direto à faturação da tua conta e não deve viver em nenhum ficheiro versionado no Git.

Confirma que o modelo gemini-3.7-flash está disponível para a tua chave correndo este pedido simples via curl. Se receberes uma lista de modelos que inclui o Gemini 3.7 Flash, a chave está ativa e pronta a usar.

export GEMINI_API_KEY="a_tua_chave_aqui"

curl -s "https://generativelanguage.googleapis.com/v1beta/models?key=$GEMINI_API_KEY" \
  | python3 -c "import json,sys; d=json.load(sys.stdin); [print(m['name']) for m in d['models']]" \
  | grep gemini-3.7

Passo 2 – Preparar o ambiente de desenvolvimento

Cria uma pasta dedicada ao projeto e isola as dependências num ambiente virtual. Isto evita conflitos entre a versão do SDK usada aqui e outras bibliotecas Python que já tenhas instaladas no sistema.

mkdir gemini-security-lab && cd gemini-security-lab
python3 -m venv .venv
source .venv/bin/activate

pip install "google-genai==2.18.1" python-dotenv garak

# Node.js só é necessário para o promptfoo
node --version   # confirma >= 22.22.0
npm install -g [email protected]

Cria um ficheiro .env na raiz do projeto com a tua chave, e adiciona .env ao .gitignore imediatamente, antes do primeiro commit. É um dos erros mais comuns em projetos que usam a Gemini API: a chave acaba num repositório público porque o .gitignore foi esquecido para depois.

echo "GEMINI_API_KEY=a_tua_chave_aqui" > .env
echo ".env" >> .gitignore
echo ".venv/" >> .gitignore

Passo 3 – Fazer a primeira chamada à API

Com o ambiente pronto, escreve um script mínimo que carrega a chave a partir do .env e faz uma chamada de teste ao Gemini 3.7 Flash. Este script vai servir de base para o agente que construímos no Passo 6.

import os
from dotenv import load_dotenv
from google import genai

load_dotenv()
client = genai.Client(api_key=os.environ["GEMINI_API_KEY"])

response = client.models.generate_content(
    model="gemini-3.7-flash",
    contents="Explica em duas frases o que é red-teaming de LLMs."
)

print(response.text)

Guarda o ficheiro como primeiro_teste.py e corre python primeiro_teste.py. A saída esperada é um pequeno parágrafo de texto gerado pelo modelo, sem erros de autenticação. Se vires um erro 403 ou PERMISSION_DENIED, salta já para a secção de resolução de problemas mais abaixo, onde este erro específico é o primeiro item da lista.

Passo 4 – Proteger a autenticação e as chaves

Nunca coloques a chave diretamente no código, mesmo em protótipos rápidos. Além do risco de a expores num commit, chaves fixas no código dificultam a rotação: se a chave for comprometida, tens de procurar todos os sítios onde ela aparece em vez de mudar uma única variável de ambiente. Em produção, usa um gestor de segredos (Google Secret Manager, HashiCorp Vault ou equivalente) em vez de ficheiros .env, que são adequados apenas para desenvolvimento local.

Define também restrições na chave dentro do Google Cloud Console: limita-a à API Gemini especificamente e, se possível, restringe por IP de origem quando o teu servidor tem um endereço fixo. Isto reduz drasticamente o impacto de uma fuga acidental, porque a chave deixa de servir para qualquer outro serviço Google.

Se trabalhas em equipa, cria uma chave por ambiente (desenvolvimento, testes, produção) em vez de partilhar uma única chave entre todos. Isto isola o impacto de um erro cometido em desenvolvimento, que nunca deve conseguir consumir o orçamento nem os limites de taxa reservados ao ambiente de produção. Revê também, pelo menos uma vez por trimestre, a lista de chaves ativas no projeto: chaves esquecidas de protótipos antigos são um dos vetores de fuga mais comuns porque ninguém se lembra que ainda existem.

Passo 5 – Perceber os limites de taxa e os custos

A Gemini API funciona com um tier gratuito seguido de faturação por utilização (pay-as-you-go) para volumes maiores. Os valores exatos por token e os limites de pedidos por minuto mudam com frequência entre versões do modelo, por isso o passo mais fiável é confirmar sempre os números atuais na página oficial de preços e na documentação de limites de taxa antes de dimensionar um projeto em produção. A Google mantém o preço introdutório do Gemini 3.7 Flash válido até 31 de dezembro de 2026, o que vale a pena aproveitar se estás a planear uma migração a partir de uma versão anterior do modelo.

Um erro comum de quem começa é ignorar os limites de taxa até ao momento em que a aplicação já está em produção. Implementa lógica de retry com backoff exponencial desde o primeiro protótipo, mesmo que nunca a vejas disparar em testes locais. Quando o tráfego real chegar, essa lógica evita que um pico de utilizadores derrube a aplicação inteira por causa de um erro 429.

import time

def chamar_com_retry(func, tentativas=4):
    for i in range(tentativas):
        try:
            return func()
        except Exception as erro:
            if i == tentativas - 1:
                raise
            espera = 2 ** i
            print(f"Pedido falhou, a tentar de novo em {espera}s")
            time.sleep(espera)

Este padrão de retry simples resolve a maioria dos erros transitórios, mas não substitui um limite de orçamento explícito. Define um alerta de faturação no Google Cloud Console desde o primeiro dia, mesmo que estejas dentro do tier gratuito. É a forma mais barata de detetar cedo um agente com um ciclo infinito de chamadas à função, um bug de código que consome API muito mais depressa do que qualquer ataque externo.

Passo 6 – Construir um agente com function calling

A maior parte dos incidentes de segurança em LLMs não acontece num chatbot simples, acontece quando o modelo ganha a capacidade de chamar funções externas. Vamos construir um agente mínimo que consulta uma “base de dados” de preços fictícia, para depois testarmos se um atacante consegue manipular o agente para revelar dados fora do âmbito pretendido.

from google import genai
from google.genai import types

def consultar_preco(produto: str) -> str:
    catalogo = {"portatil": "899 EUR", "monitor": "249 EUR"}
    return catalogo.get(produto.lower(), "produto não encontrado")

tools = types.Tool(function_declarations=[{
    "name": "consultar_preco",
    "description": "Devolve o preço de um produto do catálogo interno",
    "parameters": {
        "type": "OBJECT",
        "properties": {"produto": {"type": "STRING"}},
        "required": ["produto"]
    }
}])

client = genai.Client(api_key="a_tua_chave_aqui")
chat = client.chats.create(
    model="gemini-3.7-flash",
    config=types.GenerateContentConfig(tools=[tools])
)

resposta = chat.send_message("Quanto custa o monitor?")
print(resposta.text)

Este agente é deliberadamente simples, mas a estrutura é a mesma de agentes de produção: o modelo decide quando chamar a função, com que argumentos, e depois formula a resposta final com base no resultado. É precisamente esta decisão autónoma que queremos testar sob pressão adversarial nos passos seguintes.

Como o modelo decide chamar a função

Quando envias “Quanto custa o monitor?” ao chat, o Gemini não executa a função diretamente. Primeiro devolve uma resposta que indica a intenção de chamar consultar_preco com o argumento produto="monitor". O SDK trata essa parte automaticamente no exemplo acima, mas em produção deves inspecionar essa chamada antes de a executares, sobretudo se a função tiver efeitos reais como escrever dados ou enviar um pedido HTTP. Um agente mal desenhado que executa qualquer função sugerida pelo modelo sem validação prévia é exatamente o tipo de falha que a categoria “excessive-agency” do promptfoo foi criada para detetar.

Repara também que a função consultar_preco devolve sempre uma resposta segura (“produto não encontrado”) em vez de lançar uma exceção quando recebe um argumento fora do catálogo. Isto evita que erros internos da tua aplicação apareçam no texto final devolvido ao utilizador, o que por si só já reduz uma classe inteira de fugas de informação acidentais.

Passo 7 – Instalar e configurar o promptfoo

O promptfoo (mais de 24 mil estrelas no GitHub) é a ferramenta mais usada atualmente para testar prompts e agentes de forma automatizada, com um módulo de red-teaming dedicado a simular ataques comuns contra LLMs. Inicializa a configuração dentro da pasta do projeto:

promptfoo init --no-interactive
promptfoo redteam init --no-interactive

Isto gera um ficheiro promptfooconfig.yaml. Edita-o para apontar para o teu agente Gemini e define os plugins de red-teaming que queres correr. O exemplo abaixo cobre injeção de prompt, extração de instruções de sistema e fuga de dados sensíveis, três das categorias de risco mais comuns em agentes com function calling.

providers:
  - id: google:gemini-3.7-flash
    config:
      apiKey: "{{env.GEMINI_API_KEY}}"

prompts:
  - "{{query}}"

redteam:
  plugins:
    - prompt-injection
    - system-prompt-override
    - pii
    - excessive-agency
  strategies:
    - jailbreak
    - prompt-injection

Passo 8 – Escrever casos de teste de red-teaming

Com a configuração base pronta, corre a geração automática de casos de teste e depois a avaliação em si. O promptfoo gera dezenas de variações de ataque com base nos plugins escolhidos, poupando-te horas de escrita manual de prompts maliciosos.

promptfoo redteam generate
promptfoo redteam eval
promptfoo redteam report

O comando report abre um painel local no browser com a percentagem de testes que o agente falhou por categoria. Um agente bem protegido deve recusar consistentemente tentativas de “esquecer as instruções anteriores” ou de revelar o prompt de sistema. Se vires uma taxa de falha elevada na categoria excessive-agency, significa que o modelo está a executar ações (como chamar funções) fora do âmbito que lhe destinaste, e precisas de reforçar as restrições na definição da função no Passo 6.

Não existe um número mágico de “taxa de falha aceitável” válido para todos os projetos. Um agente que só responde a perguntas sobre o catálogo de uma loja pode tolerar um risco residual maior do que um agente que gere transferências bancárias. Define o limiar de aceitação com a equipa antes de correres os testes, não depois de veres os resultados, para evitares a tentação de baixar a fasquia só porque o número real ficou pior do que esperavas.

Passo 9 – Correr avaliações com o garak e o PyRIT

O garak, mantido atualmente sob a organização NVIDIA no GitHub com mais de 8.800 estrelas, funciona como um scanner de vulnerabilidades dedicado a LLMs, com “sondas” (probes) especializadas em categorias como fuga de dados de treino, geração de conteúdo tóxico e resistência a jailbreaks. Ao contrário do promptfoo, que se integra bem no fluxo de desenvolvimento de uma aplicação, o garak foi pensado para avaliar o modelo em si, de forma mais próxima de um scanner de segurança tradicional.

garak --model_type generativeai \
      --model_name gemini-3.7-flash \
      --probes promptinject,leakreplay,dan

Para equipas que já trabalham em ambiente Microsoft/Azure, o PyRIT (Python Risk Identification Tool, mantido pela equipa de red-teaming de IA da Microsoft) oferece uma abordagem mais programável, em que defines orquestradores de ataque em Python e encadeias múltiplas técnicas de jailbreak numa única sessão de testes. É a ferramenta mais indicada quando precisas de testes reprodutíveis e versionados junto com o resto do código do projeto.

FerramentaEstrelas no GitHubMelhor para
promptfoomais de 24.000Testes contínuos integrados no fluxo de desenvolvimento e CI/CD
garakmais de 8.800Varrimento amplo de vulnerabilidades conhecidas do modelo
PyRITmais de 100Cadeias de ataque programáveis e reprodutíveis em Python

O resultado do garak fica gravado num relatório em formato JSONL, com uma linha por tentativa de ataque e o veredito (passou ou falhou) para cada probe. Não te limites a olhar para a taxa de sucesso agregada: abre o relatório e lê algumas das tentativas que falharam, porque a forma exata como o modelo cedeu costuma revelar se o problema está no prompt de sistema, na falta de validação da função chamada, ou numa combinação dos dois. Uma prática comum é guardar apenas as tentativas falhadas num ficheiro separado e reexecutá-las depois de cada correção, para confirmar que a mitigação realmente resolveu o problema em vez de o esconder.

Passo 10 – Mitigar os riscos encontrados

Depois de identificares falhas, a correção segue quase sempre uma de três direções. Primeiro, reforça o prompt de sistema com instruções explícitas sobre o que o agente nunca deve fazer, e não apenas o que deve fazer, porque modelos respondem melhor a restrições explícitas do que a omissões. Segundo, valida e sanitiza qualquer input antes de o passar a uma função que tenha efeitos reais, como escrever num ficheiro ou consultar uma base de dados. Terceiro, limita o âmbito de cada função ao mínimo necessário, seguindo o princípio do menor privilégio: a função consultar_preco do Passo 6 não devia, por exemplo, ter acesso de escrita à mesma base de dados.

A OWASP Top 10 para Aplicações de LLM é a referência mais usada pela indústria para classificar estes riscos e vale a pena mapear cada falha encontrada pelo promptfoo ou pelo garak para uma categoria da lista. Isto ajuda a priorizar correções e a comunicar o risco a stakeholders que não estão familiarizados com os detalhes técnicos de prompt injection.

Na prática, a validação da função chamada pode ser tão simples como uma lista de permissões (allowlist) verificada antes da execução, em vez de confiares apenas na descrição da função para limitar o comportamento do modelo:

PRODUTOS_PERMITIDOS = {"portatil", "monitor"}

def executar_funcao_com_validacao(nome_funcao, argumentos):
    if nome_funcao == "consultar_preco":
        produto = argumentos.get("produto", "").lower()
        if produto not in PRODUTOS_PERMITIDOS:
            return "pedido rejeitado: produto fora do catálogo permitido"
        return consultar_preco(produto)
    return "função não reconhecida"

Esta camada extra parece redundante quando o catálogo tem apenas dois produtos, mas escala bem: em sistemas reais, com dezenas de funções e permissões diferentes por tipo de utilizador, é esta validação determinística que impede um jailbreak bem-sucedido de se traduzir numa ação real no sistema.

Passo 11 – Automatizar os testes no CI/CD e monitorizar em produção

Testes de segurança que só correm manualmente acabam por não correr. Integra o promptfoo no teu pipeline de integração contínua, para que qualquer alteração ao prompt de sistema ou às funções do agente dispare automaticamente a suite de red-teaming antes do merge.

name: gemini-security-checks

on:
  pull_request:
    paths:
      - "agente/**"
      - "promptfooconfig.yaml"

jobs:
  redteam:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: "22"
      - run: npm install -g promptfoo
      - run: promptfoo redteam eval --fail-on-error
        env:
          GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}

Depois de o agente ir para produção, mantém um registo (log) de todos os pedidos e respostas do modelo, incluindo as chamadas de função que executou. Sem esse registo, é impossível investigar um incidente depois de acontecer. Regista o input do utilizador, a decisão do modelo e o resultado da função chamada, mas evita registar dados pessoais sensíveis nos logs sem os anonimizar primeiro.

Projeto completo: agente Gemini com harness de testes

Juntando todos os passos anteriores, a estrutura final do projeto fica assim:

gemini-security-lab/
├── .env                      # chave da API (nunca no Git)
├── .gitignore
├── agente/
│   └── consultor_precos.py   # agente com function calling
├── primeiro_teste.py
├── promptfooconfig.yaml      # configuração de red-teaming
├── .github/
│   └── workflows/
│       └── gemini-security-checks.yml
└── requirements.txt

Com esta estrutura, tens um ciclo completo e repetível: qualquer alteração ao código do agente dispara o promptfoo no CI, e podes correr o garak e o PyRIT manualmente antes de cada lançamento maior, como uma migração para uma nova versão do Gemini. Guarda os relatórios de cada corrida do garak num histórico (por exemplo, um bucket de armazenamento com data no nome do ficheiro), para conseguires comparar a evolução da taxa de falhas ao longo do tempo, especialmente depois de a Google lançar uma nova versão do modelo.

O ficheiro requirements.txt deve fixar as versões exatas de cada dependência, não apenas o nome do pacote. Isto garante que qualquer pessoa da equipa, ou o próprio pipeline de CI, instala exatamente as mesmas versões que tu testaste localmente, evitando o clássico “no meu computador funciona”.

google-genai==2.18.1
python-dotenv==1.0.1
garak==0.16.0

Antes de considerares o projeto pronto para produção, corre uma última verificação: apaga o ambiente virtual, clona o repositório num diretório limpo e segue de novo os passos 2 e 3 deste guia do início. Se tudo funcionar sem intervenção manual, sabes que a configuração está corretamente documentada e reprodutível, um requisito básico para qualquer sistema que outra pessoa possa vir a operar sem ti presente.

Erros comuns a evitar

  • Testar apenas o modelo, nunca o sistema completo. O Gemini 3.7 Flash pode recusar um jailbreak direto, mas a tua camada de function calling pode continuar vulnerável a ataques indiretos vindos de documentos ou páginas web que o agente processa.
  • Confiar em system prompts como única linha de defesa. Um prompt de sistema é uma sugestão forte para o modelo, não um limite técnico. Combina sempre instruções de sistema com validação de código nas funções chamadas.
  • Ignorar ataques indiretos via ferramentas externas. Se o agente lê o conteúdo de uma página web ou de um email, esse conteúdo pode conter instruções escondidas dirigidas ao modelo, não ao utilizador humano.
  • Não fixar a versão do modelo em produção. Apontar para “o modelo mais recente” sem fixar a versão significa que o comportamento da tua aplicação pode mudar de um dia para o outro sem aviso.
  • Correr os testes de red-teaming uma única vez. Modelos são atualizados com frequência e os próprios ataques evoluem. Um relatório limpo em julho não garante nada em setembro.
  • Guardar a chave de API em variáveis de ambiente partilhadas por vários projetos. Se um projeto for comprometido, todos os outros que partilham a mesma chave ficam expostos. Usa uma chave por projeto e restringe cada uma ao mínimo necessário.
  • Assumir que uma taxa de falha baixa nos testes significa risco zero. O promptfoo e o garak cobrem ataques conhecidos e documentados. Um atacante motivado pode sempre inventar uma variação nova que nenhuma das ferramentas testou ainda, por isso os testes automatizados complementam a revisão humana, não a substituem.

Resolução de problemas

SintomaCausa provávelCorreção
Erro 403 / PERMISSION_DENIEDChave inválida ou API Gemini não ativada no projetoConfirma a chave no AI Studio e ativa a Generative Language API no Google Cloud Console
Erro 429 / RESOURCE_EXHAUSTEDLimite de pedidos por minuto excedidoImplementa retry com backoff exponencial e confirma os limites atuais na documentação oficial
promptfoo não encontra o provider “google”Versão desatualizada do promptfooAtualiza com npm install -g promptfoo@latest
garak devolve erro de módulo em faltaDependências extra não instaladasCorre pip install garak[generativeai]
Function calling nunca é acionadoDescrição da função demasiado vagaReescreve a description da função com linguagem mais explícita sobre quando a usar
Agente ignora o prompt de sistema após várias mensagensJanela de contexto saturada com histórico irrelevanteReduz o histórico enviado ou resume conversas longas antes de as reenviar
Testes do CI falham só em produção, nunca localmenteDiferença de variáveis de ambiente ou versão do modeloGarante que o workflow usa exatamente a mesma versão fixa do modelo e das dependências
Custos da API acima do esperadoContexto ou histórico demasiado longo enviado em cada pedidoCorta o histórico ao mínimo necessário e ativa cache de contexto quando disponível
promptfoo redteam report fica vazioO comando generate não foi corrido antes do evalCorre sempre os três comandos pela ordem: generate, eval e depois report
garak demora muito tempo a terminarLista de probes demasiado ampla para uma primeira corridaComeça com um subconjunto pequeno de probes (como no exemplo deste guia) e alarga depois de validares o fluxo

Dicas avançadas para produção

Depois de teres o básico a funcionar, três práticas fazem a diferença entre um protótipo e um sistema pronto para produção. A primeira é separar claramente instruções de sistema de conteúdo fornecido por utilizadores, usando delimitadores estruturados em vez de concatenar tudo numa única string de texto. Isto reduz significativamente a superfície para ataques de injeção de prompt.

A segunda é adotar um modelo de “duas camadas” para ações sensíveis: o Gemini decide a intenção, mas uma camada de código determinístico (não um LLM) valida se essa ação é permitida antes de a executar. Nunca deixes o próprio modelo ser o único guarda de segurança das suas ações.

A terceira é correr o garak e o promptfoo como parte da rotina de avaliação sempre que a Google anunciar uma nova versão do modelo, não apenas quando alteras o teu próprio código. Dado o ritmo de três semanas entre o Gemini 3.6 Flash e o 3.7 Flash, é razoável assumir que a próxima versão pode chegar ainda antes do final de 2026, e o comportamento do modelo perante os teus testes pode mudar sem que tenhas alterado uma única linha da tua aplicação.

A quarta prática, muitas vezes esquecida, é documentar as decisões de mitigação junto do código, não apenas no relatório de testes. Quando alguém da equipa reabrir o projeto daqui a seis meses, um comentário curto a explicar porque uma função tem uma allowlist específica poupa horas de investigação e evita que a restrição seja removida por engano por parecer “código morto”.

Por fim, trata a chave da Gemini API e o histórico de conversas do agente como dados sensíveis desde o primeiro dia, não como um detalhe a resolver mais tarde. Encriptar o transporte com HTTPS já vem garantido pela própria API, mas a encriptação dos dados guardados em repouso, incluindo os logs de conversas, fica sempre a teu cargo. Um agente tecnicamente seguro contra prompt injection continua vulnerável se os registos das conversas ficarem acessíveis em texto simples num disco partilhado.

Perguntas frequentes

A Gemini API é gratuita para testar?

Sim, a Google oferece um tier gratuito com limites de utilização suficientes para seguir este tutorial por completo. Para volumes de produção, consulta a página oficial de preços, já que os valores exatos por token variam por modelo e podem mudar com novos lançamentos.

Preciso de saber Node.js para seguir este guia?

Só precisas do Node.js instalado para correr o promptfoo, que é escrito em TypeScript. Não precisas de escrever nenhum código Node.js: todos os comandos usados neste artigo são invocados diretamente no terminal.

O garak e o promptfoo funcionam com outros modelos além do Gemini?

Sim, ambas as ferramentas suportam múltiplos fornecedores, incluindo OpenAI, Anthropic e modelos locais. É essa portabilidade que as torna úteis para equipas que comparam vários LLMs em simultâneo.

Qual é a diferença prática entre promptfoo, garak e PyRIT?

O promptfoo encaixa melhor no dia a dia de desenvolvimento e no CI/CD, o garak funciona como um scanner amplo de vulnerabilidades conhecidas do modelo, e o PyRIT dá mais controlo programático para construir cadeias de ataque específicas em Python. Muitas equipas usam as três em conjunto, cada uma numa fase diferente do ciclo de testes.

O que é “excessive agency” e porque aparece nos relatórios de red-teaming?

É a categoria de risco em que o modelo executa ações fora do âmbito pretendido, por exemplo, chamando uma função que não devia ter acesso naquele contexto. Aparece com frequência em agentes com function calling mal restringido, e é corrigida limitando o âmbito de cada função ao mínimo necessário.

Com que frequência devo repetir os testes de segurança?

No mínimo, sempre que alterares o prompt de sistema, as funções do agente ou a versão do modelo. Dado o ritmo de lançamentos da Google em 2026, uma corrida mensal do garak e do promptfoo é uma base razoável mesmo sem alterações no teu código.

Este processo serve para aplicações pequenas, sem equipa de segurança dedicada?

Sim. O objetivo deste guia é precisamente tornar o red-teaming acessível a uma única pessoa com um terminal e uma chave de API, sem depender de uma equipa de segurança dedicada nem de ferramentas comerciais caras.

O que acontece se eu não fixar a versão do modelo no código?

Se apontares para um alias genérico em vez de gemini-3.7-flash, a Google pode redirecionar os teus pedidos para uma versão mais recente sem aviso prévio. Isso pode alterar o comportamento do agente, incluindo a forma como reage a tentativas de jailbreak, por isso fixar a versão exata é uma prática de segurança tanto quanto uma prática de estabilidade.

Cobertura relacionada

Para mais tutoriais e análises sobre modelos de linguagem, consulta a categoria Inteligência Artificial do shattered.io.