Preparação para entrevista
Cenário realProdutoContexto brasileiro

Onboarding conversacional

Conversational onboarding

Onboarding conversacional (Conversational onboarding) é um estudo de caso real de sistema com LLM, do grupo Produto. Cadastrar clientes pelo WhatsApp, coletar documentos e retomar dias depois.

Elemento
19/25
Nível
Avançado
Leitura
12 min
Atualizado
Nesta página 11
  1. 01O negócio
  2. 02Versão 1
  3. 03O que quebrou
  4. 04Smells encontrados
  5. 05Refatorações aplicadas
  6. 06Arquitetura final
  7. 07Números
  8. 08Padrões usados
  9. 09Código de referência
  10. 10Lições
  11. 11Teste seu entendimento
  12. ··Perguntas rápidas

O negócio

Uma fintech brasileira de crédito para pequenos negócios abre contas pelo WhatsApp. O cadastro tem etapas obrigatórias: dados do sócio, CPF, CNPJ, comprovante de endereço, foto do documento, faturamento médio e aceite dos termos. Muitos clientes começam no celular durante o expediente e só terminam dias depois, quando acham o comprovante no fundo de uma gaveta.

WhatsApp é o canal padrão de empresa no Brasil. O cliente já está lá, o sócio não quer baixar um app só para enviar um PDF, e o time comercial já conversa por ali. O custo dessa escolha é o cadastro virar uma conversa longa, interrompida, fora de ordem, com documentos no meio de áudios e “oi, ainda está aí?”.

O objetivo é conduzir o cadastro em conversa natural, aceitar respostas fora de ordem, retomar de onde parou dias depois e nunca expor ou guardar dados pessoais além do necessário. LGPD pede minimização: o modelo, os logs e o time de suporte não precisam ver o CPF inteiro para perguntar o que falta.

Há ainda a janela de 24 horas da API de nuvem do WhatsApp: depois de um dia sem mensagem do cliente, a empresa só envia templates pré-aprovados, não prosa livre do modelo. Um cadastro que dorme três dias precisa de um motor que lembre o estado e de um template que chame o cliente de volta, não de um prompt que releia o histórico.

O que este cenário mede: cadastros concluídos, abandono por etapa e dados pessoais expostos.

Versão 1

A versão 1 era um prompt bem escrito, e funcionou bem em testes curtos. O roteiro cabia num parágrafo, o modelo parecia educado, e o comercial mandava o link do WhatsApp no mesmo dia da reunião.

Você conduz o cadastro da fintech. Siga esta ordem e não pule etapas:
1. Nome do sócio
2. CPF
3. CNPJ
4. Comprovante de endereço
5. Foto do documento
6. Faturamento médio mensal
7. Aceite dos termos
Se o cliente já enviou algo, não peça de novo.
Grave cada dado com a ferramenta salvar_campo.
Seja natural.
flowchart LR
  W(["1. Mensagem no WhatsApp"]):::io --> H[("2. Histórico inteiro da conversa")]:::store
  H --> P(["3. Prompt com o roteiro do cadastro"]):::llm
  P --> R(["4. Resposta"]):::io
  P --> DB[("5. Grava o que achar que coletou")]:::store
  1. Cada mensagem do cliente chega pelo webhook do WhatsApp.
  2. O código carrega toda a conversa, desde o primeiro “oi”.
  3. O prompt descreve as etapas em texto.
  4. O modelo responde.
  5. Quando acha que coletou um dado, chama uma ferramenta para gravar.

O teste interno usava conversas de cinco minutos, com uma pessoa do time respondendo na ordem do roteiro. O modelo pedia o CPF, recebia o CPF, pedia o CNPJ. Ninguém voltou no dia seguinte, ninguém mandou três campos numa frase, ninguém anexou um documento ilegível.

Por que o prompt parece suficiente

Quem escreve o roteiro em prosa está tentando poupar um grafo. “Não pule etapas” e “não peça de novo” soam como regras. Para o modelo, são duas frases no mesmo bloco de tokens, competindo com o histórico, com o áudio transcrito e com o “pode aprovar” do cliente. O guia “Building effective agents”, da Anthropic (dezembro de 2024), descreve exatamente esse atalho: colocar o controle do fluxo no prompt em vez de no código.

O que quebrou

Semana 1. Clientes relataram que o bot pediu o CPF três vezes. Em outros casos, ele pulou o comprovante de endereço e foi direto para os termos. O mesmo prompt, as duas falhas. Quando o cliente mandava nome e CPF juntos, o modelo às vezes gravava o nome, esquecia o CPF e perguntava o CPF de novo. Quando o cliente dizia “depois eu mando o comprovante”, o modelo às vezes tratava a promessa como o documento.

Semana 3. Clientes que voltavam depois de dois ou três dias encontravam um bot confuso. O histórico já tinha dezenas de mensagens, um áudio, um print ilegível e duas tentativas de CNPJ. O modelo perguntava de novo o que já tinha recebido, ou retomava numa etapa errada. Liu e colegas, no paper “Lost in the Middle” (2023), mostraram que modelos usam mal o que fica no meio de um contexto longo. O CPF enviado no primeiro dia estava exatamente ali: no meio.

Semana 4. O time descobriu CPFs e fotos de documentos inteiros nos logs de observabilidade e no histórico enviado ao modelo em toda mensagem, inclusive em conversas de suporte depois do cadastro. O dado pessoal tinha virado contexto permanente. Em 2023, a Samsung restringiu o ChatGPT depois que funcionários colaram código confidencial no modelo. Aqui o equivalente é o CPF do sócio viajando para o provedor a cada “oi”.

Semana 6. Um cliente mandou “já mandei tudo, pode aprovar”. O modelo respondeu que o cadastro estava completo, sem o comprovante. A ferramenta salvar_campo nunca tinha recebido o arquivo. Quem decidiu o fim foi a prosa do cliente, não o estado.

As quatro semanas apontam para o mesmo desenho: o roteiro e a memória do cadastro vivem no texto que o modelo relê. Texto se perde, se contradiz e se deixa convencer.

Checagem +20 XP de primeiraNa semana 1 o bot pede o CPF de novo, mesmo depois de o cliente ter mandado nome e CPF na mesma frase. Qual é a causa mais útil de atacar primeiro?

Smells encontrados

Prompt Máquina de Estados

O roteiro de etapas vivia no prompt. “Não pule” e “não peça de novo” são regras de grafo escritas em português. O modelo as aplica quando lembra, e as esquece quando o cliente improvisa. Causou as perguntas repetidas e as etapas puladas das semanas 1 e 6.

Um estado de verdade tem um lugar por campo:

nome_socio: validado
cpf:        validado
cnpj:       recebido
comprovante: faltando
documento:  faltando
faturamento: faltando
termos:     faltando

O prompt da versão 1 não tem essa tabela. Tem um parágrafo que pede para o modelo fingir que ela existe.

Contexto Podre

O histórico completo de dias de conversa ia em toda mensagem. Causou a confusão na retomada da semana 3 e espalhou dados pessoais pela semana 4. Cada “ainda está aí?” reenviava o CPF, a foto do RG e o comprovante com endereço, para o modelo e para o coletor de traces.

Refatorações aplicadas

1. Trocar Regra de Prompt por Aresta de Grafo

As etapas viraram um grafo em código, com o estado de cada campo: faltando, recebido, validado. O modelo passou a ter um papel menor: entender a mensagem e extrair os dados, em qualquer ordem. O código decide a próxima pergunta olhando o que ainda está faltando.

Recebido não é validado. Um CNPJ com dígito verificador errado fica em recebido até o código recusar ou uma pessoa olhar. O modelo não “valida” CNPJ: ele devolve os dígitos que leu.

2. Trocar Histórico por Resumo

O modelo recebe o estado do cadastro, um resumo curto (“cliente Ana, retomando depois de três dias, falta comprovante e foto”) e as últimas mensagens. Dados pessoais ficam no estado, mascarados. O texto da conversa enviado ao modelo não carrega o CPF inteiro nem a imagem do documento.

3. Mover para Execução Durável

Cada cadastro é um workflow que persiste o estado a cada etapa e pode esperar dias por um documento sem perder nada. A espera não é um bot “lembrando” da conversa. É um timer e um estado no banco. Quando o cliente volta, ou quando o template de 24 horas dispara, o workflow acorda no mesmo objeto.

Checagem +20 XP de primeiraUm cliente some na terça e volta sexta com o comprovante. Qual desenho retoma o cadastro sem pedir o CPF de novo e sem reenviar a foto do RG ao modelo?

Arquitetura final

flowchart TD
  W(["1. Mensagem ou documento"]):::io --> G["2. Guardrail: mascarar e guardar dados pessoais"]:::tool
  G --> X(["3. Extrair campos da mensagem"]):::llm
  X --> V["4. Validar: CPF, CNPJ, documento"]:::tool
  V --> S[("5. Estado do workflow")]:::store
  S --> N{"6. Próxima etapa em código"}
  N -->|"falta campo"| A(["7. Perguntar de forma natural"]):::llm
  N -->|"caso fora do roteiro"| H((("8. Atendente humano"))):::human
  N -->|"tudo validado"| T(["9. Termos e conclusão"]):::io
  A --> OUT(["Resposta no WhatsApp"]):::io
  1. A mensagem ou o arquivo chega pelo WhatsApp.
  2. Um guardrail de entrada detecta CPF, CNPJ e documentos, guarda o valor num cofre e deixa só uma referência mascarada no texto.
  3. Um modelo pequeno extrai, em saída estruturada, os campos que a mensagem traz, em qualquer ordem.
  4. O código valida cada campo: dígitos verificadores, consulta de CNPJ, legibilidade do documento.
  5. O estado do cadastro é persistido pelo workflow durável a cada mudança.
  6. O código decide a próxima etapa pelo estado, não pelo histórico.
  7. O modelo escreve a próxima pergunta de forma natural, recebendo só o estado e as últimas mensagens.
  8. Situações fora do roteiro (sócio estrangeiro, empresa em recuperação) vão para uma pessoa, com o estado.
  9. Com tudo validado, os termos são enviados e o aceite é registrado.

O modelo nunca declara o cadastro completo. Completo é um predicado no código: todos os campos obrigatórios estão validado, os termos têm aceite com carimbo de tempo, e nenhum campo está recebido parado sem validação.

O que o modelo vê, antes e depois

Suponha a quarta mensagem da sexta-feira, depois de três dias e um comprovante novo. A versão 1 reenviava tudo. A final manda só o que o passo precisa:

Versão 1 Arquitetura final
Texto ao modelo Histórico desde o “oi” da terça, com CPF, CNPJ, foto em base64 e o PDF Estado mascarado + resumo de uma linha + a mensagem nova
Quem decide a próxima pergunta O modelo, relendo o roteiro O grafo, olhando comprovante: recebido
Onde está o CPF Em toda chamada, em claro No cofre; o modelo vê ***8909

A diferença não é “menos tokens por educação”. É o CPF sair do caminho do provedor e o próximo passo deixar de depender de o modelo achar uma frase no meio do contexto.

Recebido e validado também não são sinônimos. O comprovante acaba de chegar: o estado vira recebido, um validador tenta ler um endereço no PDF, e só então vira validado. Se a imagem estiver escura, o campo não anda sozinho. Vai para a pessoa, com o arquivo no cofre. O modelo da pergunta seguinte não “chuta” que o endereço estava lá.

Exemplo trabalhado: três campos numa frase

A cliente Ana escreve: “sou a Ana Souza, CPF 123.456.789-09, CNPJ 12.345.678/0001-95, faturamento uns 40 mil”.

O guardrail troca os identificadores por referências antes de o texto chegar ao extrator:

sou a Ana Souza, CPF {{cpf:p_92}}, CNPJ {{cnpj:p_93}}, faturamento uns 40 mil

O extrator devolve um objeto:

{
  "nome_socio": "Ana Souza",
  "cpf_ref": "vault:p_92",
  "cnpj_ref": "vault:p_93",
  "faturamento_mensal_centavos": 4000000,
  "faturamento_incerto": true
}

O código valida os dígitos do CPF e do CNPJ no cofre, consulta a Receita para o CNPJ, e marca faturamento como recebido com uma flag de incerteza, porque “uns 40 mil” não é um valor fechado. A próxima pergunta que o grafo pede não é o CPF. É o comprovante de endereço, a foto do documento, e uma confirmação do faturamento em número. Uma mensagem, quatro campos tocados, zero repetição.

Retomada depois de três dias

Na quinta o workflow dispara um template aprovado: “Oi Ana, ainda falta o comprovante de endereço e a foto do documento para concluir sua conta.” Não é o modelo inventando a frase longa depois da janela de 24 horas. É o estado dizendo o que falta, e o template preenchendo dois buracos.

Ana manda o PDF. O guardrail guarda o arquivo no cofre, o validador de documento confere se dá para ler um endereço, o campo passa a validado ou vai para uma pessoa se a imagem estiver escura. O modelo da pergunta seguinte só vê: comprovante validado, falta foto, termos ainda não.

Dado pessoal fora do modelo

O cofre guarda o valor. Os logs mostram cpf=***8909. O modelo vê mascara=***.***.***-09. O atendente humano, na passagem, recebe o estado e um link temporário para o documento, não um dump do histórico. Isso atende minimização da LGPD e corta a classe de vazamento da semana 4. Transferir CPF inteiro a um provedor de modelo a cada mensagem é transferência de dado pessoal; a referência mascarada não é.

Fora do roteiro

Sócio com passaporte, empresa em recuperação judicial, dois sócios que precisam assinar: o grafo tem uma aresta explícita para pessoa. A passagem leva o estado, não um resumo em prosa do tipo “acho que falta um documento”. A pessoa vê o mesmo objeto que o código vê. O modelo não improvisa uma exceção à regra de KYC.

Armadilhas comuns

  • Deixar o modelo decidir que ‘já está completo’. A semana 6 cabe numa frase do cliente. Completo é predicado de estado.
  • Resumo que copia o CPF. Trocar histórico por resumo não ajuda se o resumo é o histórico encolhido, com os mesmos identificadores.
  • Validar CNPJ no prompt. Dígito verificador e situação cadastral são código e consulta. O modelo lê o número; o código diz se ele existe.
  • Esperar a pergunta certa. O cliente responde o que tem na mão. Extraia todos os campos de cada mensagem.
  • Retomada relendo a conversa. Três dias depois, o que você carrega é o objeto, não os áudios da terça.
  • Prosa livre depois de 24 horas. A API recusa. O template é parte do workflow, não um detalhe de produto.
Checagem +20 XP de primeiraO cliente, no meio da etapa de CPF, manda o CNPJ, o faturamento e um ‘o comprovante eu mando amanhã’. O que o extrator e o grafo devem fazer?

Números

As métricas deste cenário são cadastros concluídos, abandono por etapa e dados pessoais expostos, comparando a versão 1 com a arquitetura final num conjunto de conversas simuladas, incluindo retomadas depois de dias e respostas fora de ordem.

As três se leem juntas. Subir conclusão empurrando o cliente para “aceitar os termos agora”, sem comprovante, infla a primeira métrica e esconde um cadastro inválido. Abandono por etapa mostra onde o grafo pede demais ou pede de novo. Dados pessoais expostos conta identificadores e imagens que chegaram a log, a trace ou ao provedor do modelo. Se essa terceira não for zero no conjunto de teste, o restante não segura uma auditoria de LGPD.

O conjunto precisa incluir, no mínimo, o que quebrou a versão 1: dois campos na mesma frase, volta depois de dias, “já mandei tudo”, documento ilegível, sócio fora do roteiro, e uma conversa de suporte depois do cadastro para ver se o CPF ainda viaja no histórico. Também precisa do caminho feliz, senão qualquer mascaramento parece vitória.

Os números ainda não foram publicados. Eles virão do código de referência executável, rodando as duas versões contra o mesmo conjunto, e esta seção será atualizada com o resultado e o script que gera os números. Até lá, nenhum número aparece aqui.

Padrões usados

Padrão Papel no sistema
Workflow Durável O cadastro sobrevive a dias de espera, a falhas e à janela de 24 horas
Memória de Curto Prazo Estado explícito do cadastro em vez do histórico bruto
Memória de Longo Prazo Preferências do cliente para o atendimento depois do cadastro, sem reabrir o cofre
Guardrails de Entrada Detecção de CPF, CNPJ e documentos antes do modelo
Mascaramento de Dados Pessoais Valor no cofre, máscara no texto, referência no estado
Passagem entre Agentes Casos fora do roteiro passam para uma pessoa com o mesmo estado

A lista completa de padrões ligados a este cenário está em Relações, abaixo.

Guardrail e mascaramento trabalham em sequência: o primeiro acha o dado, o segundo decide o que o modelo pode ver. Workflow durável e memória de curto prazo são o mesmo objeto visto de dois lados: persistência entre dias, e o que o modelo recebe agora. Sem a passagem para pessoa, o grafo tenta cobrir exceção de KYC com mais prosa, e o prompt máquina de estados volta pela porta dos fundos.

Código de referência

O sistema completo, com as duas versões, as conversas simuladas e o script que gera os números desta página, fica no repositório de código de referência do ai-guru, em scenarios/conversational-onboarding/. O repositório está sendo preparado, e o link entra aqui quando for publicado.

Lições

  1. O roteiro é código; a conversa é do modelo. Quem decide a próxima etapa é o estado. O modelo só torna a pergunta natural, e nunca declara o fim.
  2. Estado explícito resolve a retomada. Voltar depois de três dias passou a ser carregar um objeto e, se a janela fechou, disparar um template. Não é reler uma conversa.
  3. Dado pessoal não precisa passar pelo modelo. Uma referência mascarada conduz a conversa. O cofre guarda o valor. A LGPD deixa de ser um poster na parede.
  4. Respostas fora de ordem são a regra. Extrair todos os campos de cada mensagem, em vez de esperar a pergunta certa, reduz o vai e vem e o abandono.
  5. Saber quando chamar uma pessoa faz parte do fluxo. Casos fora do roteiro têm aresta no grafo. Improviso do modelo não é política de cadastro.

Teste seu entendimento

Checagem +20 XP de primeiraO cliente escreve ‘já mandei tudo, pode aprovar’. O comprovante não está no estado. O modelo da versão 1 responderia que o cadastro está completo. O que a arquitetura final faz?

Checagem +20 XP de primeiraO time de observabilidade acha fotos de RG e CPF inteiro nos traces das chamadas ao modelo, inclusive numa conversa de suporte duas semanas depois do cadastro. Qual mudança corta isso na raiz?

Checagem +20 XP de primeiraO CNPJ informado pertence a uma empresa em recuperação judicial, caso que o grafo não cobre. Qual é o próximo passo?

Perguntas rápidas

O que é Onboarding conversacional?

Onboarding conversacional (Conversational onboarding) é um estudo de caso real de sistema com LLM, do grupo Produto. Cadastrar clientes pelo WhatsApp, coletar documentos e retomar dias depois.

Quais padrões de IA o cenário Onboarding conversacional usa?

Memória de Curto Prazo, Memória de Longo Prazo, Workflow Durável, Passagem entre Agentes, Guardrails de Entrada e Mascaramento de Dados Pessoais.

Para ir além

Relações

Buscar