T-Bank melhorou a qualidade do AI Code Completion com um filtro e removeu sugestões desnecessárias
T-Bank mostrou que melhorar a qualidade das sugestões de AI não depende apenas da geração. A equipe adicionou um filtro que decide se deve mostrar um…
Processado por IA de Habr AI; editado por Hamidun News
O T-Bank compartilhou como reconstruiu seu AI Code Completion interno para 7.500 desenvolvedores e aumentou a proporção de sugestões aceitas sem alterar o modelo de geração principal. Em vez de mais uma tentativa de tornar o autocomplete "mais inteligente", o time adicionou um filtro separado que decide se deve mostrar uma sugestão ou não.
Onde Estava o Limite
O serviço de autocomplete de código do T-Bank já funciona em produção há vários anos e é usado diariamente por quase toda a equipe de desenvolvimento interna—cerca de 7.500 usuários únicos. A métrica básica, Taxa de Aceitação, por muito tempo ficou perto de 20%: aproximadamente uma em cada cinco sugestões era aceita, as outras eram ignoradas.
O time tentou alongar as sugestões, mudar a estratégia de geração e expandir o número de locais para mostrar sugestões, mas isso gerou mais ruído. Quanto mais ativamente o sistema sugeria, mais frequentemente os desenvolvedores viam continuações inúteis e mais fraca se tornava sua confiança no produto. Isso levou a uma hipótese diferente: o problema pode não ser apenas na qualidade da geração, mas na ausência de um mecanismo separado para determinar exatamente quando uma sugestão deve ser ocultada.
O time notou um efeito comportamental importante: se o ruído diminuísse, os usuários começariam a pressionar Tab com mais disposição e dariam mais chances até mesmo a propostas não óbvias. Pela avaliação interna, cada ponto percentual adicional de Taxa de Aceitação ao longo do tempo adicionava cerca de 2% ao número de aceitações. Mas havia um limite comercial rigoroso: o filtro não deveria eliminar imediatamente mais de 5% das sugestões já aceitas.
Como Construíram o Filtro
O primeiro passo foi uma linha de base rápida usando CatBoost. O modelo foi treinado como um classificador binário: aceitar a sugestão ou não. Utilizaram apenas recursos que pudessem ser calculados em tempo real sem armazenar histórico de requisições: IDE, linguagem de programação, posição do cursor, tipo de sugestão, tamanho do prefixo e sufixo.
Até essa variante simples deu cerca de +2,3 pontos percentuais à Taxa de Aceitação offline e confirmou que a tarefa tinha um sinal forte. Em seguida, o time passou para um filtro de texto baseado em Qwen2.5-Coder 1.
5B. Modelos maiores não se encaixavam nas restrições de produção: o alvo de 30 requisições por segundo em uma única Nvidia A100 e latência p90 não superior a 50 ms. Então escolheram um compromisso: compacto o suficiente para inferência, mas ainda adaptado para código.
Para evitar que o modelo confundisse o contexto do arquivo com a sugestão em si, a entrada precisou ser estruturada rigidamente e ajustada não para geração, mas para classificação.
- Substituíram a cabeça de geração por classificação binária
- Marcaram contexto para prefixo, linha, resposta e sufixo
- Codificaram IDE, linguagem e posição do cursor com tokens especiais
- No estágio final, adicionaram fine-tuning, LoRA e focal loss devido ao desbalanceamento de classes
Este pipeline melhorou a qualidade em etapas: após a estruturação rigorosa, o ganho chegou a cerca de +3,9 p.p., após adicionar tokens especiais—a +5,1 p.p., e o fine-tuning completo trouxe o resultado offline a +6,8 p.p. O mais importante se mostrou não apenas o fine-tuning, mas como a entrada foi empacotada: o modelo começou a distinguir melhor onde estava o contexto do arquivo e onde estava a sugestão a ser avaliada, em vez de reescrever.
O Que Quebrou em Produção
Em testes sintéticos tudo parecia ótimo, mas uma execução em sombra rapidamente esfriou as expectativas. A simples conversão do modelo para ONNX quase triplicou a taxa de transferência e reduziu o tempo de resposta para cerca de 30 ms, mas no tráfego real, a latência em picos novamente disparou para 90 ms. A causa se mostrou não ser o modelo em si, mas o perfil de carga: em produção, rajadas de requisições quase simultâneas chegavam, o que não estava presente nos testes. O problema foi resolvido através de Triton e batching dinâmico com um tamanho de lote pequeno e tempo de espera curto na fila.
"Offline é necessário, mas a execução em sombra é o único lugar onde a
realidade começa."
Depois disso, uma segunda camada de problemas foi descoberta: o filtro se mostrou muito agressivo. Para manter o pico em sugestões aceitas dentro de 5%, o limiar precisou ser retreinado em uma janela semanal de dados em vez de alguns dias. Então, em cima da LLM, outro CatBoost foi adicionado, que recebeu a pontuação do modelo principal, recursos tabulares e sinais históricos como o intervalo entre requisições e mudanças no tamanho do prefixo.
Para isso, o estado do usuário foi armazenado no Redis. No caminho, o time encontrou um erro de engenharia típico: parte das features em produção era calculada em bytes e parte em caracteres. Após alinhar a lógica, um teste A/B mostrou 4,7% de tráfego descartado e +5,2 p.
p. na Taxa de Aceitação sem desvios por linguagem e IDE.
O Que Isso Significa
O caso do T-Bank mostra bem que o próximo aprimoramento de qualidade em ferramentas de IA nem sempre vem de um novo modelo grande. Às vezes, uma camada de decisão separada que fica quieta no momento certo traz maior efeito. Para produtos com alta frequência de uso, isso também é uma questão de confiança: se você remover sugestões desnecessárias, os usuários não apenas ficam menos irritados, mas ao longo do tempo mais frequentemente aceitam opções úteis. Na escala de milhares de desenvolvedores, isso rapidamente se torna uma economia notável de tempo.
Quer parar de ler sobre IA e começar a usar?
AI News é um feed curado de notícias de IA. A Hamidun Academy ensina você a usar IA no trabalho.