Saltar al contenido principal
Principiante IACódigoTutorial

Error 'Context Length Exceeded' en OpenAI y Claude: Cómo Solucionarlo

¿'Maximum context length exceeded' al llamar a la API de OpenAI o Claude? Causas, límites por modelo y 4 técnicas para solucionarlo: chunking, RAG, resumen y sliding window.

Fran Cobos 8 min de lectura 1401 palabras

Tabla de contenidos

Tu aplicación funcionaba perfectamente hasta que un usuario envió un documento largo:

Error: This model's maximum context length is 128000 tokens.
However, your messages resulted in 143892 tokens.
Please reduce the length of the messages.

El modelo no puede procesar más tokens de los que le caben. Y no, no basta con “cortar el texto” — perderías información crítica. En este artículo te doy 4 técnicas profesionales para manejar este error sin perder calidad.

Límites de contexto por modelo (2026)

ModeloContexto máximoOutput máximoCoste input/1M tokens
GPT-4.11.047.57632.768$2.00
GPT-4.1 mini1.047.57632.768$0.40
GPT-4.1 nano1.047.57632.768$0.10
Claude Opus 4200.00032.000$15.00
Claude Sonnet 4200.00016.000$3.00
Gemini 2.5 Pro1.048.57665.536$1.25 - $2.50
Llama 4 Scout10.000.00016.384Gratis (local)
DeepSeek V3131.07216.384$0.27

Nota: que un modelo acepte 1M de tokens no significa que debas enviarlos. Más contexto = más coste y peor calidad de respuesta (la IA se “pierde” en textos largos).

¿Por qué ocurre? Las 3 causas

1. Documento demasiado grande

Intentas enviar un archivo completo como contexto:

// ❌ Esto rompe si el archivo tiene más de ~500KB
const doc = fs.readFileSync('manual-completo.txt', 'utf-8');
await openai.chat.completions.create({
  model: 'gpt-4.1-mini',
  messages: [{ role: 'user', content: `Resume esto:\n${doc}` }]
});
// 💥 context length exceeded

2. Historial de conversación acumulado

Cada mensaje del chat se envía como contexto. Después de 50+ mensajes, el historial supera el límite:

// ❌ El historial crece sin control
messages.push({ role: 'user', content: nuevoMensaje });
messages.push({ role: 'assistant', content: respuestaIA });
// Tras 100 mensajes → 💥

3. System prompt demasiado largo

Un system prompt con instrucciones detalladas + ejemplos puede ocupar miles de tokens:

// ❌ System prompt de 10.000 tokens
const systemPrompt = `Eres un asistente experto en...
[200 líneas de instrucciones, ejemplos, formato de salida, reglas...]`;

Técnica 1: Chunking inteligente

Divide el documento en fragmentos que quepan en el contexto. La clave es cortar en puntos lógicos (párrafos, secciones) y no a mitad de frase.

/**
 * Divide un texto en chunks respetando párrafos.
 * @param text - El texto completo
 * @param maxTokens - Tokens máx. por chunk (dejar margen para prompt)
 * @param overlap - Tokens de solapamiento entre chunks
 */
function chunkText(text, maxTokens = 3000, overlap = 200) {
  const paragraphs = text.split(/\n\n+/);
  const chunks = [];
  let currentChunk = '';
  let currentTokens = 0;

  for (const paragraph of paragraphs) {
    const paragraphTokens = Math.ceil(paragraph.length / 3); // estimación español

    if (currentTokens + paragraphTokens > maxTokens && currentChunk) {
      chunks.push(currentChunk.trim());
      // Solapamiento: mantener últimos N caracteres
      const overlapText = currentChunk.slice(-(overlap * 3));
      currentChunk = overlapText + '\n\n' + paragraph;
      currentTokens = Math.ceil(currentChunk.length / 3);
    } else {
      currentChunk += (currentChunk ? '\n\n' : '') + paragraph;
      currentTokens += paragraphTokens;
    }
  }

  if (currentChunk.trim()) chunks.push(currentChunk.trim());
  return chunks;
}

// Uso: procesar un documento grande chunk a chunk
const chunks = chunkText(documentoGrande, 4000);
const resultados = [];

for (const chunk of chunks) {
  const response = await openai.chat.completions.create({
    model: 'gpt-4.1-mini',
    messages: [
      { role: 'system', content: 'Extrae los puntos clave de este fragmento.' },
      { role: 'user', content: chunk }
    ]
  });
  resultados.push(response.choices[0].message.content);
}

// Síntesis final
const resumenFinal = await openai.chat.completions.create({
  model: 'gpt-4.1-mini',
  messages: [
    { role: 'system', content: 'Combina estos resúmenes parciales en uno coherente.' },
    { role: 'user', content: resultados.join('\n---\n') }
  ]
});

Técnica 2: RAG (Retrieval-Augmented Generation)

En vez de enviar todo el documento, busca solo los fragmentos relevantes para la pregunta. Es la técnica más eficiente para documentos grandes.

import { ChromaClient } from 'chromadb';
import OpenAI from 'openai';

const chroma = new ChromaClient();
const openai = new OpenAI();

// 1. Indexar documento (una sola vez)
const collection = await chroma.getOrCreateCollection({ name: 'docs' });
const chunks = chunkText(documento, 500);  // chunks pequeños para búsqueda

await collection.add({
  ids: chunks.map((_, i) => `chunk-${i}`),
  documents: chunks,
});

// 2. Buscar solo lo relevante
async function askWithRAG(question) {
  const results = await collection.query({
    queryTexts: [question],
    nResults: 5,  // solo los 5 chunks más relevantes
  });

  const context = results.documents[0].join('\n\n');

  return openai.chat.completions.create({
    model: 'gpt-4.1-mini',
    messages: [
      { role: 'system', content: 'Responde basándote SOLO en el contexto proporcionado.' },
      { role: 'user', content: `Contexto:\n${context}\n\nPregunta: ${question}` }
    ]
  });
}

Para un tutorial completo de RAG con ChromaDB, revisa cómo crear un chatbot RAG con OpenAI desde cero. Si quieres ir un paso más allá y crear un agente que use RAG como herramienta, mira el tutorial de agentes de IA con LangChain.

Técnica 3: Sliding Window para chat

Para conversaciones largas, mantén solo los últimos N mensajes + un resumen de los anteriores:

const MAX_MESSAGES = 20;

async function manageChatHistory(messages) {
  if (messages.length <= MAX_MESSAGES) return messages;

  // Resumir los mensajes antiguos
  const oldMessages = messages.slice(0, -MAX_MESSAGES);
  const recentMessages = messages.slice(-MAX_MESSAGES);

  const summary = await openai.chat.completions.create({
    model: 'gpt-4.1-nano', // modelo barato para resumen
    messages: [
      {
        role: 'system',
        content: 'Resume esta conversación en 3-5 puntos clave. Mantén datos concretos.'
      },
      ...oldMessages
    ]
  });

  return [
    {
      role: 'system',
      content: `Resumen de la conversación anterior:\n${summary.choices[0].message.content}`
    },
    ...recentMessages
  ];
}

Técnica 4: Contar tokens antes de enviar

Prevén el error comprobando el tamaño antes de la llamada:

import { encoding_for_model } from 'tiktoken';

const encoder = encoding_for_model('gpt-4.1');

function countTokens(messages) {
  let total = 0;
  for (const msg of messages) {
    total += 4; // overhead por mensaje
    total += encoder.encode(msg.content).length;
  }
  total += 2; // overhead final
  return total;
}

async function safeChatCompletion(messages, maxOutputTokens = 4096) {
  const inputTokens = countTokens(messages);
  const modelLimit = 1_047_576; // gpt-4.1

  if (inputTokens + maxOutputTokens > modelLimit) {
    console.warn(`⚠️ ${inputTokens} tokens de input + ${maxOutputTokens} output = ${inputTokens + maxOutputTokens} (límite: ${modelLimit})`);
    // Aplicar sliding window o truncar
    messages = await manageChatHistory(messages);
  }

  return openai.chat.completions.create({
    model: 'gpt-4.1',
    messages,
    max_tokens: maxOutputTokens,
  });
}

Si combinado con este error estás viendo errores 429, es probable que estés enviando demasiadas peticiones con contextos grandes. Revisa la guía de Error 429 Too Many Requests en APIs de IA para implementar rate limiting.

Cuándo usar cada técnica

EscenarioTécnicaPor qué
Documento de 1 uso (resumir, analizar)ChunkingSimple, no necesita base de datos
Base de conocimiento + preguntasRAGSolo envía lo relevante
Chat conversacional largoSliding WindowMantiene contexto reciente
Prevención en cualquier casoConteo de tokensEvita errores antes de que ocurran
Documento + necesitas JSON exactoChunking + RAGCombina con parseo JSON robusto

Error relacionado: respuesta truncada

A veces el modelo cabe en el contexto pero la respuesta se corta por max_tokens:

const response = await openai.chat.completions.create({ /* ... */ });

if (response.choices[0].finish_reason === 'length') {
  // ⚠️ La respuesta se cortó — pedir continuación o aumentar max_tokens
  console.warn('Respuesta truncada. Aumentando max_tokens...');
}

Esto es especialmente problemático si pides respuestas en JSON — un JSON truncado es JSON inválido. Consulta las técnicas para parsear JSON de IA sin errores para manejar este caso.

Optimizar costes con contextos grandes

Enviar muchos tokens no solo genera errores — es caro. Algunas tácticas:

  1. Usa modelos con context window grande y barato: GPT-4.1 nano (1M tokens, $0.10/M)
  2. Cachea respuestas: si el mismo documento se consulta varias veces, guarda el resultado
  3. Preprocesa: extrae solo texto relevante antes de enviar (quita HTML, headers, footers)

Si quieres probar estas técnicas sin coste, revisa las APIs de IA gratuitas disponibles. Para ejecutar modelos con contexto ilimitado en local, Ollama es la mejor opción.

Conclusión

El error de “context length exceeded” no es un callejón sin salida — es una señal de que necesitas una estrategia de gestión de contexto:

  1. Chunking para documentos de un solo uso
  2. RAG para bases de conocimiento con múltiples consultas
  3. Sliding Window para chats largos
  4. Conteo preventivo como red de seguridad

La técnica más robusta para producción es RAG: envías solo lo relevante, reduces costes y mejoras la calidad de las respuestas.

Fran Cobos

Fran Cobos

Desarrollador Full Stack especializado en IA aplicada, automatización y desarrollo web. Escribo sobre herramientas, tutoriales y casos reales para programadores.

¿Necesitas desarrollo a medida?

Apps web, IA, módulos ERP — cuéntame tu proyecto.