Criando espaços de trabalho compartilhados para pessoas e agentes
Como os Projetos do Perplexity mantêm o trabalho de longa duração persistente, concorrente e rastreável.
Lançamos recentemente o recurso Projetos, em que pessoas e agentes trabalham juntos em tarefas de longa duração no Perplexity Computer. Cada projeto fica em um espaço de trabalho compartilhado com um sistema de arquivos que acumula contexto entre sessões, agentes e usuários. A colaboração multiusuário que se estende por meses exige persistência, concorrência e rastreabilidade:
- Persistência: o trabalho deve durar além de qualquer sessão de agente ou sandbox individual, para que o mesmo usuário ou agente possa continuá-lo no futuro e qualquer colaborador possa dar sequência a ele.
- Concorrência: vários usuários no mesmo projeto podem ter, cada um, vários agentes fazendo edições em paralelo, que fazem avançar um estado compartilhado em vez de se sobrescreverem.
- Rastreabilidade: tanto usuários quanto agentes devem poder ver o histórico para verificar quem alterou o quê desde a última sessão, sem reler o projeto inteiro, e reverter edições quando necessário.
Esses desafios são familiares para engenheiros de software. Os forges Git surgiram há décadas para atender a esses requisitos: um serviço hospedado que envolve o controle de versão com recursos colaborativos para que muitos colaboradores possam convergir para uma única fonte da verdade. O sistema de arquivos por trás dos Projetos é um desses forges Git, criado para colaborações entre humanos e agentes e entre agentes.
Arquitetura
O Git já cuida de persistência, concorrência e rastreabilidade. Ele identifica cada arquivo pelo seu conteúdo, então arquivos inalterados são armazenados uma única vez e as cópias salvas nunca ficam desatualizadas. Cada commit salva todos os arquivos atualizados de uma só vez, então os colaboradores nunca veem um estado pela metade. Quando duas gravações entram em conflito, a que perdeu pode reaplicar suas alterações sobre a nova versão e tentar de novo. A cadeia de commits mostra quem alterou o quê e facilita a restauração de versões anteriores. O que os agentes dispensam é o restante de um forge feito para humanos, como telas de revisão, gerenciamento de branches e notificações.
Nossa arquitetura executa todo o processo na nuvem e oferece suporte a todas as formas de trabalho intelectual, não só à programação. Cada projeto do Computer é respaldado por um repositório Git servido por 5 componentes:
- A CLI mantém checkouts locais, sincroniza atualizações e envia as alterações do agente em cada sandbox.
- O plano de controle localiza o repositório do projeto e emite credenciais de curta duração para acessá-lo.
- O serviço Git envia dados do repositório para os sandboxes, recebe seus envios e decide qual envio se torna o commit aceito mais recente.
- O armazenamento baseado no AWS S3 guarda os dados do repositório de forma durável.
- O processamento downstream extrai texto e outras informações úteis dos documentos salvos e os disponibiliza quando os agentes carregam ou atualizam o projeto.
Cada agente tem seu próprio sandbox isolado. Dentro desse sandbox, ele trabalha com uma cópia local do repositório, gerenciada por uma pequena CLI. A CLI pede ao plano de controle que localize o repositório e, em seguida, busca e envia alterações por meio do serviço Git. Um proxy de agente verifica o acesso das requisições do sandbox antes que elas cheguem ao serviço Git. O serviço Git lê e grava repositórios em um sistema de arquivos compartilhado e decide se cada envio se torna o commit aceito mais recente. Esse sistema de arquivos é fornecido pelo AWS S3Files, que torna o armazenamento baseado em S3 acessível como arquivos e diretórios comuns. O armazenamento é dividido em células isoladas, cada uma com seu próprio sistema de arquivos e suas próprias réplicas do serviço Git. Depois que um commit é aceito, workers em segundo plano extraem texto e outras informações úteis dos documentos alterados, armazenando os resultados separadamente do histórico do repositório e disponibilizando-os quando os agentes carregam ou atualizam o projeto.
A seguir, apresentamos os componentes um a um.
CLI: trabalhando com arquivos locais nos sandboxes
Os agentes são executados no SPACE, nossa plataforma interna de sandboxes. Cada sandbox tem uma pequena CLI que materializa o repositório e o mantém sincronizado. Para cada unidade de trabalho relevante feita pelo agente, ela envia as alterações como um commit.
Os agentes normalmente acessam apenas uma pequena fração dos arquivos do projeto, então não é necessário materializar o repositório inteiro de antemão. Por isso, a CLI materializa sob demanda: arquivos grandes e binários armazenados via Git Large File Storage (LFS) chegam como pequenos arquivos de ponteiro que registram o tamanho real do objeto, para que o agente possa usar o nome e o tamanho para decidir se vale a pena fazer o download. Para documentos como PDFs, o agente lê primeiro o texto extraído e só baixa os arquivos originais quando necessário.
Outra opção natural seria usar um sistema de arquivos virtual. Testamos uma implementação baseada em FUSE, mas ela foi cerca de 400 vezes mais lenta do que arquivos locais em cargas de trabalho com uso intenso do sistema de arquivos, já que cada requisição exige uma ida e volta pela rede. Ela também costuma exigir recursos privilegiados do host, então cada agente precisaria ser executado em um sandbox privilegiado.
Plano de controle: localizando repositórios e concedendo acesso
O plano de controle localiza onde cada repositório está armazenado e concede acesso a ele. Quando um repositório é criado, o plano de controle o atribui a uma célula de armazenamento, uma unidade isolada de armazenamento com suas próprias réplicas do serviço Git. Quando um agente começa a trabalhar em um projeto, a CLI pergunta ao plano de controle onde o repositório está armazenado. O plano de controle retorna o local e credenciais temporárias para o serviço Git. O plano de controle nunca lê nem grava dados do repositório. É o serviço Git que decide o que entra em um repositório.
Serviço Git: movimentando dados e coordenando atualizações
O serviço Git executa operações Git e transfere o conteúdo e o histórico de versões dos repositórios entre os sandboxes e o armazenamento. Ele é uma camada fina sobre os próprios comandos de serviço do Git. Ele oferece suporte à descoberta de refs, para informar ao cliente onde está o head do repositório, ao upload-pack, para clonar e buscar, e ao receive-pack, para receber novos objetos e uma solicitação para avançar o head do repositório. Ele também atende à API do Git LFS: para arquivos grandes e binários, emite links de curta duração para que os sandboxes possam fazer upload e download desses arquivos diretamente do S3.
Começamos com um servidor de forge pronto para uso, para que pudéssemos prototipar as interfaces do agente e do usuário em paralelo à criação do nosso próprio forge leve, focado apenas nas operações Git de que precisamos.
O serviço consiste em uma frota de réplicas, cada uma delas uma instância em execução do mesmo servidor. Uma célula agrupa o armazenamento compartilhado com um conjunto de réplicas e seus serviços de suporte. Assim, as réplicas de uma célula podem acessar o mesmo sistema de arquivos compartilhado, em vez de manter cópias independentes de cada repositório.
Esse armazenamento compartilhado permite que as réplicas continuem sem estado. Qualquer réplica da célula pode atender qualquer um dos repositórios dela, então substituir ou adicionar réplicas não exige mover dados de repositório entre servidores. As requisições para um repositório normalmente vão para a mesma réplica para manter seus caches úteis, mas o repositório não depende de que essa instância específica continue disponível.
A etapa de aceitação verifica as invariantes do repositório para garantir que um commit aceito represente um estado válido do repositório. Definimos um contrato explícito para cada repositório, para que verificações mecânicas impeçam que ele cresça demais. Arquivos grandes e binários, como PDFs e imagens, são armazenados via Git LFS, e não como blobs brutos do Git. A compactação mantém o histórico recente disponível e, ao mesmo tempo, limita o tamanho do repositório. Após um envio bem-sucedido, a CLI pergunta ao serviço Git se o repositório precisa de compactação. Se o número de commits retidos ultrapassar um limite, o serviço Git mantém apenas um conjunto menor dos commits mais recentes. O histórico mais antigo é substituído por um único snapshot inicial, e os commits recentes são reaplicados para atualizar os identificadores de commit.
Uma etapa simples de sincronização lida com gravações concorrentes. Ela acompanha o commit aceito mais recente, ou head. Quando recebe um envio, ela o aceita apenas se ele tiver sido criado sobre esse head. Caso contrário, envia uma resposta estruturada de base desatualizada; o perdedor então precisa reaplicar sua alteração sobre o novo head e reenviá-la. Esse design garante que agentes concorrentes não sobrescrevam silenciosamente o trabalho uns dos outros, sem causar lentidão significativa. Em nossos fluxos de trabalho de produção, menos de 2% dos envios são rejeitados por estarem desatualizados. No geral, a latência mediana de envio fica abaixo de 1,7 segundo, e a latência p99 fica abaixo de 8 segundos.
O serviço Git também registra cada alteração aceita. Para cada gravação aceita, ele adiciona uma entrada a uma caixa de saída (outbox), um log que lista o repositório, o novo commit, o usuário que fez a alteração e os caminhos alterados. Serviços downstream, como o parser, leem esse log para encontrar novas tarefas.
Juntas, essas peças formam uma camada de gerenciamento de repositórios, sem as partes de que os agentes não precisam. Pull requests são desnecessários, porque nenhum humano revisa cada alteração. Em vez disso, o serviço Git verifica o contrato no momento do envio, o agente que perde uma disputa reaplica a própria alteração e o histórico de commits registra quem alterou o quê. Verificações determinísticas mantêm cada repositório dentro do seu contrato, em vez de depender de um operador humano para gerenciar o crescimento.
Armazenamento: mantendo o trabalho durável
A camada de armazenamento salva os dados do repositório de forma durável, independentemente dos sandboxes e das réplicas do serviço Git. Os repositórios ficam no AWS S3Files, que expõe armazenamento baseado em S3 por meio de uma interface de sistema de arquivos que o Git padrão pode usar sem modificações. Cada um é um repositório Git bare no sistema de arquivos compartilhado, contendo os objetos e as referências do repositório, e não um checkout de trabalho.
Desacoplar armazenamento e computação permite que os sandboxes continuem efêmeros. Cada agente recebe seu próprio sandbox, e muitos agentes podem trabalhar no mesmo projeto sem compartilhar uma máquina. Se um sandbox falhar, só o trabalho que ainda não foi enviado fica em risco.
Em vez disso, poderíamos dar a cada projeto um sandbox de longa duração compartilhado por todos os seus agentes, de modo que os arquivos do projeto ficariam no disco dessa máquina. No entanto, isso amarraria a computação dos agentes ao local onde a máquina é executada e exigiria dimensioná-la para os períodos de maior demanda. Ela também precisaria permanecer íntegra por meses, com backups e recuperação gerenciados como parte do sistema de armazenamento do projeto.
Processamento downstream: tornando os documentos legíveis para os agentes
O principal componente downstream é um pipeline de parsing que extrai texto e metadados de documentos recém-adicionados ou atualizados, para que os agentes consigam ler facilmente os arquivos do projeto. Um worker de parsing consome atualizações da fila do fluxo de alterações, identifica os arquivos alterados a partir dos metadados do commit e busca os bytes brutos usando o hash do conteúdo. Em seguida, ele faz o parsing do documento para produzir o texto extraído e os metadados do documento.
Os resultados do parsing ficam fora do repositório, em um armazenamento indexado pelo hash do documento original. Esses artefatos nunca são enviados de volta ao repositório como commits, pois isso poluiria o histórico desnecessariamente e aumentaria o número de gravações concorrentes. Em vez disso, os resultados do parsing chegam a um sandbox por meio de checkout e sincronização. Cada checkout inclui um diretório reservado que a CLI usa para materializar os artefatos. O parsing acontece de forma assíncrona, então um worker de parsing em segundo plano não bloqueia os checkouts.
Como os agentes usam o espaço de trabalho
Os agentes exploram a versão do repositório carregada no sandbox usando ferramentas padrão de sistema de arquivos. Em vez de seguir um pipeline fixo de buscar e depois ler, eles listam pastas, pesquisam o conteúdo dos arquivos com grep, leem trechos relevantes e usam o que encontram para decidir onde procurar em seguida.
Assim como o Computer, o Search usa a mesma abordagem por meio de suas ferramentas de arquivo padrão. Um agente de exploração separado pesquisa o projeto com um orçamento mais limitado e retorna caminhos de arquivo relevantes e trechos de apoio. Em seguida, o modelo de resposta lê os arquivos selecionados e gera a resposta. Reutilizar um sandbox de projeto existente reduz o tempo de preparação: conectar-se a um checkout já aquecido leva cerca de 2,9 segundos, contra aproximadamente 8 segundos em uma inicialização a frio.
O texto extraído torna documentos maiores, como PDFs e arquivos do Office, pesquisáveis com as mesmas ferramentas. Primeiro, o agente consulta um manifesto, uma lista que mostra quais documentos têm texto extraído disponível, e depois pesquisa e lê esse texto como arquivos comuns. Ele só baixa o documento original quando o texto não é suficiente, por exemplo, para inspecionar figuras, o layout ou dados incorporados.
Comparamos essa abordagem com a busca semântica sobre um índice em 150 perguntas financeiras de documento único, usando o mesmo corpus. O agente de exploração obteve 0,867 na recuperação do documento correto e 0,627 na resposta correta, contra aproximadamente 0,39 e 0,37 da busca semântica: cerca de 1,7x melhor nas respostas e 2x melhor na recuperação, com latência cerca de 25% menor. O agente de exploração trabalha principalmente com o texto extraído e raramente baixa os PDFs originais.
Uma só infraestrutura compartilhada
A memória persistente do Computer usa a mesma infraestrutura de sistema de arquivos. O Perplexity Brain, a wiki de conhecimento do Computer, armazena a memória em repositórios de conhecimento com histórico e políticas próprios. Manter o conhecimento separado dos arquivos do projeto significa que as atualizações de memória em segundo plano não concorrem com as edições desses arquivos. Uma sessão que precisa de ambos carrega os dois repositórios.
Agentes em segundo plano leem o conhecimento existente, incorporam novas informações e salvam as páginas atualizadas como commits. Outros agentes leem essas páginas com ferramentas comuns de arquivo, e as pessoas também podem editá-las. Quem grava compartilha seu trabalho por meio do repositório, em vez de se coordenar diretamente com cada leitor. O histórico de commits registra quem alterou o quê, enquanto a caixa de saída informa as atualizações aceitas aos serviços downstream. Pessoas e agentes podem aproveitar o trabalho uns dos outros, com um registro de como o conhecimento evoluiu.
Conclusão
Quando pessoas e agentes compartilham um projeto, o espaço de trabalho faz mais do que armazenar arquivos. Ele oferece um lugar comum para combinar contribuições e acompanhar o que mudou. O Git já fornece grande parte dessa base. Adicionamos coordenação e verificações automatizadas para que os agentes possam enviar trabalho sem que uma pessoa aprove cada atualização. O resultado é um forge reduzido ao essencial, já que a colaboração entre agentes e o desenvolvimento de software com vários colaboradores são, no fundo, o mesmo problema.
Os agentes trabalham em sandboxes independentes e temporários enquanto contribuem para repositórios duráveis. Os limites de repositório mantêm o crescimento sob controle, os downloads explícitos permitem que os agentes escolham o que buscar e os arquivos comuns permitem que eles explorem com ferramentas conhecidas. Atualizações em segundo plano, edições interativas e tarefas agendadas podem aproveitar o trabalho umas das outras sem coordenação direta.
À medida que mais agentes trabalham de forma autônoma dentro dos Projetos, o espaço de trabalho compartilhado entre eles precisa continuar confiável e compreensível para as pessoas. O objetivo é simples: cada alteração deve durar mais do que o agente que a produziu, ficar disponível para o próximo colaborador e deixar um registro claro do que mudou.
Citação
@online{perplexity2026BuildingSharedWorkspacesForPeopleAndAgents,
author = {{Perplexity} and Se Won Jang and Peter Hart and Kartik Kapur and Kevin Lau and Sidhant Rajadnya and Ishbir Singh and Thomas Wang and Jarrod Bryan and Claire Beamer and Jeremy Yang},
title = {{Building shared workspaces for people and agents}},
date = {2026-10-12},
url = {https://www.perplexity.ai/hub/blog/building-shared-workspaces-for-people-and-agents}
}