Jangada AIJangada AI

Vision (imagens)

Imagens entram como ImagePart (bytes + mime) e são traduzidas para o formato nativo de cada SDK. Use sempre um modelo com visão.

from jangada_ai import LLM, Image

llm = LLM("openai", "gpt-4o-mini")

# por caminho
llm.complete("O que aparece aqui?", images=["foto.jpg"])

# por bytes ou base64
img = Image.from_bytes(upload_bytes, "image/png")   # ou Image.from_base64
recibo = llm.parse("Extraia o total.", Recibo, images=[img]).parsed

Tradução por provider

ProviderFormato nativo
OpenAI/Groqimage_url com data URI
Anthropicbloco image / source base64
Geminitypes.Part.from_bytes

Apenas bytes circulam (use Image.from_path/bytes/base64). Combine com Structured output passando images= no parse().

Rotular cada imagem (atalho)

Para rotular cada imagem sem montar mensagens à mão, passe tuplas (rótulo, imagem) em images= — a lib intercala um TextPart com o rótulo antes de cada imagem, na ordem dada:

llm.parse(
    "Compare os documentos.", Comparacao,
    images=[("frente", Image.from_path("a_frente.jpg")),
            ("verso",  Image.from_path("a_verso.jpg"))],
)

Itens sem rótulo (um ImagePart/caminho normal) continuam funcionando na mesma lista — você mistura rotuladas e simples à vontade.

Mensagens e multimodal intercalado

O atalho images=[...] põe o texto do prompt primeiro e as imagens depois. Para controle total da ordem (alternar vários blocos de texto e imagem, multi-turno), monte as mensagens à mão com Message, TextPart e ImagePart (todos importáveis de jangada_ai) e passe via history=.

from jangada_ai import LLM, Message, TextPart, Image

llm = LLM("openai", "gpt-4o-mini")

# texto e imagens intercalados, cada uma com seu rótulo
msg = Message("user", [
    TextPart("Documento A (frente):"),
    Image.from_path("a_frente.jpg"),      # Image.* devolve um ImagePart
    TextPart("Documento A (verso):"),
    Image.from_path("a_verso.jpg"),
    TextPart("As duas imagens são do mesmo documento? Compare."),
])

resp = llm.complete(None, history=[msg])   # prompt=None: o conteúdo vem das mensagens
print(resp.text)

Message(role, content) aceita role em "system" | "user" | "assistant" | "tool" e content como str ou uma lista de partes (TextPart / ImagePart). Para multi-turno, basta acumular as mensagens anteriores em history:

resp1 = llm.complete("Qual a capital do Brasil?")
resp2 = llm.complete(
    "E a população dela?",
    history=[
        Message("user", "Qual a capital do Brasil?"),
        Message("assistant", resp1.text),
    ],
)

ImagePart carrega só bytes (data + mime_type), então funciona igual em todos os providers; use os factories Image.from_path/bytes/base64 em vez de montar o ImagePart na mão.

Vision x Documentos

Para docx/pdf/csv/xlsx, prefira Documentos: por padrão a jangada extrai o texto localmente (mais barato, funciona em modelo sem visão) e só usa vision quando você força mode="vision" ou quando o PDF é escaneado.

Exemplo

examples/vision_example.py — script executável.

On this page