GLM 5.2 Vision API: Image Understanding, Analysis, and Multimodal Use Cases

GLM 5.2 Vision API: Image Understanding, Analysis, and Multimodal Use Cases

A complete guide to GLM 5.2's vision capabilities: how to send images via the API, what tasks it handles well, and real Python code examples for multimodal apps.

GLM 5.2 (model ID: glm-4-plus) is not just a text model. Released by Zhipu AI in May 2025, it ships with full multimodal support — meaning it can read, describe, and reason about images alongside text in a single API call. For developers building document processors, visual Q&A tools, or product cataloging pipelines, this opens up a cost-effective alternative to GPT-4o Vision at roughly one-third of the price.

This tutorial covers the exact API format for image inputs, which image types are accepted, what visual tasks GLM 5.2 handles reliably, and a set of ready-to-run Python examples for real-world multimodal applications.

If you are new to the model's text API, start with the GLM 5.2 API integration guide first — the vision API builds on the same authentication and base_url setup.

What GLM 5.2 Vision Supports

Before writing any code, it helps to know the concrete boundaries:

  • Image input formats: JPEG, PNG, WEBP, and GIF (first frame only for animated GIFs)
  • Image delivery: base64-encoded data URI or a publicly reachable HTTPS URL
  • Max image size: approximately 10 MB per image
  • Max images per request: up to 10 images in a single messages array
  • Context window: 1,048,576 tokens (1 M), which means you can pair rich text prompts with multiple images without hitting limits
  • Supported tasks: document understanding, chart reading, screenshot analysis, visual Q&A, OCR-adjacent tasks, product image description

The API is fully OpenAI-compatible. If you have existing GPT-4o Vision code, the migration is a base_url and model name swap — no new SDK required.

The Pain Point: Getting the Exact API Format Right

Most developers confirm that GLM 5.2 supports vision from a quick documentation scan, then hit a wall because the exact message structure is not always shown clearly with copy-paste Python. The key detail: image inputs go inside the content array as objects with type: "image_url" — not as a top-level parameter, and not as a plain URL string.

Both the image and the text prompt live inside the same content array. The order within the array does not affect output quality, but placing the image before the question mirrors how humans present visual context and is a common convention. Here is the minimal correct structure for a vision request:

{
    "role": "user",
    "content": [
        {
            "type": "image_url",
            "image_url": {
                "url": "https://example.com/chart.png"
            }
        },
        {
            "type": "text",
            "text": "Describe what this chart shows."
        }
    ]
}

Once you see this, the rest follows naturally. Let us look at full working examples.

Sending an Image via URL

The simplest approach is passing a public image URL. No encoding step is required — just make sure the URL is accessible from Zhipu's servers (not behind authentication, a VPN, or localhost).

import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["ZHIPU_API_KEY"],
    base_url="https://open.bigmodel.cn/api/paas/v4/",
)

response = client.chat.completions.create(
    model="glm-4-plus",
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "image_url",
                    "image_url": {
                        "url": "https://upload.wikimedia.org/wikipedia/commons/thumb/4/47/PNG_transparency_demonstration_1.png/280px-PNG_transparency_demonstration_1.png"
                    },
                },
                {
                    "type": "text",
                    "text": "Describe what you see in this image in detail.",
                },
            ],
        }
    ],
    max_tokens=512,
)

print(response.choices[0].message.content)

You can get your API key from the Zhipu AI open platform. If you want to verify the model's vision output interactively before committing to an integration, glm5.app lets you upload images and run prompts without writing any code. The base_url must include the trailing slash as shown — omitting it causes a path routing error.

Sending a Local Image via Base64

For images that are not publicly hosted — screenshots from a CI pipeline, files on disk, frames extracted from video — encode the file as base64 and embed it as a data URI:

import os
import base64
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["ZHIPU_API_KEY"],
    base_url="https://open.bigmodel.cn/api/paas/v4/",
)

def encode_image(path: str) -> str:
    with open(path, "rb") as f:
        return base64.b64encode(f.read()).decode("utf-8")

image_path = "screenshot.png"
b64 = encode_image(image_path)

response = client.chat.completions.create(
    model="glm-4-plus",
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "image_url",
                    "image_url": {
                        "url": f"data:image/png;base64,{b64}"
                    },
                },
                {
                    "type": "text",
                    "text": "What does this screenshot show? Identify any error messages.",
                },
            ],
        }
    ],
    max_tokens=1024,
)

print(response.choices[0].message.content)

The data URI prefix (data:image/png;base64,) must match the actual file type. Change image/png to image/jpeg or image/webp to match your file. The model uses this hint to decode the payload correctly. Keep each image under 10 MB — large images are rejected rather than silently truncated.

Multi-Image Requests

GLM 5.2 accepts up to 10 images per request. The content array simply lists them in sequence. This is useful for comparison tasks, before-and-after analysis, document pages, or a sequence of UI screenshots.

import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["ZHIPU_API_KEY"],
    base_url="https://open.bigmodel.cn/api/paas/v4/",
)

image_urls = [
    "https://example.com/chart-q1.png",
    "https://example.com/chart-q2.png",
    "https://example.com/chart-q3.png",
]

content = []
for url in image_urls:
    content.append({
        "type": "image_url",
        "image_url": {"url": url},
    })

content.append({
    "type": "text",
    "text": (
        "These are three quarterly revenue charts. "
        "Identify which quarter shows the highest year-over-year growth "
        "and summarize the trend across all three."
    ),
})

response = client.chat.completions.create(
    model="glm-4-plus",
    messages=[{"role": "user", "content": content}],
    max_tokens=1024,
)

print(response.choices[0].message.content)

Because the context window is 1 million tokens, you have significant headroom for rich system prompts alongside multiple images — a meaningful advantage when building document-processing pipelines that need detailed extraction instructions or few-shot examples.

Practical Use Case: Invoice Extraction with JSON Mode

This example combines vision and JSON mode to extract structured fields from an invoice image. It is the kind of pattern used in accounts-payable automation.

import os
import json
import base64
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["ZHIPU_API_KEY"],
    base_url="https://open.bigmodel.cn/api/paas/v4/",
)

def extract_invoice(image_path: str) -> dict:
    with open(image_path, "rb") as f:
        b64 = base64.b64encode(f.read()).decode("utf-8")

    response = client.chat.completions.create(
        model="glm-4-plus",
        response_format={"type": "json_object"},
        messages=[
            {
                "role": "system",
                "content": (
                    "You are a document extraction assistant. "
                    "Return only valid JSON with these fields: "
                    "invoice_number, date, vendor_name, "
                    "total_amount, currency, line_items (array of "
                    "{description, quantity, unit_price, total})."
                ),
            },
            {
                "role": "user",
                "content": [
                    {
                        "type": "image_url",
                        "image_url": {"url": f"data:image/jpeg;base64,{b64}"},
                    },
                    {
                        "type": "text",
                        "text": "Extract all fields from this invoice.",
                    },
                ],
            },
        ],
        max_tokens=2048,
    )

    return json.loads(response.choices[0].message.content)

result = extract_invoice("invoice.jpg")
print(json.dumps(result, indent=2))

The response_format={"type": "json_object"} parameter guarantees parseable output every time. At $1.40 per million input tokens, running this pipeline against tens of thousands of invoices per month costs a fraction of what the same workflow costs on GPT-4o Vision.

Streaming Vision Responses

For user-facing applications where progressive display improves perceived performance, streaming works with vision inputs exactly as it does with text:

import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["ZHIPU_API_KEY"],
    base_url="https://open.bigmodel.cn/api/paas/v4/",
)

stream = client.chat.completions.create(
    model="glm-4-plus",
    stream=True,
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "image_url",
                    "image_url": {"url": "https://example.com/architecture-diagram.png"},
                },
                {
                    "type": "text",
                    "text": "Walk me through this architecture diagram component by component.",
                },
            ],
        }
    ],
    max_tokens=1024,
)

for chunk in stream:
    delta = chunk.choices[0].delta
    if delta.content:
        print(delta.content, end="", flush=True)
print()

At 158 tokens per second (per the Artificial Analysis benchmark), GLM 5.2 delivers fast time-to-first-token — suitable for real-time applications such as customer support tooling or live UI debugging workflows.

What GLM 5.2 Vision Handles Well

Based on the model's benchmark profile (89% on GPQA Diamond, 62.1% on SWE-bench Pro) and its 753B total / 40B active MoE architecture, vision tasks benefit from a genuinely capable reasoning engine rather than a lightweight captioning model.

Document and form understanding. Scanned PDFs converted to images, receipts, invoices, and filled-in forms are processed with high accuracy. Field labels, handwritten entries, and table structures are all handled well.

Chart and graph reading. Bar charts, line graphs, pie charts, and scatter plots with axis labels and numeric values are correctly described. The model can identify trends, compare series, and report approximate values — useful for automating report analysis.

Screenshot analysis. UI screenshots from web or desktop applications are well-understood. The model identifies menu items, form fields, error dialogs, and layout structure — practical for automated QA pipelines and accessibility description generation.

Product image description. E-commerce product photos are described in detail including color, material, and inferred dimensions. Combined with batch mode (available via Zhipu's platform), this scales to large catalog operations economically.

Visual Q&A and general scene understanding. Object identification, spatial relationships, text in images (OCR-adjacent), and general scene description all perform strongly.

Where the model may lag: highly complex visual reasoning — fine-grained counting in cluttered scenes, cross-image inferences requiring multi-hop logic, or interpreting ambiguous or low-quality images — may fall behind GPT-4o's best results. For most production document and screenshot workloads, the difference is not material, but benchmark on your own data for high-stakes cases.

Cost and Context Advantage vs. GPT-4o Vision

For teams running vision workloads at scale, pricing is a concrete factor. GLM 5.2 is priced at $1.40 per million input tokens and $4.40 per million output tokens — roughly one-third the cost of GPT-4o Vision. The 1 M context window is approximately eight times larger than GPT-4o's 128K, removing the chunking complexity from long-document workflows.

FeatureGLM 5.2 (glm-4-plus)GPT-4o (as of writing)
Input price$1.40 / 1M tokens~$5.00 / 1M tokens
Output price$4.40 / 1M tokens~$15.00 / 1M tokens
Context window1,048,576 tokens128,000 tokens
Speed158 tokens/sec~90–120 tokens/sec
Image inputURL or base64URL or base64
Max images per requestUp to 10Up to 10
GPQA Diamond89%~88%
LicenseMIT open weightsProprietary

Image tokens count toward input token usage. A typical high-resolution document page at JPEG compression consumes a few hundred to a few thousand input tokens depending on resolution and content density. At GLM 5.2's pricing, an invoice extraction pipeline processing 50,000 documents per month costs roughly 3x less in API fees than an equivalent GPT-4o workflow.

The MIT open-weights license is worth noting for teams with data-privacy requirements. The weights are available on HuggingFace for self-hosting, which means image inputs can stay fully on-premise if needed.

Handling Edge Cases in Production

A few patterns that matter once you move beyond prototypes:

Pre-validate image size. Images over the 10 MB limit are rejected by the API. Add a client-side check and compress or resize before calling the endpoint. For document pages, 1920×1080 at standard JPEG quality is well within the limit.

Use base64 for private images. URLs must be publicly accessible from Zhipu's infrastructure. Anything behind authentication, a VPN, or an IP allowlist must be sent as base64 instead.

GIF first-frame limitation. Only the first frame of an animated GIF is processed. If you need to analyze video frames, extract them individually and pass them as separate PNG images.

System prompts anchor output format. For extraction tasks, a detailed system prompt with explicit JSON schema expectations dramatically improves output consistency. Combine with response_format={"type": "json_object"} for guaranteed parseable responses.

Log usage.prompt_tokens. Each image contributes to your input token count. Logging usage per request lets you track actual costs and catch unexpectedly large images slipping through the size check.

Next Steps

GLM 5.2's vision API closely follows the OpenAI messages format, keeping integration friction low for teams already working with chat completions. The key points: images go in the content array as image_url objects, base64 works for local or private files, you can batch up to 10 images per call, and the 1 M context window gives you room to include rich instructions and few-shot examples alongside your images.

To test the model on your own images before building the integration, glm5.app provides an interactive web interface where you can upload images and run prompts directly — a fast way to validate whether GLM 5.2 handles your specific document type or visual task before writing any code.

Sources

Begin vandaag met GLM 5

Probeer GLM 5 gratis — redenering, codering, agents en afbeeldingsgeneratie in één platform.