Atenção Esparsa, Cache de Prefixo e Agentes Opinionados: por que a matemática do DeepSeek muda tudo
Atenção Esparsa, Cache de Prefixo e Agentes Opinionados: por que a matemática do DeepSeek muda tudo
por Gustavo
Este texto pressupõe que você sabe programar e não tem medo de equações. Vou tratar o DeepSeek como o objeto técnico que ele é, e explicar por que a arquitetura do modelo torna frameworks genéricos estruturalmente inadequados.
1. O problema de O(L²) e como a DeepSeek o resolve
O mecanismo de atenção clássico (Vaswani et al., 2017) tem complexidade O(L²) em memória e tempo, onde L é o comprimento da sequência. Para L = 128.000 tokens, isso se torna proibitivo em produção.
A solução padrão da indústria é a atenção janelada ou flashattention, otimizações de implementação que não alteram a complexidade assintótica. A DeepSeek foi em outra direção.
O DSA (DeepSeek Sparse Attention), introduzido no V3.2, reduz a complexidade para O(Lk), onde k é uma constante pequena (k = 2.048 no V3.2, independente de L). O mecanismo tem dois componentes:
- Lightning Indexer: para cada token t, um MLP pequeno com ativação ReLU calcula scores I_{t,s} entre o token atual e todos os tokens anteriores. Os top-k tokens com maiores scores são selecionados para a atenção principal. Esse indexer opera em FP8, tornando-o implementável de forma eficiente em hardware moderno.
- Fine-grained Token Selection: apenas os k tokens selecionados participam do produto de atenção, reduzindo o custo quadrático para linear em L.
O V4 generalizou isso com o CSA (Compressed Sparse Attention) e o HCA (Heavily Compressed Attention): CSA adiciona compressão de KV (cada 4 tokens → 1 entrada) antes da atenção esparsa, e HCA aplica compressão pesada (128 tokens → 1) para cobertura de contexto de longo alcance. O resultado prático é que o V4 Pro opera com 7% do custo de KV cache do baseline V3.2, com janela de contexto de 1 milhão de tokens.
Por que isso importa para o cache de prefixo: a atenção esparsa é especialmente eficiente quando o prefixo é longo e estático. O Lightning Indexer aprende, durante o treinamento, a identificar quais tokens históricos são relevantes, e essa aprendizagem é altamente transferível entre requisições com prefixos idênticos. O sistema de cache de prefixo da API é o mecanismo pelo qual essa eficiência se traduz em desconto de preço.
2. GRPO, OPD e o custo do pós-treinamento
O DeepSeek-V3.2 investiu mais de 10% do custo de pré-treinamento em RL, um número incomum na época, quando modelos open-source gastavam pouco compute em pós-treinamento.
O algoritmo base é o GRPO (Group Relative Policy Optimization), mas com três modificações críticas de estabilidade:
- Unbiased KL Estimate: corrige o estimador K3 padrão via importance sampling, evitando gradientes explosivos quando π_θ ≪ π_ref (o modelo treinado diverge muito do modelo de referência).
- Off-Policy Sequence Masking: sequências com alta divergência KL entre π_old e π_θ são mascaradas, evitando que amostras muito off-policy desestabilizem o treinamento.
- Keep Routing / Keep Sampling Mask: congela as rotas dos especialistas MoE e preserva as máscaras de truncamento da inferência durante o treinamento, crítico para estabilidade em modelos mixture-of-experts.
O V4 substituiu o Mixed RL Training por OPD (On-Policy Distillation) com KL reversa de múltiplos professores, uma mudança que melhora a estabilidade e permite integrar múltiplos modelos especialistas como fonte de supervisão.
O pipeline de síntese agêntica do V3.2 gerou 1.800+ ambientes sintéticos com 85.000 prompts para treinamento de agentes. O Code Agent usou 24.667 tarefas reais de resolução de issues com ambientes Docker reais. O resultado, documentado nos benchmarks do paper, foi competitividade com modelos proprietários em tarefas de agente, incluindo medalhas de ouro em IMO, CMO e IOI 2025 com o modelo Speciale.
O resultado desse treinamento é observável em sessões reais: o agente não apenas resolve problemas, mas demonstra persistência estruturada. Quando uma ferramenta falha, ele tenta caminhos alternativos em vez de desistir. Quando um arquivo é escrito truncado, ele detecta e muda de estratégia. Isso não é prompting, é consequência de RL em escala sobre 1.800 ambientes diversos.
3. Por que frameworks genéricos são matematicamente inadequados
Com esse contexto, a inadequação dos frameworks genéricos não é opinião, é consequência direta da arquitetura.
O cache de prefixo funciona por comparação exata de bytes. Para uma requisição ser cacheada, os primeiros N bytes devem ser idênticos aos da requisição anterior. Qualquer diferença, um timestamp, um espaço extra, uma chave JSON em ordem diferente, invalida o cache completamente.
Frameworks genéricos como LangChain reconstroem o prompt a cada turno. A razão é estrutural: eles precisam suportar múltiplos modelos, e diferentes modelos têm diferentes convenções de serialização, diferentes formatos de mensagem, diferentes formas de injetar contexto. A abstração "provider-agnostic" exige que o prompt seja remontado de componentes em cada requisição.
O custo é direto: se o cache hit rate é 0%, você paga preço cheio por cada token de entrada em cada turno. Para sessões longas com contextos ricos, isso pode ser a diferença entre $0,06 e $6,00 pela mesma tarefa.
4. Os três pilares do Reasonix como soluções de engenharia
O Reasonix resolve esse problema com uma invariante arquitetural simples: o contexto é particionado em três regiões com disciplinas estritas.
┌─────────────────────────────────────┐
│ PREFIXO IMUTÁVEL │ ← hash fixado na construção
│ system + tool_specs + few_shots │
├─────────────────────────────────────┤
│ LOG APPEND-ONLY │ ← cresce monotonicamente
│ [user₁][assistant₁][tool₁]... │
├─────────────────────────────────────┤
│ SCRATCH VOLÁTIL │ ← apagado a cada turno
│ reasoning_content, estado trans. │
└─────────────────────────────────────┘
O prefixo imutável é o alvo do cache. O log append-only garante que os turnos anteriores preservem o prefixo intacto (são apenas adicionados ao final, nunca reorganizados). O scratch volátil nunca é enviado upstream, ele existe apenas para o Thought Harvesting.
O R1 Thought Harvesting extrai do reasoning_content um estado estruturado:
interface TypedPlanState {
subgoals: string[]; // objetivos intermediários concretos
hypotheses: string[]; // abordagens sendo pesadas
uncertainties: string[]; // pontos que o R1 sinalizou como incertos
rejectedPaths: string[]; // caminhos considerados e abandonados
}
Isso é feito via uma chamada secundária ao V3 em modo JSON (~$0,0001/turno). O custo é essencialmente irrelevante, e o impacto na qualidade das respostas é documentado pelo próprio autor: o Self-Consistency Branching com harvesting eleva a acurácia em 10-15 pontos percentuais em tarefas de raciocínio intermediário. Com o modelo 20× mais barato que Claude, três amostras paralelas ainda são mais baratas que uma única chamada ao concorrente, enquanto produzem resultados melhores.
O Tool-Call Repair trata os quirks conhecidos do DeepSeek com quatro passes automáticos: achatamento de esquemas profundos (com re-aninhamento transparente), scavenging de tool-calls perdidos no reasoning_content, recuperação de JSON truncado, e deduplicação de call storms.
5. O sistema de hooks e o princípio de extensibilidade sem abstração
O sistema de hooks do Reasonix é a extensão natural dessa filosofia. Um hook é um comando shell. Não uma função TypeScript, não uma middleware chain, um comando shell que recebe JSON no stdin e retorna um exit code. O criador do Reasonix documentou essas decisões em dois artigos de arquitetura. A transparência é incomum e valiosa: permite a outro programador entender não apenas o que a ferramenta faz, mas por que cada alternativa foi rejeitada.
{
"hooks": {
"PreToolUse": [
{
"match": "shell",
"command": "jq -r .toolArgs.command | grep -qE '^(rm -rf|sudo)' && exit 2 || exit 0"
}
]
}
}
A taxonomia de eventos é minimal e precisa: PreToolUse e UserPromptSubmit são eventos de gating (podem vetar, timeout de 5s); PostToolUse e Stop são eventos de observing (não podem reverter, timeout de 30s). Essa assimetria é codificada explicitamente:
export function decideOutcome(event: HookEvent, raw: HookSpawnResult) {
if (raw.timedOut) return BLOCKING_EVENTS.has(event) ? "block" : "warn";
if (raw.exitCode === 2 && BLOCKING_EVENTS.has(event)) return "block";
return raw.exitCode === 0 ? "pass" : "warn";
}
O princípio que governa os três bugs que se tornaram decisões de design (SIGTERM no Windows, regex malformado, JSON inválido no settings) é consistente: configuração é a parte mais frágil de qualquer sistema; ela nunca deve derrubar a parte que te deixa consertar a configuração.
6. O que ainda falta, e o que isso revela
O Reasonix está em v0.6.0, pré-alpha. As limitações abertas são tecnicamente honestas:
- Hooks não podem reescrever argumentos de ferramentas (apenas vetar). O caminho de upgrade é um flag
parseStdoutAsJson: true, ainda não implementado. - O seletor de branch usa
min(uncertainties.length)com tie-break por comprimento de resposta. É uma heurística de Occam, funcional, mas sem validação formal. - Mudanças no system prompt invalidam o prefixo cache sem caminho de migração.
- O formato DSML (XML) que o V4 usa para tool-calls não é suportado nativamente. Esse é o ponto de fricção mais relevante: um framework construído especificamente para DeepSeek deveria ser o primeiro a adotar o novo formato do modelo, mas a velocidade de evolução arquitetural do V3.2 para o V4 (contexto de 128K para 1M, DSA para CSA+HCA, JSON para XML) supera a velocidade de desenvolvimento do framework.
Essa última tensão é inerente à aposta opinionada: você compra profundidade e eficiência, mas paga com o custo de acompanhar cada mudança arquitetural do modelo ao qual está acoplado. É um trade-off, não uma falha.
7. Conclusão
A matemática do DeepSeek, atenção esparsa O(Lk), cache de prefixo por bytes, thinking tokens estruturados, quirks de tool-use, define um conjunto de problemas que ferramentas genéricas não resolvem por design. O Reasonix é uma demonstração de que resolvê-los de forma específica produz resultados mensuravelmente melhores: 85-95% de cache hit, 93-96% de economia, agentes que funcionam em condições que frameworks genéricos simplesmente deixam quebrar.
Em um mês de uso real, os números são inequívocos: 84 milhões de tokens processados por $4,56. Uma sessão de desenvolvimento de 46 turnos custou $0,33. Um jogo de 1.406 linhas custou seis centavos. Esses valores não são possíveis com um framework que trata todos os modelos como equivalentes.
O ecossistema ainda trata a escolha entre frameworks genéricos e opinionados como uma questão de preferência. Não é. É uma questão de engenharia com consequências mensuráveis. Enquanto a abstração "provider-agnostic" for considerada um valor em si mesmo, os recibos da API continuarão mostrando que ela tem um preço.
A velocidade de evolução arquitetural do DeepSeek, do V3.2 ao V4 em menos de um ano, cria uma tensão real para ferramentas acopladas. Mas é exatamente essa evolução que torna o acoplamento necessário. Um modelo que reduz o KV cache para 10% do tamanho original não pode ser usado eficientemente por um framework que não sabe o que é um KV cache.
O futuro pertence a ferramentas que entendem o modelo que estão usando. O resto é desperdício.
Gustavo escreve sobre arquitetura de sistemas e IA aplicada. Código, papers e logs reais no blog.