O Problema da Dispersão de Dados que Toda Empresa em Crescimento Enfrenta
Se você já trabalhou numa empresa que escalou rapidamente, conhece a dor. Os dados vivem em todo lugar: bancos de produção, clusters ClickHouse, streams Kafka, object storage e um monte de pipelines. Cada sistema tem suas próprias credenciais, linguagem de consulta e política de retenção. Fazer uma pergunta simples como 'Quantos domínios que se registraram hoje estão no Top 100 por tráfego?' exige conhecimento tribal — saber qual sistema consultar, quais joins fazer e se os dados estão frescos ou amostrados.
A Cloudflare enfrentou exatamente esse desafio processando mais de um bilhão de eventos por segundo em 330+ cidades. A solução não foi outra ferramenta de BI — foi repensar completamente a infraestrutura de dados. Eles construíram duas coisas: Town Lake, uma interface SQL unificada para tudo que a Cloudflare sabe, e Skipper, um agente de IA que permite qualquer pessoa fazer perguntas em inglês simples e obter respostas auditáveis em segundos.
Este é um mergulho profundo em como eles construíram ambos, as decisões arquiteturais que importam e as lições valiosas que se aplicam a qualquer esforço sério de plataforma de dados.

Town Lake: A Arquitetura Data Lakehouse
Town Lake é construído no padrão data lakehouse: um motor de consulta lendo de object storage, com uma camada de metadados que faz o storage se comportar como banco de dados. Os componentes principais são:
Motor de Consulta: Apache Trino
Trino permite que uma única consulta SQL faça join entre uma tabela Postgres, uma tabela ClickHouse e uma tabela Iceberg no R2 sem materializar resultados intermediários. Uma consulta como 'top 100 clientes pagantes por requisições Workers esta semana' compila para um plano que empurra filtros para o ClickHouse, faz join com dimensão de contas no Postgres e ranqueia contra rollups de billing no R2 — tudo de uma vez.
Armazenamento: R2 + Apache Iceberg
Dados frios e mornos ficam no R2 via serviço gerenciado Iceberg. Iceberg oferece evolução de schema, time travel e evolução de partição. O insight chave é compactação em camadas: dados por minuto viram horários, depois diários, conforme envelhecem. Custos de armazenamento diminuem com a idade dos dados mantendo a capacidade de consulta.
Metadados: DataHub
Cada tabela, coluna, dono e linhagem vive no DataHub. Quando o Skipper precisa entender dim.accounts, ele puxa o schema, descrições de colunas, time dono e dependências upstream/downstream.
Controle de Acesso: Lifeguard
Lifeguard armazena regras de acesso no D1, puxa dinamicamente membros de grupos e renderiza uma política JSON combinada que o Trino lê via HTTP. A decisão crítica: governança fechada por padrão. Tabelas ficam inacessíveis até serem revisadas.
-- Exemplo: Consultando Town Lake com redação automática de PII
-- Colunas PII são redigidas por padrão a menos que flag de sessão seja ativado
SET SESSION townlake.redact_pii = TRUE;
SELECT account_id, email, usage_amount
FROM townlake.fct.billings_allocated
WHERE date >= CURRENT_DATE - INTERVAL '30' DAY
ORDER BY usage_amount DESC
LIMIT 10;
-- coluna email será redigida (ex.: '***@***.com')
Detecção de PII: Skimmer
Skimmer continuamente amostra linhas de cada coluna e usa Workers AI para classificar PII em duas passadas. Primeiro, um classificador rápido por coluna; depois, se algo for sinalizado, uma segunda passada agentica com contexto completo da tabela. Achados fluem para DataHub e para a allowlist do Lifeguard para revisão humana.

Skipper: O Agente de Dados com IA
Skipper é um agente de IA conversacional que vai de pergunta em linguagem natural para resposta validada, fundamentada em dados reais, código e conhecimento institucional. A arquitetura usa Workers, Workers AI, Durable Objects e D1.
Cinco Camadas de Contexto (O Segredo)
O maior desafio era prevenir joins alucinados e respostas erradas. A solução é contexto em camadas:
- Metadata de schema & uso do DataHub
- Anotações humanas como 'Uma linha por account_id'
- Conhecimento derivado de código: o SQL real que produz uma tabela (ex.:
alloc_amount = billed_amount / 12 for annual) - Modelos de dados curados: documentos escritos por humanos descrevendo como pensar sobre billing, clientes, etc.
- Introspecção em runtime:
DESCRIBE table,SELECT DISTINCT col LIMIT 20como rede de segurança
Code Mode: Repensando Ferramentas MCP
Em vez de expor 30 ferramentas individuais, Skipper expõe duas: search e execute. O modelo escreve JavaScript que chama todo o conjunto programaticamente:
// Exemplo: Análise de dados multi-etapa em uma única ida e volta
const datasets = await skipper.search_datasets({ query: "billing product revenue" });
const queryId = await skipper.start_query({
sql: "SELECT region, SUM(usage_amount) FROM fct.billings_allocated GROUP BY region"
});
const results = await skipper.fetch_results({ queryId, mode: "inject" });
return skipper.create_chart({ chartType: "bar", data: results.rows });
Este JavaScript roda num isolate Dynamic Worker em sandbox. Workflows complexos acontecem numa única ida e volta, são mais rápidos, mais baratos e auditáveis como código.
![]()
Lições Principais e Limitações
O Que Funcionou
- Menos prompt é mais: Prompts de sistema prescritivos pioraram a qualidade. Orientação de alto nível permite melhor raciocínio do modelo.
- Sobreposição de ferramentas é veneno: Consolide ferramentas; cada ferramenta deve ter uma única razão de existir.
- Código, não metadata, captura significado: Os maiores ganhos de acurácia vieram de ingerir o SQL real que produz tabelas.
- Memória importa mais que esperado: Uma camada de memória para correções recorrentes torna o agente monotonicamente melhor.
Limitações e Considerações
- Infraestrutura chata é a parte difícil: Controle de acesso por linha, allowlisting fechado por padrão e logging de auditoria são o que tornam uma plataforma de dados segura. Não pule isso.
- Contexto em runtime é caro: Consultas de introspecção ao vivo custam dinheiro e tempo; use com moderação.
- Modelo de segurança = modelo de dados: Tudo que Skipper faz roda como o usuário chamando. Sem escalonamento de privilégio, ponto.
Próximos Passos para seu Aprendizado
- Comece com um lakehouse pequeno: Monte Trino + Iceberg em object storage. Familiarize-se com o motor de consulta.
- Implemente governança fechada por padrão: Construa detecção automatizada de PII e allowlisting de tabelas desde o dia um.
- Camadas de contexto para seu agente de IA: Comece com metadata de schema, depois anotações humanas, depois conhecimento derivado de código.
- Estude o padrão MCP: A abordagem Code Mode é uma forma nova de reduzir idas e voltas em workflows agenticos.
Para mais sobre infraestrutura de dados em larga escala, veja este guia sobre migração de sistemas de ingestão em escala petabyte. E se você está construindo interfaces de agentes de IA, esta análise do diretório de adaptadores Chat SDK da Vercel oferece padrões úteis.