Context engineering: por qué tu agent se vuelve más tonto en el turno 40
Mover un dato tres líneas abajo en un prompt que ocupa el 2,6 % de la context window baja la recuperación del 84 % al 19 %. La ventana no era el problema.
En esta página
Aquí tienes un prompt enviado 288 veces al mismo modelo con decodificación greedy. Tiene 853 tokens. Contiene un registro de veinticinco tickets de soporte — ciudad, cola, prioridad, propietario, extensión — y una pregunta: Marta Ferreira necesita que le devuelvan la llamada sobre su ticket. ¿Cuál es la extensión directa de ese ticket?
El registro es idéntico cada vez. El modelo es idéntico cada vez. Lo único que cambia es cuál de las veinticinco líneas contiene la respuesta.
| posición de la respuesta | aciertos | tasa de recuperación | intervalo del 95 % |
|---|---|---|---|
| 1 de 25 | 27/32 | 84 % | 68–93 % |
| 4 de 25 | 6/32 | 19 % | 9–35 % |
| 7 de 25 | 6/32 | 19 % | 9–35 % |
| 10 de 25 | 9/32 | 28 % | 16–45 % |
| 13 de 25 | 8/32 | 25 % | 13–42 % |
| 16 de 25 | 6/32 | 19 % | 9–35 % |
| 19 de 25 | 6/32 | 19 % | 9–35 % |
| 22 de 25 | 3/32 | 9 % | 3–24 % |
| 25 de 25 | 7/32 | 22 % | 11–39 % |
Treinta y dos ensayos por fila, un ticket distinto en cada ensayo, intervalos de Wilson de Capítulo 4, porque diecisiete de veinte no distingue nada de nada.
La primera posición se responde el 84 % de las veces. Todas las demás posiciones se quedan entre el 9 % y el 28 %, y los ocho intervalos se solapan, así que la lectura honesta es primero, y luego todo lo demás. Liu et al. encontraron una U — alto en ambos extremos, bajo en el medio — y el brazo de recencia no aparece con claridad aquí: el 22 % en la última posición cae dentro de la dispersión de las posiciones intermedias. Lo que no cae dentro de nada es la caída de la posición 1 a la posición 4. Tres líneas.
La context window de este modelo es de 32.768 tokens. El prompt usa 853 de ellos, el 2,6 %. Nada se desbordó, nada se truncó, no se alcanzó ningún límite, no apareció ningún aviso. El modelo dejó de encontrar una línea que se le había entregado porque la línea se movió tres posiciones hacia abajo en una lista de veinticinco.
Capítulo 16 puso precio a la context window y terminó advirtiendo que tener un millón de tokens no es usarlos, y apuntó aquí. Esto es aquí.
Mostrar detalles
Lo que este capítulo necesita de los anteriores.
- Capítulo 9 derivó self-attention y su coste . Cada token atiende a todos los demás, así que el número de relaciones por pares crece con el cuadrado de la longitud. Ese hecho se usa más abajo, no se vuelve a derivar.
- Capítulo 16 contó los cinco grupos de tokens facturables y mostró que la factura de una conversación crece cuadráticamente. Este capítulo trata de qué haces al respecto sin romper el agent.
- Capítulo 18 construyó el catálogo de herramientas y midió que veinte herramientas no perjudicaban la selección, pero multiplicaban el prompt por seis. Aquí está su factura.
- Capítulo 19 construyó la recuperación. La recuperación just-in-time de abajo es ese capítulo aplicado al historial propio de un agent; el chunking no se vuelve a explicar.
- Capítulo 23 construyó el harness. Todo en este capítulo es una política que se ejecuta dentro de su bucle, por eso es TypeScript: el artefacto es un servicio de larga vida que mantiene estado, no un cuaderno que mantiene tensores.
Dos trabajos con nombres parecidos
Enlace a la sección: Dos trabajos con nombres parecidosAnthropic trazó la línea en septiembre de 2025 y las dos frases van una al lado de la otra. Prompt engineering es «métodos para escribir y organizar instrucciones para LLM con el fin de obtener resultados óptimos». Context engineering es «el conjunto de estrategias para seleccionar y mantener el conjunto óptimo de tokens (información) durante la inferencia de LLM, incluida toda la demás información que pueda acabar ahí fuera de los prompts».1
La diferencia operativa es cuándo, y por quién. Un prompt lo redacta una vez una persona, y se revisa. Un contexto se monta en cada llamada, mediante código que nadie está mirando, a partir de material que nadie escribió a mano: cuarenta turnos de historial, seis resultados de herramientas, cuatro pasajes recuperados, un perfil de usuario, doce esquemas JSON. Capítulo 15 midió lo que aportan unas instrucciones mejores. Este capítulo trata sobre el otro noventa por ciento de los tokens, que llegan solos.
El mismo documento nombra el recurso que todos gastan: los modelos «tienen un “presupuesto de attention” del que tiran al analizar grandes volúmenes de contexto. Cada token nuevo introducido agota parte de ese presupuesto». Y nombra el síntoma: «a medida que aumenta el número de tokens en la context window, disminuye la capacidad del modelo para recordar información de ese contexto con precisión» — putrefacción del contexto.1
Esa última frase es una afirmación sobre comportamiento, lo que significa que puede comprobarse, y la tabla de la parte superior de esta página es la comprobación.
Cómo se hizo esa tabla
Enlace a la sección: Cómo se hizo esa tablaCuarenta líneas contra el endpoint local de Capítulo 22 — un pequeño servidor Python que mantiene Qwen2.5-0.5B-Instruct en la CPU y habla con la forma de chat-completions, de modo que el bucle se queda en TypeScript y los tensores se quedan al otro lado del puerto.
const DEPTHS = [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1];
for (const d of DEPTHS) {
const slot = Math.round(d * (N - 1));
let hits = 0, other = 0;
for (let t = 0; t < TRIALS; t++) {
const recs = buildRecords(N, 1000 + t); // 25 unique tickets
const gold = recs[Math.floor(rng(7 + t)() * N)]; // a different one each trial
const rest = recs.filter((x) => x.ticket !== gold.ticket).slice(0, N - 1);
const lines = [...rest.slice(0, slot).map((x) => x.line),
gold.line,
...rest.slice(slot).map((x) => x.line)];
const r = await complete(prompt(lines, ask(gold.owner)), { maxTokens: 12 });
const said = /\d{4}/.exec(r.text)?.[0];
if (said === String(gold.ext)) hits++;
else if (said && recs.some((x) => String(x.ext) === said)) other++;
}
}El contador other es lo que convierte un resultado decepcionante en uno útil: cuando el modelo se equivoca, ¿está perdido o está seguro?
La respuesta es que está seguro. En las ocho posiciones que no son la primera, 136 de las 205 respuestas incorrectas eran la extensión de otro ticket: un número real de cuatro dígitos, con formato correcto, leído de la línea equivocada. En la posición 1 solo una de las cinco respuestas fallidas lo era; en la posición 7, veintiuna de veintiséis.
Esa distinción es lo que importa en producción. Un modelo que dice no lo encuentro es un bug que notas; un modelo que devuelve el número de una fila vecina es un bug que envías, porque en pantalla ambos parecen idénticos. Es el fallo contra el que el Capítulo 19 construyó citas verificables, llegando desde dentro del prompt en lugar de desde el índice.
No es solo dónde. Es cuánto.
Enlace a la sección: No es solo dónde. Es cuánto.La posición es un eje. La longitud es el otro, y es más fácil de probar: mantén la respuesta en el medio y haz crecer la lista.
| registros | tokens del prompt | aciertos | tasa | intervalo del 95 % | línea equivocada | ninguno |
|---|---|---|---|---|---|---|
| 1 | 97 | 18/20 | 90 % | 70–97 % | 0 | 2 |
| 3 | 159 | 11/20 | 55 % | 34–74 % | 9 | 0 |
| 8 | 315 | 3/20 | 15 % | 5–36 % | 17 | 0 |
| 20 | 695 | 2/20 | 10 % | 3–30 % | 16 | 2 |
| 40 | 1.324 | 3/20 | 15 % | 5–36 % | 15 | 2 |
| 80 | 2.587 | 1/20 | 5 % | 1–24 % | 18 | 1 |
| 140 | 4.477 | 2/20 | 10 % | 3–30 % | 18 | 0 |
Un registro y 97 tokens: 90 %. Tres registros y 159 tokens: 55 %. Ocho registros y 315 tokens: 15 %, y desde ahí plano y bajo hasta 140 registros y 4.477 tokens. Todo el colapso ocurre entre la primera y la octava línea de una lista.
La última columna es todo lo que no es ni la extensión correcta ni la de otro registro, lo que con un solo registro en la página es el único sitio donde puede caer una respuesta incorrecta. Los dos fallos con un registro merecen contarse en lugar de redondearse fuera, porque ninguno fue una negativa: uno respondió 5806 a un registro cuya única línea dice 5805. Con 97 tokens y un único candidato, este modelo aún copia mal un dígito dos veces de veinte, y ese es el suelo contra el que se mide todo lo demás.
De ahí salen dos cosas. Una context window más grande compra el derecho a enviar más, no la certeza de que se lea: este modelo tiene una ventana de 32.768 tokens y un rango de trabajo, en esta tarea, de unos pocos cientos de tokens. Y no hay umbral, ni precipicio, ni estado de «contexto lleno»: la degradación ya está en marcha en el tercer registro y se completa en el octavo, al uno por ciento de la ventana. Sea lo que sea un límite de contexto, no es lo que gobierna esto.
Por qué
Enlace a la sección: Por quéSuelen proponerse dos mecanismos. El primero es la aritmética del Capítulo 9, que Anthropic formula en los mismos términos que este curso: los modelos «se basan en la arquitectura transformer, que permite que cada token atienda a todos los demás tokens en todo el contexto. Esto da lugar a n² relaciones por pares para n tokens».1 La attention sobre una secuencia más larga no es la misma operación aplicada a más material; es un presupuesto fijo de masa de probabilidad repartido entre más competidores. El segundo es el entrenamiento: los modelos ven muchas más secuencias cortas que largas, así que los patrones posicionales de largo alcance son la parte menos practicada de la red. Eso es un argumento, no una medición, y este capítulo no puede zanjarlo.
Lo que sí está zanjado es la forma, y lo está desde 2023. Liu et al. probaron respuesta a preguntas multi-documento y recuperación clave-valor en familias y tamaños de modelos, y descubrieron que «el rendimiento suele ser más alto cuando la información relevante aparece al principio o al final del contexto de entrada, y se degrada de forma significativa cuando los modelos deben acceder a información relevante en medio de contextos largos, incluso en modelos explícitamente de contexto largo».2 El Capítulo 15 tomó de ese artículo su regla de posición; el Capítulo 19 tomó de él la razón por la que veinte chunks recuperados pueden puntuar peor que cuatro. La forma práctica del hecho es la única frase de aquí sobre la que deberías actuar: esto se mide en cinco minutos en tu propio modelo con tus propios datos, y ninguna curva publicada sustituye a la tuya.
Nadie sabe qué hay en su ventana
Enlace a la sección: Nadie sabe qué hay en su ventanaPregunta a un equipo qué llena el contexto de su agent y obtendrás una estimación, porque ninguna API devuelve la respuesta: la respuesta te da prompt_tokens, un único número para todo.
Puedes reconstruir el desglose con cuatro recuentos y tres restas: el prompt completo renderizado, el mismo sin definiciones de herramientas, solo el mensaje de sistema con y sin ellas, y todo sin los resultados de herramientas:
async function buckets(messages: Msg[]) {
const sys = messages.slice(0, 1);
const withoutResults = messages.filter((m) => m.role !== "tool");
const [total, sysWithTools, sysNoTools, noResults] = await Promise.all([
countPrompt(messages, CATALOGUE), // everything
countPrompt(sys, CATALOGUE), // system + scaffolding + schemas
countPrompt(sys), // system + scaffolding
countPrompt(withoutResults, CATALOGUE), // everything but tool output
]);
return {
system: sysNoTools,
tools: sysWithTools - sysNoTools,
toolResults: total - noResults,
conversation: total - sysWithTools - (total - noResults),
total,
};
}countPrompt aplica la plantilla de chat del propio modelo antes de tokenizar, lo cual importa más de lo que parece: tu texto no es lo que se cuenta. Los marcadores de rol, el preámbulo de tool calling y el renderizado del esquema son todos tokens que pagas y que nunca has escrito. Capítulo 7 construyó un tokenizador y el Capítulo 16 contó con js-tiktoken; aquí el recuento viene del mismo modelo que leerá el prompt, que es el único recuento exactamente correcto.
Ahora pásale un agent real: cuarenta turnos de una investigación de incidente, doce herramientas, un entorno de operaciones falso que devuelve volcados de logs y series de métricas realistas.
| turno | sistema | definiciones de herramientas | conversación | resultados de herramientas | prompt total | entrada facturada en este turno |
|---|---|---|---|---|---|---|
| 1 | 85 | 1.817 | 155 | 490 | 2.547 | 4.370 |
| 2 | 85 | 1.817 | 282 | 529 | 2.713 | 5.275 |
| 5 | 85 | 1.817 | 647 | 1.870 | 4.419 | 8.093 |
| 10 | 85 | 1.817 | 946 | 2.141 | 4.989 | 4.951 |
| 20 | 85 | 1.817 | 1.500 | 2.943 | 6.345 | 6.316 |
| 30 | 85 | 1.817 | 2.187 | 4.000 | 8.089 | 8.059 |
| 40 | 85 | 1.817 | 3.053 | 5.677 | 10.632 | 21.090 |
Lee la primera fila frente a la última.
En el turno 1, el prompt tiene 2.547 tokens y el 71 % son definiciones de herramientas. El system prompt es el 3 %. Lo que escribió el usuario es el 6 %. El agent aún no ha hecho nada y ya carga con 1.817 tokens de esquema JSON.
Para el turno 40, el prompt tiene 10.632 tokens y las proporciones se han invertido: definiciones 17 %, conversación 29 %, resultados de herramientas 53 %. La salida de herramientas superó a las definiciones en el turno 5; la conversación no las superó hasta el turno 25, así que durante el primer sesenta por ciento de la sesión el catálogo de herramientas fue más grande que todo lo que se había dicho.
Luego el total. En 57 llamadas al modelo, la ejecución facturó 370.291 tokens de entrada para un contexto final de 10.632: el último prompt se pagó unas treinta y cinco veces, que es la cuadrática del Capítulo 16 con el multiplicador de un agent encima. De esos 370.291, 103.569, o el 28 % de todo lo facturado, fueron las doce definiciones de herramientas, reenviadas byte a byte en cada llamada.
Lo que cuesta una definición de herramienta
Enlace a la sección: Lo que cuesta una definición de herramientaEl catálogo de herramientas es el mayor coste fijo de un agent y es invisible, porque nunca lo ves: pasas un array de objetos y el proveedor lo renderiza dentro del prompt por ti. Medido, con las mismas doce herramientas:
system prompt + chat scaffolding, no tools: 85 tokens
all twelve definitions: 1,817 tokens
of which fixed tool-calling scaffolding: 126 tokens
three tools instead of twelve: 605 tokens
same twelve, one-sentence descriptions,
no parameter prose: 1,291 tokens (-29 %)Por herramienta, el coste marginal va de 80 tokens para get_current_time, que recibe una cadena, a 263 para search_tickets, que recibe cuatro parámetros con un enum y una frase de orientación cada uno. Ese es el tipo de cambio detrás del consejo central del Capítulo 18 de que la descripción es la API: una buena descripción cuesta unos cien tokens en cada solicitud durante el resto de la vida del agent. Tres consecuencias.
Una herramienta que no usas también factura. El agent llamó a siete de las doce. Las otras cinco costaron 697 tokens en cada una de las 57 solicitudes: 39.729 en total, más de una décima parte de todo lo facturado en la ejecución, por capacidades que nunca tocó. Una de las cinco contiene el detalle más afilado del trace: el modelo intentó tres veces llamar a read_log, que no existe. La herramienta que quería era search_logs, la segunda definición más cara del catálogo, con 237 tokens. Pagó esa definición 57 veces, nunca la usó y nunca encontró su nombre.
Recortar prosa es la optimización más barata disponible, y es un intercambio. Reducir las descripciones a una frase y eliminar la documentación de parámetros ahorró 526 tokens por llamada, un 29 %, sin tocar una línea de lógica, y empeoró las llamadas a herramientas del modelo, que es lo que midió el Capítulo 18. La cuestión es que ahora ambos lados de ese intercambio están en la misma unidad.
A cierta escala, enviar definiciones deja de tener sentido. Anthropic le puso número en noviembre de 2025: un conjunto grande de servidores conectados implica procesar «cientos de miles de tokens» de definiciones antes de leer la solicitud, y sustituir eso por ejecución de código — que el agent descubra y cargue solo las definiciones que necesita — «reduce el uso de tokens de 150.000 tokens a 2.000 tokens, un ahorro de tiempo y coste del 98,7 %».3 La misma idea que el resto de este capítulo, aplicada a esquemas en lugar de historial: mantén el índice, resuelve la entrada bajo demanda.
Romperlo a propósito
Enlace a la sección: Romperlo a propósitoSe plantaron dos cosas en esa transcripción de cuarenta turnos. En el turno 2, antes de cualquier trabajo real, el usuario declara una regla permanente: cualquier ticket que abras debe archivarse con mi número de empleado, 4417. En el turno 19, en mitad del incidente, un dato: el shard afectado es pay-shard-7, confirmado por el equipo de pagos. En el turno 40 el usuario pide al agent que abra el ticket de incidente, lo que requiere ambas cosas. Cada prueba se pregunta en seis formulaciones distintas y se puntúa sobre seis; la decodificación greedy es determinista, así que una llamada da un sí o no irrepetible y seis dan una tasa.
La transcripción se reproduce después bajo siete políticas de contexto. Se reproduce en lugar de volver a ejecutarse, deliberadamente: los mensajes, las llamadas a herramientas y los resultados de herramientas son byte a byte idénticos en las siete, así que la única variable es lo que cada política decidió conservar. El Capítulo 16 mostró por qué una ventana deslizante es una mala jugada económica, porque destruye el prefijo cacheable. Esto es lo que le hace al comportamiento:
| política de contexto | tokens de entrada en los 40 turnos | prompt del turno 40 | regla del turno 2 | dato del turno 19 |
|---|---|---|---|---|
| historial completo | 370.291 | 10.632 | 6/6 | 5/6 |
| ventana deslizante, últimos 12 mensajes | 157.578 | 2.922 | 5/6 | 0/6 |
| omitir resultados de herramientas de hace más de 4 turnos | 243.445 | 6.311 | 6/6 | 3/6 |
| compactación cada 6 turnos | 195.515 | 3.220 | 6/6 | 0/6 |
| compactación más notas escritas por el modelo | 200.849 | 3.286 | 6/6 | 0/6 |
| fijar los turnos propios del usuario, al principio | 168.550 | 3.559 | 6/6 | 5/6 |
| fijar los turnos propios del usuario, al final | 168.835 | 3.564 | 6/6 | 6/6 |
| control: los dos turnos y nada más | — | 1.981 | 6/6 | 6/6 |
Las filas de compactación incluyen lo que costó compactar: 18.581 tokens de entrada para siete resúmenes y 3.392 más para el tomador de notas. La fila de control está ahí para que un cero pueda leerse como un cero: con los dos mensajes solos en un prompt de 1.981 tokens, este modelo responde perfectamente a ambas pruebas, así que ninguna fila es que la tarea sea demasiado difícil.
El historial completo recuerda, y es lo más caro de la tabla: 370.291 tokens de entrada para una sesión cuyo contenido duradero son dos frases.
Eso responde a una pregunta que el arranque dejó abierta. ¿Por qué una transcripción de 10.632 tokens contiene un dato que un registro de 853 tokens pierde? Porque la longitud es la variable equivocada. El registro contiene veinticinco extensiones de cuatro dígitos en veinticinco frases idénticas: veinticuatro señuelos casi perfectos para la que quieres. La transcripción contiene exactamente un número de empleado y un nombre de shard. La putrefacción del contexto es interferencia antes que volumen, por eso 136 de las 205 respuestas incorrectas de arriba eran el valor de un vecino. La pregunta útil sobre una ventana no es lo larga que es; es cuántas cosas dentro de ella se parecen a la respuesta.
La ventana deslizante es un 57 % más barata y ha perdido el incidente. El número de empleado sobrevive solo porque el agent lo había repetido en los turnos recientes. El shard, mencionado una vez en el turno 19, no está en los últimos doce mensajes, y el modelo no lo dice. Preguntado seis veces respondió «el shard de pagos afectado es shard 4417», tirando del número de empleado, el único otro identificador que quedaba en su ventana, y dos veces «pool», sacado de la cadena pool_exhausted en una línea de log.
La compactación es barata y perdió el mismo dato. Siete resúmenes, escritos por el modelo bajo una instrucción explícita de conservar identificadores, números, instrucciones permanentes y preguntas abiertas, y pay-shard-7 no está en ninguno de los que importaban; las seis conjeturas fueron shard 1, pay_shard_1 y pool. La compactación no falla en voz alta. Produce una sesión fluida, plausible y mucho más corta que ha dejado caer una línea en silencio.
Tres filas sacaron 0/6 en el dato del turno 19: la ventana deslizante, la compactación y la compactación con notas. Dieciocho respuestas incorrectas entre ellas, y ni una sola fue «no lo sé».
Luego la fila que debería dar vergüenza. Conservar literalmente los cuarenta mensajes propios del usuario, más los últimos cuatro turnos completos y nada más, cuesta 168.550 tokens — un 54 % menos que el historial completo — y responde a ambas pruebas tan bien como el historial completo o mejor. Sin resumidor, sin tomador de notas, sin segundo modelo: un filtro sobre role === "user". Las palabras del usuario son los tokens baratos de alto valor en la ventana de un agent, y la mayoría de los diseños las descartan con todo lo demás.
Las dos últimas filas son otra vez la tabla inicial, dentro del agent. El mismo bloque fijado, movido del mensaje de sistema al final del prompt: 5/6 se convierte en 6/6. En seis ensayos no es una diferencia significativa y no se presenta como tal; se presenta como recordatorio de que dónde es un parámetro que estás fijando lo sepas o no.
Cuatro formas de gastar menos ventana
Enlace a la sección: Cuatro formas de gastar menos ventanaLas cuatro estrategias de abajo son de Anthropic, en su orden, aunque solo las tres últimas son su lista de largo horizonte.1 Las cuatro son variaciones de una instrucción: no cargues lo que puedas recuperar, y no cargues en bruto lo que puedas llevar comprimido.
Recuperación just-in-time
Enlace a la sección: Recuperación just-in-timeNo precargues contenido. Conserva identificadores — una ruta de archivo, una consulta, un número de ticket, el nombre de una herramienta y sus argumentos — y resuélvelos cuando hagan falta. El grupo más grande en el agent de arriba es salida de herramientas que se leyó una vez, se usó una vez y luego se cargó durante treinta turnos más. Sustituir cada resultado de hace más de cuatro turnos por un stub que diga qué era y cómo recuperarlo son seis líneas:
const elide: Policy = (h) => [SYSTEM, ...h.flatMap((turn, ti) =>
turn.map((m) => (ti < h.length - 4 && m.role === "tool"
? { role: "tool", name: m.name,
content: `[${m.name} result from turn ${ti + 1}, ${m.content.length} chars, ` +
`elided; call ${m.name} again with the same arguments to re-read it]` }
: m)))];Esto es el Capítulo 19 con el corpus sustituido por el propio pasado del agent. La maquinaria de recuperación ya está ahí: es el catálogo de herramientas.
Compactación
Enlace a la sección: CompactaciónCuando la transcripción pase un umbral, sustituye su parte más antigua por un resumen escrito por el modelo y continúa. El prompt que escribe el resumen es todo el diseño, y ahí es donde la compactación se gana o se pierde: conserva identificadores, números, instrucciones permanentes y preguntas abiertas; elimina cortesías y salida de herramientas que puedas recuperar de nuevo.
La compactación es con pérdida por construcción, lo que pierde lo elige un modelo por ti, y nada da error cuando elige mal. Tampoco es gratis: cada compactación es una llamada extra cuya entrada es lo que se está compactando.
Toma de notas estructurada
Enlace a la sección: Toma de notas estructuradaMantén un pequeño almacén fuera del contexto y reinsértalo entero en cada turno. A diferencia de un resumen, es append-only y direccionable: una regla escrita en el turno 2 sigue ahí literalmente en el turno 400. La versión medida aquí pregunta al modelo, después de cada mensaje del usuario, si contiene algo duradero:
const r = await complete([
{ role: "system", content:
"You keep a durable note file for a support session. Given one user message, " +
"output one short note ONLY if it states a standing rule, an identifier or a fact " +
"that must survive the rest of the session. Otherwise output exactly NONE." },
{ role: "user", content: `Turn ${i + 1}: ${user}` },
], { maxTokens: 40 });
if (!/^none\b/i.test(r.text.trim())) notes.push(`turn ${i + 1}: ${r.text.trim()}`);Esta es la estrategia con el techo más alto aquí, y es la que falló en la medición. En cuarenta mensajes de usuario, el tomador de notas conservó tres notas y ninguna de las dos que importaban: una línea de consejo de runbook, un anuncio de que la sesión terminaba y Europe/Madrid is currently 13:45 — una hora que inventó, ya que la herramienta que estaba parafraseando devolvió 09:52 UTC. El tomador de notas es un modelo, y todo en este capítulo también se le aplica.
Sub-agents
Enlace a la sección: Sub-agentsDale a una tarea enfocada su propia ventana: su propio system prompt, su propio catálogo pequeño, nada del historial del padre, y devuelve una respuesta corta en lugar de una transcripción. El Capítulo 23 puso uno detrás de un esquema de herramienta y dejó la factura aquí; la factura es que la respuesta del hijo es la única parte de la ventana del hijo que el padre paga alguna vez.
El sub-agent no está en la tabla de arriba porque no se ejecuta durante cuarenta turnos: se ejecuta una vez, en una ventana que alguien acotó para él. Dado el system prompt, los turnos 17 a 19 y nada más — 2.737 tokens — respondió a la prueba del shard 6/6, mejor que cualquier política de la tabla, y a la prueba del empleado 0/6, porque ese número no está en los tres turnos que se le entregaron.
Eso son los sub-agents en dos números: una ventana limpia no es inteligencia, es alcance, y el acotamiento lo hace por adelantado un código que ya tiene que saber qué turnos importan. Hay una cosa más en esas respuestas que merece conservarse. Esta fue la única política que respondió «None available» en lugar de inventar algo. Un modelo con un contexto pequeño y coherente sabe qué le falta; un modelo con uno grande y ruidoso no.
Las tres memorias
Enlace a la sección: Las tres memoriasCasi todas las conversaciones confusas sobre memoria de agents son tres mecanismos llevando la misma palabra. Tienen vidas, propietarios y modos de fallo distintos, y un sistema que los guarda en el mismo sitio tiene un problema que aún no ha notado.
| historial de conversación | recuperación | memoria persistente del usuario | |
|---|---|---|---|
| contiene | lo que se dijo en esta sesión | documentos que posees | datos sobre una persona |
| vive | una sesión | hasta que se reindexa | en todas las sesiones, para siempre |
| escrito por | el bucle, automáticamente | una pipeline de ingesta | el modelo, a propósito |
| entra en el prompt | completo, en cada llamada | cuatro pasajes, cuando una consulta coincide | completo, en cada llamada |
| falla por | crecer hasta pudrirse | recuperar el chunk equivocado | recordar algo erróneo sobre ti |
| construido en | Capítulo 23 | Capítulo 19 | este capítulo |
El marco académico es el de CoALA, que organiza los language agents en torno a «componentes de memoria modulares» y separa la memoria de trabajo de los almacenes episódicos, semánticos y procedimentales.4 MemGPT toma la misma idea al pie de la letra, tomando prestada la memoria virtual de los sistemas operativos: un nivel rápido dentro de la ventana, un nivel lento fuera de ella, y el propio modelo moviendo datos entre ambos con function calls.5 Ambos obligan a plantear la pregunta que un producto debe responder de todos modos: no cuánto puedo conservar, sino a qué almacén pertenece esto y cuándo caduca.
La prueba práctica es una pregunta por dato: ¿qué debería seguir siendo verdad mañana? Un resultado de herramienta del turno 12, nada. Un resumen de la sesión, hasta que termine la sesión. Que el número de empleado del usuario es 4417, hasta que cambie de trabajo. Tres respuestas, tres almacenes.
Adónde va esto ahora
Enlace a la sección: Adónde va esto ahoraAhora puedes medir qué hay en una ventana, decidir qué se queda en ella y distinguir entre un agent que olvidó algo y uno que lo llevaba y no miró.
La última de las cuatro estrategias es la que no encaja aquí. Un sub-agent no es una política de contexto, es un segundo agent, y en el momento en que hay dos tienes que decidir qué pasa entre ellos y cuál manda. Capítulo 25 es eso: los cinco patrones de orquestación y de dónde sale realmente cada uno de sus nombres, las dos topologías que se confunden — pedir a un sub-agent y recibir una respuesta de vuelta, frente a entregarle la conversación y no recuperarla — y el hallazgo medido de que, en la tarea a la que pone precio, la disposición más simple gana, seguido de la prueba para saber cuándo deja de ganar.
También hereda exactamente lo que este capítulo acaba de medir. Un sub-agent devuelve un resumen. Un resumen es una compactación que no escribiste, producida por un modelo cuya ventana no puedes ver, y el padre no tiene forma de distinguir uno bueno de uno incorrecto y seguro: la misma distinción que separaba el 84 % del 19 % al principio de esta página, y que convirtió dieciocho datos ausentes en dieciocho inventados. Así que: cuando el sub-agent se equivoca, ¿qué puede mirar exactamente el padre?
Fuentes y método
Enlace a la sección: Fuentes y métodoTodos los números de aquí se produjeron en esta máquina y ninguno se estimó. El modelo es Qwen2.5-0.5B-Instruct en float32 en la CPU con decodificación greedy, servido sobre loopback por un pequeño endpoint Python que habla con la forma de chat-completions y expone una ruta de recuento de tokens — otra vez la costura del Capítulo 14, tensores en el lado Python y el bucle en el lado TypeScript — así que cada recuento es el tokenizador propio de ese modelo aplicado a su propia plantilla de chat. La tabla de posición son 288 llamadas, nueve posiciones por treinta y dos ensayos con un ticket distinto en cada ensayo; la tabla de longitud son 140 llamadas; la ejecución del agent son 57 llamadas al modelo durante 43 minutos de reloj; la tabla de políticas es esa única transcripción reproducida bajo siete políticas. Los intervalos son de Wilson, del Capítulo 4. No se llamó a ninguna API de pago, que también es la razón por la que no hay ningún precio en el capítulo: los recuentos de tokens son exactos y las tarifas por las que los multiplicarías son las del Capítulo 16.
Referencias
Enlace a la sección: Referencias-
Anthropic, Effective context engineering for AI agents, 29 de septiembre de 2025,
anthropic.com/engineering/effective-context-engineering-for-ai-agents, consultado el 7 de septiembre de 2026. Fuente de las dos definiciones citadas al principio, del «presupuesto de attention» y de la afirmación de que cada token nuevo lo agota, de la descripción de la putrefacción del contexto, del encuadre de las relaciones por pares n² y de las estrategias usadas como columna vertebral de este capítulo. Tres de ellas son su lista de largo horizonte: compactación, toma de notas estructurada y arquitecturas multi-agent; la recuperación just-in-time aparece antes en el mismo artículo, bajo recuperación de contexto y búsqueda agentic, y aquí se agrupa con ellas. ↩ ↩2 ↩3 ↩4 -
Liu, N. F., Lin, K., Hewitt, J., Paranjape, A., Bevilacqua, M., Petroni, F. and Liang, P. Lost in the Middle: How Language Models Use Long Contexts. arXiv:2307.03172 (v1 julio de 2023, v3 noviembre de 2023). Citado en los Capítulos 15, 16 y 19, y medido aquí. La frase citada procede del resumen; las dos tareas del artículo son respuesta a preguntas multi-documento y recuperación clave-valor, y su hallazgo de que el efecto persiste en modelos explícitamente de contexto largo es la parte que importa para una decisión de producto. ↩
-
Anthropic, Code execution with MCP: building more efficient agents, 4 de noviembre de 2025,
anthropic.com/engineering/code-execution-with-mcp, consultado el 7 de septiembre de 2026. Fuente de la reducción de 150.000 a 2.000 tokens y de la cifra del 98,7 %, y de la observación de que las definiciones de herramientas cargadas por adelantado ocupan contexto antes de que se lea la solicitud. ↩ -
Sumers, T. R., Yao, S., Narasimhan, K. and Griffiths, T. L. Cognitive Architectures for Language Agents. arXiv:2309.02427 (2023). Organiza los language agents en torno a «componentes de memoria modulares, un espacio de acción estructurado para interactuar con la memoria interna y los entornos externos, y un proceso generalizado de toma de decisiones para elegir acciones», y divide la memoria en de trabajo, episódica, semántica y procedimental. El Capítulo 22 usó su taxonomía para el agent que aprende; la tabla de tres almacenes de arriba es su sombra práctica. ↩
-
Packer, C., Wooders, S., Lin, K., Fang, V., Patil, S. G., Stoica, I. and Gonzalez, J. E. MemGPT: Towards LLMs as Operating Systems. arXiv:2310.08560 (octubre de 2023). Propone «gestión de contexto virtual, una técnica inspirada en los sistemas de memoria jerárquica de los sistemas operativos tradicionales», con el propio modelo moviendo datos entre un nivel rápido dentro de la ventana y un nivel lento fuera de ella. La formulación más clara en cualquier sitio de por qué la ventana es una caché y no una memoria. ↩