Extraia texto PDF em seu navegador com LiteParse para a web

Extraia texto PDF em seu navegador com LiteParse para a web


Extraia texto PDF em seu navegador com LiteParse para a web

23 de abril de 2026

LlamaIndex tem um excelente projeto de código aberto chamado LiteParse, que fornece uma ferramenta CLI Node.js para extrair texto de PDFs. Consegui uma versão do LiteParse funcionando inteiramente no navegador, usando a maioria das mesmas bibliotecas que o LiteParse usa para rodar em Node.js.

Análise de texto espacial

Curiosamente, o LiteParse não usa modelos de IA para fazer o que faz: é a boa e antiga análise de PDF, recorrendo ao Tesseract OCR (ou outros mecanismos de OCR conectáveis) para PDFs que contêm imagens de texto em vez do próprio texto.

O difícil problema que o LiteParse resolve é extrair texto em uma ordem sensata, apesar dos caprichos irritantes dos layouts de PDF. Eles descrevem isso como “análise espacial de texto” – eles usam algumas heurísticas muito inteligentes para detectar coisas como layouts e grupos de múltiplas colunas e retornar o texto em um fluxo linear sensato.

A documentação do LiteParse descreve um padrão para implementar citações visuais com caixas delimitadoras. Eu realmente gosto dessa ideia: ser capaz de responder perguntas em um PDF e acompanhar essas respostas com imagens cortadas e destacadas parece uma ótima maneira de aumentar a credibilidade das respostas de perguntas e respostas no estilo RAG.

LiteParse é fornecido como uma ferramenta CLI pura, projetada para ser usada por agentes. Você executa assim:

npm i -g @llamaindex/liteparse
lit parse document.pdf

Explorei seus recursos com Claude e rapidamente determinei que não havia nenhum motivo real para ele continuar sendo um aplicativo CLI: ele foi construído sobre PDF.js e Tesseract.js, duas bibliotecas que usei para algo semelhante em um navegador no passado.

A única razão pela qual o LiteParse não tinha uma versão puramente baseada em navegador é que ninguém havia construído uma ainda…

Apresentando o LiteParse para a web

Visite https://simonw.github.io/liteparse/ para testar o LiteParse em qualquer arquivo PDF, rodando inteiramente no seu navegador. Aqui está o que parece:

Captura de tela da página de demonstração do navegador LiteParse. Leituras de cabeçalho "LiteParse" com legenda "Demonstração do LiteParse no navegador - analise PDFs em seu navegador. Nada sai da sua máquina." Uma zona de lançamento com borda tracejada diz "Solte um PDF aqui ou clique para escolher / Seu arquivo permanece no seu navegador." com um comprimido de arquivo rotulado "19720005243.pdf". Abaixo estão verificados "Execute o OCR" caixa de seleção, um desmarcado "Renderizar capturas de tela da página" caixa de seleção e um azul "Analisar" botão. Texto de status: "Analisou 86 páginas." Seguem dois painéis lado a lado. Painel esquerdo intitulado "Texto" com um botão Copiar mostra o texto extraído monoespaçado começando "A Apollo 5 era um sistema não tripulado, com ambos os sistemas de propulsão em estágios de subida e descida". Painel direito intitulado "JSON"também com um botão de cópia, contém JSON mostrando as dimensões, a posição e a fonte detectada de cada trecho de texto.

A ferramenta pode funcionar com ou sem execução de OCR e, opcionalmente, exibir imagens para cada página do PDF mais abaixo na página.

Construindo com Claude Code e Opus 4.7

O processo de construção disso começou no aplicativo Claude normal no meu iPhone. Eu queria experimentar o LiteParse sozinho, então comecei enviando um PDF aleatório que tinha no meu telefone junto com este prompt:

Clone https://github.com/run-llama/liteparse and try it against this file

Atualmente, o bate-papo normal do Claude pode ser clonado diretamente do GitHub e, embora por padrão não possa acessar a maior parte da Internet a partir de seu contêiner, ele também pode instalar pacotes do PyPI e do npm.

Costumo usar isso para experimentar novos softwares de código aberto no meu telefone – é uma maneira rápida de exercitar algo sem ter que sentar com meu laptop.

Você pode acompanhar minha conversa completa nesta transcrição compartilhada de Claude. Fiz algumas perguntas de acompanhamento sobre como funcionava e depois perguntei:

Does this library run in a browser? Could it?

Isso me deu uma resposta completa o suficiente para que eu estivesse convencido de que valia a pena tentar fazer com que isso funcionasse de verdade. Abri meu laptop e mudei para Claude Code.

Bifurquei o repositório original no GitHub, clonei uma cópia local, iniciei um novo web branch e colei a última resposta de Claude em um novo arquivo chamado notes.md. Então eu disse a Claude Code:

Get this working as a web app. index.html, when loaded, should render an app that lets users open a PDF in their browser and select OCR or non-OCR mode and have this run. Read notes.md for initial research on this problem, then write out plan.md with your detailed implementation plan

Sempre gosto de começar com um plano para esse tipo de projeto. Às vezes eu uso o “modo de planejamento” de Claude, mas neste caso eu sabia que iria querer o plano como um artefato no repositório, então disse para ele escrever plan.md diretamente.

Isso também significa que posso repetir o plano com Claude. Percebi que Claude decidiu gerar capturas de tela de imagens no PDF e sugeriu que adiássemos uma “troca de codificação de tela” para a v2. Eu consertei isso solicitando:

Update the plan to say we WILL do the canvas-encode swap so the screenshots thing works

Depois de algumas breves instruções de acompanhamento, aqui está o plan.md que achei forte o suficiente para ser implementado.

Eu perguntei:

build it.

E então, principalmente, deixou Claude Code por conta própria, mexeu em alguns outros projetos, atualizou-se no Duolingo e ocasionalmente fez check-in para ver como estava.

Adicionei alguns prompts à fila enquanto trabalhava. Eles ainda não aparecem na minha transcrição exportada, mas acontece que estou executando rg queue-operation --no-filename | grep enqueue | jq -r '.content' no relevante ~/.claude/projects/ pasta os extrai.

Aqui estão as principais instruções de acompanhamento com algumas notas:

  • When you implement this use playwright and red/green TDD, plan that too—Escrevi mais sobre TDD vermelho/verde aqui.
  • let's use PDF.js's own renderer (estava brincando com o pdfium)
  • The final UI should include both the text and the pretty-printed JSON output, both of those in textareas and both with copy-to-clipboard buttons - it should also be mobile friendly—Tive uma nova ideia de como a IU deveria funcionar
  • small commits along the way-Veja abaixo
  • Make sure the index.html page includes a link back to https://github.com/run-llama/liteparse near the top of the page—é importante creditar suas dependências em um projeto como este!
  • View on GitHub → is bad copy because that's not the repo with this web app in, it's the web app for the underlying LiteParse library
  • Run OCR should be unchecked by default
  • When I try to parse a PDF in my browser I see 'Parse failed: undefined is not a function (near '...value of readableStream...')—estava testando com o Playwright no Chrome, descobri que havia um bug no Safari
  • ... oh that is in safari but it works in chrome
  • When "Copy" is clicked the text should change to "Copied!" for 1.5s
  • (Image #1) Style the file input so that long filenames don't break things on Firefox like this - in fact add one of those drag-drop zone UIs which you can also click to select a file– colocar capturas de tela de pequenas falhas na interface do usuário funciona surpreendentemente bem
  • Tweak the drop zone such that the text is vertically centered, right now it is a bit closer to the top
  • it breaks in Safari on macOS, works in both Chrome and Firefox. On Safari I see "Parse failed: undefined is not a function (near '...value of readableStream...')" after I click the Parse button, when OCR is not checked—ainda não estava funcionando no Safari…
  • works in safari now -mas isso foi corrigido rapidamente quando eu apontei isso e o Playwright começou a trabalhar com aquele navegador

Comecei a pedir habitualmente “pequenos commits ao longo do caminho” porque isso torna o código mais fácil de entender ou revisar mais tarde, e tenho um palpite não comprovado de que isso também ajuda o agente a trabalhar de forma mais eficaz – é mais um incentivo para planejar e enfrentar um problema de cada vez.

Enquanto funcionava, decidi que seria bom poder interagir com uma versão em andamento. Solicitei a uma sessão separada do Claude Code no mesmo diretório dicas sobre como executá-lo, e ela me disse para usar npx vite. A execução disso iniciou um servidor de desenvolvimento com recarregamento ao vivo, o que significa que pude ver instantaneamente o efeito de cada alteração feita no disco – e solicitar mais solicitações de ajustes e correções.

No final, decidi que seria bom o suficiente para publicar. Iniciei uma nova instância do Claude Code e disse:

Look at the web/ folder - set up GitHub actions for this repo such that any push runs the tests, and if the tests pass it then does a GitHub Pages deploy of the built vite app such that the web/index.html page is the index.html page for the thing that is deployed and it works on GitHub Pages

Depois de mais um pouco de iteração, aqui está o fluxo de trabalho do GitHub Actions que cria o aplicativo usando Vite e implanta o resultado em https://simonw.github.io/liteparse/.

Adoro o GitHub Pages para esse tipo de coisa porque ele pode ser configurado rapidamente (por Claude, neste caso) para transformar qualquer repositório em um aplicativo web implantado, com custo zero e com qualquer etapa de construção necessária. Funciona até mesmo contra repositórios privados, se você não se importa que sua única segurança seja um URL secreto.

Com este tipo de projeto há sempre um grande risco de que o modelo possa “trapacear” – marcar recursos-chave como “TODO” e falsificá-los, ou usar atalhos que ignorem os requisitos iniciais.

A maneira responsável de evitar isso é revisar todo o código… mas isso não era esse tipo de projeto, então, em vez disso, iniciei o OpenAI Codex com GPT-5.5 (eu tinha acesso de visualização) e disse:

Describe the difference between how the node.js CLI tool runs and how the web/ version runs

A resposta que recebi foi suficiente para me dar a confiança de que Claude não havia tomado nenhum atalho que pudesse ameaçar o projeto.

… e foi isso. O tempo total no Claude Code para a etapa de “construir” foi de 59 minutos. Usei minha ferramenta claude-code-transcripts para exportar uma versão legível da transcrição completa que você pode visualizar aqui, embora sem esses prompts adicionais na fila (aqui está meu problema para corrigir isso).

Isso ainda é vibração de codificação?

Sou um defensor pedante quando se trata da definição original de codificação de vibração – a codificação de vibração faz não significa que sempre que você usa IA para ajudá-lo a escrever código, é quando você usa IA sem revisar ou se preocupar com o código que está escrito.

Pela minha própria definição, este projeto LiteParse para a web é a codificação mais pura possível! Eu não olhei para um linha única do HTML e TypeScript escritos para este projeto – na verdade, enquanto escrevia esta frase, tive que verificar se ela usava JavaScript ou TypeScript.

No entanto, de alguma forma, este não parece tão codificado por vibração para mim como muitos dos meus outros projetos codificados por vibração:

  • Como um aplicativo da web estático no navegador hospedado nas páginas do GitHub, o raio de explosão para quaisquer bugs é quase inexistente: ele funciona para o seu PDF ou não.
  • Nenhum dado privado é transferido para lugar nenhum – todo o processamento acontece no seu navegador – portanto, uma auditoria de segurança é desnecessária. Dei uma olhada no painel de rede uma vez enquanto ele estava em execução e nenhuma solicitação adicional foi feita quando um PDF está sendo analisado.
  • Ainda havia muita experiência e conhecimento de engenharia necessários para usar os modelos dessa maneira. Identificar que portar o LiteParse para rodar diretamente em um navegador foi fundamental para o restante do projeto.

Mais importante ainda, estou feliz em atribuir minha reputação a este projeto e recomendar que outras pessoas o experimentem. Ao contrário da maioria das minhas ferramentas codificadas por vibração, não estou convencido de que gastar um tempo adicional significativo de engenharia nisso teria resultado em um lançamento inicial significativamente melhor. Está tudo bem como está!

Não abri um PR no repositório Origin porque não discuti isso com a equipe LiteParse. Abri um problema e se eles quiserem minha implementação codificada em vibração como ponto de partida para algo mais oficial, eles podem aceitá-la.



Source link

Postagens Similares

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *