Quando muitos clientes compartilham um modelo do Bedrock, o modelo não oferece isolamento nenhum e nunca ofereceria. É uma função sem estado: mesma entrada, mesmo comportamento, nenhuma memória de quem chamou. Toda fronteira entre clientes tem que ser construída nas camadas ao redor do modelo, não esperada dele. Times entendem isso ao contrário, assumem que o serviço gerenciado cuida da separação, e lançam um app onde os dados, o custo e a carga de um cliente vazam para outro. O modelo compartilhado está bem. O tudo-mais compartilhado é o problema.

A parte tranquilizadora é que o modelo não ter estado também é o que torna a multi-tenancy viável. Não há estado por cliente dentro do modelo para vazar, porque não há estado algum. O isolamento se reduz a três fronteiras concretas que você já sabe construir: quais dados a requisição de um cliente pode alcançar, quanto da capacidade compartilhada ela pode consumir, e sob qual identidade ela roda.

Isolamento de dados: delimite a busca, não o modelo

O risco real de vazamento em um app de RAG ou agente não são os pesos, é o contexto que você coloca na frente deles. Se a pergunta do cliente A busca os documentos do cliente B, você tem uma violação de dados disfarçada de resposta útil. Então a camada de busca é onde vive a separação de clientes.

Dois formatos viáveis, dependendo de quão rígida a fronteira precisa ser:

  • Knowledge Base por cliente. A fronteira rígida. Cada cliente ganha sua própria Bedrock Knowledge Base, então uma consulta só pode buscar no corpus daquele cliente. Mais simples de raciocinar, mais peças móveis para gerenciar conforme o número de clientes cresce.
  • Armazenamento compartilhado, filtrado por cliente. Um único vector store com um filtro obrigatório de ID de cliente em toda consulta, para que os resultados sejam delimitados por metadados. Mais barato de operar, mas o filtro agora é segurança de sustentação. Precisa ser aplicado do lado do servidor a partir de uma identidade autenticada, nunca de um valor que o cliente pode definir.

A falha a evitar é filtrar por um ID de cliente que chegou no corpo da requisição. Se o cliente pode nomear o próprio tenant, o cliente pode nomear o tenant de outra pessoa. Derive o tenant a partir do principal autenticado e aplique o escopo onde o cliente não consegue alcançar.

O vizinho barulhento: uma cota compartilhada é uma falha compartilhada

O Bedrock limita por tokens por minuto no nível da conta e do modelo. Esse número é compartilhado entre todos os clientes que acessam aquele modelo na sua conta. Então um cliente rodando um job em lote pesado gasta o orçamento compartilhado de tokens, e todo outro cliente começa a coletar erros de throttling por uma carga que não gerou. O modelo é isolado logicamente e acoplado operacionalmente.

Isolamento aqui significa medir e limitar por cliente antes que o teto compartilhado faça isso por você:

  • Orçamentos de token por cliente. Acompanhe tokens consumidos por cliente por janela e rejeite ou enfileire um cliente que estoura sua própria alocação, para que seu pico não consuma o pool compartilhado.
  • Fila justa. Um pool de workers limitado por cliente na frente do modelo transforma o pico de um cliente na lentidão daquele cliente, não em uma indisponibilidade para todos.
  • Camadas de prioridade. Se os clientes pagam por níveis de serviço diferentes, aplique isso no controle de admissão. Um lote de nível gratuito não deveria conseguir esganar o tráfego interativo de um cliente pagante.

Identidade: a fronteira do cliente deve alcançar as ferramentas

O isolamento não pode parar na busca. No momento em que um agente chama uma ferramenta, lê de um banco de dados, ou escreve em um armazenamento, a fronteira do cliente precisa viajar junto com a requisição. Isso significa que a requisição roda sob uma identidade delimitada ao cliente, para que mesmo se o modelo for convencido a pedir os dados errados, as credenciais por trás da ferramenta não consigam buscá-los. A camada do modelo não confia em nada; a camada de IAM aplica tudo. Isso é privilégio mínimo aplicado por cliente, e é o que impede que uma tentativa de prompt injection vire uma leitura entre clientes.

A conclusão

Um modelo compartilhado não é um app de tudo-compartilhado. O modelo não tem estado, então não oferece isolamento e não precisa de nenhum estado próprio protegido. Seu trabalho são as três fronteiras ao redor dele: delimite a busca para que um cliente só veja seus próprios dados, meça e limite a capacidade para que nenhum cliente esganhe os outros na cota de tokens compartilhada, e carregue uma identidade por cliente até as ferramentas para que uma credencial delimitada seja a última linha de defesa quando a camada de prompt for enganada. Construa essas três e um modelo atende muitos clientes com segurança. Ignore qualquer uma e o modelo servirá alegremente os dados do cliente errado para o cliente errado.

Leia isso a seguir

Para o lado de plataforma e isolamento multi-conta do mesmo problema, as notas de campo sobre cloud estão em ercan.cloud, e o hub está em ercanermis.com.