Pilar 2 — Modelo Soberano
A tese. Construir um modelo soberano sobre os dados proprietários do fundo fiduciário. O comutador de inferência na região sobre pesos abertos já está construído e testado atrás da mesma costura de provedor: quando ativado, os dados e a consulta nunca saem da jurisdição. O default de produção segue sendo qualidade frontier até alcançar paridade nas avaliações; o ajuste fino e a destilação vêm depois, quando o corpus o justificar. Os fatos vivem em RAG com citações determinísticas; os pesos só aprendem comportamento. Nunca embutimos fatos no modelo, porque quebraríamos o fosso da procedência.
É o segundo pilar do ciclo: consome o corpus do fundo fiduciário (1 → 2) e alimenta tanto a governança (2 → 3) quanto a inteligência de fronteira (2 → 4).
Nota sobre o marco de três pilares
Em materiais de subvenção a iniciativa é apresentada como três pilares: o Fundo Fiduciário de Dados (1), o Modelo Soberano (2) e o Motor de Governança, que agrupa a governança democrática (3) com a camada de decisão do pilar 4. O cânone da plataforma segue sendo o ciclo de quatro pilares; o mapeamento canônico vive em state/FOUR_PILLARS.md.
A soberania é um toggle de provedor, não uma reescrita
O loop do agente de chat está escrito na Anthropic Messages API (system + cache_control + tool_use). A resolução de provedor vive em um só lugar — server/chat/provider.ts — e seleciona por primeira coincidência:
SOVEREIGN_INFERENCE_URL+SOVEREIGN_INFERENCE_KEYconfigurados → roteia para um endpoint auto-hospedado / na região, de pesos abertos, que fala a Messages API. Este é o modo soberano.OPENROUTER_API_KEYconfigurado → roteia via OpenRouter (endpoint nativo Anthropic).ANTHROPIC_API_KEYconfigurado → chamaapi.anthropic.comdiretamente.- Nenhum → não configurado (o chat emite o evento
not_configured).
Essa lista escolhe o provedor primário; desde a onda de robustez do chat, providerChain() constrói também uma cadeia de failover ordenada: o primário primeiro e todo outro provedor configurado atrás, como reserva transparente. Com uma só chave o comportamento é idêntico; com duas ou mais, um primário caído faz failover no meio da solicitação sem intervenção — e o badge de provedor é re-anunciado se a troca ocorre no meio da resposta. Os ids de modelo são re-resolvidos por provedor (os namespaces diferem: anthropic/claude-sonnet-4.6 no OpenRouter vs. claude-sonnet-4-6 direto), e os overrides CHAT_MODEL / CHAT_FOLLOWUP_MODEL aplicam-se só ao primário. O evento not_configured é emitido quando a cadeia fica vazia — não diante da mera ausência de uma chave: uma chave soberana sem sua URL é diagnosticada honestamente.
O failover no meio da solicitação (server/chat/handler.ts) obedece a quatro invariantes:
| Invariante | Por quê |
|---|---|
Só dispara diante de Anthropic.APIError | Um abort próprio (aba fechada, orçamento de relógio esgotado) nunca provoca uma troca de provedor. |
Só se a rodada não emitiu texto visível (roundText vazio) | Uma vez que há tokens na tela, um segundo provedor retransmitindo duplicaria o texto visível. A narração de rodadas anteriores já foi apagada no cliente (reset_text). |
Repete a mesma rodada (round -= 1) | Um failover não consome orçamento de recuperação de ferramentas. |
Re-emite o evento provider | O badge sempre nomeia o host que realmente respondeu — e as sugestões de acompanhamento também rodam no provedor sobrevivente, no namespace de modelos dele. |
Re-resolução de ids de modelo por provedor
Cada ChatProvider da cadeia carrega seus próprios ids nativos — reutilizar o slug do OpenRouter contra api.anthropic.com daria 404, por isso o failover re-resolve o modelo junto com o cliente:
| Provedor | Modelo de resposta | Modelo de acompanhamentos |
|---|---|---|
sovereign | SOVEREIGN_INFERENCE_MODEL (default local-model) | o mesmo modelo servido |
openrouter | anthropic/claude-sonnet-4.6 | anthropic/claude-haiku-4.5 |
anthropic | claude-sonnet-4-6 | claude-haiku-4-5 |
CHAT_MODEL / CHAT_FOLLOWUP_MODEL sobrescrevem apenas a entrada primária da cadeia: um override cruzado arrastaria o namespace errado para uma reserva.
Endurecimento do cliente SDK (CLIENT_OPTS)
Todo cliente Anthropic que constrói a costura — soberano, OpenRouter ou direto — é criado com { timeout: 20_000, maxRetries: 2 } em vez dos defaults do SDK (timeout de 10 min):
timeout: 20slimita só conexão + tempo-até-o-primeiro-byte, não a geração de tokens: o SDK desarma o temporizador assim que chegam os cabeçalhos da resposta, antes de fluir um único token. Por isso este timeout nunca pode abortar uma resposta longa legítima em streaming — seu único trabalho é fazer um upstream morto ou travado aflorar rápido comoAPIConnectionTimeoutErrorpara queproviderChain()faça failover, em vez de o default de 10 minutos derivar em umFUNCTION_INVOCATION_TIMEOUTopaco da Vercel com o stream SSE truncado em silêncio. O limite real de duração do stream é o orçamento de relógio do handler + omaxDurationda função.maxRetries: 2retenta só falhas transitórias: o SDK retenta 408/409/429/5xx mas não 400/401/402/403 — assim uma queda por autenticação ou créditos esgotados no primário faz failover no ato, sem dormir entre tentativas, enquanto uma oscilação transitória se auto-repara no mesmo provedor.- As chamadas curtas pós-resposta (acompanhamentos com Haiku, sem streaming) carregam ainda seu próprio limite mais estrito no local da chamada (
server/chat/followups.ts,Promise.racecom deadline), porque para uma chamada sem streaming o timeout do SDK segue cobrindo só até os cabeçalhos e pode não ver uma leitura de corpo estagnada — e essas chamadas jamais devem atrasar o evento terminaldone.
A ramificação soberana é a costura de sovereignty do pilar: aponta o mesmo loop Messages para um gateway na jurisdição (LiteLLM/vLLM atrás de um shim Messages, servindo Llama, Qwen, DeepSeek ou Mistral) de modo que o corpus e a consulta nunca deixam o host soberano. Só muda o baseURL — o loop do agente, as ferramentas e a disciplina de fundamentação são idênticos.
Por que isso importa
A soberania de dados não se consegue com uma promessa contratual de "não olhamos seus dados". Consegue-se fazendo os dados e a inferência viverem fisicamente dentro da jurisdição da região. Como o loop é idêntico entre provedores, mudar para o soberano não degrada a lógica — só muda onde a computação acontece.
O badge "modo soberano" no chat
O evento SSE provider leva ao cliente a identidade da entrada ativa da cadeia (e é re-emitido se um failover troca de provedor no meio da resposta); a interface mostra um badge de "modo soberano" quando sovereign: true. O usuário vê, em cada resposta, onde a inferência rodou. A garantia é visível, não uma nota de rodapé.
O código separa deliberadamente duas afirmações que costumam se confundir:
sovereign: true= a inferência roda auto-hospedada, sob controle do operador.inRegion= a afirmação geográfica mais forte — "os dados permanecem na região" — e só é asseverada quandoSOVEREIGN_INFERENCE_REGIONestá declarada. A residência na região nunca é inferida da mera presença de um endpoint, porque a costura poderia apontar para um host fora da LATAM.
Variáveis de ambiente da costura soberana
| Variável | O que controla |
|---|---|
SOVEREIGN_INFERENCE_URL / _KEY | Ativam o modo soberano (gateway Messages-compatible). |
SOVEREIGN_INFERENCE_MODEL | Nome do modelo servido (default local-model). |
SOVEREIGN_INFERENCE_LABEL | Etiqueta do badge (default Soberano). |
SOVEREIGN_INFERENCE_REGION | Declara a região do gateway; é a única via para assertar inRegion. |
CHAT_MODEL / CHAT_FOLLOWUP_MODEL | Overrides de modelo, ligados ao provedor primário. |
O assistente usa dois modelos: um para a resposta fundamentada (default Sonnet) e um menor para as sugestões de acompanhamento descartáveis (default Haiku); um deployment soberano reutiliza seu único modelo servido para ambos, salvo se CHAT_FOLLOWUP_MODEL disser outra coisa.
A regra RAG-não-fine-tune: o fosso da procedência
A decisão de arquitetura mais importante do pilar: os fatos nunca são embutidos nos pesos.
- Os fatos vivem em RAG. Cada cifra que o modelo cita provém do corpus recuperado em tempo de consulta, ligada a um
citation_iddeterminístico. A resposta é fundamentada e verificável contra a fonte primária. - Os pesos só aprendem comportamento. O ajuste fino, quando chegar, ensina como raciocinar e responder — não o que é verdade. Um peso não pode citar sua fonte; uma passagem recuperada, sim.
Embutir fatos nos pesos quebraria o fosso: um número gerado a partir dos pesos não pode ser rastreado até uma fonte primária, e a rastreabilidade em dois cliques é o contrato de toda a plataforma. Por isso o modelo padrão (Sonnet na rota direta/OpenRouter) prioriza a disciplina de fundamentação — ligar o citation_id correto a cada cifra e aflorar contradições entre fontes — acima da fluência crua.
O caminho por fases
| Fase | O quê |
|---|---|
| Agora | Comutador de inferência na região construído e testado (toggle + failover + tests); o default de produção segue sendo qualidade frontier até paridade nas avaliações. |
| Roteiro | Inferência na região sobre pesos abertos como default de produção, quando as avaliações mostrarem paridade. |
| Roteiro | Passada de adaptação regional: ajuste fino / destilação sobre o corpus do fundo fiduciário, com gate: só quando o harness de avaliação (fidelidade / recuperação) demonstrar que o corpus o justifica. |
| Roteiro | Inferência ZK sobre registros cifrados: responder consultas sem decifrar o registro subjacente, alinhada com a fase ZK do roteiro de procedência avançada. |
O ajuste fino não é um objetivo em si. Está condicionado pelo harness de avaliação existente: enquanto um modelo aberto ajustado não igualar a fidelidade e a qualidade de recuperação medidas, a qualidade frontier segue sendo o default. Avança-se quando os números permitirem, não antes.
Os gates de avaliação já existem como harnesses no repositório: scripts/chat-eval.ts (qualidade de resposta), scripts/chat-faithfulness.ts (precisão de atribuição, limiar CHAT_FAITH_MIN, default 0.85) e scripts/eval-retrieval.ts (qualidade de recuperação). A ressalva honesta: seus resultados ainda não são publicados como artefato público; hoje rodam como verificações internas do repositório.
Por que o fosso é o corpus, não os pesos base
Qualquer um pode baixar Llama ou Qwen. Os pesos base são uma commodity. O que não é commodity é um corpus com procedência verificada e licença limpa de 25 países — construído pelo fundo fiduciário, impossível de raspar, e ligado cifra por cifra à sua fonte. O modelo soberano é valioso não porque seus pesos sejam secretos, mas porque está fundamentado em dados que ninguém mais tem e que ele pode citar de forma determinística.
Isso inverte a intuição habitual sobre modelos: o ativo defensável não está dentro do modelo, está no corpus que o fundamenta e na disciplina que garante que cada resposta remonta a ele.
Verificação
Tudo o que está acima se verifica contra server/chat/provider.ts (seleção de provedor, providerChain(), usingSovereign()) e os testes de failover do handler (server/chat/handler-failover.test.ts). A disciplina de fundamentação e o harness de avaliação são detalhados na página do assistente e em metodologia.
Superfícies relacionadas
- O assistente fundamentado vive em /sala e ao longo de toda a plataforma.
- O badge de provedor aparece em cada resposta do chat.
- A perna física da soberania: /soberania-computo — o Índice de Soberania de Cômputo (ISC) classifica os 25 países por sua preparação para hospedar computação soberana, sobre 4 componentes com pesos publicados (energia limpa, conectividade, financiamento, escala) e a restrição vinculante por país; cada insumo citado. Tratamento completo no Pilar 4.
Siga o ciclo: os resultados deste modelo servem à governança democrática e à inteligência de fronteira.