Documentos (docx, pdf, csv, xlsx)
Anexe arquivos a qualquer chamada com files=. Por padrão a jangada extrai o
texto do arquivo localmente em vez de usar vision — é mais barato e funciona
em qualquer modelo, inclusive os sem visão.
pip install "jangada-ai[files]" # pypdf, python-docx, openpyxlfrom jangada_ai import LLM, Document
llm = LLM("openai", "gpt-4o-mini")
# caminhos: tipo detectado pela extensão
llm.complete("Resuma:", files=["relatorio.pdf", "contrato.docx"])
# xlsx: TODAS as abas entram, cada uma rotulada (## Aba: ...)
llm.complete("Maior total?", files=[Document("vendas.xlsx", max_rows=200)])
# bytes em memória (upload/fila) — informe o nome para detectar o tipo
llm.parse("Há duplicadas?", Relatorio, files=[Document(blob, name="x.csv")])
# forçar vision (PDF escaneado / quando o layout importa)
llm.complete("Transcreva:", files=[Document("scan.pdf", mode="vision")])Regra de mode
mode | Comportamento |
|---|---|
"auto" | (padrão) extrai texto de csv/xlsx/docx/pdf-com-texto; imagem → vision |
"text" | força extração de texto (erro se o formato não tiver texto) |
"vision" | força o caminho de imagem |
Por que não usar vision para tudo
- Mais barato: texto custa muito menos que tokens de imagem.
- Funciona em qualquer modelo, inclusive sem visão.
- Preserva tabelas como markdown.
Um PDF sem camada de texto (escaneado) levanta DocumentError sugerindo
mode="vision" — nunca devolve um bloco vazio em silêncio.
Detalhes
files=existe emcomplete/parse/stream(sync e async) e convive comimages=.- A conversão acontece na fronteira do client (
files.py→to_part()): cada arquivo viraTextPartouImagePart, então os adapters nunca veem formato de documento. - Formatos:
.csv,.tsv,.xlsx,.xlsm,.docx,.pdf, além de texto puro (.txt,.md,.json, ...).
Relacionado: Vision, Structured output.
O que mudou na 1.9.0
- PDF escaneado com
mode="vision"funciona de verdade: cada página é renderizada em PNG (atéDocument(..., max_pages=20)) e vai como imagem. Usa opypdfium2(agora no extra[files]) ou opymupdf, se instalado; sem nenhum dos dois, o erro diz o que instalar. A lib nunca manda um PDF como se fosse imagem (isso dava 400 no provider). Para montar as partes você mesmo:jangada_ai.files.to_parts(doc)devolve uma parte por página. - Encoding de CSV: tenta UTF-8 (com e sem BOM), depois cp1252 e latin-1 — CSV
exportado do Excel brasileiro não vira mais
�. - CSV/TSV grandes são lidos em streaming até
max_rows;.tsvusa o extrator próprio. - PDF protegido: tenta abrir com senha vazia; se não der, levanta
DocumentErrorclaro (PDF corrompido também). - xlsx: célula de fórmula sem valor calculado aparece como
[fórmula sem valor calculado: =...]em vez de vazia;|e quebras de linha nas células são escapados na tabela markdown. - Bytes sem nome: o formato é detectado pelo conteúdo (PDF, PNG, JPEG, GIF, WEBP, BMP, docx, xlsx).
from jangada_ai import LLM, Document
llm = LLM("gemini", "gemini-3.5-flash")
comp = llm.complete("Transcreva a nota fiscal.",
files=[Document("nota_escaneada.pdf", mode="vision", max_pages=3)])Exemplo
examples/files_example.py — script executável.