IA air-gapped: executar LLMs totalmente offline com Ollama
Uma arquitetura prática para IA sem conectividade de saída: Ollama como LLM local, LanceDB para vetores, redação DLP em cada prompt, tudo em um contêiner offline.
Por que air-gap é uma forma de implantação, não um flag de recurso
A maioria dos produtos de IA "self-hosted" ainda vaza dados. Uma chamada a uma API de modelo aqui, uma requisição de embedding ali, um ping de telemetria, uma verificação de licença que liga para casa - cada uma defensável isoladamente, e juntas significam que seus documentos internos, prompts e respostas atravessam uma fronteira de rede que você não controla. Para prestadores de serviços de defesa, hospitais, bancos e qualquer organização com exigência de residência de dados, isso é eliminatório. O requisito não é "quase offline" - é um sistema de IA que funciona com o cabo de rede desconectado.
O Simmetric Chat é construído em torno desse requisito. A operação air-gapped não é um modo que você desbloqueia nem um plugin que você compra: a configuração padrão da plataforma comunitária já é a offline - um LLM local, embeddings locais, um armazenamento vetorial local baseado em arquivos e um pipeline de documentos que nunca precisa da internet. Este artigo percorre cada camada que faz a conectividade zero de saída funcionar, e o que você abre mão - muito pouco - ao fechar o perímetro.
A pilha local: cada camada tem um padrão offline
Um chat de IA tem quatro dependências externas numa arquitetura SaaS típica: o modelo de linguagem, o modelo de embedding, o armazenamento vetorial e o pipeline de documentos. Os padrões do Simmetric Chat substituem os quatro por componentes locais:
- O LLM roda no Ollama. O provider padrão da plataforma é o Ollama na rede local, e o modelo padrão (
gemma4:latest) é baixado no momento da instalação para que o chat funcione antes de qualquer download de modelo em tempo de execução. O Ollama fala HTTP compatível com OpenAI na sua própria rede, e a configuração do provider aponta para ele com uma URL - não um endpoint na nuvem. - Os embeddings rodam localmente. O provider de embedding padrão é um modelo transformers local (384 dimensões, executado in-process no collector), não uma API de embeddings hospedada. Embeddings locais são compatíveis com air-gap por construção, e a guarda de incompatibilidade de embeddings significa que alternar entre providers locais e remotos depois é seguro - o retrieval degrada para busca por palavras-chave até a reindexação terminar, em vez de servir pontuações de espaços misturados.
- Os vetores vivem no LanceDB. O armazenamento vetorial padrão é baseado em arquivos, guardado no diretório de storage da própria implantação, com uma coleção por workspace. Sem servidor de banco vetorial, sem salto de rede. Qdrant, pgvector e Chroma continuam disponíveis para equipes cuja escala pede um índice em rede, mas nada os exige.
- O parsing de documentos acontece na sua rede. O collector - o serviço que faz parsing, chunking e embedding dos uploads - faz parte da sua implantação. PDFs, arquivos Word e Excel, apresentações e transcrições do YouTube são processados dentro do perímetro, incluindo documentos digitalizados encaminhados pelo pipeline de OCR com modelo de visão do lado do servidor, que usa um modelo de visão local.
Nada nessa lista é tratado como caso especial ou adicionado depois. O padrão de estratégia em cada fronteira faz da opção local simplesmente o provider padrão, selecionado por configuração como qualquer outro.
DLP: redação antes de qualquer coisa sair - ou antes mesmo de se mover
Fechar a conectividade de saída não fecha todos os caminhos de exfiltração, porque o conteúdo também circula dentro da sua rede: prompts entram na plataforma, respostas fluem para os usuários, e ambos passam por interfaces de chat das quais as pessoas copiam. O filtro de data-loss-prevention do Simmetric Chat escaneia as duas direções - o prompt de entrada e a resposta de saída, incluindo os flushes de streaming token a token - e redige as correspondências antes que o conteúdo seja armazenado ou exibido.
O scanner reconhece as classes de PII que importam num contexto de chat: endereços de email, números de cartão de crédito, chaves de API e chaves privadas, e - adicionados na v0.22 - identificadores europeus estruturados: Partita IVA italiana, codice fiscale e IBAN, semeados como patterns integrados idempotentes e ancorados no rótulo para que números comuns nunca os acionem. A configuração de patterns é gerenciada pelo admin e respaldada por banco de dados: ative ou desative qualquer pattern, adicione até cinquenta patterns personalizados com validação de compilação ao vivo e prévia de teste, e inspecione um painel de histórico de correspondências filtrado por origem.
A intenção de design é que o DLP seja a última linha, não a primeira. A primeira linha é a arquitetura: com modelos locais, embeddings locais e vetores locais, não existe endpoint de terceiros para onde conteúdo sensível possa ir em primeiro lugar. O DLP então cobre os caminhos que restam - conteúdo que sai da plataforma na direção dos seus próprios usuários, ou que um funcionário bem-intencionado cola num prompt. Ele também cobre a superfície do widget, para que as conversas voltadas a visitantes no seu site sejam redigidas pela mesma cadeia de filtros, com a trilha de auditoria distinguindo tráfego de chat do de widget.
A implantação em contêiner único: tudo em um host
Fechar o perímetro é uma coisa; levar o software para dentro de um perímetro é outra. Ambientes air-gap normalmente não conseguem rodar confortavelmente uma pilha compose de cinco serviços - eles rodam um host com uma única imagem, e quanto menos partes móveis, menos artefatos precisam ser verificados e transferidos.
O Simmetric Chat entrega uma imagem all-in-one em contêiner único exatamente para este caso. Um contêiner, supervisionado por um gerenciador de processos, executa tudo: PostgreSQL 16 (com a extensão pgvector compilada a partir do código-fonte no build da imagem, portanto instalada offline), o servidor de API, o collector de documentos e o serviço de widget. O contêiner expõe três portas - 3000 para a API, 3210 para o collector, 3211 para o widget - e faz healthcheck do próprio endpoint /api/health, que reporta o estado do banco de dados, do collector e do disco.
Colocar a imagem para dentro segue a mesma disciplina de qualquer outro artefato: transfira o tarball da imagem (ou o espelho de registry que você validou), carregue e execute. Os padrões de ambiente na imagem são placeholders de andaime - a produção sobrescreve JWT_SECRET, COLLECTOR_SECRET e a chave de criptografia pela configuração de ambiente, e o servidor falha em voz alta no boot se os segredos de produção estiverem ausentes, para que uma implantação air-gap mal configurada nunca inicie silenciosamente. Após o boot, atualizações de software são novas versões de imagem, não instalações de pacotes - nenhum acesso à internet é necessário em nenhum ponto do ciclo de vida.
# Transfira para dentro do perímetro, depois:
docker load -i simmetric-chat-all-in-one.tar
docker run -d \
-p 3000:3000 -p 3210:3210 -p 3211:3211 \
-v simmetric-storage:/app/storage \
-e JWT_SECRET=$(openssl rand -hex 32) \
-e COLLECTOR_SECRET=$(openssl rand -hex 32) \
simmetric-chat:all-in-oneOs pesos dos modelos seguem o mesmo caminho. Modelos do Ollama são baixados numa máquina conectada, salvos como blobs e importados dentro do perímetro - a plataforma então os trata como qualquer outro modelo local. Nada na pilha liga para casa para verificar um modelo, uma licença ou a si mesma: a telemetria vem desativada por padrão, não há dependência externa de relatório de erros, e a validação de licença é uma checagem local de assinatura RS256 contra uma chave pública embutida.
O que ainda funciona offline - e o que realmente falta
Uma implantação air-gapped deve ser honesta sobre suas bordas. O que funciona com conectividade zero de saída:
- Chat com LLMs locais via Ollama, em streaming token a token por SSE
- Upload e ingestão de documentos - parsing, chunking, embeddings locais, vetores LanceDB
- Retrieval híbrido com citações, filtragem por metadados e pipelines de síntese
- RBAC, workspaces, projetos, trilhas de auditoria e toda a superfície de administração
- Webhooks (entregues aos seus próprios receptores), Web Push (VAPID do seu próprio servidor) e chaves de API
- O widget embutível, rodando contra o seu próprio serviço de widget
O que realmente falta: providers de LLM na nuvem, embeddings hospedados, busca web externa e qualquer outra coisa que exija uma chamada de saída. O design de degradação graciosa significa que cada uma dessas integrações é um acréscimo de configuração, não uma mudança de código - mas o padrão offline simplesmente é entregue sem elas. A plataforma inicia, atende requisições e processa documentos de forma idêntica, esteja o perímetro aberto ou fechado.
O resultado é um workspace de IA cuja postura de segurança não depende de confiar no tratamento de dados de um fornecedor, porque não há fornecedor no caminho dos dados. Tudo o que toca os seus documentos - o modelo, os embeddings, o índice vetorial, o parser - roda em hardware que você possui, dentro de uma rede que você controla, numa imagem de contêiner que você pode auditar.
