Seu agente de IA vai duplicar cliente no CRM, e o culpado não é o LLM
O modelo entende a mensagem do WhatsApp, responde bonito... e grava no cadastro errado. Na maioria dos casos que vi, o erro está na ponte entre a conversa e o banco, não no modelo.
Três armadilhas que dá para testar hoje, sem CRM nenhum:
- “João” ≠ “João”
python
import unicodedata
a = "Joa\u0303o" # acento combinante
b = "João" # caractere pré-composto
a == b # False
unicodedata.normalize("NFC", a) == b # True
unicodedata.normalize("NFKC", "𝐉𝐨𝐚𝐨") # 'Joao' (letra "estilizada" de perfil)
Use a forma normalizada só como chave de busca de possíveis duplicados. Nunca use para mesclar contatos sozinha nem para sobrescrever o nome exibido.
- Caracteres invisíveis
O NFKC troca o U+00A0 (espaço não separável) por espaço comum, mas mantém o U+200B (espaço de largura zero). Então “normalizar” não limpa tudo:
python
def invisiveis(s):
return [hex(ord(c)) for c in s
if unicodedata.category(c) == "Cf"
or (unicodedata.category(c) == "Zs" and c != " ")]
invisiveis("Ana\u200bSilva") # ['0x200b']
Sinalize para revisão. Não apague em silêncio.
- Webhook repetido = contato duplicado
Se o provedor reentrega o mesmo evento, seu fluxo cria outro contato? Isso se resolve com idempotência no backend, não com instrução no prompt:
sql
CREATE TABLE eventos_processados (event_id VARCHAR(100) PRIMARY KEY);
-- INSERT antes de processar; se der chave duplicada, ignora o evento
A regra de arquitetura que resolve metade dos problemas: a saída do modelo é uma proposta de ação. Quem decide gravar é o backend, depois de checar identidade, permissão e confirmação explícita do cliente.
No Algoritmo Diário publicamos o roteiro completo: 5 testes com dados sintéticos e uma matriz de QA para rodar antes de liberar a integração. Inclui os casos de telefone em E.164 e de handoff para humano:
👉 https://algoritmodiario.com/agente-ia-crm-testes-cadastro
Alguém aqui já pegou duplicado por caractere invisível em produção?