Inferência de rotas por meio de um gateway

CloudflareBeginner
Pratique Agora

Introdução

No curso de Workers AI, uma aplicação enviou um prompt diretamente para um modelo hospedado pela Cloudflare. Isso funciona, mas uma aplicação em crescimento também precisa de um ponto único para observar e controlar o tráfego dos modelos. O Cloudflare AI Gateway é esse ponto de controle: o chamador envia uma solicitação para um gateway nomeado, e o gateway encaminha a solicitação para um provedor de modelos upstream, como o Workers AI.

Este laboratório mantém as três funções visíveis:

  • o chamador é o curl na sua VM do LabEx;
  • o gateway verifica se o chamador pode entrar e registra a solicitação;
  • o provedor upstream é o Workers AI, que verifica se a solicitação pode executar o modelo.

As duas últimas verificações usam credenciais diferentes. cf-aig-authorization autentica o chamador no AI Gateway. O cabeçalho Authorization comum autentica a solicitação do gateway no Workers AI. Um token válido do gateway não é automaticamente uma credencial do Workers AI, e uma credencial do Workers AI não contorna um gateway autenticado.

Você criará um gateway autenticado descartável no Cloudflare Dashboard, criará um token do AI Gateway com escopo restrito, enviará uma solicitação curta ao modelo Llama 3.3 hospedado pela Cloudflare e consultará o log resultante. Em seguida, substituirá apenas a credencial do gateway por um valor inválido para provar qual limite rejeita a solicitação. Por fim, excluirá o gateway, excluirá o token para que ele não possa mais autorizar solicitações e encerrará a sessão do Wrangler.

Se você entrou diretamente neste curso, primeiro conclua Conectar o LabEx à sua conta da Cloudflare. Esse laboratório ensina a usar o terminal da VM do LabEx, a autorização de dispositivo do Wrangler, a confirmação da conta e os IDs explícitos de conta. O laboratório de inferência do Workers AI também é um pré-requisito útil.

O AI Gateway está disponível no plano Free, e o registro principal é gratuito dentro dos limites da conta. O modelo selecionado @cf/meta/llama-3.3-70b-instruct-fp8-fast pode usar a alocação gratuita compartilhada do Workers AI com o faturamento Standard. Workers Paid e Unified Billing não são necessários. Pare em vez de tentar repetidamente se a alocação diária do Workers AI da conta não estiver disponível.

A configuração instala o Node.js 22.22.0 e o Wrangler 4.132.0 local do projeto em /home/labex/project/ai-gateway-route. Ela fornece verificações independentes somente leitura, mas não autoriza o Wrangler, não cria um token ou gateway, não envia inferências nem modifica sua conta da Cloudflare. O LabEx não salva essa VM temporária depois do fim do laboratório. Ainda assim, você deverá excluir explicitamente o token na nuvem e apagar a cópia dele na VM para concluir a limpeza antes de a VM ser destruída.

Autorizar a VM e registrar os nomes utilizados

Nesta etapa, você conectará a VM recém-criada à sua conta de aprendizado e salvará nomes que tornam os recursos deste laboratório inequívocos.

O login do dispositivo do Wrangler autoriza o Workers AI, mas não cria a credencial separada do chamador do AI Gateway usada mais adiante. Manter essas credenciais separadas facilita visualizar o limite de confiança.

Entre no projeto preparado e confirme a versão fixada da CLI:

cd /home/labex/project/ai-gateway-route
npx wrangler --version

O resultado esperado é 4.132.0. Inicie a autorização do dispositivo com a identidade da conta e acesso ao Workers AI:

npx wrangler login --device --browser=false --scopes account:read user:read ai:write

Abra o link exibido, informe o código e autorize a conta de aprendizado pretendida. Em seguida, consulte a identidade estruturada:

npx wrangler whoami --json

Confirme loggedIn: true. Crie um ID exclusivo para o gateway e o nome do token relacionado. Substitua YOUR_ACCOUNT_ID pelo ID real de 32 caracteres exibido para a conta pretendida:

GATEWAY_ID="labex-c09-g01-$(openssl rand -hex 6)"
TOKEN_NAME="$GATEWAY_ID-token"
cat > .labex/state.json <<JSON
{
  "accountId": "YOUR_ACCOUNT_ID",
  "gatewayId": "$GATEWAY_ID",
  "tokenName": "$TOKEN_NAME"
}
JSON
cat .labex/state.json

O sufixo aleatório evita colisões. O arquivo de estado contém identificadores de recursos, não credenciais, e permite que cada comando posterior tenha como destino o recurso exato pertencente a este laboratório.

Criar um gateway autenticado e um token do chamador

Nesta etapa, você criará o ponto de controle e uma credencial que poderá tanto acessá-lo quanto consultá-lo.

Abra o Cloudflare Dashboard e escolha AI → AI Gateway → Create gateway → Custom gateway. Use o gatewayId de .labex/state.json como nome do gateway. Mantenha estas configurações:

  • registro de solicitações: ativado;
  • autenticação do gateway: ativada;
  • cache, limites de taxa, limites de gastos e novas tentativas: desativados;
  • faturamento do Workers AI: Standard.

O faturamento Standard mantém o uso do Workers AI na alocação normal. Unified Billing é uma forma de pagamento diferente e está fora do escopo deste laboratório para iniciantes.

Depois que a Cloudflare abrir o novo recurso, use a trilha de navegação e a guia Overview selecionada para confirmar que você está dentro do gateway descartável exato, e não na lista de gateways de toda a conta.

A visão Overview do novo gateway, com seu ID exclusivo e métricas iniciais sem solicitações

Depois da criação, abra Settings. Confirme que o ID do gateway exibido corresponde exatamente ao ID salvo e que o registro e a autenticação estão ativados.

Agora escolha Create an AI Gateway authentication token. Dê ao token o nome salvo em tokenName, selecione somente a conta de aprendizado pretendida e adicione estas permissões:

  • AI Gateway — Run permite que o chamador entre em um gateway autenticado;
  • AI Gateway — Edit permite que o laboratório leia e exclua recursos do AI Gateway pela API de gerenciamento.

Não adicione a permissão do Workers AI a este token. O Workers AI continua autorizado pela credencial separada e de curta duração do Wrangler.

Formulário de permissões do token, limitado a AI Gateway Run e Edit

Crie o token somente depois de revisar a conta e as permissões. A Cloudflare exibirá o valor uma única vez. Armazene-o de forma privada, sem exibi-lo:

bash -c '
while :; do
  read -rsp "Paste the AI Gateway token: " GATEWAY_TOKEN
  printf "\n"
  [ -n "$GATEWAY_TOKEN" ] && break
  printf "Token cannot be empty; paste it again.\n" >&2
done
umask 077
printf "%s" "$GATEWAY_TOKEN" > .labex/gateway-token
unset GATEWAY_TOKEN
chmod 600 .labex/gateway-token
'

O terminal preparado usa zsh interativamente, portanto este bloco inicia um subprocesso Bash curto para usar o prompt oculto de read do Bash. Uma entrada vazia é rejeitada antes de o comando retornar ao shell. O token permanece somente no subprocesso e no arquivo privado.

O token é mantido deliberadamente fora da configuração e da saída dos comandos. Verifique o gateway real por meio da API de gerenciamento autenticada:

ACCOUNT_ID=$(node -p 'JSON.parse(require("fs").readFileSync(".labex/state.json")).accountId')
GATEWAY_ID=$(node -p 'JSON.parse(require("fs").readFileSync(".labex/state.json")).gatewayId')
GATEWAY_TOKEN=$(cat .labex/gateway-token)
curl --http1.1 -fsS \
  -H "Authorization: Bearer $GATEWAY_TOKEN" \
  "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/ai-gateway/gateways/$GATEWAY_ID" \
  | node -e 'let s="";process.stdin.on("data",d=>s+=d).on("end",()=>{const b=JSON.parse(s),g=b.result||{};console.log(JSON.stringify({success:b.success,id:g.id,collect_logs:g.collect_logs,authentication:g.authentication},null,2))})'
unset GATEWAY_TOKEN

O resultado esperado é o ID utilizado, com collect_logs e authentication definidos como true. Nenhum segredo é exibido.

A visão Settings do gateway, mostrando autenticação, logs e faturamento Standard

Encaminhar uma solicitação do Workers AI pelo gateway

Nesta etapa, você enviará uma solicitação pequena pelo gateway, em vez de enviá-la diretamente ao Workers AI.

A URL do gateway nativo do provedor contém a conta, o gateway, o provedor e o modelo. Os dois cabeçalhos de autorização permanecem separados de propósito:

caller → cf-aig-authorization → AI Gateway → Authorization → Workers AI model

Obtenha o token atual e de curta duração do Workers AI do Wrangler como dados estruturados e faça a solicitação. O comando grava somente a resposta JSON no disco; nenhuma das credenciais é exibida:

ACCOUNT_ID=$(node -p 'JSON.parse(require("fs").readFileSync(".labex/state.json")).accountId')
GATEWAY_ID=$(node -p 'JSON.parse(require("fs").readFileSync(".labex/state.json")).gatewayId')
MODEL='@cf/meta/llama-3.3-70b-instruct-fp8-fast'
GATEWAY_TOKEN=$(cat .labex/gateway-token)
UPSTREAM_TOKEN=$(npx wrangler auth token --json | node -e 'let s="";process.stdin.on("data",d=>s+=d).on("end",()=>process.stdout.write(JSON.parse(s).token))')
curl --http1.1 -fsS \
  -H "cf-aig-authorization: Bearer $GATEWAY_TOKEN" \
  -H "Authorization: Bearer $UPSTREAM_TOKEN" \
  -H 'Content-Type: application/json' \
  --data '{"prompt":"In one sentence, explain why an AI gateway is useful.","max_tokens":64}' \
  "https://gateway.ai.cloudflare.com/v1/$ACCOUNT_ID/$GATEWAY_ID/workers-ai/$MODEL" \
  > .labex/valid-response.json
unset GATEWAY_TOKEN UPSTREAM_TOKEN
node -e 'const b=require("./.labex/valid-response.json"); console.log(b.result?.response ?? b.result)'

O texto pode variar porque a geração não é determinística. A avaliação verifica somente se o provedor retornou um resultado bem-sucedido e não vazio por meio do gateway utilizado.

Isolar o limite de autenticação do gateway

Nesta etapa, você manterá válida a credencial do Workers AI, mas substituirá somente a credencial do gateway.

Um teste negativo controlado deve alterar uma condição por vez. Se as duas credenciais fossem inválidas, uma falha HTTP não indicaria qual sistema rejeitou a solicitação. Esta solicitação mantém o token upstream válido do Wrangler e envia um valor claramente inválido em cf-aig-authorization:

ACCOUNT_ID=$(node -p 'JSON.parse(require("fs").readFileSync(".labex/state.json")).accountId')
GATEWAY_ID=$(node -p 'JSON.parse(require("fs").readFileSync(".labex/state.json")).gatewayId')
MODEL='@cf/meta/llama-3.3-70b-instruct-fp8-fast'
UPSTREAM_TOKEN=$(npx wrangler auth token --json | node -e 'let s="";process.stdin.on("data",d=>s+=d).on("end",()=>process.stdout.write(JSON.parse(s).token))')
STATUS=$(curl --http1.1 -sS -o .labex/invalid-response.json -w '%{http_code}' \
  -H 'cf-aig-authorization: Bearer deliberately-invalid' \
  -H "Authorization: Bearer $UPSTREAM_TOKEN" \
  -H 'Content-Type: application/json' \
  --data '{"prompt":"This request must not reach the model.","max_tokens":8}' \
  "https://gateway.ai.cloudflare.com/v1/$ACCOUNT_ID/$GATEWAY_ID/workers-ai/$MODEL")
unset UPSTREAM_TOKEN
printf '%s\n' "$STATUS" | tee .labex/invalid-status.txt

O resultado esperado é 401 ou 403. Não exiba o corpo da resposta: o status já é evidência suficiente, e manter a saída de erro limitada reduz a possibilidade de expor detalhes da solicitação.

Associar a solicitação ao log do gateway

Nesta etapa, você usará a observabilidade para associar o comportamento em tempo de execução a um registro visível do gateway.

Observabilidade significa coletar evidências suficientes para explicar o que um sistema fez depois que uma solicitação saiu do chamador. Um log do gateway pode mostrar o provedor, o modelo, o status, a latência e o uso de tokens sem solicitar novamente ao modelo. Os logs podem levar alguns instantes para aparecer.

Leia os logs existentes pela API de gerenciamento autenticada. Esta é uma verificação somente leitura; ela não envia outra solicitação ao modelo:

ACCOUNT_ID=$(node -p 'JSON.parse(require("fs").readFileSync(".labex/state.json")).accountId')
GATEWAY_ID=$(node -p 'JSON.parse(require("fs").readFileSync(".labex/state.json")).gatewayId')
GATEWAY_TOKEN=$(cat .labex/gateway-token)
curl --http1.1 -fsS \
  -H "Authorization: Bearer $GATEWAY_TOKEN" \
  "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/ai-gateway/gateways/$GATEWAY_ID/logs?per_page=50" \
  > .labex/logs.json
unset GATEWAY_TOKEN
node - <<'NODE'
const body = require('./.labex/logs.json')
const model = '@cf/meta/llama-3.3-70b-instruct-fp8-fast'
const matches = (body.result || []).filter(row =>
  row.provider === 'workers-ai' && row.model === model
)
console.log(matches.map(row => ({
  id: row.id,
  provider: row.provider,
  model: row.model,
  success: row.success,
  created_at: row.created_at
})))
if (!matches.some(row => row.success === true)) process.exit(2)
NODE

O resultado esperado é uma entrada com provider: "workers-ai", o modelo pretendido e success: true. Se o comando terminar sem essa entrada, aguarde cerca de 20 segundos e execute novamente este mesmo bloco somente leitura, em vez de enviar mais solicitações de inferência.

Abra a visão Logs do gateway no Dashboard. Localize a linha bem-sucedida do Workers AI para @cf/meta/llama-3.3-70b-instruct-fp8-fast. Confirme o sucesso, o provedor e o modelo antes de abrir o painel de detalhes.

A tabela Logs do gateway, com a solicitação bem-sucedida do Workers AI destacada

A duração exata, a quantidade de tokens e o texto gerado podem variar. Esses valores descrevem esta solicitação; não são metas que você precise reproduzir exatamente. Nunca coloque credenciais ou informações pessoais em um prompt apenas para facilitar a localização de um log.

O painel de detalhes do log, mostrando modelo, status, latência e uso de tokens

Excluir o gateway descartável

Nesta etapa, você removerá o recurso na nuvem enquanto a credencial de gerenciamento ainda estiver disponível.

A limpeza deve ter como alvo o ID exato utilizado e deve ser comprovada por um inventário autenticado. Uma página ausente causada por logout ou falha de rede não comprova a exclusão.

ACCOUNT_ID=$(node -p 'JSON.parse(require("fs").readFileSync(".labex/state.json")).accountId')
GATEWAY_ID=$(node -p 'JSON.parse(require("fs").readFileSync(".labex/state.json")).gatewayId')
GATEWAY_TOKEN=$(cat .labex/gateway-token)
curl --http1.1 -fsS -X DELETE \
  -H "Authorization: Bearer $GATEWAY_TOKEN" \
  "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/ai-gateway/gateways/$GATEWAY_ID" \
  | node -e 'let s="";process.stdin.on("data",d=>s+=d).on("end",()=>{const b=JSON.parse(s);if(!b.success)process.exit(1);console.log("gateway deletion accepted")})'
unset GATEWAY_TOKEN

GATEWAY_TOKEN=$(cat .labex/gateway-token)
curl --http1.1 -fsS \
  -H "Authorization: Bearer $GATEWAY_TOKEN" \
  "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/ai-gateway/gateways" \
  > .labex/gateways-after-delete.json
unset GATEWAY_TOKEN
node -e 'const b=require("./.labex/gateways-after-delete.json"),id=process.argv[1],found=(b.result||[]).some(g=>g.id===id);console.log("gateway absent:",!found);if(found)process.exit(1)' "$GATEWAY_ID"

O resultado esperado é gateway absent: true. Esta segunda solicitação lista os gateways com autorização válida e falha se o ID utilizado ainda existir. Nenhum outro gateway da sua conta é modificado.

Excluir o token e encerrar a sessão

Nesta etapa, você removerá as duas credenciais independentes na ordem inversa à que usou.

No Cloudflare Dashboard, abra My Profile → API Tokens. Localize o nome exato do token armazenado em .labex/state.json, abra o menu Actions, escolha Delete, revise a confirmação e exclua somente esse token. A exclusão do token revoga imediatamente o acesso dele. É seguro removê-lo agora porque o gateway já foi excluído.

Remova a cópia local e encerre a autorização separada do Wrangler na VM:

shred -u .labex/gateway-token
npx wrangler logout
npx wrangler whoami --json || true

O resultado esperado é uma saída estruturada com loggedIn: false. A sessão do navegador no Dashboard é separada e continua conectada. Execute a verificação local final:

test ! -e .labex/gateway-token && echo "local gateway token removed"

A mensagem confirma que a cópia na VM não existe mais. O botão Check do LabEx repete de forma independente as verificações do arquivo local e do logout do Wrangler; o script de backend usado para isso não faz parte do projeto do aluno de propósito.

Agora você removeu o gateway, excluiu o token do chamador e de gerenciamento, apagou a cópia local do token e desconectou a VM recém-criada. Ao encerrar o laboratório, o LabEx destruirá essa VM temporária em vez de salvá-la. Ainda assim, a limpeza na nuvem é importante, porque destruir uma VM, por si só, não revoga um token da Cloudflare nem remove um gateway.

Resumo

Você criou um Cloudflare AI Gateway autenticado e encaminhou uma inferência real do Workers AI por ele. Manteve a autorização do gateway separada da autorização do modelo upstream, alterou apenas uma credencial para identificar o limite que rejeitou a solicitação e associou a solicitação bem-sucedida ao log do gateway. Por fim, comprovou a exclusão autenticada do recurso antes de excluir o token e encerrar a sessão da VM.

O próximo laboratório desenvolve esse fluxo de solicitações observável. Você adicionará pequenos metadados não secretos, rastreará uma falha intencional e usará evidências do gateway em vez de tentar adivinhar onde a solicitação falhou.