Ir al contenido

Ajustar el contexto de herramientas de un agente

Esta guía cubre el trabajo práctico en torno a la superficie de herramientas de dos niveles: ver qué envía una ejecución, cambiarlo y diagnosticar a un agente que echó mano de la herramienta equivocada. Para entender por qué funciona así, lee Contexto de herramientas y caché de prompts.

Abre una conversación y toca el indicador de uso del contexto en la cabecera de la conversación. Reconstruye la superficie exacta que enviaría el siguiente despacho, sin ejecutar nada. Ver más (o el comando /context) abre el explorador de contexto completo, donde puedes inspeccionar cada herramienta.

Aquí importan dos segmentos:

  • Definiciones de herramientas y MCP y herramientas dinámicas — el conjunto residente, con el coste real en tokens de cada herramienta.
  • Herramientas cargadas bajo demanda — el índice diferido. A cada entrada solo se le cobra su nombre, porque un nombre es todo lo que lleva la petición; abrir una sigue mostrando la descripción y el esquema completos, de modo que puedes ver lo que costaría si la ejecución la cargara.

Si el segmento diferido está vacío, la carga diferida está desactivada para este servidor. Consulta --tool-deferral en la CLI de cc_server.

Cambia qué herramientas se cargan de antemano

Sección titulada «Cambia qué herramientas se cargan de antemano»

El conjunto residente es política, no configuración: vive en ModeToolPolicy (packages/cc_domain/lib/features/mcp/domain/value_objects/mode_tool_policy.dart) y se aplica a todas las ejecuciones:

  • residentBuiltins — el vocabulario de archivos y shell.
  • residentDiscovery — search_tools y list_my_tools. No las elimines; son la forma en que un agente llega a todo lo demás.
  • residentMcpTools — el puñado de herramientas de Control Center que merecen su esquema en cada petición.
  • Un bloque por modo, para las herramientas que un modo dado usa en casi todos los turnos.

Dos reglas al editarlo:

Añade una herramienta solo si la mayoría de las ejecuciones la usan. Cada nombre cuesta su esquema en cada petición de cada ejecución, para siempre. Una herramienta que es importante cuando se usa pero que en conjunto es poco frecuente pertenece a la mitad diferida: el agente seguirá encontrándola.

Usa el nombre real de la herramienta. Un nombre residente que no coincide con ninguna herramienta es inerte: sin error, sin aviso, la herramienta simplemente queda diferida. test/tooling/resident_tool_names_test.dart detecta esto y además mantiene cada modo por debajo de 40 herramientas residentes, que es el objetivo del ejercicio: por encima de esa banda, la selección de herramientas se degrada de forma medible.

Los verbos obligatorios y fijados de un modo se añaden automáticamente, así que nunca necesitas enumerar el verbo de salida propio de un modo.

Diagnostica una mala elección de herramienta

Sección titulada «Diagnostica una mala elección de herramienta»

Cuando un agente usó la herramienta equivocada o afirmó que no podía hacer algo, averigua cuál de estas tres cosas ocurrió.

Cada ejecución registra las herramientas diferidas que cargó y qué lo desencadenó: una llamada directa por nombre o una consulta a search_tools. Abre el flujo de eventos de la ejecución (Ajustes → Espacio de trabajo → Agentes → el agente → Registros → Vista) y busca [harness] loaded N deferred tool(s).

  • No hay nada registrado y el agente dijo que faltaba la capacidad — nunca miró. Eso es un problema del prompt, no de recuperación: el índice diferido está en su prompt de sistema con la instrucción de no declarar que falta una capacidad hasta que una búsqueda haya vuelto vacía.
  • Se registró una búsqueda, pero no se cargó nada — un fallo de recuperación genuino. Pasa al paso 2.
  • Se cargaron herramientas, pero usó la equivocada — las herramientas que encontró se parecen demasiado. Pasa al paso 3.

search_tools hace coincidir nombres, descripciones y nombres de argumentos. Un fallo casi siempre significa que la descripción no contiene las palabras que usó el agente.

Añádelas. Las descripciones son el índice de recuperación, así que alárgalas en lugar de recortarlas — escribe el vocabulario que un operador teclearía de verdad («asignar», «delegar», «dar a»), no solo el sustantivo interno. Recortar una descripción para ahorrar tokens te cuesta tanto el acierto de búsqueda como la precisión de selección, y ahorra casi nada en comparación con el esquema.

Si la herramienta correcta existe pero queda en un puesto bajo, para eso está el argumento limit; la descripción de la propia herramienta le indica al agente que amplíe una búsqueda que se queda cerca pero no acierta.

3. Corrige herramientas que se parecen demasiado

Sección titulada «3. Corrige herramientas que se parecen demasiado»

Si dos herramientas tienen descripciones que se leerían igual para alguien que no conoce ya la diferencia, el modelo está adivinando. Fusiónalas en una sola herramienta con un argumento discriminante.

ticket_relation y ticket_pr_link siguen este patrón: cada una gestiona el enlazado y el desenlazado mediante un argumento discriminante. Una elección hecha dentro de una llamada, con todo el contexto de la petición, es más fiable que una elección hecha entre dos descripciones que se parecen.

Mantén las herramientas separadas cuando necesiten un control de aprobación distinto, una auditoría distinta o una representación distinta: esas son razones por las que una fusión te costaría algo real.

La tasa de aciertos de caché aparece en Observabilidad → Resumen como Tasa de caché. Una conversación larga y sana se mantiene alta; si es persistentemente baja, algo está reescribiendo el prefijo en cada turno.

Causas habituales, por orden de probabilidad:

  • Cualquier cosa no determinista al principio del prompt. Una marca de tiempo, un id de petición o un conjunto iterado en un orden variable bastan para provocarlo.
  • Un cambio de modelo o de esfuerzo a mitad de conversación. Ambos cambian el prefijo. Los subagentes son especialmente fáciles de equivocar aquí: ejecutar a los hijos con un esfuerzo menor para ahorrar dinero puede costar más en pérdida de caché compartida de lo que ahorra.
  • Compactación frecuente. La compactación reescribe el historial por diseño, así que su coste es real; la solución es compactar de forma poco frecuente y profunda en lugar de a menudo y superficial.

Desactivar la carga diferida con --tool-deferral=off es una prueba A/B válida para aislar si un cambio de comportamiento provino de la superficie de dos niveles. Reproduce exactamente la petición anterior a la carga diferida, así que si el comportamiento persiste con ella desactivada, la superficie no es la causa.