Por que a lista de “Fontes” do seu chatbot de IA provavelmente está errada

ai-agents

Quase todo chatbot de suporte com IA mostra uma linha de fontes embaixo das respostas. É o recurso que faz a resposta parecer verificável: foi daqui que eu tirei isso.

Na maioria das implementações, essa linha mente para você. Não por maldade — ela só responde a uma pergunta diferente da que o usuário está fazendo.

Recuperado não é o mesmo que usado

Um chatbot com geração aumentada por recuperação (RAG) responde mais ou menos assim: pesquisa a base de conhecimento, coloca os primeiros resultados no contexto do modelo e deixa que ele escreva. A forma óbvia de montar a linha de fontes é mostrar tudo o que voltou dessa pesquisa.

É o que a maioria dos produtos faz, e isso está errado de um jeito específico. Uma busca semântica devolve dez candidatos porque dez é um número razoável de opções para um modelo de linguagem escolher. O modelo lê os dez e usa um. Mostrar os dez como fontes diz ao usuário que dez artigos embasaram a resposta, quando nove foram descartados.

A falha é silenciosa. Ninguém abre um bug dizendo “a linha de fontes tem itens demais”. Os usuários só aprendem, aos poucos, que a linha é decorativa — e param de lê-la. Você pagou o custo inteiro de engenharia das citações e não recebeu nada da confiança que elas deveriam trazer.

O problema do “liste tudo”

A falha fica mais evidente quando o usuário pergunta algo sobre a estrutura.

“Sobre o que vocês têm artigos?”

Um bom assistente responde com uma lista dos seus artigos. Agora a linha de fontes traz todos os artigos da sua central de ajuda e repete, logo abaixo da resposta, exatamente os links que já estão nela. O usuário vê os mesmos trinta títulos duas vezes.

É nesse ponto que a abstração quebra à vista de todos, e vale levar isso a sério, porque revela o bug de verdade: não dá para deduzir a procedência a partir da recuperação. É preciso deduzi-la a partir do que o modelo fez.

Três conjuntos, não um

A correção é parar de tratar isso como uma lista só. Por trás de qualquer resposta há três conjuntos distintos de documentos:

Recuperados — tudo o que qualquer ferramenta devolveu durante o turno. É o conjunto que a maioria dos produtos exibe. A função real dele é outra, e importante: ele é a lista de permissões. Se o modelo cita um documento que nunca foi recuperado, ele inventou a referência, e você a descarta. Essa checagem não é teórica. Nos meus próprios testes, um modelo que transcrevia trinta IDs de documentos errou um deles por um único caractere — a verificação pegou o erro e se recusou a transformar um ID corrompido em fonte.

Citados — os documentos para os quais a resposta de fato tem links. É isso que torna clicáveis as citações no texto, e é a base honesta para a cobrança por uso.

Consultados — os documentos cujo texto o modelo leu. Esse é o único conjunto que tem lugar numa linha de fontes.

O terceiro conjunto é o que ninguém calcula, e calculá-lo não é difícil. Você já sabe qual ferramenta devolveu cada documento. Algumas entregam ao modelo conteúdo de verdade: uma busca que devolve trechos, ou uma chamada “busque este documento” que devolve o texto inteiro. Outras entregam um sumário: listar as categorias, listar os artigos, navegar por uma seção. Essas devolvem títulos.

Então:

  • O modelo abriu um documento inteiro → é uma fonte, quer a resposta tenha link para ele ou não. Abrir o documento é a procedência. Se o modelo resume um artigo e esquece de escrever um link em markdown, é um deslize de formatação, não ausência de evidência.

  • Uma busca o devolveu e a resposta o citou → é uma fonte. A citação identifica qual dos dez candidatos foi usado.

  • O modelo só o viu como título numa listagem → nunca é fonte, mesmo que a resposta tenha link para ele.

Com essa regra, “quais artigos vocês têm?” produz uma lista limpa de links que funcionam e nenhuma linha de fontes, porque o modelo não leu nada. E “como configuro o SSO?” produz um parágrafo com um ou dois chips embaixo — os artigos que ele realmente leu.

O detalhe de design que causa problemas

Há uma armadilha na implementação, e vale nomeá-la porque é fácil errar de um jeito que parece certo até o usuário clicar em algo.

O seu array de fontes costuma ter dupla função. Ele guarda os dados dos chips e é a tabela de consulta que torna clicáveis as citações no texto — o handler de clique procura o ID do documento da citação nesse array e o abre.

Por isso não dá para simplesmente reduzir o array ao conjunto consultado. Faça isso e todo link numa resposta de listagem morre: renderizado como citação, estilizado como citação e sem reação ao clique.

Mantenha o conjunto citado inteiro no payload, marque cada item com uma flag e filtre só na hora de exibir. Um booleano por fonte, filtrado no renderizador. Os links continuam funcionando; os chips dizem a verdade.

Deixe a flag opcional

Se você lançar isso como uma mudança de API, deixe o campo opcional em vez de obrigatório e trate a ausência de valor como “sim, mostre”.

Essa única decisão faz com que um cliente antigo falando com um servidor novo continue funcionando, e que um cliente novo falando com um servidor antigo volte ao comportamento anterior em vez de esconder todas as fontes. Você não vai fazer o deploy dos dois lados no mesmo instante, e os usuários mantêm cópias do seu widget em cache por mais tempo do que você gostaria.

Por que vale o esforço

Uma linha de fontes é uma afirmação: esta resposta veio destes documentos. Se a afirmação sai da recuperação, ela é aproximadamente verdadeira, e cedo ou tarde os usuários percebem. Se sai do que o modelo de fato leu, ela é exatamente verdadeira e vira o jeito mais rápido de a sua equipe de suporte auditar uma resposta que deu errado.

Há um segundo ganho. Quando “sem fontes” passa a significar com segurança “o modelo não leu nada”, isso vira um sinal real. Uma resposta sem fontes a uma pergunta concreta sobre o produto é uma lacuna na documentação, e dá para filtrar essas respostas e transformá-las numa fila de artigos a escrever.

Isso só funciona se a linha significar alguma coisa.


O assistente de chat com IA do Kookee segue a regra acima: a linha Fontes mostra os artigos em que a resposta se baseou, e todo artigo para o qual a resposta tem link continua clicável. Veja Como o assistente escolhe as fontes para os detalhes, ou Como criar uma central de ajuda para o seu SaaS para o panorama geral.