Ir al contenido

Contexto de herramientas y caché de prompts

Dos cosas son ciertas en cada petición que hace el arnés integrado: las definiciones de herramientas son su mayor coste fijo y casi ninguna de ellas se va a usar. Esta página explica qué hace Control Center al respecto y por qué la respuesta no es simplemente «enviar menos herramientas».

Control Center registra unas 126 herramientas. Si se enviaran enteras, sus definiciones costarían aproximadamente 23.000 tokens en cada petición, un coste que ninguna compactación puede tocar, porque las definiciones de herramientas viajan en una parte de la petición distinta de la conversación.

La factura de tokens es la queja obvia y, con la caché de prompts, también la menor. El coste real es la precisión de selección. Las evaluaciones publicadas sobre llamadas a herramientas coinciden en que los modelos eligen la herramienta correcta de forma fiable hasta unas 30–50 herramientas en contexto, y empeoran progresivamente a partir de ahí. La causa señalada no es el recuento de tokens, sino el solapamiento semántico: cuando un catálogo contiene varias herramientas cuyas descripciones se leen igual, el modelo elige entre casi idénticas en lugar de recordar una capacidad.

Con 126 herramientas, un agente se queda muy por encima de esa banda en cada turno, incluidos los muchos turnos en los que solo necesitaba leer un archivo.

Por tanto, a cada ejecución se le muestran dos cosas:

  • un conjunto residente — unas dos docenas de herramientas, que se envía con sus esquemas completos en cada petición;
  • un índice de nombres con todo lo demás, agrupado bajo encabezados como «Tickets and projects» o «Memory and knowledge», que cuesta unos cientos de tokens para todo el catálogo.

Medido con el catálogo actual, eso lleva el bloque de herramientas de ~23,1k tokens a ~5,0k, un 78 % menos, y deja el conjunto siempre visible dentro de la banda en la que la selección es fiable.

El conjunto residente son las herramientas que una ejecución usa en la mayoría de las ejecuciones: el vocabulario de archivos y shell (read, write, edit, search, bash, …), las herramientas de descubrimiento, la lista de tareas, la búsqueda en memoria y el verbo que deba invocar el modo actual para entregar su salida. El verbo de salida propio de un modo siempre es residente: una ejecución nunca debe tener que ir a buscar la llamada que produce su entregable.

Esta es la parte que hace que el diseño sea seguro y no solo barato. Una herramienta diferida se puede llamar desde el primer turno. Lo único que se retiene es su esquema.

El agente ve el nombre en su prompt. Si llama a ese nombre directamente, el arnés carga el esquema y ejecuta la herramienta en el mismo paso: sin error y sin ida y vuelta. El modelo no necesita saber que la herramienta llegó a estar «descargada».

Cuando el agente conoce la tarea pero no el nombre, search_tools acepta una descripción en lenguaje natural («asignar un ticket a alguien»), ordena toda la superficie de la ejecución y devuelve las coincidencias con sus esquemas ya cargados, de modo que el turno siguiente pueda llamar a una. Si una búsqueda no encuentra nada, lo dice con claridad y sugiere otras palabras o una búsqueda más amplia; y lo hace a propósito, porque un agente que interpreta una búsqueda vacía como «esta capacidad no existe» se inventará un sustituto en lugar de volver a mirar.

search_tools solo existe en el arnés integrado. Los clientes MCP externos disponen en su lugar de search_tool_bm25, que ordena el mismo índice pero solo describe las coincidencias: esos clientes ya han recibido todos los esquemas de tools/list, así que no hay nada que cargar.

La carga diferida se aplica después del filtro de herramientas del modo, nunca en su lugar. Oculta un esquema; no puede revelar una herramienta que el modo ha denegado. Una herramienta activada sigue pasando por la solicitud de aprobación y por las barandillas de acción exactamente igual que una residente, y una herramienta no puede cargar un nombre que no estuviera en la superficie de la ejecución de partida.

La superficie MCP que ven los clientes externos no se ve afectada. tools/list sigue devolviendo el catálogo completo. Un intento anterior de recortarlo rompió a los agentes sin más: los clientes MCP validan los nombres de las herramientas contra su propia lista en caché y rechazan todo lo que no figure en ella sin llegar a preguntar al servidor, de modo que una herramienta «oculta pero invocable» era sencillamente inalcanzable. La carga diferida vive en el arnés, donde cargar una herramienta a mitad de ejecución es algo que el arnés sí puede hacer.

--tool-deferral=off (o CC_SERVER_TOOL_DEFERRAL=off) vuelve a hacer residentes todas las herramientas admitidas, lo que produce exactamente las peticiones que el servidor hacía antes de que existiera la carga diferida. Consulta la referencia de la CLI de cc_server.

Las cargas de trabajo de los agentes están desequilibradas: envían prompts enormes y reciben respuestas pequeñas, turno tras turno, con el mismo prefijo cada vez. Los proveedores mantienen ese prefijo en caché, y una lectura de caché cuesta alrededor de una décima parte de una nueva. La tasa de aciertos de caché es, por tanto, una propiedad de primer orden del arnés y no una optimización; además, en Anthropic también aporta rendimiento, porque los tokens cacheados no cuentan para el límite de entrada por minuto.

El almacenamiento en caché funciona por coincidencia exacta de prefijo, lo que da lugar a una única regla rectora.

Cualquier byte que cambie invalida la caché a partir de ese punto. Por eso el arnés solo añade: los mensajes nuevos al final y los esquemas de herramientas recién activados después del bloque de herramientas cacheado, en lugar de fusionarlos con él. Ese orden es la razón de que la activación sea barata: el prefijo cacheado permanece idéntico y la ejecución solo paga por los esquemas que acaba de cargar.

El bucle también recorta la salida obsoleta de herramientas de turnos anteriores para recuperar contexto. Espera a que haya suficiente que recuperar como para que merezca la pena reescribir, de modo que un recorte es una reescritura profunda y poco frecuente en lugar de un fallo de caché continuo.

Un proveedor permite un número limitado de marcadores de caché, y Control Center los reparte de forma deliberada:

Marcador Cubre Vigencia
Última herramienta residente El bloque de herramientas 1 hora
Último bloque de sistema Herramientas + prompt de sistema 1 hora
La cola del turno anterior Historial hasta la última petición 5 min
La cola del turno actual El historial completo 5 min

Los dos últimos forman un par móvil, y la razón de ese par es sutil: una consulta de caché busca hacia atrás en un número acotado de bloques algo que almacenó una petición anterior. Un solo turno que ejecute muchas herramientas en paralelo puede emitir más bloques que esa ventana, y en ese momento uno de los marcadores de cola falla en silencio y la petición paga el precio completo sin que nada en la respuesta lo indique. Marcar el punto exacto en el que se detuvo la petición anterior convierte el acierto en algo estructural en lugar de una carrera.

El prefijo de herramientas y sistema recibe la vigencia larga porque es constante durante toda la ejecución, lo comparten todas las ejecuciones y subagentes con la misma forma, y porque el reloj empieza cuando una petición comienza: un turno que transmite en streaming durante varios minutos ya ha consumido la mayor parte de una ventana corta antes de que se forme la petición siguiente.

Los subagentes del mismo tipo producen prefijos de prompt idénticos byte a byte, así que deberían leer una única entrada de caché en lugar de escribir cada uno la suya. Pero una entrada solo se vuelve legible cuando la petición que la escribió empieza a responder, de modo que un abanico lanzado de golpe hace que todos los hijos paguen la prima por un prefijo que comparten.

El arnés deja que arranque el primer hijo de una forma dada y luego libera a sus hermanos en cuanto empieza a transmitir. La espera está acotada: un primer hijo lento cuesta un acierto de caché, nunca el abanico en sí. Por la misma razón, todos los subagentes reciben el mismo conjunto de herramientas residentes independientemente de su perfil; variarlo por perfil fragmentaría el prefijo compartido sin ninguna ganancia, ya que el perfil ya ha decidido a qué puede llamar el hijo.

Ambas mitades son observables en lugar de darse por supuestas:

  • El explorador de contexto de una conversación informa de las herramientas residentes, del índice diferido y de lo que costaría cada esquema retenido, y se construye con el mismo camino de código que usa una ejecución real.
  • Cada ejecución registra qué herramientas diferidas cargó y qué lo desencadenó, de modo que una búsqueda que no encuentra nada se ve como un fallo de recuperación en lugar de desaparecer en un agente que, en silencio, hace algo parecido.
  • Observabilidad informa de la Tasa de caché como las lecturas de caché sobre todos los tokens de prompt procesados, incluidas las escrituras de caché: una ejecución que no deja de reconstruir su prefijo obtiene una puntuación baja, en lugar de puntuar como una que nunca necesitó caché.