Todos os case studies

03Detalhamento · office3d

Transformar rastros do agente num escritório 3D ao vivo

Os mesmos rastros que eu uso pra depurar o sistema também desenham ele: um escritório isométrico onde cada figura é uma conversa acontecendo. Como eu tirei 5.000 draw calls e deixei em 8 com instanced meshes.

Em produçãoDavid RochaFaz parte do sistema ZapBeta
01

O problema

Toda conversa que os Especialistas atendem já fica registrada como trace: cada turno, cada chamada de ferramenta, cada decisão. É de onde eu depuro o sistema. Um dia percebi que dava pra desenhar esse mesmo dado — um escritório isométrico onde cada figura é uma conversa acontecendo, e você vê os Especialistas trabalhando. Serve pra mostrar numa demo e serve pra eu achar bug, com o mesmo código.

02

As restrições

  • 01Verdade, não teatro. Toda figura tem que ser conversa real vinda dos traces; animação roteirizada um CTO percebe na hora.
  • 02Aguentar a sala cheia. Quando o escritório enche, desenhar de forma ingênua vira milhares de draw calls e um slideshow.
  • 03Público sem vazar. A mesma cena roda no meu portfólio, e ali ela lê de uma fonte filtrada e opt-in — nunca da interna, com nome de cliente e faturamento.
  • 04Interativa: orbitar, dar zoom e clicar numa figura pra ver o que aquela conversa fez.
03

A arquitetura

  1. agent_traces (Postgres)

    a fonte da verdade, já escrita pelos agentes em produção

  2. carregador da cena

    agrupa os traces por conversa → posto, balão, desfecho

  3. React Three Fiber

    dynamic({ ssr: false }) — o bundle de WebGL nunca toca outras páginas

  4. duas fontes, um componente

    logada lê /api/vitrine/* · pública lê /api/showcase/* (allowlist + rate limit)

A plateia de clientes já atendidos é a armadilha de render: um dia inteiro dá milhares de figuras, e desenhadas uma a uma são milhares de draw calls. Um InstancedMesh junta tudo num punhado — a multidão saiu de cerca de 5.000 draw calls pra 8, uma por tipo de malha, com cada posição escrita num buffer só.

04

A parte difícil

As armadilhas do 3D não aparecem em teste unitário. Aparecem no instante em que você orbita a câmera.

As etiquetas <Html> do drei carregam z-index na casa dos milhões e passavam por cima de um modal que devia estar na frente, então tiveram que se esconder quando o modal da transcrição abre. O mesmo <Html> engolia clique destinado à figura atrás dele. As placas de setor, presas na parede do fundo, escorregavam pro lado conforme a câmera girava, porque estavam numa profundidade diferente das mesas que rotulavam — e nenhum offset fixo em x acerta em todos os ângulos; resolvi ancorando cada placa no centro de profundidade do próprio setor. E o chão brigou por z com os tapetes até eu afastar as coordenadas. Nada disso eu teria previsto lendo documentação.

05

Trade-offs

  • WebGL é bundle de verdade. Eu mantenho ele fora de toda página que não desenha a cena, com import dinâmico só de cliente. O custo só é pago quando o escritório aparece.
  • Instancing troca flexibilidade por frame. Todo cliente da multidão divide um material só; estilizar figura por figura seria abrir mão do caminho instanciado. Pra multidão, eu fico com os frames.
  • A cena lê quase em tempo real por polling, não por websocket. É mais simples, é amigável a cache, e alguns segundos de atraso ninguém enxerga numa vista ambiente.
06

O que eu faria diferente

Eu separaria melhor o cenário do escritório dos atores. Hoje a geometria da sala e as figuras movidas por trace moram mais perto do que deviam, então mexer no cenário arrisca o movimento. Com um cenário estático e atores por cima dele, eu cresceria o ambiente na direção do escritório caminhável que eu quero, sem ameaçar a órbita, o zoom e a caminhada — que é o que faz a pessoa lembrar dessa tela.

Vamos conversar

Estou aberto a trabalhos remotos construindo com LLMs: agentes, avaliação, ferramental e o produto inteiro em volta disso. Ficarei feliz em mostrar muito mais numa call. Pode chamar.

Disponível para posições remotas, trabalhando do Brasil.Fuso: UTC−3 (Brazil)