ISMS Copilot Docs

Redação SSE: Defendendo Prompts de Sistema de LLM em Arquiteturas de Streaming

Por Better ISMS — Fevereiro de 2026

Por Better ISMS — Fevereiro de 2026

Se você está construindo um produto com base em um LLM, o seu prompt de sistema é a sua lógica de produto. Quando alguém o extrai, obtém o seu raciocínio, as suas proteções, a sua vantagem competitiva — tudo. E se você estiver transmitindo respostas via Server-Sent Events (o que provavelmente está), defender-se contra extrações é mais difícil do que imagina.

Este artigo descreve a redação SSE, uma técnica que desenvolvemos para o ISMS Copilot para detectar e neutralizar vazamentos de prompts de sistema durante a transmissão. Estamos compartilhando a arquitetura para que outros que constroem produtos com LLM possam implementar algo semelhante.

O Problema

A maioria das aplicações de LLM transmite respostas ao cliente em pedaços usando SSE. Cada pedaço é enviado no momento em que é gerado. Não há uma etapa de "revisar a resposta completa antes de enviar" — isso derrotaria o propósito do streaming.

Isso cria uma lacuna de segurança: se um prompt de jailbreak convencer o modelo a vazar suas instruções de sistema, o conteúdo já estará sendo enviado ao cliente antes que você possa detê-lo. Quando perceber o que aconteceu, o usuário já terá visto centenas ou milhares de caracteres do seu prompt de sistema.

A filtragem tradicional de saída não funciona aqui. Você não pode armazenar em buffer a resposta completa (a latência prejudica a UX), e não pode verificar cada pequeno pedaço isoladamente (um fragmento de 5 palavras não parece um prompt de sistema).

Para estratégias gerais de prevenção de jailbreaks, consulte Mitigar Jailbreaks e Injeções de Prompt. A redação SSE é uma medida de defesa em profundidade para quando essas prevenções falham.

A Arquitetura

A redação SSE funciona em quatro etapas.

Etapa 1 — Impressão digital. Antes que qualquer conversa aconteça, você extrai um conjunto de frases de impressão digital do seu prompt de sistema. Estas são strings distintivas que só apareceriam juntas se o modelo estivesse reproduzindo suas instruções. Você quer frases espalhadas por diferentes seções do seu prompt — definições de função, nomes de restrições, regras comportamentais. O número de impressões digitais e o limite de correspondência são parâmetros ajustáveis que você mantém em segredo.

Etapa 2 — Acumulação e verificação periódica. À medida que o modelo transmite os pedaços, um guard acumula o texto completo da resposta. Em intervalos regulares (medidos pela contagem de caracteres, não por pedaço), ele verifica o conteúdo acumulado em relação ao conjunto de impressões digitais. Verificar cada pedaço seria um desperdício — as impressões digitais precisam de contexto suficiente ao redor para corresponder de forma significativa.

Etapa 3 — Propagação de erro. Quando o guard detecta correspondências suficientes de impressões digitais, ele lança um erro tipado (no nosso caso, SystemPromptLeakError). Aqui reside a sutileza. Em uma arquitetura de streaming, o loop de processamento de pedaços normalmente tem um try/catch para lidar com dados SSE malformados (JSON inválido, formatos inesperados). Esse bloco catch genérico engolirá o seu erro de segurança se você não tomar cuidado. Você precisa de uma cláusula de guarda que relance o seu tipo de erro específico antes que o manipulador genérico seja executado:

catch (e) {
  if (e instanceof Error && e.name === 'SystemPromptLeakError') throw e;
  // o tratamento de erro genérico continua para todo o resto
}

Isso é uma linha de código, mas, sem ela, todo o sistema de detecção fica inerte. O guard dispara, registra a detecção e o stream continua felizmente entregando o seu prompt de sistema ao invasor. Aprendemos isso da maneira mais difícil — o nosso guard estava detectando vazamentos perfeitamente nos registros enquanto não fazia absolutamente nada para impedi-los.

Etapa 4 — Redação. Uma vez que o erro se propaga até o controlador de stream, ele envia um evento SSE de redação ao cliente. O cliente substitui o que já foi renderizado por uma mensagem de recusa. O servidor simultaneamente substitui o conteúdo armazenado no banco de dados para que o vazamento não persista.

O Que o Usuário Vê

O invasor vê brevemente o conteúdo transmitido parcialmente — talvez alguns segundos de conteúdo — então toda a resposta é substituída por uma recusa genérica. A experiência é: o texto aparece e, em seguida, desaparece e é substituído. O conteúdo parcial que ele vislumbrou está incompleto e misturado com o texto normal da resposta, tornando-o não confiável para extração.

Saiba mais sobre como as mensagens de recusa funcionam em Lidar com Recusas e Limites de Escopo.

O Problema do Bloco Catch

Isso merece ênfase porque é o tipo de bug que passa em todos os testes, mas falha em produção.

Se você estiver usando geradores assíncronos para streaming, o seu loop de análise de SSE provavelmente se parece com isto:

for (const line of sseLines) {
  try {
    const data = JSON.parse(line);
    const text = extractText(data);
    await onChunkCallback(text);  // <-- o guard é executado aqui
    yield text;
  } catch (e) {
    console.error('Erro ao analisar pedaço:', e);
    // continua para a próxima linha
  }
}

A callback está dentro do bloco try. Se o guard lançar uma exceção, o catch a registra como um erro de análise e segue em frente. No nosso caso, o guard detectou o vazamento corretamente em cada pedaço após o limite — os registros mostravam o SystemPromptLeakError sendo disparado repetidamente — enquanto o stream era concluído normalmente, salvava o prompt vazado completo no banco de dados e o enviava ao cliente.

A complicação adicional: esse comportamento depende do ambiente de execução. No Node.js, erros de geradores assíncronos de callbacks podem se propagar de forma diferente do que no Deno. Nossos testes passaram no ambiente de teste do Node.js porque o erro coincidentemente se propagou. Na produção com Deno, ele foi engolido. Se estiver construindo isso, teste no seu ambiente de produção real, não apenas no seu executor de testes.

Decisões de Design que Vale a Pena Observar

Por que impressões digitais em vez de similaridade de embedding ou correspondência exata? As impressões digitais são rápidas (correspondência de strings), determinísticas (sem chamadas de modelo) e robustas contra paráfrase. O modelo raramente parafraseia o seu próprio prompt de sistema durante um vazamento — ele o reproduz de forma literal ou quase literal. A similaridade de embedding adiciona latência por verificação e introduz o risco de falsos positivos em conteúdo legítimo de conformidade. A correspondência exata de substring é muito frágil (diferenças de espaço em branco, formatação).

Por que verificar periodicamente em vez de a cada pedaço? Os pedaços são pequenos (geralmente 3–10 caracteres). Um único pedaço não tem significado para detecção. Acumular até um limite mínimo antes de verificar reduz a computação e garante contexto suficiente para correspondência confiável.

Por que não armazenar em buffer a resposta completa? Armazenar em buffer prejudica a UX de streaming. Os usuários esperam ver o texto aparecer em tempo real. Um buffer de 2 segundos é perceptível; armazenar em buffer uma resposta completa de 4000+ caracteres é inaceitável. A redação SSE preserva o streaming em tempo real para 99,99% das conversas e só intervém durante um vazamento ativo.

Por que substituir também no banco de dados? Se você redigir apenas no cliente, o conteúdo vazado persiste no lado do servidor. Qualquer pessoa com acesso ao banco de dados, qualquer recurso de exportação, qualquer endpoint de histórico de conversas o exporia.

O Que Isso Não Resolve

A redação SSE é uma medida de defesa em profundidade, não uma solução milagrosa.

Ela não impede o modelo de tentar vazar. Isso é tratado pelas próprias instruções do seu prompt de sistema (instruções explícitas de recusa, seções de restrição). A redação SSE é a rede de segurança para quando essas instruções falham — e, com criatividade suficiente, os jailbreaks ocasionalmente têm sucesso.

Ela não impede vazamentos menores que o limite de detecção. Se alguém induzir o modelo a revelar uma única frase do prompt de sistema, a contagem de impressões digitais não atingirá o limite. Isso é por design — você está fazendo uma troca entre capturar extrações completas (alta confiança) e sinalizar menções parciais (alto risco de falso positivo).

O invasor vê conteúdo parcial antes da redação. Por alguns segundos, o texto transmitido é visível. Isso é inerente às arquiteturas de streaming. O conteúdo parcial está incompleto e carece de estrutura, mas não é exposição zero.

A redação SSE complementa, mas não substitui, as melhores práticas de segurança de prompts de sistema. Consulte Prompts de Sistema e Proteger Workspace e Instruções Personalizadas para medidas de segurança fundamentais.

Lista de Verificação de Implementação

Se quiser construir isso para o seu próprio produto de LLM:

  1. Extraia frases de impressão digital do seu prompt de sistema — escolha strings distintivas que abranjam seções.
  2. Construa um guard que acumule o conteúdo transmitido e verifique periodicamente em relação às impressões digitais.
  3. Defina uma classe de erro tipada com um nome distintivo para detecção de vazamento.
  4. Audite todos os blocos catch no seu pipeline de streaming — adicione guardas de relançamento para o seu tipo de erro.
  5. No seu controlador de stream, trate o erro enviando um evento de redação e substituindo o conteúdo armazenado.
  6. No cliente, trate o evento de redação substituindo o conteúdo renderizado por uma mensagem de recusa.
  7. Teste no seu ambiente de produção, não apenas no seu executor de testes.
  8. Mantenha suas impressões digitais, limites e intervalos de verificação em segredo.

Consideração Final

A parte mais difícil disso não foi o algoritmo de detecção — foi um bug de uma linha em um bloco catch que desativou silenciosamente todo o sistema. A segurança em arquiteturas de streaming falha no nível da infraestrutura, não no nível do algoritmo. Se estiver construindo recursos de segurança para LLM, rastreie o caminho completo do erro desde a detecção até a ação voltada ao usuário e verifique-o no seu ambiente de produção real.

Para uma visão mais ampla das práticas de segurança de IA no ISMS Copilot, consulte Visão Geral de Segurança e Uso Responsável de IA.

Better ISMS constrói ferramentas de conformidade para equipes de segurança da informação. O ISMS Copilot é o nosso assistente de IA para ISO 27001, SOC 2, GDPR e frameworks relacionados.

On this page