Skip to content

Compactación de contexto ​

La compactación reemplaza los mensajes antiguos por un checkpoint estructurado generado por el proveedor actual y conserva intactos los turnos recientes. Los mensajes reemplazados permanecen en la base de datos de sesiones marcados como compactados (para auditoría), pero ya no se envían al modelo.

Secciones del checkpoint ​

Al resumidor se le pide JSON validado con zod. El checkpoint tiene estas secciones:

SecciónCampoContenido
GoalgoalLo que la sesión intenta lograr
User instructions/constraintsinstructionsInstrucciones y restricciones indicadas por el usuario
DiscoveriesdiscoveriesHechos aprendidos en el camino
AccomplishedaccomplishedTrabajo ya realizado
Current statecurrentStateSituación actual
Next stepsnextStepsLo que queda pendiente
Relevant filesrelevantFilesArchivos relevantes

Si el resumidor no devuelve JSON válido, su texto se usa tal cual (un checkpoint solo de texto).

Garantías ​

  • Una llamada a herramienta nunca se separa de sus resultados, y los IDs de llamada nunca se alteran.
  • Se conservan keepTurns turnos recientes; si hay menos, se conserva al menos el último. Dentro de un único turno largo, el corte se hace en el último límite seguro entre llamadas.
  • Una sesión con resultados de herramientas inciertos no se compacta hasta recuperarla.
  • La persistencia es transaccional.

Manual y automática ​

  • Manual: /compact [focus] en la TUI, con instrucciones de foco opcionales.
  • Automática: antes de una llamada al modelo, cuando el contexto usado alcanza threshold de una ventana de contexto conocida (provider.contextWindow, el values.contextWindow del perfil activo de /connect, o GET /models). Cuando la ventana es desconocida — o una ventana declarada es absurdamente grande (más de 2_000_000 tokens, para que ventana × threshold no oculte la presión real) — Alisio recurre a limits.maxContextChars: los tokens estimados (≈ caracteres / 4) que alcanzan maxContextChars / 4 también compactan. Independientemente de eso, el presupuesto de caracteres es también un disparador para todos los modelos: cuando la conversación (instrucciones + transcript) alcanza threshold (85 %) de limits.maxContextChars, Alisio compacta, aunque una ventana grande (por ejemplo 1M de tokens) indique que sobra espacio. La regla de la ventana y la de caracteres son alternativas: cualquiera de las dos dispara la compactación. Los criterios de ventana y de reserva miden la petición completa (instrucciones, transcript y el catálogo fijo de herramientas), porque protegen lo que el modelo ve realmente. maxContextChars además sigue siendo el límite duro posterior a la compactación — pero allí cuenta solo el contenido reducible (instrucciones + transcript), nunca el catálogo de herramientas (ver más abajo). Si comprimir no logra dejar la conversación por debajo, la cola conservada se reduce (ver más abajo) y solo una sesión irreducible falla con un error accionable en vez de enviar una petición descomunal. auto: false desactiva la compactación automática por completo.
  • Último recurso: si la conversación sigue por encima de maxContextChars tras el recorte descrito abajo, Alisio ejecuta una compactación automática (motivo "budget") y recorta de nuevo antes de fallar. Se intenta como máximo una vez por turno.

El respaldo por defecto es de 800000 caracteres (≈ 200000 tokens): una suposición para ventanas desconocidas, el mismo presupuesto de ~200k tokens que OpenCode asume para proveedores personalizados, para que los servidores locales que no informan su ventana (por ejemplo llama.cpp) obtengan un presupuesto de unos 200k tokens en lugar de uno de 40k. Una ventana conocida (hasta el límite de confianza de 2M de tokens) siempre la anula, y /settings → Presupuesto de caracteres de contexto permite bajar el respaldo en cualquier momento.

Configuración ​

json
{
  "compaction": { "auto": true, "threshold": 0.85, "keepTurns": 2, "maxOutputTokens": 16000 }
}
CampoPor defectoDescripción
autotrueCompactación automática
threshold0.85Fracción de una ventana de contexto conocida (0.1–0.99)
keepTurns2Turnos recientes conservados sin cambios (0–20)
maxOutputTokens16000Presupuesto de tokens de salida para la llamada del resumidor; independiente de limits.maxOutputTokens

La ventana de contexto proviene de provider.contextWindow, del values.contextWindow del perfil activo de /connect, o de GET /models. El consumo de tokens de la compactación no se descuenta de limits.maxTokens, y las estimaciones antes/después son aproximadas (unos 4 caracteres por token).

Resúmenes truncados ​

El resumidor tiene su propio presupuesto de salida (compaction.maxOutputTokens, por defecto 16000 — mayor que el limits.maxOutputTokens del bucle del agente a propósito, porque un resumen debe caber en todo el historial). Si el presupuesto corta un resumen:

  • Un resumen parcial aprovechable (JSON de checkpoint estructurado o texto plano) se conserva: la compactación termina y compaction_completed incluye "partial": true. El aviso de la TUI marca el checkpoint como parcial y sugiere aumentar compaction.maxOutputTokens.
  • Si el corte no produjo nada aprovechable, la compactación falla con un mensaje accionable que apunta a compaction.maxOutputTokens.

Un checkpoint parcial conserva todo lo que el modelo produjo antes del corte, pero puede omitir contexto posterior; trátelo como un respaldo degradado, no como un resumen completo.

Reducción de una cola conservada descomunal ​

La compactación conserva keepTurns turnos recientes sin cambios. Si esos turnos contienen salidas enormes de herramientas (por ejemplo grep sobre un repositorio grande), ni siquiera un checkpoint perfecto logra dejar el contenido reducible de la sesión por debajo de limits.maxContextChars, y la sesión solía morir en cada prompt. En su lugar, tras una compactación el runner ahora comprueba el límite duro y, si sigue superado, reduce los mensajes conservados en su sitio antes de enviar nada:

  • La reducción apunta a un presupuesto total de caracteres para el transcript: objetivo = max(4 000, limits.maxContextChars − instrucciones), de modo que también cubre sesiones con muchos resultados MEDIOS de herramientas (por ejemplo salidas MCP de unos pocos miles de caracteres cada una) que individualmente quedan bajo los límites por mensaje pero juntos superan el límite.
  • El contenido se recorta de forma iterativa, primero el más grande, en rondas de límites descendentes: resultados de herramientas a 8 000 → 4 096 → 2 048 → 1 024 → 512 caracteres, textos de usuario/asistente a 16 000 → 8 192 → 4 096 → 2 048 → 1 024. Cada ronda corta primero los mensajes más caros (empates por posición), de modo que el menor número de cambios alcanza el objetivo; el recorrido se detiene en cuanto el transcript cabe, o al llegar a los límites mínimos.
  • Cada corte lleva el marcador explícito … [truncated by context budget]. Solo cambia el contenido de los mensajes: roles, IDs de llamada, orden y fronteras de mensajes quedan idénticos, de modo que el transcript sigue siendo válido y reproducible y una llamada a herramienta nunca se separa de sus resultados. El transcript reducido se persiste (los originales permanecen en la base marcados como compactados, igual que en la propia compactación).
  • El evento context_reduced informa cuántos mensajes se cortaron.
  • Solo una sesión patológica — las instrucciones por sí solas (más el mínimo de 4 000 caracteres) que ya superan el límite, de modo que ni siquiera el suelo de la reducción cabe — falla con un error accionable que nombra el tamaño aproximado de la conversación y sugiere /compact, recortar salidas grandes de herramientas, iniciar una sesión nueva o desactivar con /plugins los servidores MCP innecesarios. El mensaje dice qué hizo la compactación: Context budget exceeded (approximately N characters of conversation; limit L). Automatic compaction ran but could not reduce it enough. (o was skipped because there is no safe boundary to summarize, failed (<error>) o is disabled). Un único turno enorme sin frontera segura todavía puede fallar, ahora con ese mensaje exacto. La reducción igualmente se persiste, así que la sesión sigue funcionando para prompts posteriores.

Los checkpoints (summary: true) están acotados por diseño y este paso nunca los corta.

El catálogo de herramientas no se cuenta ​

El límite duro anterior mide deliberadamente solo el contenido reducible — instrucciones más el transcript. El catálogo serializado de herramientas (toolsText: nombre, esquema y descripción de cada herramienta registrada) es una realidad de despliegue fija: forma parte de cada petición sin importar la historia, de modo que un servidor con decenas de herramientas (por ejemplo un catálogo MCP grande) puede valer por sí solo 100k+ caracteres, y un transcript pequeño ya no cabe bajo el límite una vez que se cuenta el catálogo. Antes de esta distinción, esas sesiones fallaban con el error fatal «Context budget exceeded» incluso con un transcript casi vacío — la falla reportada en subagentes y exploraciones en repositorios con varios servidores MCP.

  • El tamaño del catálogo es una decisión de /plugins, no crecimiento de sesión: desactive allí los servidores MCP innecesarios (/mcps muestra el recuento de herramientas de cada servidor), en lugar de que el runner corrompa un transcript sano para «caber» un catálogo que no puede reducir.
  • La compactación automática sigue midiendo la petición completa (los umbrales de ventana protegen todo lo que el modelo ve, herramientas incluidas); solo el límite duro posterior a la compactación y la reducción del transcript excluyen el catálogo, de modo que el error fatal nunca se dispara por toolsText solo.

Eventos ​

EventoCuándo
compaction_startedComienza la compactación
compaction_completedTerminó; incluye estimaciones before/after, el tamaño del tramo resumido y del checkpoint, informes de plugins y partial: true cuando el resumen se cortó pero se conservó
compaction_skippedNo hay historia suficiente para compactar
context_reducedTras la compactación los mensajes conservados seguían superando maxContextChars y se recortaron hasta un objetivo total de caracteres (messages = cuántos)
compaction_failedFalló la llamada al resumidor (incluido un resumen cortado sin nada aprovechable)
plugin_hook_failedUn hook de plugin falló o agotó su tiempo; la compactación continúa sin él

Con --json los eventos se emiten como JSONL versionado.

Modo Responses ​

En modo Responses, los items opacos de continuación (por ejemplo, el razonamiento cifrado) del tramo resumido se descartan junto con esos mensajes. Los mensajes conservados mantienen los suyos sin cambios.

Hooks de plugins ​

Los plugins pueden ampliar la compactación con compaction.register({ beforeCompact, afterCompact }):

  • beforeCompact añade instrucciones y campos JSON adicionales (outputFields) a la misma llamada al resumidor.
  • afterCompact recibe el checkpoint y los campos extraídos propios del plugin, y puede devolver injectContext (texto añadido tras el checkpoint) y un report (su summary se muestra en la TUI).

Los hooks se ejecutan con el tiempo límite del host pluginHooks.timeoutMs. El plugin de memoria integrado usa estos hooks. Consulte Escribir plugins.

Resultados inciertos de herramientas ​

Si una caída deja una herramienta con un resultado incierto, Alisio no la repite automáticamente. Inspeccione sus efectos y después ejecute:

sh
alisio sessions recover <session> --acknowledge

La recuperación registra la incertidumbre como resultado; no asegura que un efecto externo se haya completado ni deshace cambios.

Released under the MIT License.