Por que (não) construir mais um app de finanças - Parte 3: categorização e IA
Em 2026, categorizar gasto parece problema resolvido. Manda a descrição para um modelo de IA, recebe "Mercado" ou "Transporte" de volta, pronto.
Na nossa cabeça, era um prompt e uma lista de categorias.
Esta é a Parte 3 do diário que começamos na Parte 0. Na Parte 1, falamos de Open Finance. Na Parte 2, de cobrar pelo app. Agora é a vez de responder a pergunta que todo app de finanças promete responder: para onde foi o dinheiro?
Contexto rápido: as transações chegam do banco pelo Open Finance, com uma descrição curta (às vezes só "PIX ENVIADO") e, em geral, com uma categoria genérica sugerida pelo próprio banco.
O que a gente achou que era
- Uma lista fixa de categorias
- A IA lê a descrição e escolhe uma
- Se errar, o usuário corrige
O que realmente era
A IA é a quarta da fila
A IA sabe que "UBER *TRIP" é transporte. O que ela não sabe é que "PIX ENVIADO" para uma pessoa específica é o seu aluguel, a sua diarista ou a sua aula de inglês. Essa informação não está na descrição. Está no que você fez da última vez.
Por isso, cada transação nova passa por uma fila de tentativas, da pista mais forte para a mais fraca. A IA só é chamada quando as anteriores não acharam nada:
- 1O seu histórico. Você já categorizou algo parecido? Vale o que você escolheu.
- 2O modelo do seu tipo de conta. Pessoal, compartilhada e empresa organizam os mesmos gastos de jeitos diferentes.
- 3A tradução da categoria do banco. Um dicionário com 175 rótulos do Open Finance, de "Transfers" a "Groceries".
- 4A IA. Rótulo novo, que o dicionário ainda não conhece.
- 5O rótulo do banco, sem tradução.
- 6"A definir". Nenhuma pista. Melhor admitir do que chutar.
Desde o começo de outubro de 2026, cada transação guarda qual dessas tentativas deu a categoria. Nas primeiras semanas, o placar ficou assim:
Pouco mais de 10 mil transações novas, sem contar as marcadas como "Ignorado". O resto (menos de 2%) veio de importação de planilha, do usuário ou ficou "A definir".
A IA é ótima para o que é igual para todo mundo. O que importa é o que é só seu.
O banco já manda uma categoria. E ela é genérica.
Pelo Open Finance, a maioria das transações chega com uma sugestão de categoria do próprio banco, em inglês. "Groceries" vira "Mercado" sem drama. O problema é "Transfers".
Todo PIX para pessoa física é "Transfers". O aluguel, a mesada do filho, a diarista, a vaquinha do churrasco. Traduzir para "Transferências" é tecnicamente certo e não ajuda em nada quem quer saber quanto gastou com a casa.
O PIX que não cabia na janela
Para resolver isso, o Snabber olha o seu histórico. Se o PIX de junho para uma pessoa foi categorizado como "Diarista", o de setembro para a mesma pessoa também deveria ser.
Só que não era. Em setembro de 2026, achamos o motivo: a busca no histórico olhava as 10 transações mais recentes com o mesmo rótulo do banco. Para quem faz PIX toda semana, essas 10 linhas eram PIX para outras pessoas. A transação certa, de meses atrás, nunca cabia na janela. E a categoria caía em "Transferências".
Parece só aumentar um número. Não é. As descrições das transações ficam criptografadas no banco de dados (a Parte 6 é sobre isso), então não dá para perguntar ao banco de dados "quem já mandou PIX para essa pessoa?". É preciso decifrar o histórico em memória, uma vez por sincronização, e montar ali um índice de "pessoa → categoria".
E o casamento tem regras que só aparecem quando quebram:
- Direção importa. Um PIX que você recebeu de alguém não herda a categoria do PIX que você mandou para essa pessoa. Pagar a diarista não é o mesmo que ela te devolver um troco.
- O nome vem sujo. Data, número de documento e sufixos como "LTDA" saem antes de comparar. Às vezes o banco só manda "PIX ENVIADO", e o nome está escondido em outro campo.
- A escolha de gente vale mais. Entre duas categorias possíveis, ganha a que alguém escolheu, não a que veio do banco.
O rótulo genérico ganhava no desempate
Corrigimos a janela, testamos, e o bug continuou. No mesmo dia.
O histórico daquela pessoa tinha uma transação na categoria certa (junho) e uma em "Transferências" (setembro, a que tinha entrado errada). Um contra um. O desempate era "a mais recente", e a mais recente era justamente a errada. O erro se perpetuava sozinho.
Hoje, um rótulo genérico do banco perde para qualquer categoria específica, não importa quantas vezes ele apareceu nem quando.
Renomear não era renomear
Até agosto de 2026, a categoria de cada transação era guardada pelo nome. Funciona, até alguém renomear "Mercado" para "Supermercado". Aí a próxima sincronização olhava o histórico, encontrava "Mercado" e recriava a categoria antiga. O nome velho ressuscitava.
Nas contas compartilhadas era pior: cada membro tinha a própria cópia de cada categoria, escondida na tela por um filtro que mostrava só uma. E as cópias podiam ter limites diferentes para a mesma categoria.
A correção levou de 20 de agosto ao fim de setembro: dar um identificador de verdade para cada categoria, juntar as cópias numa só por conta, e passar a gravar o identificador em todos os caminhos por onde uma transação entra no app: sincronização do banco, planilha, formulário, edição em massa, IA e Telegram. Em duas fases, para que um erro na primeira fosse só uma coluna mal preenchida, e não um relatório somando errado em silêncio.
Nem todo gasto é gasto
Pagar a fatura do cartão sai da conta corrente. Mas as compras dessa fatura já foram contadas, uma por uma, no cartão. Se o pagamento também contar como gasto, o mês gasta o dobro.
O mesmo vale para transferir entre as suas próprias contas e para guardar dinheiro num investimento. São categorias que existem para não entrar na conta. Até agosto de 2026, os agentes de IA do Snabber só deixavam de fora o que o usuário marcava como "Ignorado". Pagamento de fatura entrava no resumo. (A fatura merece uma parte inteira, e ela é a próxima.)
Alguns dos 91 commits com "categor" na mensagem, de agosto de 2025 a outubro de 2026.
O que fizemos
- ✓Uma fila de seis tentativas, com o seu histórico na frente e a IA como reforço.
- ✓Categoria por quem recebeu ou mandou o dinheiro, no histórico inteiro e respeitando a direção.
- ✓Rótulo genérico do banco sempre perde para uma categoria escolhida por alguém.
- ✓Categorias com identificador próprio: renomear não ressuscita o nome antigo, e a conta compartilhada tem uma lista só.
- ✓Fatura, transferência entre contas próprias e investimento fora dos totais de gasto, também nos agentes de IA.
- ✓Registro de onde veio cada categoria, para medir quem acerta mais.
O que ainda não resolvemos
A primeira vez continua sendo um chute. O primeiro PIX para o seu novo senhorio vai entrar como "Transferências". O Snabber aprende quando você corrige, e só aí. Adivinhar que "a mesma pessoa todo dia 5" é aluguel, sem ninguém ter dito, ainda não é algo que a gente faça bem.
Uma transação tem uma categoria só. A compra no mercado que incluiu remédio e ração continua sendo uma linha, inteira em "Mercado".
E medir acerto é mais difícil do que parece. Hoje sabemos quantas categorias o usuário manteve: cerca de 95%, seja qual for a fonte. Mas as transações que ficaram "A definir" também foram 100% mantidas. Manter não quer dizer que estava certo. Muitas vezes quer dizer só que ninguém olhou.
Se você vai categorizar transações
Comece pelo histórico do usuário, não pelo modelo. A melhor pista sobre uma transação é o que a própria pessoa fez com a anterior.
Dê um identificador para a categoria desde o primeiro dia, e grave de onde veio cada uma. Você vai querer essas duas coisas antes do que imagina.
Quer ver como ficou? Crie sua conta no Snabber e teste o plano gratuito.
Na próxima parte: por que uma fatura de cartão não é só uma lista de gastos.
