RAG com citações: como gerar resposta auditável

Um sistema RAG que responde "O prazo de entrega é de 5 dias úteis" está correto ou está alucinando? Sem saber de qual documento, qual cláusula e qual versão essa informação veio, você não tem como saber. Citações não são um detalhe de UX — são o mecanismo que transforma uma resposta em evidência auditável. Neste artigo, o template de prompt e a lógica de validação que realmente funcionam.

Por que citações são críticas em domínios regulados

Em domínios como jurídico, saúde, financeiro e compliance, a rastreabilidade não é funcionalidade opcional — é requisito mínimo de confiabilidade. Considere os cenários:

Mesmo fora de domínios regulados, citações reduzem o risco de alucinação "útil": o modelo que sabe que precisa citar uma fonte tende a ser mais conservador em afirmar coisas que não estão explicitamente no contexto.

Para entender o impacto de citações nas métricas de qualidade, veja avaliação de RAG: faithfulness, relevance e precision.

Template de prompt que força citações

A instrução genérica "cite as fontes" produz resultados inconsistentes. LLMs precisam de formato explícito, exemplos (few-shot) e instruções sobre o que fazer quando a informação não está disponível.

System prompt completo

SISTEMA: Você é um assistente especializado em consulta de documentos internos.

REGRAS OBRIGATÓRIAS DE CITAÇÃO:
1. Toda afirmação factual DEVE ser seguida de um número de referência entre colchetes: [1], [2], etc.
2. Use o mesmo número para citações do mesmo trecho.
3. Liste TODAS as referências ao final da resposta na seção "Fontes".
4. Se a informação não estiver nos documentos fornecidos, diga explicitamente:
   "Não encontrei essa informação nos documentos disponíveis."
   Nunca invente ou complemente com conhecimento próprio.
5. Não parafraseie de forma que distorça o sentido original. Prefira citar o trecho exato.

FORMATO DA SEÇÃO DE FONTES:
---
Fontes:
[N] Nome do documento — Seção/Cláusula X.X — Página Y
---

DOCUMENTOS DISPONÍVEIS:
{contexto_formatado}

Formatação do contexto para facilitar citações

A chave para citações funcionarem é que cada chunk seja apresentado ao LLM com um identificador claro:

def formatar_contexto_com_ids(chunks: list) -> str:
    """Formata os chunks recuperados com identificadores de citação."""
    contexto_partes = []

    for i, chunk in enumerate(chunks, start=1):
        parte = f"""[DOCUMENTO {i}]
Arquivo: {chunk.metadados['nome_arquivo']}
Seção: {chunk.metadados.get('secao', 'N/A')}
Página: {chunk.metadados.get('pagina', 'N/A')}
Data: {chunk.metadados.get('data_documento', 'N/A')}

{chunk.texto}
---"""
        contexto_partes.append(parte)

    return "\n\n".join(contexto_partes)

Exemplo de resposta com footnotes formatados

Com o prompt acima, uma pergunta sobre prazo de entrega geraria:

Pergunta: Qual é o prazo de entrega padrão para pedidos acima de R$ 10.000?

Resposta do sistema:
Para pedidos com valor superior a R$ 10.000, o prazo de entrega padrão é de
7 (sete) dias úteis contados a partir da confirmação do pagamento [1].
Pedidos com itens sob encomenda podem ter prazo estendido em até 15 dias
adicionais, conforme comunicação prévia ao cliente [2].

Em casos de força maior, o prazo pode ser suspenso por período equivalente
ao impedimento, mediante notificação formal em até 24 horas [1].

---
Fontes:
[1] Contrato Padrão de Fornecimento v3.2 — Cláusula 8.1 (Prazos) — Página 12
[2] Adendo Comercial 2025-03 — Seção 2 (Itens Sob Encomenda) — Página 2

Validação programática: a citação realmente existe?

O maior risco em RAG com citações é o LLM citar uma referência que não existe no chunk fornecido — ou distorcer o que estava escrito. A validação programática é a defesa contra isso.

import re

def validar_citacoes(resposta: str, chunks_fornecidos: list) -> dict:
    """
    Verifica se cada referência [N] na resposta corresponde
    a um chunk real com conteúdo compatível.
    """
    # Extrair todos os números de citação usados
    numeros_citados = set(re.findall(r'\[(\d+)\]', resposta))

    resultados = {}

    for num_str in numeros_citados:
        num = int(num_str)

        # Verificar se o número de chunk existe
        if num > len(chunks_fornecidos):
            resultados[num] = {
                "valida": False,
                "motivo": f"Chunk [{num}] não existe no contexto (total: {len(chunks_fornecidos)})"
            }
            continue

        chunk = chunks_fornecidos[num - 1]

        # Verificar se as afirmações da resposta referentes a [N]
        # têm suporte textual no chunk (verificação simplificada por overlap)
        trechos_afirmados = extrair_afirmacoes_por_citacao(resposta, num)
        suporte_encontrado = any(
            verificar_suporte_semantico(afirmacao, chunk.texto)
            for afirmacao in trechos_afirmados
        )

        resultados[num] = {
            "valida": suporte_encontrado,
            "chunk_id": chunk.metadados["id"],
            "documento": chunk.metadados["nome_arquivo"],
            "motivo": "OK" if suporte_encontrado else "Afirmação não encontrada no chunk citado"
        }

    return resultados

Se alguma citação falhar na validação, você tem duas opções: retornar a resposta com um aviso de citação não verificada, ou registrar o evento para revisão humana e retornar apenas as partes validadas.

UX de apresentação: como mostrar citações sem poluir a interface

Uma resposta cheia de [1][2][3] pode ser tecnicamente correta mas visualmente perturbadora para o usuário não técnico. Algumas estratégias de apresentação:

A escolha depende do público: advogados e auditores querem verificar tudo e preferem o painel lateral; equipes operacionais querem a resposta rápida e usam citações apenas quando algo parece errado.

Limitações honestas: o que citações não resolvem

Citações melhoram muito a confiabilidade, mas não são garantia absoluta:

Para rastreabilidade além das citações — incluindo log de auditoria de queries — veja auditoria e rastreabilidade de decisões tomadas por IA.

Quando implementar citações: decisão pragmática

Citações adicionam complexidade ao sistema e custo (mais tokens no prompt). Vale implementar quando:

Para sistemas de atendimento ao cliente com perguntas simples e corpus bem curado, citações podem ser desnecessárias e atrapalhar a experiência. Para o assistente jurídico interno, são inegociáveis.

O fundamental é entender o que é RAG e como o contexto é enviado ao LLM para estruturar bem o sistema de citações. Veja o guia completo sobre RAG.