API de OpenAI - Guía Completa
Versión: Listo para producción ✅ Paquete: [email protected] Última actualización: 2025-11-26
Estado
✅ Listo para producción:
- ✅ API de Chat Completions (GPT-5, GPT-4o, GPT-4 Turbo)
- ✅ API de Embeddings (text-embedding-3-small, text-embedding-3-large)
- ✅ API de Imágenes (generación DALL-E 3 + edición GPT-Image-1)
- ✅ API de Audio (transcripción Whisper + TTS con 11 voces)
- ✅ API de Moderación (11 categorías de seguridad)
- ✅ Patrones de streaming (SSE)
- ✅ Llamadas a funciones / Herramientas
- ✅ Salidas estructuradas (esquemas JSON)
- ✅ Visión (GPT-4o)
- ✅ Enfoques con SDK de Node.js y fetch
Tabla de Contenidos
- Inicio Rápido
- API de Chat Completions
- Modelos de la Serie GPT-5
- Patrones de Streaming
- Llamadas a Funciones
- Salidas Estructuradas
- Visión (GPT-4o)
- API de Embeddings
- API de Imágenes
- API de Audio
- API de Moderación
- Manejo de Errores
- Límites de Velocidad
- Mejores Prácticas de Producción
- Relación con openai-responses
Inicio Rápido
Instalación
npm install [email protected]
Configuración del Entorno
export OPENAI_API_KEY="sk-..."
O crea un archivo .env:
OPENAI_API_KEY=sk-...
Primer Chat Completion (SDK de Node.js)
import OpenAI from 'openai';
const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
});
const completion = await openai.chat.completions.create({
model: 'gpt-5',
messages: [
{ role: 'user', content: '¿Cuáles son las tres leyes de la robótica?' }
],
});
console.log(completion.choices[0].message.content);
Primer Chat Completion (Fetch - Cloudflare Workers)
const response = await fetch('https://api.openai.com/v1/chat/completions', {
method: 'POST',
headers: {
'Authorization': `Bearer ${env.OPENAI_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
model: 'gpt-5',
messages: [
{ role: 'user', content: '¿Cuáles son las tres leyes de la robótica?' }
],
}),
});
const data = await response.json();
console.log(data.choices[0].message.content);
API de Chat Completions
Endpoint: POST /v1/chat/completions
La API de Chat Completions es la interfaz principal para interactuar con los modelos de lenguaje de OpenAI. Admite IA conversacional, generación de texto, llamadas a funciones, salidas estructuradas y capacidades de visión.
Modelos Compatibles
Serie GPT-5 (Lanzada en agosto de 2025)
- gpt-5: Modelo de razonamiento con todas las funciones y capacidades avanzadas
- gpt-5-mini: Alternativa rentable con buen rendimiento
- gpt-5-nano: Variante más pequeña/rápida para tareas simples
Serie GPT-4o
- gpt-4o: Modelo multimodal con capacidades de visión
- gpt-4-turbo: Variante rápida de GPT-4
Serie GPT-4
- gpt-4: Modelo GPT-4 original
Estructura Básica de la Solicitud
{
model: string, // Modelo a usar (ej., "gpt-5")
messages: Message[], // Historial de la conversación
reasoning_effort?: string, // Solo GPT-5: "minimal" | "low" | "medium" | "high"
verbosity?: string, // Solo GPT-5: "low" | "medium" | "high"
temperature?: number, // NO compatible con GPT-5
max_tokens?: number, // Máximo de tokens a generar
stream?: boolean, // Habilitar streaming
tools?: Tool[], // Herramientas de llamada a funciones
}
Estructura de la Respuesta
{
id: string, // ID único de finalización
object: "chat.completion",
created: number, // Marca de tiempo Unix
model: string, // Modelo utilizado
choices: [{
index: number,
message: {
role: "assistant",
content: string, // Texto generado
tool_calls?: ToolCall[] // Si se llama a funciones
},
finish_reason: string // "stop" | "length" | "tool_calls"
}],
usage: {
prompt_tokens: number,
completion_tokens: number,
total_tokens: number
}
}
Roles de Mensaje y Conversaciones Multiturno
Tres roles: system (comportamiento), user (entrada), assistant (respuestas del modelo).
Importante: La API es sin estado: envía el historial completo de la conversación en cada solicitud. Para conversaciones con estado, usa el skill openai-responses.
Modelos de la Serie GPT-5
Los modelos GPT-5 (lanzados en agosto de 2025) introducen controles de razonamiento y verbosidad:
GPT-5.1 (Lanzado el 13 de noviembre de 2025)
Modelo más reciente con mejoras importantes:
- gpt-5.1: Razonamiento adaptativo que varía dinámicamente el tiempo de pensamiento
- Caching de prompts extendido de 24 horas: Consultas de seguimiento más rápidas a menor costo
- Nuevas herramientas para desarrolladores: apply_patch (edición de código), shell (ejecución de comandos)
CAMBIO IMPORTANTE: GPT-5.1 tiene como valor predeterminado reasoning_effort: 'none' (mientras que GPT-5 tiene como valor predeterminado 'medium'). ¡Actualiza tu código al migrar!
Parámetro reasoning_effort
Controla la profundidad del pensamiento (disponible en GPT-5 y GPT-5.1):
- "none": Sin razonamiento (más rápido, menor latencia) - valor predeterminado de GPT-5.1
- "minimal": Respuestas rápidas, pensamiento mínimo
- "low": Razonamiento básico
- "medium": Razonamiento equilibrado - valor predeterminado de GPT-5
- "high": Razonamiento profundo para problemas complejos
// GPT-5.1 sin razonamiento (rápido)
const completion = await openai.chat.completions.create({
model: 'gpt-5.1',
messages: [{ role: 'user', content: 'Consulta simple' }],
// reasoning_effort: 'none' es el valor implícito para GPT-5.1
});
// GPT-5.1 con razonamiento alto (tareas complejas)
const completion = await openai.chat.completions.create({
model: 'gpt-5.1',
messages: [{ role: 'user', content: 'Resuelve este problema matemático complejo...' }],
reasoning_effort: 'high',
});
Parámetro verbosity
Controla el detalle de la salida (GPT-5/GPT-5.1):
- "low": Conciso
- "medium": Equilibrado (predeterminado)
- "high": Detallado
Limitaciones de GPT-5
NO Compatible:
- ❌ Parámetros
temperature,top_p,logprobs - ❌ Cadena de pensamiento con estado entre turnos
Alternativas: Usa GPT-4o para temperature/top_p, o el skill openai-responses para razonamiento con estado
Patrones de Streaming
Habilita con stream: true para la entrega token por token.
SDK de Node.js
const stream = await openai.chat.completions.create({
model: 'gpt-5.1',
messages: [{ role: 'user', content: 'Escribe un poema' }],
stream: true,
});
for await (const chunk of stream) {
const content = chunk.choices[0]?.delta?.content || '';
process.stdout.write(content);
}
Fetch (Cloudflare Workers)
const response = await fetch('https://api.openai.com/v1/chat/completions', {
method: 'POST',
headers: {
'Authorization': `Bearer ${env.OPENAI_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
model: 'gpt-5.1',
messages: [{ role: 'user', content: 'Escribe un poema' }],
stream: true,
}),
});
const reader = response.body?.getReader();
const decoder = new TextDecoder();
while (true) {
const { done, value } = await reader!.read();
if (done) break;
const chunk = decoder.decode(value);
const lines = chunk.split('\n').filter(line => line.trim() !== '');
for (const line of lines) {
if (line.startsWith('data: ')) {
const data = line.slice(6);
if (data === '[DONE]') break;
try {
const json = JSON.parse(data);
const content = json.choices[0]?.delta?.content || '';
console.log(content);
} catch (e) {
// Ignorar JSON no válido
}
}
}
}
Formato de eventos enviados por el servidor (SSE):
data: {"id":"chatcmpl-xyz","choices":[{"delta":{"content":"Hola"}}]}
data: [DONE]
Puntos Clave: Maneja fragmentos incompletos, la señal [DONE] y JSON no válido de forma elegante.
Llamadas a Funciones
Define herramientas con esquema JSON, el modelo las invoca según el contexto.
Definición y Solicitud de Herramientas
const tools = [{
type: 'function',
function: {
name: 'get_weather',
description: 'Obtener el clima actual de una ubicación',
parameters: {
type: 'object',
properties: {
location: { type: 'string', description: 'Nombre de la ciudad' },
unit: { type: 'string', enum: ['celsius', 'fahrenheit'] }
},
required: ['location']
}
}
}];
const completion = await openai.chat.completions.create({
model: 'gpt-5.1',
messages: [{ role: 'user', content: '¿Cómo está el clima en SF?' }],
tools: tools,
});
Manejar Llamadas a Herramientas
const message = completion.choices[0].message;
if (message.tool_calls) {
for (const toolCall of message.tool_calls) {
const args = JSON.parse(toolCall.function.arguments);
const result = await executeFunction(toolCall.function.name, args);
// Enviar resultado de vuelta al modelo
await openai.chat.completions.create({
model: 'gpt-5.1',
messages: [
...messages,
message,
{
role: 'tool',
tool_call_id: toolCall.id,
content: JSON.stringify(result)
}
],
tools: tools,
});
}
}
Patrón de bucle: Continúa llamando a la API hasta que no haya tool_calls en la respuesta.
Salidas Estructuradas
Las salidas estructuradas te permiten aplicar la validación de esquemas JSON en las respuestas del modelo.
Usando Esquema JSON
const completion = await openai.chat.completions.create({
model: 'gpt-4o', // Nota: Las salidas estructuradas son mejor compatibles con GPT-4o
messages: [
{ role: 'user', content: 'Genera un perfil de persona' }
],
response_format: {
type: 'json_schema',
json_schema: {
name: 'person_profile',
strict: true,
schema: {
type: 'object',
properties: {
name: { type: 'string' },
age: { type: 'number' },
skills: {
type: 'array',
items: { type: 'string' }
}
},
required: ['name', 'age', 'skills'],
additionalProperties: false
}
}
}
});
const person = JSON.parse(completion.choices[0].message.content);
// { name: "Alicia", age: 28, skills: ["TypeScript", "React"] }
Modo JSON (Simple)
Para casos de uso más simples sin validación estricta de esquemas:
const completion = await openai.chat.completions.create({
model: 'gpt-5',
messages: [
{ role: 'user', content: 'Enumera 3 lenguajes de programación como JSON' }
],
response_format: { type: 'json_object' }
});
const data = JSON.parse(completion.choices[0].message.content);
Importante: Al usar response_format, incluye "JSON" en tu prompt para guiar al modelo.
Visión (GPT-4o)
GPT-4o admite la comprensión de imágenes junto con texto.
Imagen a través de URL
const completion = await openai.chat.completions.create({
model: 'gpt-4o',
messages: [
{
role: 'user',
content: [
{ type: 'text', text: '¿Qué hay en esta imagen?' },
{
type: 'image_url',
image_url: {
url: 'https://example.com/image.jpg'
}
}
]
}
]
});
Imagen a través de Base64
import fs from 'fs';
const imageBuffer = fs.readFileSync('./image.jpg');
const base64Image = imageBuffer.toString('base64');
const completion = await openai.chat.completions.create({
model: 'gpt-4o',
messages: [
{
role: 'user',
content: [
{ type: 'text', text: 'Describe esta imagen en detalle' },
{
type: 'image_url',
image_url: {
url: `data:image/jpeg;base64,${base64Image}`
}
}
]
}
]
});
Múltiples Imágenes
const completion = await openai.chat.completions.create({
model: 'gpt-4o',
messages: [
{
role: 'user',
content: [
{ type: 'text', text: 'Compara estas dos imágenes' },
{ type: 'image_url', image_url: { url: 'https://example.com/image1.jpg' } },
{ type: 'image_url', image_url: { url: 'https://example.com/image2.jpg' } }
]
}
]
});
API de Embeddings
Endpoint: POST /v1/embeddings
Convierte texto en vectores para búsqueda semántica y RAG.
Modelos
- text-embedding-3-large: 3072 dims (personalizable: 256-3072), máxima calidad
- text-embedding-3-small: 1536 dims (personalizable: 256-1536), rentable, recomendado
Solicitud Básica
const embedding = await openai.embeddings.create({
model: 'text-embedding-3-small',
input: 'La comida estaba deliciosa.',
});
// Devuelve: { data: [{ embedding: [0.002, -0.009, ...] }] }
Dimensiones Personalizadas (Específico de OpenAI)
const embedding = await openai.embeddings.create({
model: 'text-embedding-3-small',
input: 'Texto de ejemplo',
dimensions: 256, // Reducido de 1536 predeterminado
});
Beneficios: Reducción de almacenamiento de 4x a 12x, búsqueda más rápida, pérdida mínima de calidad.
Procesamiento por Lotes
const embeddings = await openai.embeddings.create({
model: 'text-embedding-3-small',
input: ['Primer doc', 'Segundo doc', 'Tercer doc'],
});
Límites: 8192 tokens/entrada, 300k tokens totales por lote, tamaño máximo de matriz 2048.
Puntos Clave: Usa dimensiones personalizadas para eficiencia, procesa por lotes hasta 2048 documentos, almacena en caché los embeddings (deterministas).
API de Imágenes
Generación de Imágenes (DALL-E 3)
Endpoint: POST /v1/images/generations
const image = await openai.images.generate({
model: 'dall-e-3',
prompt: 'Un gato siamés blanco con ojos azules impactantes',
size: '1024x1024', // También: 1024x1536, 1536x1024, 1024x1792, 1792x1024
quality: 'standard', // o 'hd'
style: 'vivid', // o 'natural'
});
console.log(image.data[0].url);
console.log(image.data[0].revised_prompt); // DALL-E 3 puede revisar el prompt por seguridad
Especificidades de DALL-E 3:
- Solo admite
n: 1(una imagen por solicitud) - Puede revisar prompts por seguridad/calidad (verifica
revised_prompt) - Las URL caducan en 1 hora (usa
response_format: 'b64_json'para persistencia)