Case: como construímos um SaaS de restituição tributária com LLM para análise de SPED
Case técnico de uma plataforma SaaS para recuperação de PIS, COFINS e ICMS. Arquitetura multi-tenant, LLM para SPED e stack Next.js + Python.
O problema: R$ 12 bilhões abandonados por ano
Segundo estimativas do IBPT (Instituto Brasileiro de Planejamento e Tributação), empresas brasileiras pagam a mais em tributos algo na faixa de R$ 12 a R$ 15 bilhões por ano. A maior parte dessas inconsistências envolve PIS, COFINS e ICMS. O motivo é simples: a legislação tributária brasileira tem mais de 400.000 normas acumuladas, e os arquivos SPED (EFD Contribuições, EFD ICMS/IPI) contêm milhões de linhas que escritórios contábeis revisam manualmente ou com ferramentas limitadas.
Um escritório de contabilidade tributária nos procurou com um desafio concreto. Eles tinham 340 clientes, cada um gerando entre 50.000 e 2 milhões de linhas de SPED por mês. A equipe de 8 analistas conseguia revisar no máximo 40 clientes por mês com profundidade suficiente para identificar créditos recuperáveis. Os outros 300 recebiam uma análise superficial ou nenhuma.
A pergunta deles foi direta: "Vocês conseguem construir um sistema que faça a pré-análise dos SPEDs automaticamente e nos diga onde estão os créditos?"
A resposta foi sim. Com ressalvas.
Decisões de arquitetura
Multi-tenant desde o dia zero
O escritório queria, no futuro, vender a plataforma para outros escritórios. Então a arquitetura precisava ser multi-tenant de verdade, não "a gente refatora depois". Escolhemos o modelo de banco compartilhado com RLS (Row-Level Security) no PostgreSQL. Cada tenant (escritório) tem seus dados isolados por tenant_id em todas as tabelas, com policies do PostgreSQL garantindo que uma query nunca vaze dados entre tenants.
Por que não banco dedicado por tenant? Porque o perfil dos tenants é homogêneo. Todos são escritórios contábeis com volumes de dados parecidos. O modelo compartilhado simplifica migrations e reduz custo de infra. Se no futuro aparecer um tenant muito grande (banco de dados acima de 500GB), migramos esse tenant para banco dedicado. Mas projetamos para o cenário dos primeiros 50 clientes, não para o cenário hipotético de 2029.
Stack: Next.js no front, Python no processamento, PostgreSQL como backbone
O frontend é Next.js com Server Components para o dashboard. SSR para as páginas que o Google precisa indexar (landing page, blog, pricing). O dashboard em si é protegido por auth e não precisa de SEO, então usamos Client Components com React Query para buscar dados.
O backend de processamento é Python. A escolha aqui foi pragmática: as bibliotecas para parsing de arquivos SPED (formato texto posicional com registros hierárquicos) são mais maduras em Python. Usamos FastAPI para a API de processamento e Celery com Redis para filas de jobs assíncronos.
O PostgreSQL (versão 16, hospedado no Supabase para simplificar o managed hosting) é o banco principal. Armazenamos os dados parseados do SPED em tabelas normalizadas, o que permite queries analíticas rápidas com índices compostos. Testamos usar JSON columns para flexibilidade, mas a performance de queries com filtros em campos dentro de JSON era 8x mais lenta que colunas normalizadas. Esse benchmark nos custou 3 dias, mas economizou meses de dor de cabeça.
Onde o LLM entra (e onde não entra)
A integração de LLM foi a parte mais delicada do projeto. O hype dizia "joga o SPED no GPT e deixa ele achar os créditos". A realidade é completamente diferente.
O que o LLM faz:
-
Classificação de NCM para enquadramento tributário. Alimentamos o modelo com a tabela TIPI atualizada e a legislação de cada estado. O LLM classifica itens que o sistema rule-based não consegue resolver (NCMs ambíguos, produtos com classificação disputada). Taxa de acerto: 87% para classificações complexas, validadas por amostragem de 500 itens.
-
Sumarização de divergências. Depois que o sistema rule-based identifica as divergências numéricas (alíquota aplicada vs. alíquota devida, base de cálculo incorreta), o LLM gera um resumo em linguagem natural para o analista. Isso reduziu o tempo de revisão por cliente de 4 horas para 45 minutos.
-
Análise de legislação estadual. Cada estado tem suas próprias regras de ICMS, benefícios fiscais e regimes especiais. O LLM, alimentado com RAG sobre a base de legislação, sugere quais benefícios podem se aplicar a cada caso.
O que o LLM NÃO faz:
O LLM não calcula valores. Nunca. Cálculos tributários são determinísticos. PIS é 1,65% sobre receita bruta no regime não-cumulativo, não "aproximadamente 1,65%". Toda conta é feita por código Python com Decimal de precisão arbitrária. O LLM é consultor, não calculadora.
Também não toma decisões finais. Toda sugestão do LLM é marcada como "pendente de revisão humana". O analista aprova ou rejeita cada item.
O pipeline de processamento
O fluxo completo quando um arquivo SPED é importado:
-
Upload e validação. O arquivo SPED é enviado pelo dashboard. Validamos formato, encoding (muitos vêm em ISO-8859-1, não UTF-8) e integridade dos registros. Arquivos corrompidos são rejeitados com erro específico.
-
Parsing. O parser Python lê o arquivo linha a linha, identifica os registros (0000, 0100, C100, C170, etc.) e monta a estrutura hierárquica. Um SPED de 1 milhão de linhas é parseado em 12 a 18 segundos.
-
Normalização e carga. Os dados parseados são inseridos no PostgreSQL em batch (COPY, não INSERT um a um). 1 milhão de registros leva cerca de 8 segundos para carregar.
-
Análise rule-based. Queries SQL comparam alíquotas aplicadas vs. tabela de alíquotas vigentes, verificam NCMs contra TIPI, checam base de cálculo de ICMS por estado. Essa etapa encontra 70 a 80% das divergências.
-
Análise assistida por LLM. Os casos que o rule-based flagou como "inconclusivo" (NCM ambíguo, benefício fiscal possível, regime especial) são enviados para o LLM via API. Usamos batching para reduzir custo: agrupamos até 20 itens por request.
-
Geração de relatório. O sistema gera um relatório PDF com todas as divergências encontradas, valores estimados de recuperação e fundamentação legal. O LLM gera o texto da fundamentação. O analista revisa e assina digitalmente.
Números reais
Após 6 meses em produção com 340 clientes do escritório original e 12 escritórios parceiros:
- R$ 47 milhões em créditos identificados para recuperação
- Tempo médio de análise por cliente: 45 minutos (era 4 horas)
- Capacidade: 340 clientes analisados por mês com a mesma equipe de 8 analistas (era 40)
- Custo de infra: R$ 4.200/mês (Supabase Pro + Redis + Celery workers em Railway)
- Custo de LLM: R$ 2.800/mês (API calls para classificação e sumarização)
- Uptime: 99,7% nos primeiros 6 meses
O que deu errado
Nem tudo foi suave.
O encoding dos SPEDs é uma bagunça. Cerca de 15% dos arquivos vinham com encoding diferente do declarado no registro 0000. Tivemos que implementar detecção automática de encoding com chardet + heurísticas manuais para caracteres específicos do português (ç, ã, é).
A legislação muda mais rápido do que imaginávamos. Em 6 meses, houve 3 alterações em alíquotas de ICMS em estados diferentes. O sistema de RAG para legislação precisa ser atualizado semanalmente. Automatizamos parte disso com web scraping dos diários oficiais, mas a validação final ainda é manual.
O LLM alucina em edge cases tributários. Na primeira versão, o LLM sugeriu um benefício fiscal que havia sido revogado em 2024. Depois disso, implementamos uma camada de validação que cruza toda sugestão do LLM com uma base de vigência de normas. Se a norma citada não estiver vigente na data de referência, a sugestão é automaticamente descartada.
Lições para quem quer construir algo parecido
-
Não comece pelo LLM. Comece pelo rule-based. LLM é a camada de inteligência sobre uma base sólida de regras determinísticas.
-
Invista em parsing robusto. 40% do tempo do projeto foi gasto em parsing de SPED. Não subestime a complexidade de formatos legados brasileiros.
-
Multi-tenant não é feature, é arquitetura. Adicionar multi-tenancy depois custa 3 a 5x mais do que começar com ele.
-
Meça o custo de LLM por cliente, não por mês. No nosso caso, R$ 8 por cliente por mês. Se o escritório cobra R$ 3.000 de honorário de sucesso, a margem é confortável.
-
O analista humano é insubstituível. O sistema reduz o trabalho braçal, mas a decisão final de assinar um pedido de restituição de R$ 500.000 precisa de um especialista. Qualquer promessa de "IA que substitui o tributarista" é irresponsável.
O projeto continua evoluindo. As próximas funcionalidades incluem integração direta com o e-CAC da Receita Federal para envio automatizado de PER/DCOMP e um módulo de monitoramento contínuo que alerta quando novas oportunidades de crédito surgem baseado em mudanças legislativas.
Na Bradata, esse projeto nos ensinou que o valor real da IA em software empresarial não está em substituir pessoas. Está em multiplicar a capacidade de especialistas que já sabem o que estão fazendo.
Posts relacionados
Guia de plataforma SaaS no Brasil: do MVP à escala, multi-tenant, billing, LGPD e métricas
Guia de IA para empresas no Brasil em 2026: o que funciona, quanto custa e como começar
Case Atlas: ERP/CRM comercial com pipeline visual, faturamento e dashboard executivo
Precisa de um talento tech agora?
Fale com a Bradata e receba uma proposta em 24 horas úteis.