Gestión del historial
El entorno de ejecución mantiene el historial de conversación de cada sesión de agente y envía al modelo un historial de trabajo orientado al proveedor. Dos límites complementarios operan sobre representaciones distintas:
- El recorte según el presupuesto de tokens actúa sobre el historial de trabajo de
ChatMessagedestinado al proveedor y descarta los turnos completos más antiguos hasta que el contexto estimado se ajuste al presupuesto de tokens. - Retención de turnos completos aplica el límite de historial configurado en el perfil de ejecución al
Agent::historyestructurado (ConversationMessage) y al historialChatMessageorientado al proveedor que usa el bucle de agente heredado.
Ambos límites conservan los turnos de forma atómica. Un turno comienza con un mensaje real del usuario e incluye la respuesta del asistente y cualquier llamada a herramientas y resultado de herramientas antes del siguiente mensaje del usuario. Por lo tanto, al recortar no se separa una llamada a herramienta de su resultado. Un mensaje del usuario cuyo texto comienza casualmente con [Tool results] se trata como parte del turno anterior, no como un nuevo turno.
Retención de turno completo
history_trim::trim_to_recent_turns aplica el presupuesto de tokens. history_trim::trim_to_recent_turn_count y history_trim::trim_conversation_to_recent_turns aplican el límite de turnos configurado para las dos representaciones del historial. Cada una conserva el turno completo más reciente incluso cuando el valor configurado es 0. Esto es intencional: conservar un turno actual completo es más seguro que descartar sus mensajes más recientes o romper un intercambio de herramientas.
Se conservan los mensajes del sistema iniciales. Cuando no se necesita ningún recorte, el orden y la estructura de los mensajes se mantienen sin cambios.
Presupuesto de tokens
El presupuesto de tokens proviene de ResolvedRuntime::effective_context_budget():
- Los perfiles existentes conservan el presupuesto histórico de 32.000 tokens cuando no se establece ni
max_context_tokensnicontext_compact_ratio, limitado por la capacidad configurada del modelo seleccionado cuando esta es menor. max_context_tokenssigue siendo un presupuesto absoluto. Un valor explícito de0desactiva el recorte proactivo basado en el presupuesto de tokens.- Establecer
context_compact_ratioactiva un presupuesto relativo al modelo: elcontext_windowdel alias/modelo del proveedor seleccionado (o un valor de respaldo de 32,000 cuando se desconoce su capacidad) multiplicado por el ratio. Los valores fuera de(0.0, 1.0]se tratan como no establecidos. Cuando ambos ajustes están presentes,max_context_tokenses un límite superior descendente sobre el presupuesto derivado del ratio. - Cuando
history_pruning.enabledestá activado yhistory_pruning.max_tokenstiene un valor positivo, ese valor reduce el presupuesto (nunca lo aumenta), lo que permite a los operadores recortar el historial antes. - Cada presupuesto efectivo positivo está limitado por la capacidad configurada del modelo seleccionado. El valor de 32.000 de reserva es un stub de compatibilidad, no la verdad del modelo: cuando el perfil del proveedor no declara
context_windowy el perfil de ejecución establece unmax_context_tokenspositivo, ese presupuesto se respeta y además se convierte en el operando de ventana (de modo que un ratio se aplica sobre él), en lugar de reducirse a 32.000. El valor cero explícito como centinela sigue siendo cero y continúa desactivando el recorte proactivo.
El presupuesto efectivo es un objetivo de recorte proactivo, no un límite estricto de la solicitud. Tras descartar todos los turnos antiguos elegibles, el runtime conserva el turno completo más reciente aunque siga por encima de ese objetivo. Envía la solicitud cuando los mensajes preparados, las imágenes, los hooks y los esquemas de herramientas caben en la ventana de contexto del modelo resuelta. Una solicitud que aún excede esa capacidad falla antes del envío al proveedor; aumentar únicamente el objetivo proactivo no puede hacer que quepa. Esta comprobación de capacidad también se aplica cuando el recorte proactivo está deshabilitado (max_context_tokens = 0) y a la solicitud de resumen final tras alcanzar el límite de iteraciones de herramientas.
La capacidad y el presupuesto se resuelven juntos para la ruta de proveedor/modelo activa. Las sugerencias del clasificador y los cambios explícitos de sesión usan la misma selección de ruta que el despacho al proveedor, de modo que la siguiente llamada al modelo, el recorte proactivo, el diagnóstico de desbordamiento, la atribución de costos y el medidor de contexto del cliente usan el proveedor/modelo seleccionado y su par resuelto. Si el modelo seleccionado no coincide con el modelo configurado en el perfil de ese proveedor, la capacidad se considera desconocida en lugar de tomar prestados los metadatos del perfil para un modelo diferente. El valor de compatibilidad interno de 32.000 sigue disponible para los cálculos de seguridad, pero los clientes de protocolo no reciben ningún valor de model_context_window para una capacidad desconocida.
Los recuentos de tokens se estiman mediante history::estimate_history_tokens: aproximadamente cuatro caracteres por token más cuatro tokens de encuadre por mensaje. Se trata de una heurística, no de un tokenizador del proveedor. Los marcadores [IMAGE:...] cargables tienen un coste fijo por imagen solo en los mensajes cuyas imágenes se envían: los turnos del usuario y los resultados de herramientas del turno actual del usuario. Las imágenes de un resultado de herramienta son los adjuntos que declaró la herramienta, no el texto del marcador en su salida. Los resultados de herramientas anteriores se valoran por los bytes de su mensaje, y el texto del sistema y del asistente se valora como texto.
El recorte proactivo del presupuesto de tokens se ejecuta antes de la primera llamada al proveedor de un turno cuando el historial ya supera el presupuesto efectivo, y en los límites de llamada al proveedor entre las iteraciones del bucle de herramientas. Si un proveedor informa de un desbordamiento de la ventana de contexto, la ruta de recuperación reactiva existente vuelve a intentarlo tras recortar el historial a dos tercios de su tamaño estimado actual. No deriva un nuevo objetivo de recuperación a partir de la capacidad del modelo. Ambas rutas conservan turnos completos, por lo que ninguna divide un intercambio de herramientas.
Límite de turno completo
max_history_messages es el nombre heredado del ajuste de historial en el perfil de ejecución de un agente. En los agentes estructurados y en el bucle de agente heredado, su unidad es un turno completo del usuario y no una fila de mensaje individual. Las llamadas a herramientas y sus resultados permanecen dentro del turno que los contiene y no consumen espacios independientes.
El valor predeterminado es 50 turnos. Un valor configurado explícitamente es determinante, incluido 0; el turno completo más reciente se sigue conservando. El nombre del campo se mantiene por compatibilidad con el esquema y podrá cambiarse en una versión futura del esquema.
Las cachés del remitente de canales siguen siendo una excepción aparte: cuentan filas de mensajes individuales y conservan su comportamiento existente de 0-equivale-al-valor-predeterminado.
Recorte visible
Cada vez que el recorte por presupuesto de tokens o el límite de turno completo descarta turnos anteriores, el entorno de ejecución:
- Inserta una nota de contexto antes del primer turno conservado para que el modelo sepa que se omitió contexto anterior.
- Emite
HistoryTrimmedcon el número de mensajes descartados, los turnos conservados y un motivo que identifica el presupuesto de tokens o el límite de turnos.
El evento se expone a través del transporte del cliente activo y a través de la ruta del observador utilizada por los paneles de control y los suscriptores de eventos. El recorte, por lo tanto, no es exclusivo del registro y no es silencioso ni para el modelo ni para los clientes conectados.
La ruta heredada agent::run en loop_.rs informa del recorte basado en recuento solo a través de los registros, sin el breadcrumb ni el evento HistoryTrimmed. Esta ruta sirve tanto para el uso interactivo como para los llamadores de ejecución única y no interactivos de daemon, cron, subagente y SOP.
Seguridad de emparejamiento
La retención de turno completo es la garantía principal de emparejamiento de herramientas: una llamada a herramienta y su resultado pertenecen al mismo turno y se retienen o descartan juntos. El barrido de huérfanos sigue siendo una red de seguridad final para historiales que ya eran inconsistentes, como sesiones restauradas o modificadas externamente.
Los límites de longitud de los resultados de herramientas son independientes. max_tool_result_chars acota un resultado individual cuando se registra; no recorta el historial de la conversación. La aplicación del contexto del lado del proveedor también es independiente, aunque un desbordamiento del proveedor puede desencadenar el recorte reactivo del presupuesto de tokens del entorno de ejecución.