O que é o Unstructured

O Unstructured é uma biblioteca Python open source que transforma documentos bagunçados (PDF, Word, PowerPoint, HTML, e-mails, imagens) em dados estruturados prontos para alimentar modelos de linguagem. Em vez de você escrever um parser para cada formato, ele entrega uma lista de elementos limpos: títulos, parágrafos, tabelas e listas.

O projeto é mantido pela Unstructured Technologies, empresa fundada em 2022 nos Estados Unidos. O código fica no GitHub sob licença Apache 2.0 e já passou de 10 mil estrelas. Nesta semana ele voltou ao GitHub Trending, o que mostra que a dor de preparar documentos para IA continua muito viva.

O problema que ele resolve é simples de explicar e difícil de fazer: cerca de 80% dos dados de uma empresa estão em arquivos não estruturados. Para montar um RAG (Retrieval Augmented Generation) decente, você precisa extrair esse conteúdo com qualidade, e é exatamente aí que a maioria dos projetos trava.

Como funciona

O coração da biblioteca é a função partition. Você passa o caminho de um arquivo e ela detecta o tipo automaticamente, escolhe o parser adequado e devolve uma lista de elementos. Cada elemento tem um tipo (Title, NarrativeText, Table, ListItem, Image, entre outros), o texto extraído e metadados como número da página e arquivo de origem.

Para PDFs e imagens existem três estratégias de processamento. A fast usa apenas a camada de texto do PDF e é bem rápida. A hi_res aplica modelos de visão computacional para detectar layout, tabelas e colunas, com resultado muito melhor e custo de processamento maior. A ocr_only roda OCR com Tesseract em documentos escaneados.

Depois da extração entra o chunking. A biblioteca sabe agrupar elementos respeitando a hierarquia do documento: a estratégia by_title, por exemplo, nunca mistura o final de uma seção com o começo da próxima. Isso faz uma diferença enorme na qualidade das respostas do seu RAG, porque o chunk chega ao modelo com contexto coerente.

💡
Dica

Pense no Unstructured como um tradutor universal de documentos: entra qualquer formato, sai sempre a mesma estrutura em Python. Seu código de RAG passa a lidar com um único tipo de dado.

Principais recursos

A lista de formatos suportados é o primeiro grande diferencial. Sem escrever nada específico você processa PDF, DOCX, PPTX, XLSX, HTML, Markdown, EPUB, CSV, e-mails (EML e MSG) e imagens (PNG, JPG, TIFF). Quase qualquer coisa que aparece numa pasta compartilhada de empresa entra pelo mesmo funil.

  • Detecção de layout: identifica títulos, cabeçalhos, rodapés, colunas e tabelas em PDFs complexos.
  • Extração de tabelas: converte tabelas para HTML nos metadados, preservando linhas e colunas para o modelo.
  • Limpeza de texto: funções prontas para remover espaços extras, bullets, marcações e ruído de OCR.
  • Chunking inteligente: estratégias basic e by_title com controle de tamanho máximo em caracteres.
  • Metadados ricos: página, coordenadas, idioma detectado e hierarquia entre elementos.

Outro ponto forte é a integração com o ecossistema. LangChain e LlamaIndex têm loaders oficiais baseados no Unstructured, então você conecta a extração ao resto do pipeline em poucas linhas. Também existem conectores para fontes como S3, Google Drive, SharePoint e bancos vetoriais.

A empresa mantém ainda uma API hospedada e a Unstructured Platform, versão gerenciada com processamento em escala. Para este post o foco é a biblioteca open source, que já resolve a maioria dos cenários de quem está começando.

Como começar: instalação passo a passo

Passo 1: tenha Python 3.9 ou superior e crie um ambiente virtual. Isso evita conflito com as dependências pesadas de visão computacional que a versão completa instala.

Python -m venv .venv
# Linux/macOS
source .venv/bin/activate
# Windows
.venv\Scripts\activate

Passo 2: instale a biblioteca. A instalação básica cobre formatos de texto puro. Para PDF, DOCX e imagens use os extras entre colchetes, ou instale tudo de uma vez com o extra all-docs.

# instalação mínima
pip install unstructured

# com suporte a PDF, Word e PowerPoint
pip install "unstructured[pdf,docx,pptx]"

# tudo de uma vez (pesado, vários GB)
pip install "unstructured[all-docs]"

Passo 3: instale as dependências de sistema. Para PDF e OCR são necessários o poppler, o tesseract e o libmagic. No Ubuntu é um apt install; no macOS, um brew install; no Windows, a forma mais simples é usar a imagem Docker oficial.

# Ubuntu / Debian
sudo apt install -y poppler-utils tesseract-ocr tesseract-ocr-por libmagic1

# macOS
brew install poppler tesseract libmagic
⚠️
Atenção

A estratégia hi_res baixa modelos de detecção de layout no primeiro uso e exige bastante memória. Em máquinas modestas comece com a estratégia fast e só suba para hi_res nos documentos que realmente precisam.

Exemplo prático

Vamos processar um PDF de manual técnico, quebrar em chunks por seção e deixar tudo pronto para gerar embeddings. É o cenário clássico de quem quer montar um assistente que responde perguntas sobre documentação interna.

from unstructured.partition.auto import partition
from unstructured.chunking.title import chunk_by_title

# 1. extrai os elementos do documento
elementos = partition(
    filename="manual-técnico.pdf",
    strategy="hi_res",
    languages=["por"],
)

print(f"{len(elementos)} elementos extraídos")
for el in elementos[:5]:
    print(type(el).__name__, "->", el.text[:80])

# 2. agrupa em chunks respeitando os títulos
chunks = chunk_by_title(
    elementos,
    max_characters=1200,
    combine_text_under_n_chars=300,
)

# 3. prepara para o banco vetorial
docs = [
    {
        "texto": c.text,
        "página": c.metadata.page_number,
        "arquivo": c.metadata.filename,
    }
    for c in chunks
]
print(f"{len(docs)} chunks prontos para embedding")

Repare em três detalhes. O parâmetro languages melhora o OCR e a detecção em português. O combine_text_under_n_chars junta seções muito curtas para não gerar chunks inúteis. E os metadados de página permitem que sua resposta final cite exatamente de onde veio a informação.

Se o documento tiver tabelas, cada elemento Table traz o HTML da tabela em metadata.text_as_html. Vale enviar esse HTML para o modelo em vez do texto puro: LLMs modernos interpretam tabelas em HTML muito melhor do que colunas achatadas em uma linha.

🚀
Pro tip

Guarde os elementos brutos em disco (JSON) antes de fazer o chunking. Assim, quando quiser testar outra estratégia de chunk, você não precisa reprocessar o PDF com hi_res, que é a etapa mais cara.

Comparação com alternativas

O Docling, da IBM, é o concorrente open source mais direto. Ele tem excelente qualidade em PDFs académicos e tabelas, e exporta Markdown com facilidade. O Unstructured leva vantagem na variedade de formatos (e-mails, planilhas, HTML) e na maturidade das integrações com LangChain e LlamaIndex.

O LlamaParse é o serviço de parsing da LlamaIndex. Funciona muito bem, mas é uma API paga na nuvem: seus documentos saem da sua infraestrutura. O Unstructured open source roda 100% local, o que costuma ser requisito em projetos com dados sensíveis, especialmente com LGPD no radar.

Ferramentas como PyMuPDF, pdfplumber e Apache Tika são ótimas para extrair texto bruto, mas não entendem estrutura semântica nem fazem chunking pensado para RAG. O MarkItDown, da Microsoft, converte tudo para Markdown de forma rápida, mas com menos controle sobre layout e tabelas. Resumindo: precisa só de texto, use algo leve; precisa de estrutura para IA, o Unstructured é a escolha mais completa.

Pontos positivos e limitações

Do lado positivo, a API unificada é o grande ganho: uma função para dezenas de formatos economiza semanas de código. A qualidade da estratégia hi_res em PDFs de layout complexo é bem superior a extratores tradicionais, e o chunking por título gera contexto muito mais coerente.

A principal limitação é o peso. A instalação completa puxa PyTorch, modelos de detecção de layout e várias dependências de sistema. O processamento em hi_res é lento: em CPU comum, um PDF de 100 páginas pode levar vários minutos. Para volumes grandes, é preciso paralelizar ou usar GPU.

Outro ponto é que a documentação evolui rápido e alguns exemplos antigos na internet usam nomes de funções já alterados. Consulte sempre a documentação oficial em docs.unstructured.io. E vale lembrar que a versão hospedada tem recursos extras (modelos melhores, conectores enterprise) que não estão na biblioteca gratuita.

🔴
Cuidado

Nunca rode a estratégia fast em PDFs escaneados: ela lê apenas a camada de texto, que nesses arquivos está vazia, e você acaba com chunks em branco sem nenhum erro aparente. Detecte imagens escaneadas e force ocr_only ou hi_res nesses casos.

Casos de uso reais

Dev montando um RAG corporativo: centenas de PDFs de políticas internas, manuais e atas em uma pasta do SharePoint. O Unstructured extrai, chunka e alimenta o banco vetorial, e o assistente responde citando página e arquivo.

Time jurídico ou de compliance: contratos em DOCX e PDF escaneado, com cláusulas em tabelas. A estratégia hi_res mais OCR em português transforma isso em texto pesquisável com estrutura preservada.

Cientista de dados em pesquisa: milhares de artigos académicos em PDF de duas colunas. A detecção de layout evita o erro clássico de misturar as colunas, e os metadados mantêm figuras e tabelas identificadas.

Startup de atendimento: histórico de e-mails e anexos de clientes. Com suporte nativo a EML e MSG, o pipeline processa mensagem e anexo no mesmo fluxo, sem parser customizado.

Dicas e boas práticas

💡
Dica

Comece com a estratégia fast em todo o acervo para ter um resultado em minutos. Depois identifique quais arquivos ficaram ruins (texto vazio ou embaralhado) e reprocesse só esses com hi_res.

💡
Dica

Sempre informe languages=['por'] ao processar documentos em português. Sem isso o Tesseract assume inglês e a qualidade do OCR cai bastante em acentos e cedilhas.

🚀
Pro tip

Use a imagem Docker oficial (downloads.unstructured.io/unstructured-io/unstructured) em produção. Ela já vem com poppler, tesseract e todos os modelos, eliminando o inferno de dependências de sistema, principalmente no Windows.

⚠️
Atenção

Erro comum de iniciante: chunks grandes demais. Um max_characters acima de 2000 costuma piorar a recuperação no RAG. Entre 800 e 1500 caracteres, com by_title, é um bom ponto de partida.

🚀
Pro tip

Filtre elementos por tipo antes do chunking. Remover Header, Footer e PageBreak elimina ruído como numeração de página e nome da empresa repetido em cada folha, que só polui o embedding.

Vale a pena?

Se você está construindo qualquer coisa com RAG sobre documentos reais de empresa, sim, vale muito. A economia de tempo em relação a escrever parsers por formato é gigantesca, e a qualidade da extração em PDFs complexos é difícil de reproduzir por conta própria.

Não vale a pena se o seu caso é simples: alguns arquivos Markdown ou PDFs de texto limpo. Nesse cenário uma biblioteca leve como PyMuPDF resolve sem instalar gigabytes de dependências. Também pense duas vezes se precisa processar milhões de páginas por dia sem GPU; aí a versão hospedada ou uma arquitetura distribuída entra na conta.

Próximo passo sugerido: pegue um PDF real do seu trabalho, rode o exemplo deste post com strategy fast e depois com hi_res, e compare os elementos extraídos. Em 15 minutos você vai entender exatamente o que a ferramenta entrega e onde ela se encaixa no seu pipeline.