Preparar PDFs para LLMs e pipelines de recuperação

Última revisão

Dar PDFs a um modelo de linguagem — para geração aumentada por recuperação, para resumo, ou só para colar numa janela de contexto longa — é hoje uma das razões mais comuns para converter um documento.

É também o uso em que a qualidade da conversão mais importa e menos se percebe, porque um pipeline de recuperação falha em silêncio. Um documento mal convertido não lança erro. Ele simplesmente devolve a passagem errada, ou uma passagem com a tabela destruída, e o modelo responde com confiança a partir dela.

9 min de leitura

Por que não basta extrair o texto cru

Qualquer biblioteca de PDF te dá o texto de um documento em duas linhas de código, e para um memorando de coluna única isso basta mesmo. Para qualquer outra coisa não basta, por três razões que custam qualidade de recuperação.

Primeira, a ordem de leitura. A extração crua devolve o texto na ordem em que os glifos foram desenhados, o que numa página de duas colunas entrelaça as colunas. Metade dos seus chunks vira fragmento de frase alternando entre parágrafos sem relação, e eles se incorporam num ponto do espaço vetorial que não corresponde a nada.

Segunda, os limites. Sem títulos não há por onde fatiar além da contagem de caracteres, então os chunks partem no meio de frases e no meio de tabelas, e um chunk que começa no meio de uma explicação não se entende sozinho — que é exatamente o que um chunk recuperado precisa fazer.

Terceira, as tabelas. Extraída como texto cru, uma tabela vira um fluxo de números sem indicação de qual coluna cada um veio. Um modelo lendo isso vai responder à sua pergunta assim mesmo. A resposta é que vai estar errada.

O que o Markdown dá ao pipeline

O Markdown é um bom formato intermediário aqui por razões que nada têm a ver com ele ser bonito.

  • Os títulos dão limites semânticos de chunk, então um chunk é uma seção e não uma janela de mil caracteres.
  • O caminho de títulos dá contexto a cada chunk — dá para prefixar "Capítulo 3 › Limites de taxa › Comportamento em rajada" antes de incorporar, o que melhora de forma mensurável a recuperação em documentos onde a mesma palavra significa coisas diferentes em seções diferentes.
  • As tabelas de barras mantêm linhas e colunas associadas, então um modelo lendo uma tabela recuperada sabe qual número pertence a qual cabeçalho.
  • É compacto. O Markdown carrega estrutura ao custo de poucos caracteres por elemento, enquanto HTML ou formatos JSON de layout gastam tokens em marcação que não diz nada ao modelo.
  • É um formato do qual todo modelo atual viu quantidades enormes no treinamento, então não precisa de explicação no prompt.

Fatiar, na prática

A abordagem que funciona em documentos convertidos é partir primeiro nos títulos e só recorrer a limites de tamanho dentro de uma seção grande demais.

Parâmetros aproximados que se sustentam na maioria dos tipos de documento:

Corte principalEm H2, recuando para H3 em seções longas
Tamanho-alvo de chunk500–1.000 tokens
Máximo rígidoO que deixar espaço para vários chunks no contexto
Sobreposição1–2 frases, ou nenhuma se os chunks seguem títulos
Prefixo do chunkTítulo do documento mais o caminho completo de títulos
TabelasNunca partir — inteiras, mesmo acima do tamanho

Nunca parta uma tabela

Esta é a regra que a maioria dos pipelines quebra, porque um fatiador ingênuo não faz ideia de que está dentro de uma.

Uma tabela GFM partida ao meio produz dois chunks, e nenhum é uma tabela válida: o primeiro tem cabeçalho e algumas linhas, o segundo tem linhas sem cabeçalho nenhum. O segundo é pior que inútil, porque os números nele estão sem rótulo e um modelo vai rotulá-los adivinhando.

Detecte blocos de tabela antes de fatiar e mantenha cada um inteiro, mesmo que isso dê um chunk acima do tamanho-alvo. Se uma tabela for genuinamente grande demais para um chunk, repita a linha de cabeçalho em cada pedaço.

Onde entram os documentos digitalizados

Uma digitalização não tem texto, então não há o que fatiar. O reconhecimento de texto precisa vir antes — e a saída dele tem propriedades que um pipeline precisa considerar, porque reconhecimento é estimativa e não transcrição.

Duas em especial. A confiança varia por página, então um documento pode ser quase perfeito por quarenta páginas e duvidoso em três; se a sua etapa de reconhecimento informa confiança por página, leve isso para os metadados do chunk para poder sinalizar uma resposta de baixa confiança. E as palavras ilegíveis são descartadas em vez de marcadas, o que significa que o texto parece fluente e completo enquanto falta justamente o que o motor achou mais difícil — muitas vezes nomes, códigos de referência e números.

Para qualquer coisa em que um erro tenha consequências, texto reconhecido deve ser tratado como pista a verificar contra o original, não como fonte de registro.

O que conferir antes de indexar um corpus

Indexar é a etapa cara, lenta e difícil de desfazer, então vale gastar vinte minutos numa amostra antes. Converta cinco documentos escolhidos por serem diferentes entre si e leia o Markdown.

  • Os títulos formam uma escada sensata? Se estiverem achatados, seu fatiador não tem onde partir e você vai cair em janelas de tamanho fixo no corpus inteiro.
  • As tabelas sobreviveram? Conte as colunas contra o original em duas ou três.
  • A ordem de leitura está certa nas páginas de várias colunas? Colunas entrelaçadas são óbvias quando você olha e invisíveis depois de indexadas.
  • Há conversões vazias ou quase vazias? Aquilo são digitalizações, e precisam de outro caminho.
  • O mesmo texto padrão se repete em todos os documentos? Cabeçalhos e rodapés repetidos viram chunks quase duplicados que empurram o conteúdo real para fora dos resultados.

A dimensão de privacidade, que não é acessória

Corpora de RAG são montados justamente com os documentos que as organizações menos querem entregar a terceiros: contratos, relatórios internos, dados de clientes, pesquisa ainda não publicada.

Vale ser deliberado sobre quais etapas do seu pipeline mandam esses documentos para algum lugar. A conversão não precisa ser uma delas: um conversor que roda no navegador processa o arquivo na máquina onde ele já está, então a etapa de conversão não acrescenta nenhuma parte à cadeia. Se as etapas seguintes acrescentam é outra decisão — mas é uma decisão que você pode tomar separadamente.