Gestión de Contexto
Avanzado⏱70 min📖5 min de lecturaLección 4 de 10

Gestión de Contexto

Domina las ventanas de contexto, los sistemas de memoria, la generación aumentada por recuperación (RAG), las estrategias de resumen y el manejo eficiente del contexto para agentes de IA.

El Desafío del Contexto

Los agentes de IA enfrentan una restricción fundamental: ventanas de contexto limitadas. Incluso los modelos más grandes (200K+ tokens) no pueden contener a la vez toda una base de código, el historial de la conversación y las instrucciones de la tarea. Una gestión de contexto eficaz marca la diferencia entre un agente capaz y uno que pierde repetidamente el hilo de la información importante.

100%
ℹ️Nota

La gestión de contexto no consiste solo en hacer caber cosas en un presupuesto de tokens. Consiste en tomar decisiones inteligentes sobre qué conservar, qué comprimir, qué recuperar bajo demanda y qué olvidar.


Arquitectura de la Ventana de Contexto

Comprender cómo interactúan los diferentes tipos de contexto dentro de la ventana es crucial para un diseño eficiente de agentes.

100%

Sistemas de Memoria

Los agentes eficaces usan una arquitectura de memoria jerarquizada (en niveles) para gestionar el contexto de forma eficiente:

python
class TieredMemory: def __init__(self): # Ephemeral: current conversation turn self.working_memory = {} # Short-term: recent conversation (sliding window) self.short_term = [] # Long-term: persistent facts across sessions self.long_term = {} # Semantic: indexed knowledge for retrieval self.semantic_store = [] def add_to_working(self, key, value): self.working_memory[key] = value def get_working(self, key): return self.working_memory.get(key) def add_to_short_term(self, message, max_size=20): self.short_term.append(message) if len(self.short_term) > max_size: # Evict oldest messages self.short_term = self.short_term[-max_size:] def remember(self, key, value, importance=1.0): # High importance facts persist longer self.long_term[key] = { "value": value, "importance": importance, "timestamp": __import__('time').time() } def recall(self, key): entry = self.long_term.get(key) if entry: return entry["value"] return None def recall_by_relevance(self, query, top_k=3): # Simple keyword matching for semantic recall scores = [] for key, entry in self.long_term.items(): if query.lower() in key.lower(): scores.append((entry["importance"], key, entry["value"])) scores.sort(reverse=True) return [(k, v) for _, k, v in scores[:top_k]] def store_semantic(self, text, metadata=None): self.semantic_store.append({ "text": text, "metadata": metadata or {}, "timestamp": __import__('time').time() }) def summarize_and_archive(self): """Compress short-term memory into a summary for long-term storage.""" if len(self.short_term) > 10: texts = [m["content"] for m in self.short_term[:5]] summary = " | ".join(texts) self.long_term["conversation_summary"] = { "value": summary[:500], "importance": 0.5, "timestamp": __import__('time').time() } # Keep only recent messages self.short_term = self.short_term[-5:] memory = TieredMemory() # Store project facts long-term memory.remember("project_name", "Nova Platform", importance=1.0) memory.remember("tech_stack", ["Python", "FastAPI", "React", "PostgreSQL"], importance=0.9) memory.remember("deployment_env", "production", importance=0.8) # Add conversation to short-term memory.add_to_short_term({"role": "user", "content": "Fix the login bug"}) memory.add_to_short_term({"role": "assistant", "content": "Found the issue in auth.py"}) # Retrieve relevant facts relevant = memory.recall_by_relevance("deploy") print(f"Deployment context: {relevant}") # Summarize when needed memory.summarize_and_archive()

Generación Aumentada por Recuperación (RAG)

RAG permite a los agentes acceder a grandes bases de conocimiento obteniendo solo la información más relevante en el momento de la consulta.

python
class RAGSystem: def __init__(self): self.documents = [] self.index = {} def add_document(self, doc_id, content, metadata=None): self.documents.append({ "id": doc_id, "content": content, "metadata": metadata or {} }) # Simple keyword indexing for word in content.lower().split(): if word not in self.index: self.index[word] = [] self.index[word].append(len(self.documents) - 1) def search(self, query, top_k=3): query_words = query.lower().split() scores = {} for q_word in query_words: for doc_idx in self.index.get(q_word, []): if doc_idx not in scores: scores[doc_idx] = 0 scores[doc_idx] += 1 # Sort by relevance score ranked = sorted(scores.items(), key=lambda x: x[1], reverse=True) results = [] for doc_idx, score in ranked[:top_k]: doc = self.documents[doc_idx] results.append({ "id": doc["id"], "content": doc["content"][:500], # Truncate for context "relevance": score / len(query_words), "metadata": doc["metadata"] }) return results def build_context_prompt(self, query, max_tokens=2000): results = self.search(query) context_parts = [] token_count = 0 for r in results: snippet = f"[Source: {r['id']}]\n{r['content']}\n" snippet_tokens = len(snippet.split()) if token_count + snippet_tokens > max_tokens: break context_parts.append(snippet) token_count += snippet_tokens return "\n---\n".join(context_parts) # Build a RAG system for an agent rag = RAGSystem() rag.add_document( "auth-flow.md", "The authentication flow uses JWT tokens with 1-hour expiry. " "Refresh tokens are stored in HTTP-only cookies and have 7-day expiry. " "OAuth2 is supported for Google and GitHub providers.", {"type": "documentation", "module": "auth"} ) rag.add_document( "api-endpoints.md", "POST /api/auth/login - Authenticate user\n" "POST /api/auth/refresh - Refresh access token\n" "POST /api/auth/logout - Invalidate session\n" "GET /api/auth/profile - Get user profile", {"type": "api", "module": "auth"} ) rag.add_document( "db-schema.sql", "CREATE TABLE users (id UUID PRIMARY KEY, email VARCHAR UNIQUE, " "password_hash VARCHAR, created_at TIMESTAMP);\n" "CREATE TABLE sessions (id UUID PRIMARY KEY, user_id UUID REFERENCES users(id), " "token VARCHAR, expires_at TIMESTAMP);", {"type": "schema", "module": "database"} ) context = rag.build_context_prompt("How does authentication work?") print(context)
⚠️Advertencia

RAG no es magia. La calidad de la recuperación depende de la calidad de tu estrategia de indexación. La búsqueda por palabras clave simple funciona para bases de código pequeñas, pero los sistemas de producción necesitan búsqueda semántica basada en embeddings. Valida siempre que el recuperador encuentre los documentos correctos para las consultas comunes.


Estrategias de Resumen

Cuando las ventanas de contexto se llenan, el resumen comprime la información mientras preserva los detalles clave.

python
class SummarizationEngine: def __init__(self, llm_client): self.llm = llm_client def summarize_conversation(self, messages): """Summarize a conversation history into key points.""" if len(messages) < 3: return messages # Too short to summarize text = "\n".join( f"{m['role']}: {m['content']}" for m in messages ) prompt = f""" Summarize the following conversation, preserving: 1. All decisions made 2. Key facts discovered 3. Action items or next steps 4. Technical details (file paths, function names, versions) Conversation: {text} Summary: """ return self.llm.complete(prompt) def hierarchical_summary(self, sessions, max_levels=3): """Create a hierarchical summary of multiple sessions.""" summaries = [] for session in sessions: summary = self.summarize_conversation(session) summaries.append(summary) # If we have too many session summaries, summarize those too level = 1 while len(summaries) > 5 and level < max_levels: batch_size = 3 new_summaries = [] for i in range(0, len(summaries), batch_size): batch = summaries[i:i + batch_size] combined = "\n".join(batch) meta_summary = self.llm.complete( f"Summarize these session summaries:\n{combined}" ) new_summaries.append(meta_summary) summaries = new_summaries level += 1 return summaries def token_aware_truncation(self, text, max_tokens=4000): """Truncate text intelligently at token boundaries.""" tokens = text.split() if len(tokens) <= max_tokens: return text # Keep beginning and end, summarize middle keep_start = max_tokens // 3 keep_end = max_tokens // 3 middle_start = text[:keep_start * 10] # Approximate char→token middle_end = text[-keep_end * 10:] return f"{middle_start}\n\n...[{len(tokens) - keep_start - keep_end} tokens omitted]...\n\n{middle_end}"
yaml
# Summarization configuration for an agent summarization: strategy: hierarchical thresholds: short_term: 10 # Summarize when >10 messages session: 50 # Summarize when >50 messages per session total: 200 # Create meta-summary across sessions include_in_summary: - decisions_made - code_changes - error_patterns - user_preferences preserve_fields: - file_paths - function_names - version_numbers - api_endpoints
💡Consejo

Usa el resumen jerárquico para sesiones largas del agente. Resume en tres niveles: (1) turnos individuales de la conversación, (2) resúmenes a nivel de sesión, (3) meta-resúmenes entre sesiones. Esto preserva la información crítica mientras se mantiene un contexto compacto.


Priorización del Contexto

No todo el contexto es igual de importante. Los agentes deben priorizar qué entra en la ventana de contexto limitada.

python
class ContextPrioritizer: def __init__(self, max_tokens=128000): self.max_tokens = max_tokens self.priority_levels = { "critical": 5, "high": 4, "medium": 3, "low": 2, "background": 1 } def prioritize(self, context_items): """Sort and filter context items by priority, fit within token budget.""" # Assign priority scores scored = [] for item in context_items: score = self._calculate_priority(item) tokens = len(item["content"].split()) scored.append((score, tokens, item)) # Sort by priority (descending) scored.sort(key=lambda x: x[0], reverse=True) # Fit within budget result = [] used_tokens = 0 # Always include system prompt and current request for item in context_items: if item["type"] in ("system_prompt", "current_request"): result.append(item) used_tokens += len(item["content"].split()) # Add high priority items remaining = self.max_tokens - used_tokens for score, tokens, item in scored: if item["type"] in ("system_prompt", "current_request"): continue # Already included if used_tokens + tokens <= self.max_tokens: result.append(item) used_tokens += tokens return result def _calculate_priority(self, item): base = self.priority_levels.get(item.get("priority", "medium"), 3) # Boost relevance to current task if item.get("relevance_to_current", 0) > 0.8: base += 1 # Boost recent items if item.get("recency", 0) > 0.9: base += 1 # Penalize very large items tokens = len(item["content"].split()) if tokens > 10000: base -= 1 return max(1, base) prioritizer = ContextPrioritizer(max_tokens=8000) context = [ {"type": "system_prompt", "content": "You are a coding agent...", "priority": "critical"}, {"type": "current_request", "content": "Fix the payment bug", "priority": "critical"}, {"type": "file_content", "content": "def process(): ...", "priority": "high", "relevance_to_current": 0.9}, {"type": "conversation_history", "content": "User: The payment fails...", "priority": "medium", "recency": 1.0}, {"type": "project_readme", "content": "# Project...", "priority": "low"}, ] prioritized = prioritizer.prioritize(context) print(f"Included {len(prioritized)} items in context window")

Límites de la Ventana de Contexto por Modelo

Proveedor del Modelo
Modelo
Ventana de Contexto
Presupuesto Efectivo
OpenAI
GPT-4o
128K tokens
~96K (tras la sobrecarga)
OpenAI
GPT-4o-mini
128K tokens
~96K
Anthropic
Claude Sonnet 4
200K tokens
~170K
Anthropic
Claude Opus 4
200K tokens
~170K
Google
Gemini 1.5 Pro
1M tokens
~800K
Meta
Llama 3.1 70B
128K tokens
~100K
Mistral
Mixtral 8x22B
64K tokens
~48K
ℹ️Nota

El "Presupuesto Efectivo" tiene en cuenta los tokens consumidos por el procesamiento interno del modelo (prompts de sistema, sobrecarga de tokenización, generación de respuestas). Una ventana de 128K normalmente tiene unos 96K tokens disponibles para tu contenido.


Gestión Práctica del Contexto en OpenCode

OpenCode proporciona gestión de contexto integrada mediante su sistema de configuración de agentes:

json
{ "agents": { "default": { "model": "gpt-4o", "description": "General coding agent", "context": { "maxTokens": 128000, "summarizationThreshold": 80000, "memoryStrategy": "tiered", "shortTermLimit": 20, "longTermEnabled": true, "ragEnabled": true, "ragMaxDocs": 5, "prioritizeByRelevance": true } }, "code-reviewer": { "model": "claude-sonnet-4-20250514", "description": "Code review specialist", "context": { "maxTokens": 200000, "summarizationThreshold": 150000, "focusOnCurrentChanges": true, "includeGitDiff": true } } } }
yaml
# context-management-strategy.yaml strategy: name: "tiered-context" layers: working: label: "Working Memory" size: "2-3 turns" content: "Current task, immediate tool results" eviction: "FIFO" short_term: label: "Short-Term Memory" size: "15-20 turns" content: "Recent conversation, recent file reads" eviction: "Summarize and archive" long_term: label: "Long-Term Memory" size: "Unlimited (external)" content: "Project facts, decisions, user preferences" access: "On-demand retrieval" episodic: label: "Episodic Memory" size: "Compressed" content: "Key events, errors encountered, solutions found" access: "Similarity search"

Trampas Comunes en la Gestión de Contexto

Trampa
Síntoma
Solución
Desbordamiento de contexto
El agente pierde el hilo de las instrucciones iniciales
Implementa ventana deslizante + resumen
Contexto obsoleto
El agente referencia información desactualizada
Añade puntuación de recencia en la priorización
Contexto faltante
El agente pide información que ya tiene
Mejora el recuerdo de la memoria a largo plazo
Desperdicio de tokens
El agente incluye contenidos de archivos irrelevantes
Usa RAG con consultas precisas
Explosión de memoria
El contexto crece sin límites
Establece límites duros con disparadores de resumen
Deriva de hechos
El agente se contradice entre sesiones
Usa un almacén de memoria a largo plazo persistente
⚠️Advertencia

El error más costoso es perder información crítica por una mala gestión del contexto. Un agente que olvida el stack tecnológico de tu proyecto o una decisión clave producirá resultados inconsistentes. Valida siempre que tu sistema de memoria preserva los hechos esenciales.


Ejercicios de Práctica

Pregunta de Práctica
Cómo responder

Pregunta de opción múltiple con 4 opciones. Selecciona una opción y elige Comprobar respuesta.

¿Cuál es el propósito principal de una ventana deslizante (sliding window) en la gestión de contexto?

Pregunta de Práctica
Cómo responder

Pregunta de opción múltiple con 4 opciones. Selecciona una opción y elige Comprobar respuesta.

En un sistema de memoria jerarquizado, ¿qué tipo de información debería almacenarse en la memoria a largo plazo?

Pregunta de Práctica
Cómo responder

Pregunta de opción múltiple con 4 opciones. Selecciona una opción y elige Comprobar respuesta.

¿Qué sucede cuando la ventana de contexto de un agente supera el límite de tokens del modelo?

Pregunta de Práctica
Cómo responder

Pregunta de opción múltiple con 4 opciones. Selecciona una opción y elige Comprobar respuesta.

¿Para qué se usa RAG (Generación Aumentada por Recuperación) en la gestión de contexto de un agente?

Pregunta de Práctica
Cómo responder

Pregunta de opción múltiple con 4 opciones. Selecciona una opción y elige Comprobar respuesta.

Un agente tiene un límite de 128K tokens y está usando unos 100K tokens para el historial de la conversación. ¿Qué estrategia debería usar cuando el usuario envía una petición nueva y compleja?

Pregunta de Práctica
Cómo responder

Pregunta de opción múltiple con 4 opciones. Selecciona una opción y elige Comprobar respuesta.

¿Cuál es el 'presupuesto efectivo' de una ventana de contexto de 128K tokens?

Pregunta de Práctica
Cómo responder

Pregunta de opción múltiple con 4 opciones. Selecciona una opción y elige Comprobar respuesta.

¿Cuál es el riesgo principal de usar solo una ventana deslizante sin resumen?

Pregunta de Práctica
Cómo responder

Pregunta de opción múltiple con 4 opciones. Selecciona una opción y elige Comprobar respuesta.

En la priorización de contexto, ¿qué elementos deberían incluirse siempre en la ventana de contexto independientemente del presupuesto de tokens?


✅Conclusiones Clave (Key Takeaways):
  • La gestión de contexto consiste en decisiones inteligentes sobre qué conservar, comprimir, recuperar y olvidar
  • La memoria jerarquizada (de trabajo, a corto plazo, a largo plazo y semántica) proporciona una arquitectura escalable
  • RAG permite acceder a grandes bases de conocimiento sin llenar la ventana de contexto
  • Las estrategias de resumen (lineal, jerárquica y consciente de tokens) comprimen la información de forma eficaz
  • La priorización del contexto asegura que los elementos críticos siempre quepan en el presupuesto de tokens
  • Diferentes modelos tienen diferentes límites de contexto; diseña para el presupuesto efectivo
  • OpenCode proporciona configuración de contexto integrada para los agentes
  • Sin gestión explícita, el desbordamiento de contexto degrada silenciosamente el rendimiento del agente
  • Las trampas comunes incluyen el desbordamiento de contexto, el contexto obsoleto, el contexto faltante y la explosión de memoria
Progreso40%