Comment utiliser l'API GLM-5.3-Flash avec des images en entrée

Appelez l'API GLM-5.3-Flash avec le SDK OpenAI : authentification, la charge utile image_url pour l'entrée d'image native, l'effort de raisonnement, le streaming et l'appel d'outils.

Ashley Innocent

Ashley Innocent

27 August 2026

Comment utiliser l'API GLM-5.3-Flash avec des images en entrée

Apidog pour les entreprises

Déploiement sur site

SSO & RBAC

Conforme SOC 2

Découvrir Apidog Enterprise

GLM-5.3-Flash est compatible avec OpenAI, ce qui signifie que le moyen le plus rapide de faire un appel fonctionnel est de pointer un client que vous avez déjà vers une URL de base différente et de changer une seule chaîne de caractères. La nouveauté réside dans l'entrée d'images : c'est le premier modèle GLM-5 qui prend des images dans la même requête que votre texte, et la forme de la charge utile pose problème à certains.

Ce guide couvre l'obtention d'une clé, la réalisation d'un appel texte, l'envoi d'images, le contrôle de l'effort de raisonnement, le streaming et l'appel d'outils. Chaque exemple utilise l'identifiant de modèle glm-5.3-flash.

Si vous souhaitez connaître les bases de ce modèle avant de le configurer, commencez par notre explication de GLM-5.3-Flash. Si vous utilisez déjà son grand frère, le guide API de GLM-5.3 couvre ce modèle, et les différences ci-dessous sont réelles : un identifiant de modèle différent, une grille tarifaire différente, et un chemin d'accès aux images que GLM-5.3 n'a pas nativement.

Obtenir une clé API

Créez un compte sur z.ai, ouvrez la section des clés API du tableau de bord et générez une clé. Placez-la dans votre environnement plutôt que dans votre code source :

export ZAI_API_KEY="votre-clé-ici"

L'URL de base pour l'API standard est :

https://api.z.ai/api/paas/v4/

Il existe une URL de base distincte utilisée par les points de terminaison du plan de codage, ce qui est important si vous configurez Claude Code ou Cline plutôt que d'appeler directement l'API. Cette configuration est couverte dans notre guide Claude Code et Cline.

Votre premier appel

Comme le point de terminaison est compatible avec OpenAI, le SDK officiel OpenAI fonctionne sans modification :

from openai import OpenAI
import os

client = OpenAI(
    api_key=os.environ["ZAI_API_KEY"],
    base_url="https://api.z.ai/api/paas/v4/",
)

response = client.chat.completions.create(
    model="glm-5.3-flash",
    messages=[
        {"role": "user", "content": "Explain what a KV cache is in two sentences."}
    ],
)

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

La même chose en curl :

curl https://api.z.ai/api/paas/v4/chat/completions \
  -H "Authorization: Bearer $ZAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "glm-5.3-flash",
    "messages": [
      {"role": "user", "content": "Explain what a KV cache is in two sentences."}
    ]
  }'

Et en Node :

import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.ZAI_API_KEY,
  baseURL: "https://api.z.ai/api/paas/v4/",
});

const response = await client.chat.completions.create({
  model: "glm-5.3-flash",
  messages: [
    { role: "user", content: "Explain what a KV cache is in two sentences." },
  ],
});

console.log(response.choices[0].message.content);

Rien ici n'est spécifique à GLM, sauf l'URL de base et la chaîne du modèle. C'est le but d'une surface compatible OpenAI, et c'est pourquoi changer de modèle est suffisamment peu coûteux pour justifier de faire des benchmarks par rapport à votre propre charge de travail.

Envoi d'images

Cette section n'existe pas pour GLM-5.3. L'entrée d'images fonctionne via des blocs de contenu : au lieu que content soit une chaîne simple, il devient un tableau de blocs typés.

response = client.chat.completions.create(
    model="glm-5.3-flash",
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "text",
                    "text": "This screenshot shows a rendering bug. What is wrong with the layout?",
                },
                {
                    "type": "image_url",
                    "image_url": {
                        "url": "https://example.com/screenshots/broken-layout.png"
                    },
                },
            ],
        }
    ],
)

Trois règles régissent cette charge utile :

Le champ URL accepte une URL publique ou une URL de données base64. Si votre image est locale ou privée, encodez-la :

import base64

with open("broken-layout.png", "rb") as f:
    encoded = base64.b64encode(f.read()).decode("utf-8")

image_block = {
    "type": "image_url",
    "image_url": {"url": f"data:image/png;base64,{encoded}"},
}

Plusieurs images signifient plusieurs blocs. Il n'y a pas de raccourci de tableau d'URLs. Pour comparer un design à son implémentation, envoyez deux blocs image_url dans le même tableau de contenu :

content = [
    {"type": "text", "text": "Does the second image match the design in the first?"},
    {"type": "image_url", "image_url": {"url": design_data_url}},
    {"type": "image_url", "image_url": {"url": built_data_url}},
]

L'ordre a un sens. Le modèle lit le tableau de contenu séquentiellement, donc placez le texte qui encadre la tâche avant les images auxquelles il fait référence. « Comparez ces deux » suivi de deux images se lit mieux que deux images suivies d'une question.

La documentation de Z.ai mentionne également l'entrée vidéo et fichier utilisant le même mécanisme de bloc de contenu. La vidéo est plus récente et beaucoup moins utilisée en pratique que l'entrée d'images, alors validez-la avec vos propres médias avant de construire une fonctionnalité basée dessus.

Pour un traitement plus approfondi de l'aspect vision, y compris les workflows de capture d'écran vers le code et le placement d'images à côté d'un long document dans la même fenêtre de 1M de jetons, consultez notre guide de vision GLM-5.3-Flash.

Contrôler l'effort de raisonnement

GLM-5.3-Flash expose trois modes de pensée via reasoning_effort :

response = client.chat.completions.create(
    model="glm-5.3-flash",
    messages=[{"role": "user", "content": "Refactor this function for clarity."}],
    extra_body={"reasoning_effort": "low"},
)

Les valeurs acceptées sont low, high et max. La valeur par défaut est max, ce qu'il est bon de savoir car c'est la plus coûteuse. Si vous effectuez des classifications ou extractions à grand volume où la réponse n'a pas besoin de délibération, définir explicitement low réduira considérablement votre nombre de jetons de sortie.

C'est un changement par rapport à GLM-5.2, qui n'exposait que High et Max. Le niveau low est nouveau, et pour les travaux par lots sensibles aux coûts, c'est probablement le paramètre le plus utile du modèle.

Notez que reasoning_effort va dans extra_body lorsque vous utilisez le SDK Python d'OpenAI, car il ne fait pas partie du schéma OpenAI standard. En curl brut, c'est juste un champ de premier niveau.

Paramètres d'échantillonnage recommandés

Z.ai publie des valeurs par défaut différentes selon ce que vous faites :

Cas d'utilisation temperature top_p
Général 1.0 0.95
Codage 0.95 1.0

Ces valeurs sont suffisamment proches pour que la différence soit marginale pour la plupart des applications, mais si vous obtenez une sortie de code incohérente, le profil de codage est celui à essayer.

Streaming

Les sémantiques de streaming standard d'OpenAI s'appliquent :

stream = client.chat.completions.create(
    model="glm-5.3-flash",
    messages=[{"role": "user", "content": "Write a bash script that rotates logs."}],
    stream=True,
)

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

Définissez les attentes ici. GLM-5.3-Flash génère à environ 49 jetons par seconde selon Artificial Analysis, ce qui est plus lent que son grand frère GLM-5.3 à environ 86. Le temps de premier jeton est bon à 1,52 seconde, donc la réponse commence rapidement puis arrive de manière constante plutôt que rapide. Si vous diffusez vers une interface utilisateur, ce profil est acceptable. Si vous générez de longs documents dans une tâche par lots, prévoyez-le.

Appel d'outils

Les outils utilisent le schéma OpenAI standard :

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_deployment_status",
            "description": "Returns the current status of a named deployment.",
            "parameters": {
                "type": "object",
                "properties": {
                    "service": {
                        "type": "string",
                        "description": "The service name, for example 'checkout-api'.",
                    }
                },
                "required": ["service"],
            },
        },
    }
]

response = client.chat.completions.create(
    model="glm-5.3-flash",
    messages=[{"role": "user", "content": "Is checkout-api healthy?"}],
    tools=tools,
)

call = response.choices[0].message.tool_calls[0]
print(call.function.name, call.function.arguments)

Les benchmarks agentiques que Z.ai a publiés au lancement s'appuient fortement sur l'utilisation d'outils, avec AutomationBench à 48,8 contre 26,2 pour GLM-5.2. Ce sont des chiffres de fournisseur, mais la direction est cohérente avec le modèle étant réglé pour les boucles d'appel d'outils plutôt que pour le chat en un seul tour.

Si vous générez des définitions d'outils à partir d'une API que vous possédez déjà, notre article sur la transformation d'une spécification OpenAPI en outils d'agent explique comment le faire sans écrire manuellement des schémas.

Gestion des erreurs à prendre en compte

Trois modes de défaillance représentent la plupart des problèmes de production sur ce point de terminaison.

Limites de débit. Réessayez avec un backoff exponentiel et une gigue. Un intervalle de réessai fixe sur de nombreux travailleurs produit des réessais synchronisés, ce qui est la manière classique de transformer une brève limite en une limite soutenue.

import time, random
from openai import RateLimitError

def call_with_retry(**kwargs):
    for attempt in range(5):
        try:
            return client.chat.completions.create(**kwargs)
        except RateLimitError:
            if attempt == 4:
                raise
            time.sleep((2 ** attempt) + random.random())

Débordement de contexte. Une fenêtre de 1M de jetons est suffisamment grande pour que les gens arrêtent de compter, puis un long document plus quelques images haute résolution la dépasse. Les images consomment du contexte, et l'erreur arrive au moment de la requête plutôt qu'au moment de l'assemblage du prompt. Suivez votre budget de jetons à l'entrée.

Sortie tronquée. Si une réponse s'arrête au milieu d'une phrase, vérifiez finish_reason sur le choix. Une valeur de length signifie que vous avez atteint la limite de sortie, pas que le modèle a abandonné. Étant donné que le chiffre de sortie maximal est lui-même contesté entre les sources, cela vaut la peine de le vérifier explicitement plutôt que de l'assumer.

Lecture de l'utilisation des jetons

Chaque réponse contient un objet usage, et c'est la seule source fiable pour connaître le coût réel d'un appel :

print(response.usage.prompt_tokens, response.usage.completion_tokens)

Surveillez en particulier le nombre de complétions. Avec reasoning_effort à sa valeur par défaut max, les jetons de raisonnement sont facturés comme sortie, donc une courte réponse visible peut entraîner un grand nombre de complétions derrière elle. Comparer ce nombre entre les niveaux d'effort sur vos propres invites est le moyen le plus rapide de décider quel réglage vous avez réellement besoin.

Ce que cela coûte

Les prix catalogue sont de 0,15 $ par million de jetons d'entrée, 0,50 $ par million de jetons de sortie et 0,03 $ par million de jetons d'entrée mis en cache. Une réduction de lancement de 50 % est valable jusqu'au 9 septembre 2026, réduisant ces prix à 0,075 $, 0,25 $ et 0,015 $.

Les prix varient selon les revendeurs. OpenRouter, Cloudflare Workers AI, Vercel AI Gateway, DeepInfra et d'autres proposent tous le modèle à leurs propres tarifs. Notre analyse des prix examine le calcul des coûts et ce qui change lorsque la réduction expire. Vérifiez tout chiffre auprès du fournisseur que vous utilisez réellement avant d'établir votre budget.

Tester l'intégration

Deux choses concernant cette API sont pénibles à vérifier manuellement. La charge utile multimodale est verbeuse, donc un bloc d'image base64 dans une commande curl est désagréable à écrire et pire à réexécuter. Et les échanges de modèles sont exactement le genre de changement qui modifie silencieusement la forme de la réponse.

Apidog gère les deux. Enregistrez l'appel texte, l'appel d'image et l'appel d'outil en tant que collection, attachez des assertions aux champs de réponse que votre application lit réellement, et stockez la clé API comme variable d'environnement plutôt que de la coller dans un shell. Lorsque la réduction de lancement se termine et que vous décidez de rester sur Flash ou de passer à GLM-5.3, vous pouvez changer l'ID du modèle à un seul endroit et réexécuter la suite sur les deux.

Cela transforme une migration de modèle en un diff que vous pouvez examiner au lieu d'une chose que vous espérez fonctionner.

FAQ

Quel est l'ID exact du modèle ? glm-5.3-flash sur l'API Z.ai. Sur OpenRouter, c'est z-ai/glm-5.3-flash.

Le SDK OpenAI fonctionne-t-il vraiment sans modifications ? Oui, pour les complétions de chat, le streaming et l'appel d'outils. Les paramètres non standards comme reasoning_effort nécessitent extra_body dans le SDK Python.

Combien d'images puis-je envoyer en une seule requête ? Plusieurs, chacune comme son propre bloc image_url. Les limites pratiques proviennent de votre budget de contexte plutôt que d'un nombre fixe.

Pourquoi mes réponses sont-elles si verbeuses et lentes ? reasoning_effort est par défaut à max. Définissez-le sur low pour les tâches qui ne nécessitent pas de délibération.

Quelle est la longueur maximale de la sortie ? Les sources divergent : OpenRouter indique 131 072 jetons et la carte Hugging Face indique 163 840. Vérifiez auprès de votre fournisseur avant de vous fier à des générations très longues.

Pratiquez le Design-first d'API dans Apidog

Découvrez une manière plus simple de créer et utiliser des API