GLM-5.3-Flash es compatible con OpenAI, lo que significa que la forma más rápida de realizar una llamada funcional es apuntar un cliente que ya tengas a una URL base diferente y cambiar una cadena. La parte realmente nueva es la entrada de imágenes: este es el primer modelo GLM-5 que toma imágenes en la misma solicitud que tu texto, y la forma del payload suele confundir a la gente.
Esta guía cubre cómo obtener una clave, realizar una llamada de texto, enviar imágenes, controlar el esfuerzo de razonamiento, streaming y la llamada a herramientas. Cada ejemplo utiliza el ID de modelo glm-5.3-flash.
Si quieres el trasfondo de lo que es este modelo antes de configurarlo, empieza con nuestra explicación de GLM-5.3-Flash. Si ya estás utilizando su hermano mayor, la guía de la API de GLM-5.3 cubre ese modelo, y las diferencias a continuación son reales: diferente ID de modelo, diferente tarjeta de tarifas y una vía de imágenes que GLM-5.3 no tiene de forma nativa.

Obtener una clave de API
Crea una cuenta en z.ai, abre la sección de claves de API del panel y genera una clave. Ponla en tu entorno en lugar de en tu código fuente:
export ZAI_API_KEY="your-key-here"
La URL base para la API estándar es:
https://api.z.ai/api/paas/v4/
Hay una URL base separada utilizada por los endpoints del plan de codificación, lo que es relevante si estás configurando Claude Code o Cline en lugar de llamar directamente a la API. Esa configuración se cubre en nuestra guía de Claude Code y Cline.
Tu primera llamada
Debido a que el endpoint es compatible con OpenAI, el SDK oficial de OpenAI funciona sin modificaciones:
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)
Lo mismo 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."}
]
}'
Y 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);
Nada de esto es específico de GLM, excepto la URL base y la cadena del modelo. Ese es el objetivo de una superficie compatible con OpenAI, y es por eso que cambiar de modelo es lo suficientemente económico como para que valga la pena compararlo con tu propia carga de trabajo.
Envío de imágenes
Esta es la sección que no existe para GLM-5.3. La entrada de imágenes funciona a través de bloques de contenido: en lugar de que content sea una cadena simple, se convierte en un array de bloques tipados.
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"
},
},
],
}
],
)
Tres reglas rigen este payload:
El campo URL acepta una URL pública o una URL de datos base64. Si tu imagen es local o privada, codifícala:
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}"},
}
Múltiples imágenes significan múltiples bloques. No hay un atajo de array de URLs. Para comparar un diseño con su implementación, envía dos bloques image_url en el mismo array de contenido:
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}},
]
El orden tiene significado. El modelo lee el array de contenido en secuencia, así que coloca el texto que enmarca la tarea antes de las imágenes a las que se refiere. "Compara estas dos" seguido de dos imágenes se lee mejor que dos imágenes seguidas de una pregunta.
La documentación de Z.ai también enumera la entrada de video y archivos utilizando el mismo mecanismo de bloques de contenido. El video es más reciente y mucho menos probado en la práctica que la entrada de imágenes, así que valídalo con tus propios medios antes de construir una función sobre él.
Para un tratamiento más profundo del lado de la visión, incluyendo flujos de trabajo de captura de pantalla a código y la colocación de imágenes junto a un documento largo en la misma ventana de 1M de tokens, consulta nuestra guía de visión de GLM-5.3-Flash.
Controlando el esfuerzo de razonamiento
GLM-5.3-Flash expone tres modos de pensamiento a través de 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"},
)
Los valores aceptados son low, high y max. El valor predeterminado es max, lo cual es importante saber porque es el más caro. Si estás realizando clasificación o extracción de alto volumen donde la respuesta no necesita deliberación, establecer explícitamente low reducirá sustancialmente tu conteo de tokens de salida.
Esto es un cambio con respecto a GLM-5.2, que solo exponía High y Max. El nivel low es nuevo, y para trabajos por lotes sensibles al costo, es probablemente el parámetro más útil del modelo.
Ten en cuenta que reasoning_effort va en extra_body cuando usas el SDK de Python de OpenAI, porque no forma parte del esquema estándar de OpenAI. En curl puro, es simplemente un campo de nivel superior.
Parámetros de muestreo recomendados
Z.ai publica diferentes valores predeterminados dependiendo de lo que estés haciendo:
| Caso de uso | temperature | top_p |
|---|---|---|
| General | 1.0 | 0.95 |
| Codificación | 0.95 | 1.0 |
Estos son lo suficientemente cercanos como para que la diferencia sea marginal para la mayoría de las aplicaciones, pero si estás obteniendo una salida de código inconsistente, el perfil de codificación es el que debes probar.
Streaming
Se aplican las semánticas de streaming estándar de OpenAI:
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)
Establece expectativas aquí. GLM-5.3-Flash genera aproximadamente 49 tokens por segundo según Artificial Analysis, lo cual es más lento que su hermano mayor GLM-5.3, que genera alrededor de 86. El tiempo hasta el primer token es bueno, 1.52 segundos, por lo que la respuesta comienza rápidamente y luego llega de manera constante en lugar de rápidamente. Si estás haciendo streaming a una interfaz de usuario, ese perfil está bien. Si estás generando documentos largos en un trabajo por lotes, tenlo en cuenta en tu presupuesto.
Llamada a herramientas
Las herramientas utilizan el esquema estándar de OpenAI:
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)
Los benchmarks agenciales que Z.ai publicó en el lanzamiento se apoyan en gran medida en el uso de herramientas, con AutomationBench en 48.8 frente a los 26.2 de GLM-5.2. Esas son cifras del proveedor, pero la dirección es consistente con el modelo ajustado para bucles de llamada a herramientas en lugar de chat de un solo turno.
Si estás generando definiciones de herramientas a partir de una API que ya posees, nuestra publicación sobre cómo convertir una especificación OpenAPI en herramientas de agente cubre cómo hacerlo sin escribir esquemas a mano.
Manejo de errores que vale la pena escribir
Tres modos de fallo representan la mayoría de los problemas de producción en este endpoint.
Límites de tasa. Reintenta con retroceso exponencial y *jitter*. Un intervalo de reintento fijo en muchos trabajadores produce reintentos sincronizados, que es la forma clásica de convertir un límite breve en uno sostenido.
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())
Desbordamiento de contexto. Una ventana de 1M de tokens es lo suficientemente grande como para que la gente deje de contar, y luego un documento largo más algunas imágenes de alta resolución la superan. Las imágenes consumen contexto, y el error llega en el momento de la solicitud en lugar de cuando ensamblas el prompt. Rastrea tu presupuesto de tokens al entrar.
Salida truncada. Si una respuesta se detiene a mitad de frase, verifica finish_reason en la elección. Un valor de length significa que alcanzaste el límite de salida, no que el modelo se rindió. Dado que la cifra máxima de salida es en sí misma discutida entre fuentes, vale la pena verificar esto explícitamente en lugar de asumir.
Lectura del uso de tokens
Cada respuesta lleva un objeto usage, y es la única fuente confiable de lo que realmente costó una llamada:
print(response.usage.prompt_tokens, response.usage.completion_tokens)
Observa el conteo de finalización en particular. Con reasoning_effort en su valor predeterminado max, los tokens de razonamiento se facturan como salida, por lo que una respuesta visible corta puede llevar un gran conteo de finalización detrás. Comparar ese número en los diferentes niveles de esfuerzo con tus propios prompts es la forma más rápida de decidir qué configuración necesitas realmente.
Cuánto cuesta
El precio de lista es de $0.15 por millón de tokens de entrada, $0.50 por millón de tokens de salida y $0.03 por millón de tokens de entrada en caché. Un descuento de lanzamiento del 50% estará vigente hasta el 9 de septiembre de 2026, reduciendo esos precios a $0.075, $0.25 y $0.015.
Los precios difieren entre revendedores. OpenRouter, Cloudflare Workers AI, Vercel AI Gateway, DeepInfra y otros ofrecen el modelo a sus propias tarifas. Nuestro desglose de precios explica las matemáticas de los costos y qué cambia cuando el descuento expira. Verifica cualquier cifra con el proveedor que realmente uses antes de presupuestar.
Probando la integración
Dos cosas de esta API son molestas de verificar manualmente. El payload multimodal es verboso, por lo que un bloque de imagen base64 en un comando curl es desagradable de escribir y peor de volver a ejecutar. Y los cambios de modelo son exactamente el tipo de cambio que altera silenciosamente la forma de la respuesta.
Apidog maneja ambos. Guarda la llamada de texto, la llamada de imagen y la llamada a herramientas como una colección, adjunta aserciones a los campos de respuesta que tu aplicación realmente lee, y almacena la clave de API como una variable de entorno en lugar de pegarla en una terminal. Cuando termine el descuento de lanzamiento y decidas si quedarte en Flash o pasar a GLM-5.3, puedes cambiar el ID del modelo en un solo lugar y volver a ejecutar la suite contra ambos.
Eso convierte una migración de modelo en una diferencia que puedes examinar en lugar de algo que esperas que funcione.
Preguntas frecuentes
¿Cuál es el ID exacto del modelo? glm-5.3-flash en la API de Z.ai. En OpenRouter es z-ai/glm-5.3-flash.
¿El SDK de OpenAI realmente funciona sin cambios? Sí, para completaciones de chat, streaming y llamada a herramientas. Los parámetros no estándar como reasoning_effort necesitan extra_body en el SDK de Python.
¿Cuántas imágenes puedo enviar en una solicitud? Múltiples, cada una como su propio bloque image_url. Los límites prácticos provienen de tu presupuesto de contexto en lugar de un conteo fijo.
¿Por qué mis respuestas son tan verbosas y lentas? reasoning_effort por defecto es max. Establécelo en low para trabajos que no necesiten deliberación.
¿Cuál es la longitud máxima de salida? Las fuentes no están de acuerdo: OpenRouter enumera 131.072 tokens y la tarjeta de Hugging Face indica 163.840. Consulta a tu proveedor antes de confiar en generaciones muy largas.
