Curso
La semana pasada, xAI lanzó la esperada actualización de Grok. Al igual que en versiones anteriores, se puede acceder fácilmente al modelo principal a través de la API.
En este tutorial, explicaré qué ofrece Grok 4 y cómo empezar a utilizar la API de Grok 4. Aprovecharemos al máximo sus funciones avanzadas, como el procesamiento de imágenes, la llamada de funciones y las salidas estructuradas.
Mantenemos a nuestros lectores al día sobre las últimas novedades en IA mediante el envío de The Median, nuestro boletín informativo gratuito de los viernes que resume las noticias más importantes de la semana. Suscríbete y mantente al día en solo unos minutos a la semana:
¿Qué hay de nuevo en Grok 4?
Grok 4 es el último LLM desarrollado por xAI, diseñado para el razonamiento avanzado y la resolución de problemas. A diferencia de su predecesor, Grok 4 funciona exclusivamente como un modelo de razonamiento; no hay ningún modo sin razonamiento disponible. Se ha eliminado el parámetro « reasoning_effort
», que anteriormente permitía a los usuarios ajustar el nivel de «reflexión» del modelo antes de responder.
Existen dos variantes principales: Grok 4 y Grok 4 Heavy. Grok 4 Heavy es la variante multigente de alto rendimiento, que ejecuta varios agentes de IA en paralelo para aumentar la precisión y reducir las alucinaciones, lo que lo hace especialmente potente para tareas analíticas complejas y aplicaciones de alto riesgo. El acceso a Grok 4 Heavy está restringido: necesitarás una suscripción activa a SuperGrok Heavy para utilizarlo, incluso a través de la API.
La ventana de contexto casi se duplicó, pasando de 131 072 tokens en Grok 3 a 256 000, lo que le permite procesar y recordar documentos y conversaciones mucho más largos que antes, lo que lo hace adecuado para aplicaciones exigentes.
Si deseas obtener más información sobre las características y los puntos de referencia, te recomiendo este blog en Grok 4. Si prefieres ver un vídeo resumen, no te pierdas este vídeo:
Introducción a la API de Grok 4
Antes de realizar nuestra primera solicitud de usuario, necesitamos una clave API y un entorno Python que sea capaz de conectarse a la API de Grok.
Creación de tu clave API
Para crear una clave API que puedas utilizar para autenticar el cliente con la API, sigue estos pasos:
- Visita el sitio web oficial de documentación de xAI. sitio web de documentación de xAI.
- Inicia sesión con tu cuenta X, xAI o Google. Si aún no tienes una cuenta, puedes registrarte para obtener una nueva cuenta xAI.
- Busca la opción «Crear una clave API». Introduce un nombre para tu clave y haz clic en «Guardar».
- Una vez que aparezca la clave, cópiala inmediatamente. No podrás volver a verlo más tarde, pero siempre puedes generar uno nuevo si lo necesitas.
- En el directorio del proyecto, crea un archivo llamado .env. Pega tu clave API dentro, utilizando este formato:
XAI_API_KEY=<your_api_key_here>
Precios de la API de Grok 4
Aunque utilizar la API puede resultar más asequible que optar por una suscripción premium, no es gratuita. A diferencia del plan SuperGrok, que tiene un precio mensual fijo de 30 $, los costes de la API se basan íntegramente en el uso que hagas del servicio. Sin embargo, si deseas acceder a Grok 4 Heavy, el funcionamiento es diferente: necesitarás una suscripción activa a SuperGrok Heavy (300 $ al mes), incluso si utilizas la API.
Para obtener un desglose detallado de los posibles gastos, consulta la página de precios en xAI.
Fuente: xAI
El precio de la API Grok se basa en el uso, medido por cada millón de tokens. A modo de referencia, un millón de tokens equivale aproximadamente a 750 000 palabras en inglés, ya sea en entrada o en salida. Aunque el tamaño de la ventana contextual casi se ha duplicado en comparación con su predecesor, Grok 4 tiene exactamente el mismo precio que el modelo estándar Grok 3. Pagarás 3 $ por cada millón de tokens de entrada y 15 $ por cada millón de tokens de salida.
Para acceder a la API, deberás adquirir créditos. Al empezar, es recomendable utilizar créditos prepagados en lugar de la facturación automática, ya que así evitarás cargos sorpresa. Puedes comprar tokens y realizar un seguimiento de tu uso en la consola xAI, en Facturas > Créditos.
Configuración del entorno Python
Una vez que tengas tu clave API y tus créditos listos, el siguiente paso es preparar tu entorno Python. Necesitarás dos paquetes para una integración fluida de la API:
python-dotenv
para cargar tu clave API desde el archivo.env
como una variable de entorno.- El cliente
openai
para interactuar con la API Grok 4.
Para mantener limpias las dependencias de tu proyecto, es recomendable utilizar Anaconda. Después de instalar Anaconda, configura un nuevo entorno llamado grok4
con Python 3.10 ejecutando:
conda create -n grok4 python=3.10
conda activate grok4
Con tu entorno activo, instala los paquetes necesarios:
pip install python-dotenv openai
Últimos preparativos
Empecemos escribiendo nuestro primer script. Comienza importando las funciones necesarias de los paquetes que has instalado, junto con os
para acceder a tu clave API:
import os
from dotenv import load_dotenv
from openai import OpenAI
A continuación, utiliza load_dotenv()
del paquete dotenv
para cargar tus variables de entorno, haciendo que tu clave API esté disponible para el script:
# Load environment variables
load_dotenv()
Ahora, inicializa el cliente API pasando tu clave API (del archivo .env
) y la URL del servidor Grok a la clase OpenAI
(en este tutorial utilizaremos el SDK de OpenAI, pero Grok 4 también tiene un SDK nativo xAI Python, y también es compatible con el SDK de Antrhopic). Asigna esto a la variable client
:
client = OpenAI(
api_key=os.getenv("XAI_API_KEY"),
base_url="https://api.x.ai/v1",
)
Con estos pasos, tu script está listo para enviar solicitudes a Grok 4.
Reconocimiento de imágenes con Grok 4
Ahora que ya hemos sentado las bases, probemos el reconocimiento de imágenes, una de las nuevas funciones de Grok 4. Lo demostraremos subiendo la foto de una lasaña vegetariana que aparece a continuación y pidiendo a Grok que identifique los ingredientes visibles.
Para analizar una imagen con la API de Grok 4, necesitamos enviar una solicitud que incluya tanto una imagen como un mensaje. La forma recomendada es utilizar un cliente Python compatible con OpenAI, especificando el modelo como grok-4
e incluyendo la URL de la imagen y tu pregunta en el arreglo de mensajes. La API devolverá una respuesta detallada que describe el contenido de la imagen, a la que se puede acceder en el objeto de respuesta.
Antes de enviar la solicitud, debemos asegurarnos de que la imagen cumple los requisitos de la API. Solo se admiten los formatos JPEG y PNG, y el tamaño del archivo no debe superar los 20 MB. La imagen debe ser accesible a través de un enlace directo, y el servidor debe enviar el encabezado Content-Type correcto ( image/jpeg o image/png).
Después de importar los paquetes necesarios, cargar las variables de entorno y configurar el cliente, podemos enviar nuestra consulta de la siguiente manera:
# Sending the query
response = client.chat.completions.create(
model="grok-4",
messages=[
{
"role": "user",
"content": [
{
"type": "image_url",
"image_url": {
"url": "https://shorturl.at/mVDEh",
"detail": "high"
}
},
{
"type": "text",
"text": "Which ingredients do you notice on the picture?"
}
]
}
],
max_tokens=2000,
temperature=0.2, # lower temperature for more deterministic answers
)
# Print the response
print(response.choices[0].message.content)
Based on the picture, it looks like a delicious slice of vegetarian lasagna! Here's what I can clearly see in terms of ingredients (I'm basing this purely on visual cues, so it's not a full recipe—just what's noticeable):
### Main Visible Ingredients:
- **Pasta sheets/lasagna noodles**: The flat, layered pasta that's the base structure of the dish.
- **Tomato sauce**: A red, chunky sauce (likely marinara or similar) that's spread between layers and on top.
- **Cheese**:
- Melted, bubbly cheese on top (probably mozzarella or Parmesan, given the golden-brown spots).
- White, creamy cheese in the filling layers (looks like ricotta or cottage cheese).
- **Spinach (or similar greens)**: Dark green leaves mixed into the layers, giving it a veggie-packed look (this seems like a spinach lasagna variant).
- **Basil leaf**: A fresh green leaf garnishing the top for decoration and flavor.
It doesn't appear to have any meat (like ground beef or sausage), so it's likely a vegetarian version. If this is from a specific recipe or if you have more context, I could refine my observations! What do you think it is? 😊
En este caso, Grok incluso reconoció que se trataba de una versión vegetariana solo con la imagen, ¡impresionante!
Razonamiento con Grok 4
Grok 4 está diseñado para el razonamiento avanzado y puede resolver problemas complejos paso a paso. Sin embargo, a diferencia de algunos modelos anteriores, Grok 4 no expone sus rastros de razonamiento interno, por lo que no es posible extraer un «proceso de pensamiento» detallado o una cadena de pensamiento como un campo separado de la respuesta de la API. El resultado que recibes es la respuesta final, no los pasos intermedios del modelo ni el contenido del razonamiento sin procesar.
Además, Grok 4 no admite el parámetro « reasoning_effort
» utilizado, por ejemplo, en Grok 3 mini (para aprender a utilizar ese parámetro, consulta este tutorial de la API de Grok 3). Esto significa que no puedes ajustar cuánto «piensa» el modelo antes de llegar a una conclusión final. Por lo tanto, cualquier consulta de razonamiento se construye exactamente igual que una consulta normal.
Pongamos a prueba a Grok con otra tarea de razonamiento relacionada con la lasaña y pedí que muestre su razonamiento en la salida.
# Send a basic reasoning query
response = client.chat.completions.create(
model="grok-4",
messages=[
{"role": "user", "content": (
"You want to cook lasagna for a dinner party, but several guests have dietary restrictions. One is vegetarian, one is lactose-intolerant, and another cannot eat gluten. You have six different lasagna recipes (classic, vegetarian, vegan, gluten-free, cheese-heavy, and meat-based). Which recipe or combination of recipes would best satisfy everyone, and what specific ingredient substitutions would you need to make? Explain your reasoning step by step."
)}
],
max_tokens=5000,
temperature=0.2, # lower randomness
)
# Print the final answer
print(response.choices[0].message.content)
Below, I'll explain my reasoning step by step for selecting the best recipe (or combination of recipes) to satisfy all guests at your dinner party, including the vegetarian, the lactose-intolerant person, the gluten-intolerant person, and everyone else (who presumably have no restrictions). I'll base this on logical inferences about what each recipe likely contains, since the problem doesn't provide exact ingredient lists. Then, I'll recommend specific ingredient substitutions and why this approach works.
(...)
### Step 3: Selecting the Best Recipe or Combination
- **Recommended approach**: Use a **combination of the vegan and gluten-free recipes** to create a single modified lasagna that everyone can eat. Start with the vegan recipe as your base (it already handles no meat and no lactose/dairy), then incorporate elements from the gluten-free recipe (e.g., ingredient swaps to eliminate gluten). This results in a **vegan, gluten-free lasagna**.
- Why not multiple lasagnas? Preparing separate dishes (e.g., one vegetarian, one gluten-free) could work but might not fully satisfy everyone in a shared meal—e.g., the lactose-intolerant guest couldn't eat a dairy-based vegetarian version. A single inclusive dish promotes unity at the party and simplifies cooking/serving. If you have time and oven space, you could make a small "classic" version on the side for unrestricted guests who prefer meat and cheese, but the modified vegan/gluten-free one would still be the core option.
- Why this combination over others? Vegan + gluten-free covers all restrictions without needing to add meat or dairy (which would violate rules). Starting with gluten-free and making it vegan would require more substitutions (e.g., removing meat and cheese), while vegan is already "80% there." Other combos (e.g., vegetarian + gluten-free) would still need dairy removals for lactose intolerance, making them less efficient.
This approach ensures:
- The vegetarian can eat it (no meat).
- The lactose-intolerant can eat it (no dairy/lactose).
- The gluten-intolerant can eat it (no gluten).
- Others can eat it (it's still a flavorful lasagna, though it won't have "real" meat or cheese—unrestricted guests might find it less indulgent, but it's a fair compromise).
(...)
He recortado la respuesta de Grok para destacar los puntos clave, pero incluso con esta versión más breve, queda claro que el modelo ha funcionado bien. Grok siguió paso a paso las instrucciones para
- Comprender las restricciones alimentarias
- Evalúa las recetas disponibles.
- Selecciona la mejor combinación de recetas
- Sugiere sustituciones específicas de ingredientes.
- Proporciona un resumen completo de la receta modificada.
- Vuelve sobre por qué satisface a todos.
- Discute los posibles inconvenientes y alternativas.
Llamada a funciones con Grok 4
Al igual que su predecesor, Grok 4 admite llamadas a funciones. Permite al modelo interactuar directamente con herramientas y servicios externos. Esto significa que Grok no se limita a generar texto, sino que también puede realizar acciones como obtener información meteorológica actualizada, consultar horarios de eventos, analizar registros de bases de datos o incluso manejar dispositivos domésticos inteligentes.
Cuando envías una solicitud, Grok puede determinar si necesita datos adicionales y solicitará que se llame a una función específica con los parámetros adecuados. El cliente Python se encarga de ejecutar esta función localmente, devuelve el resultado a Grok y, a continuación, recibes una respuesta completa y bien razonada.
Preparación
Para trabajar con llamadas a funciones, necesitamos importar el paquete json
, que nos permite acceder a la estructura de argumentos de cualquier función que Grok llame. A continuación, definimos una función de devolución de llamada que Grok invocará cuando solicite datos específicos.
Para este ejemplo, la función suggest_lasagna_recipe
es una función Python sencilla que devuelve una sugerencia de receta fija. Este enfoque codificado mantiene la demostración sencilla y evita la dependencia de servicios externos.
import json
# Define the callback function
def suggest_lasagna_recipe(ingredients: list) -> dict:
# Very simplified logic for demo purposes
if "zucchini" in ingredients:
return {"recipe": "Vegetarian Zucchini Lasagna"}
if "beef" in ingredients:
return {"recipe": "Classic Beef Lasagna"}
if "tofu" in ingredients:
return {"recipe": "Vegan Tofu Lasagna"}
return {"recipe": "Basic Cheese Lasagna"}
También necesitamos definir la herramienta que Grok puede llamar. Esto implica especificar el nombre de la herramienta, su finalidad y los parámetros necesarios en un esquema JSON. Este esquema se envía a Grok con la solicitud, informándole de que puede llamar a esta herramienta siempre que necesite información adicional para respaldar su razonamiento.
# Define the JSON schema for the tool
tools = [
{
"type": "function",
"function": {
"name": "suggest_lasagna_recipe",
"description": "Suggests a lasagna recipe based on available ingredients.",
"parameters": {
"type": "object",
"properties": {
"ingredients": {
"type": "array",
"items": {"type": "string"},
"description": "List of available ingredients"
}
},
"required": ["ingredients"]
}
}
}
]
Por último, el diccionario tools_map
conecta los nombres de las funciones que utiliza Grok con las funciones Python reales de tu código. Este mapeo permite al cliente ejecutar correctamente las llamadas a funciones solicitadas.
# link the function names to the functions
tools_map = {
"suggest_lasagna_recipe": suggest_lasagna_recipe
}
Aunque definir manualmente los esquemas de herramientas funciona bien para proyectos sencillos, utilizar una biblioteca de validación de datos como Pydantic es muy recomendable a medida que tu proyecto crece. Pydantic proporciona validación automática de las entradas de las funciones, mejora la gestión de errores y da como resultado un código más limpio y fácil de mantener.
Ejecución
Comprobemos si Grok utiliza nuestra función cuando se le pide una receta de lasaña. Así es como se desarrolla el flujo de trabajo de llamada a funciones:
- En primer lugar, enviamos una pregunta del usuario («¿Qué lasaña puedo preparar con los ingredientes que tengo?»), junto con las recetas disponibles (
tools
), a Grok. - A continuación, Grok revisa la solicitud y, si determina que es necesario llamar a una función, solicita la receta activando nuestra función local. Si no se realiza ninguna llamada a la herramienta, simplemente utilizamos la respuesta inicial de Grok.
- Cuando se solicita una llamada a una herramienta, ejecutamos la función local correspondiente y añadimos el resultado al historial de mensajes en curso.
- Este historial actualizado se envía de vuelta a Grok, lo que le permite completar su razonamiento y proporcionar una respuesta final que tiene en cuenta el contexto.
# Step 1: Send the initial user request
messages = [
{"role": "user", "content": "I have beef, ricotta, and tomato sauce. Which lasagna can I make?"}
]
response = client.chat.completions.create(
model="grok-4",
messages=messages,
tools=tools,
tool_choice="auto",
)
# Step 2: Check if a tool call was requested
tool_calls = getattr(response.choices[0].message, "tool_calls", [])
if tool_calls:
for tool_call in tool_calls:
function_name = tool_call.function.name
print(f"{function_name} successfully called")
function_args = json.loads(tool_call.function.arguments)
# Find and call the matching local function
if function_name in tools_map:
function_result = tools_map[function_name](**function_args)
# Step 3: Add the function result back to the message history
messages.append(response.choices[0].message) # Assistant's tool call message
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": json.dumps(function_result)
})
# Step 4: Send a new request including the tool response
final_response = client.chat.completions.create(
model="grok-4",
messages=messages,
tools=tools,
tool_choice="auto"
)
# Print the final answer
print("\nFinal Answer:")
print(final_response.choices[0].message.content)
else:
# No tool call: respond directly
print("\nNo tool call was requested. Final Answer:")
print(response.choices[0].message.content)
suggest_lasagna_recipe successfully called
Final Answer:
Based on your available ingredients (beef, ricotta, and tomato sauce), you can make a **Classic Beef Lasagna**! (...)
Como podemos ver, Grok llamó a nuestra función y sugirió la receta correspondiente.
También es posible que observes el argumento tool_choice
en la solicitud inicial. De forma predeterminada, «auto» permite a Grok decidir si llamar a una función y, en caso afirmativo, a cuál. Si deseas tener más control, puedes forzar una llamada a una función específica, especificar exactamente qué función utilizar o desactivar por completo las llamadas a funciones cambiando este parámetro.
Salidas estructuradas con Grok 4
De forma similar a las llamadas a funciones, las salidas estructuradas son una característica introducida con Grok 3. Permiten que Grok proporcione respuestas en un formato estricto como JSON en lugar de texto sin formato. Este enfoque facilita enormemente el análisis, la validación y el uso de las respuestas del modelo en tus aplicaciones o flujos de trabajo.
Al configurar un esquema por adelantado, puedes estar seguro de que los resultados de Grok siempre serán coherentes, legibles por máquinas y estarán listos para su posterior procesamiento. Esto resulta especialmente útil cuando necesitas extraer datos estructurados de documentos o enviar contenido generado por IA directamente a bases de datos, paneles de control o herramientas de automatización, sin preocuparte por un análisis de texto poco fiable.
Para definir el esquema de salida, utilizamos Pydantic, que simplifica la estructuración de datos complejos y los hace más legibles (este tutorial de Pydantic te ayudará a aprender más). Para ello, tendrás que importar tanto BaseModel
como Field
desde pydantic
. Dado que nuestra salida contiene una lista de ingredientes, también importamos List
desde el módulo typing
de Python para especificar claramente el tipo de cada elemento de la lista.
Aunque podríamos configurar el esquema utilizando JSON sin formato, Grok a veces devuelve resultados que no coinciden exactamente con la estructura esperada. El significado puede ser el mismo, pero el esquema podría diferir, lo que puede causar problemas si tu aplicación necesita un formato específico. Esto es especialmente cierto en el caso de elementos anidados, como las listas. Por eso recomiendo utilizar Pydantic, ya que ayuda a garantizar que la salida estructurada se valide y analice de forma fiable en todo momento.
En nuestro ejemplo, el esquema, denominado « Recipe
», incluye su nombre, el número de raciones y una lista de ingredientes. Cada « Ingredient
» se define por su nombre, la cantidad necesaria para la receta, su disponibilidad, el precio por kilogramo e información sobre si el ingrediente es vegetariano, vegano o sin gluten. Es útil establecer valores predeterminados en el propio esquema, como estamos haciendo con el número de porciones.
# import additionally needed packages
from pydantic import BaseModel, Field
from typing import List
# Define the schema for the structured output
class Ingredient(BaseModel):
name: str = Field(description="Name of the ingredient")
amount: int = Field(description="Amount in g needed for recipe")
is_at_home: bool = Field(description="Is the item already at home?")
price: float = Field(description="Price of the ingredient in USD per kg")
is_vegetarian: bool = Field(description="Is the ingredient vegetarian?")
is_vegan: bool = Field(description="Is the ingredient vegan?")
is_gluten_free: bool = Field(description="Is the ingredient gluten-free?")
class Recipe(BaseModel):
name: str = Field(description="The name of the recipe")
portions: int = Field(default=4, description="Amount of portions")
ingredients: List[Ingredient] = Field(description="List of ingredients for the recipe")
Hay algunos detalles que debes tener en cuenta al realizar la solicitud. En lugar de utilizar client.chat.completions.create()
, queremos llamar a client.beta.chat.completions.parse()
. Esto le indica a Grok que esperamos la salida en un formato específico, y nuestro esquema Recipe
se pasa como el argumento response_format
.
También es útil incluir todas las instrucciones clave para la tarea en el mensaje del sistema. Esto mantiene a Grok 4 centrado y coherente a lo largo de toda la conversación. Dado que el esquema se define por separado, la solicitud al usuario puede centrarse en la tarea en sí, sin necesidad de enumerar los campos necesarios para el JSON de salida.
Por ejemplo, podrías configurar Grok para que desempeñe el papel de un chef italiano, asegurándote de que todas las recetas que te ofrece sean auténticamente italianas, ¡para que no te encuentres piña en tu pizza!
# Send a prompt and request structured output
completion = client.beta.chat.completions.parse(
model="grok-4",
messages=[
{"role": "system", "content": (
"You are a master chef specialized in italian cuisine."
"When asked about recipes, return the output in structured JSON format following the provided schema, without any extra text."
)},
{"role": "user", "content": (
"I have beef, ricotta, and tomato sauce, and want to cook for 4 persons. Which lasagna can I make?"
)}
],
response_format=Recipe,
)
Una vez que hemos analizado la salida estructurada de Grok 4, sus ventajas sobre el texto sin formato quedan claras. Podemos reorganizar y personalizar fácilmente la información para adaptarla a nuestras necesidades, o incluso introducir datos específicos directamente en flujos de trabajo automatizados. En nuestro ejemplo, esto significa que podemos multiplicar rápidamente los precios de los ingredientes por kilogramo por las cantidades necesarias, sumar los costes en función de lo que ya hay en la despensa y calcular el precio final por ración en solo unos pasos.
# Access the parsed result
recipe = completion.choices[0].message.parsed
price = 0 # initialize price variable
print(f"Recipe: {recipe.name}")
print("Ingredients:")
for i in recipe.ingredients:
print("- " + i.name + " " + str(i.amount) + " g")
if not i.is_at_home:
price += (i.price * i.amount / 1000)
print(f"Price per portion: USD {round((price/recipe.portions), 2)}")
Recipe: Classic Beef Lasagna
Ingredients:
- Ground beef 500 g
- Ricotta cheese 400 g
- Tomato sauce 800 g
- Lasagna noodles 300 g
- Mozzarella cheese 300 g
- Parmesan cheese 100 g
- Onion 200 g
- Garlic 20 g
- Olive oil 30 g
- Egg 50 g
Price per portion: USD 1.7625
Conclusión
Grok 4 incorpora nuevas funciones, como una ventana de contexto más grande y mejores capacidades de razonamiento. Su reconocimiento de imágenes y su capacidad para ejecutar funciones abren interesantes posibilidades para combinar la IA con datos y acciones del mundo real, mientras que los resultados estructurados garantizan respuestas fiables y legibles por máquinas. La configuración de la API es sencilla, lo que permite una rápida integración en tus proyectos Python con solo unas pocas dependencias.
Y si todos los ejemplos de lasaña te han dado hambre, no eres el único: ¡yo también voy a por un trozo!