> labs.luisguisado.cloud
Principiante~25 min·por Luis Guisado·actualizado 4 de mayo de 2026

Llama a un LLM desde Python por primera vez

Tu primera llamada a un LLM desde Python. Usas Groq con free tier y el SDK de OpenAI, que es el formato estándar que casi todos los proveedores hablan hoy.

Costo estimado: free

Aparece en: Agentic AI desde cero para Backend y Cloud Developers

Por qué este lab existe

Hablas de “ChatGPT” todos los días. Lo abres, escribes, te responde. Pero hasta acá nunca has hecho que tu propio software llame a un LLM. La diferencia entre los dos importa:

  • ChatGPT (la web): un producto. Tú eres el usuario humano. La suscripción mensual paga el acceso a la interfaz.
  • API del modelo: un endpoint HTTP. Tu programa es el usuario. Pagas por token consumido (o nada, si usas un free tier), separado de la web.

Este lab es donde dejas de ver al LLM como “la página de ChatGPT” y empiezas a verlo como un servicio HTTP cualquiera. Tu app le habla con un cliente, una API key y un payload JSON. Es la base sobre la que el resto de la serie construye.

Duración: ~25 min · Nivel: Beginner · Costo: gratis (free tier de Groq).


Lo que vas a tener al terminar

  1. Una API key de Groq válida, exportada en tu shell y guardada en un archivo .env.
  2. Un script Python (call_llm.py) que envía un prompt al modelo y muestra la respuesta en tu terminal.
  3. El conteo de tokens consumidos visible al final de cada ejecución.
  4. Claridad sobre qué significa que un proveedor sea “OpenAI-compatible” y por qué eso importa para el resto de la serie.

Qué vas a aprender

  • Obtener una API key gratuita en Groq y guardarla fuera del código.
  • Llamar a un LLM desde Python con el SDK openai apuntando a Groq.
  • Distinguir entre proveedores OpenAI-compatible y proveedores con SDK nativo.

Vocabulario base

Antes de tocar código, cuatro términos que vas a escuchar todo el rato.

Qué es un LLM

LLM significa Large Language Model (“modelo de lenguaje grande”). Es un modelo de inteligencia artificial entrenado con un montón de texto, capaz de procesar lo que le mandas y generar texto en respuesta. Ejemplos conocidos: GPT-4 (OpenAI), Claude (Anthropic), Llama (Meta), Gemini (Google). Cuando un proveedor “expone un LLM por API”, lo que hace es ponerlo detrás de un endpoint HTTP al que tu programa le manda peticiones.

Qué es un prompt

El prompt es el texto que tú le mandas al modelo. Puede ser una pregunta (“¿qué es AWS Lambda?”), una instrucción (“traduce esto al inglés”), o algo más estructurado que combine varias cosas. La calidad del prompt afecta directamente la calidad de la respuesta.

Qué es un token

Un token es la unidad mínima con la que el modelo procesa texto. Aproximadamente equivale a una palabra corta o a un fragmento de palabra. En español, un token cubre cerca de 1.5 caracteres en promedio. Importa por dos razones: los proveedores cobran por token consumido, y los rate limits y context windows también se miden en tokens. Cada respuesta del modelo viene con el desglose: cuántos tokens usó tu prompt, cuántos su respuesta, cuántos en total.

Qué es un model

Un model (en este contexto, no “model” de tu base de datos) es el LLM concreto al que le hablas. Cada proveedor expone varios modelos distintos. Cuando llamas a la API, eliges uno con un identificador como llama-3.3-70b-versatile o gpt-4o. Modelos diferentes varían en: capacidad de razonamiento, velocidad, costo, tamaño del context window, fecha de corte del entrenamiento. En este lab usamos llama-3.3-70b-versatile porque es gratis vía Groq y rinde bien para tareas generales.

system message vs user message

Cuando le mandas un prompt al modelo, técnicamente le mandas una lista de mensajes. Cada mensaje tiene un role. Los dos que te interesan al inicio son:

  • role: "system": define el “modo de operación” o “personalidad” del modelo. Algo como “eres un experto en AWS que responde en oraciones cortas”. Va antes de la conversación.
  • role: "user": el mensaje del usuario humano (o de tu app actuando como usuario). Es la pregunta o la instrucción concreta.

El modelo lee la lista en orden y genera una respuesta consistente con ambas. Sin system, el modelo improvisa el tono.

Llamar un LLM por API: la idea

Un LLM expuesto vía API es un endpoint HTTP. Tú le mandas un POST con un payload JSON que dice “qué modelo, qué mensajes” y te devuelve un JSON con la respuesta. La gran mayoría de proveedores actuales usa el mismo formato de request y response que popularizó OpenAI. Cuando un proveedor copia ese formato, se le llama OpenAI-compatible.

¿Por qué importa? Porque el SDK oficial de OpenAI funciona contra cualquier proveedor compatible cambiándole solo la URL. Mismo cliente, mismo client.chat.completions.create(...), distinto host. Esa propiedad la vamos a usar a lo largo de toda la serie para cambiar de proveedor sin reescribir el código de la app.

API key fuera del código

Una API key es una credencial. Si la dejas hardcodeada en un archivo .py y haces commit al repo, vas a publicar tu credencial al mundo. La práctica estándar es leerla desde una variable de entorno, y mantener el archivo .env (donde la guardas localmente) fuera del control de versiones vía .gitignore. Si por error commiteas un .env, no basta con borrarlo en el siguiente commit: la key queda en el historial de git. Lo correcto es rotarla (revocarla en la consola del proveedor y emitir otra).


Mapa visual

   ┌───────────────┐                      ┌──────────────────────┐
   │ Tu script .py │ ──HTTPS── POST ────▶ │ api.groq.com         │
   │               │   Authorization:     │ /openai/v1/chat/...  │
   │  openai SDK   │   Bearer GROQ_KEY    │                      │
   │               │   { model, messages }│  Llama 3.3 70B       │
   │               │ ◀────────────────────│                      │
   │  print(text)  │   { choices: [...] } │                      │
   └───────────────┘                      └──────────────────────┘

El SDK openai no asume el host. Tú le dices base_url=... y le hablas a Groq. Mismo SDK, distinto proveedor.


Sobre las versiones y el modelo

Este lab no pinea las versiones de las dependencias en el pip install. Cuando corras el comando, vas a instalar lo último que haya en PyPI ese día. La razón es práctica: la serie evoluciona en el tiempo, y si pineáramos hoy, dentro de 6 meses estarías instalando una versión vieja con bugs ya conocidos.

Para que sepas con qué se validó este lab por última vez (al día updatedAt: 2026-05-04):

  • openai SDK: validado con 2.34.0. Última versión en pypi.org/project/openai o el changelog en GitHub.
  • python-dotenv: validado con 1.2.2. Última en pypi.org/project/python-dotenv.
  • Python: validado con 3.10+. Cualquier 3.10 o superior debería andar.
  • Modelo de Groq: este lab usa llama-3.3-70b-versatile. Lista vigente de modelos en console.groq.com/docs/models. Si Groq lo deprecó al momento que corres el lab, en esa página vas a ver el reemplazo recomendado, y solo tienes que cambiar el string en model="...".

Si entre la versión validada y la última que descargaste hubo un major version bump (por ejemplo, openai 2.x3.x), revisa el changelog antes de seguir: la firma del cliente o de chat.completions.create() puede haber cambiado y el código del lab podría requerir un ajuste mínimo.


Paso 1. Obtener la API key de Groq

Groq es un proveedor con free tier OpenAI-compatible. Para esta serie nos da:

  • API key gratis con email (sin tarjeta de crédito, sin teléfono).
  • Acceso al modelo llama-3.3-70b-versatile con un cupo holgado.
  • Latencia muy baja gracias al hardware LPU propio.

Acción:

  1. Entra a console.groq.com y crea una cuenta con tu correo.
  2. Una vez dentro, ve a API KeysCreate API Key y copia el valor (empieza con gsk_...).
  3. Guarda el valor en un lugar temporal. La consola no te la vuelve a mostrar: si la pierdes, tienes que generar otra.

Exportarla a tu shell

Antes de usarla con curl, dile a tu shell que esta variable existe. En bash o zsh:

export GROQ_API_KEY=gsk_tu_valor_aqui

Reglas críticas (y la causa #1 de errores en este paso):

  • Sin espacios alrededor del =. Esto está bien: export GROQ_API_KEY=gsk_xxx. Esto da error: export GROQ_API_KEY = gsk_xxx. zsh responde con zsh: bad assignment y se siente injusto, pero la regla es así.
  • Sin comillas si el valor no tiene caracteres raros. Las API keys de Groq solo son letras, números y guiones bajos, así que no hace falta poner comillas. Si las pones, no rompe.
  • Esto solo dura en tu shell actual. Si abres otra terminal, la perdiste y tienes que volver a exportarla. En el Paso 2 la vamos a mover a un archivo .env para que el script la lea sola y no dependa de tu shell.

Probar la key con curl

curl https://api.groq.com/openai/v1/models \
  -H "Authorization: Bearer $GROQ_API_KEY"

Respuesta esperada (recortada):

{
  "object": "list",
  "data": [
    { "id": "llama-3.3-70b-versatile", "object": "model", "owned_by": "Meta" }
  ]
}

Si te responde 401 Unauthorized, la key está mal copiada o no exportaste GROQ_API_KEY en tu shell. Si te responde la lista de modelos, la credencial funciona.

Por qué Groq y no otro: todos los proveedores de la siguiente tabla son OpenAI-compatible (mismo schema de request/response que OpenAI). La diferencia está en el free tier, los modelos disponibles y la fricción de signup.

Proveedor Modelos top Free tier Signup
Groq Llama 3.3 70B, qwen3-32b, Whisper hasta 14,400 req/día Email
Cerebras gpt-oss-120b, Llama 3.1 8B 30 rpm, 60k tok/min Email
OpenRouter Agregador (Gemma, Llama, Qwen, Hermes) 20 rpm, 50 req/día Email
GitHub Models GPT-4, Llama, DeepSeek, Codestral tokens muy restrictivos GitHub
Vercel AI Gateway Routea a varios proveedores $5/mes en crédito Cuenta Vercel

Elegimos Groq por la combinación de signup sin fricción, free tier holgado y latencia muy baja. Para conocer la lista de regiones donde Groq está disponible, ver groq.com/policies/legal-disclaimers o tu propio test de signup. Si no logras crear cuenta, Cerebras es el sustituto natural: mismo dialecto, distintos modelos, signup también con email.


Paso 2. Preparar el proyecto Python

Vamos a aislar las dependencias en un virtualenv y guardar la API key en un .env para que el script la lea sola.

mkdir agentic-ai-lab && cd agentic-ai-lab
python3 -m venv .venv
source .venv/bin/activate     # en Windows: .venv\Scripts\activate
pip install openai python-dotenv

Este pip install no pinea versiones a propósito: te instala las últimas. Las versiones con las que se validó por última vez están listadas arriba en “Sobre las versiones y el modelo”.

Archivo: .env (NUEVO)

GROQ_API_KEY=gsk_tu_valor_aqui

Archivo: .gitignore (NUEVO)

.venv/
.env
__pycache__/

Probar:

ls -la

Respuesta esperada: ves .venv/, .env y .gitignore en el listado.

Tip: si quieres seguir usando curl después de pasar la key al .env (es decir, si tu shell ya no tiene GROQ_API_KEY exportada), puedes recuperarla con:

export $(grep -v '^#' .env | xargs)

Eso lee tu .env, ignora comentarios, y exporta cada par KEY=VALUE al shell actual. Útil para alternar entre el script Python y pruebas con curl sin volver a copiar la key a mano.

Tip alternativo: si prefieres uv en lugar de venv + pip, los pasos equivalentes son uv init, uv add openai python-dotenv y uv run python .... El resto del lab funciona igual.


Paso 3. Primera llamada al modelo

Vamos a crear el script que envía un prompt y muestra la respuesta.

Archivo: call_llm.py (NUEVO)

import os
from dotenv import load_dotenv
from openai import OpenAI

load_dotenv()

client = OpenAI(
    base_url="https://api.groq.com/openai/v1",
    api_key=os.environ["GROQ_API_KEY"],
)

response = client.chat.completions.create(
    model="llama-3.3-70b-versatile",
    messages=[
        {"role": "user", "content": "Explícame qué es AWS Lambda en 3 oraciones."}
    ],
)

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

Probar:

python call_llm.py

Respuesta esperada (variará entre runs):

AWS Lambda es un servicio de cómputo serverless de Amazon Web Services
que ejecuta tu código en respuesta a eventos sin que tengas que
provisionar ni administrar servidores. Pagas solo por el tiempo de
cómputo que tu código consume, medido en milisegundos. Es ideal para
APIs, procesamiento de eventos y tareas asíncronas que no requieren
un servidor permanente.

Acabas de hacer la primera llamada. Pocas líneas: un cliente, un request, un print.

Reto antes de seguir: modifica el script para hacer 3 llamadas con prompts distintos (por ejemplo: “Define IAM en una oración”, “Define S3 en una oración”, “Define VPC en una oración”) y al final imprime la suma total de tokens consumidos en las 3. Pista: cada response.usage.total_tokens es un número, y los puedes acumular. Lo formalizamos en el siguiente paso.


Paso 4. Parametrizar y entender la respuesta

El script anterior funciona pero tiene tres datos hardcodeados que normalmente querrás controlar: el modelo, el prompt y los parámetros de generación. Vamos a separarlos y de paso medir el consumo de tokens.

Archivo: call_llm.py (REESCRITO)

import os
from dotenv import load_dotenv
from openai import OpenAI

load_dotenv()

MODEL = "llama-3.3-70b-versatile"
SYSTEM_PROMPT = "Eres un experto en AWS que explica con ejemplos breves."
USER_PROMPT = "Explícame qué es AWS Lambda en 3 oraciones."

client = OpenAI(
    base_url="https://api.groq.com/openai/v1",
    api_key=os.environ["GROQ_API_KEY"],
)

response = client.chat.completions.create(
    model=MODEL,
    messages=[
        {"role": "system", "content": SYSTEM_PROMPT},
        {"role": "user", "content": USER_PROMPT},
    ],
    temperature=0.3,
)

print("Respuesta:")
print(response.choices[0].message.content)
print()
print(
    f"Tokens usados | prompt: {response.usage.prompt_tokens}, "
    f"completion: {response.usage.completion_tokens}, "
    f"total: {response.usage.total_tokens}"
)

Tres cambios respecto al script anterior:

  1. role: "system" define la “personalidad” del modelo antes del mensaje del usuario. Sin él, el modelo improvisa el tono.
  2. temperature=0.3 controla la aleatoriedad de la respuesta. Valores bajos (cercanos a 0.0) tienden a respuestas más reproducibles, valores altos (cercanos a 1.0) tienden a respuestas más creativas. La reproducibilidad exacta depende del proveedor y del modelo, no es un contrato fuerte.
  3. response.usage te da el desglose de tokens. Importa porque los proveedores cobran por token (en proveedores no gratuitos) y los rate limits se miden ahí.

Probar:

python call_llm.py

Respuesta esperada:

Respuesta:
[explicación de Lambda]

Tokens usados | prompt: 35, completion: 78, total: 113

Errores comunes

Error 1: zsh: bad assignment al hacer export

Síntoma: corres export GROQ_API_KEY = gsk_xxx y zsh te responde zsh: bad assignment.

Causa raíz: bash y zsh exigen cero espacios alrededor del = en una asignación. VAR = valor no es válido.

Corrección: quita los espacios, así:

export GROQ_API_KEY=gsk_tu_valor_aqui

Error 2: API key con espacios o saltos de línea

Síntoma: la consola devuelve 401 Unauthorized aunque copiaste la key correctamente.

Causa raíz: al copiar de la consola del proveedor, pegaste un espacio invisible al inicio o un salto de línea al final dentro del .env. El SDK envía la cadena tal cual al header Authorization y el servidor la rechaza.

Corrección: abre el .env, asegúrate de que la línea sea exactamente GROQ_API_KEY=gsk_... sin espacios alrededor del = y sin línea en blanco antes de la key.

Error 3: importar openai sin pasar base_url

Síntoma: el código corre pero la respuesta es AuthenticationError: Incorrect API key provided.

Causa raíz: sin base_url, el SDK apunta por defecto a https://api.openai.com/v1. Tu key de Groq no es válida para OpenAI, así que OpenAI rechaza la request.

Corrección: pasa siempre base_url="https://api.groq.com/openai/v1" al instanciar OpenAI(...). Si en el futuro quieres usar el verdadero OpenAI, omite ese parámetro y usa una key de OpenAI.

Error 4: KeyError: 'GROQ_API_KEY' al correr el script

Síntoma: Python explota con KeyError: 'GROQ_API_KEY' apenas arranca.

Causa raíz: el script intenta leer la variable de entorno con os.environ["GROQ_API_KEY"], pero ni el shell la tiene exportada ni el .env se cargó. Causas posibles: olvidaste crear el .env, lo creaste con otro nombre (.env.local, env.txt), o el script se está ejecutando desde un directorio donde .env no existe.

Corrección: verifica que ls .env devuelva el archivo desde el directorio donde corres python call_llm.py. python-dotenv busca .env en el cwd actual.


Buenas prácticas

  • Nunca commitees credenciales. El .env va en .gitignore desde el primer commit. Si una credencial filtra al repo, rótala (revoca y emite otra) en lugar de intentar borrarla del historial. Ref: 12-Factor App · Config.
  • Versiona las dependencias en proyectos reales. Este lab te muestra pip install openai python-dotenv sin pinear para que siempre instales la última versión, porque los labs envejecen rápido. En un proyecto real, debes pinear (requirements.txt con ==X.Y.Z, o un lock file con Poetry, uv o pip-tools) para que el equipo y CI tengan exactamente las mismas versiones. Una API que aceptaba messages=[...] puede cambiar de una major version a la siguiente, y sin pin la reproducibilidad se pierde. Ref: Hunt & Thomas, The Pragmatic Programmer, sección sobre tooling y reproducibilidad.
  • Mide siempre los tokens. response.usage aparece en cada respuesta. Loggearlo desde el día uno te evita la sorpresa de un bill alto cuando pases a un proveedor de pago. Ref: OpenAI · Usage object.

Estado del proyecto al finalizar

agentic-ai-lab/
├── .venv/                    ← virtualenv (no versionado)
├── .env                      ← NUEVO (no versionado, contiene GROQ_API_KEY)
├── .gitignore                ← NUEVO
└── call_llm.py               ← NUEVO (parametrizado en el Paso 4)

Checklist:

  • Tienes una API key de Groq válida exportada en GROQ_API_KEY.
  • python call_llm.py imprime una respuesta del modelo y el desglose de tokens.
  • El .env no está en git status.
  • Entiendes por qué el SDK openai puede hablar con Groq (dialecto OpenAI-compatible).

¿Qué viene en el Lab 2?

Ya sabes llamar al modelo. Ahora viene la pregunta que separa “un script que llama una API” de “un agente”: ¿cómo le doy a este modelo un rol, un objetivo y una identidad estable? En el Lab 2 vas a construir tu primer “pseudo-agente” sin frameworks: una clase Python con instrucciones fijas, un objetivo declarado y un método que recibe tareas. Vas a entender que un agente no es magia: es código + instrucciones + modelo + objetivo.


Referencias

Documentación oficial

Specs y estándares

Lecturas recomendadas

  • Free LLM API resources: catálogo mantenido de proveedores con free tier o crédito de prueba; útil para Lab 5 cuando comparemos proveedores.

Repositorios y librerías

  • openai-python: SDK oficial de OpenAI usado en este lab para hablar con Groq.
  • python-dotenv: carga variables de entorno desde un archivo .env.