· 9 min de lectura

Tu agente no necesita todas las herramientas en su contexto

El agente de IA de DynoTable puede alcanzar 38 herramientas. Rara vez las ve todas a la vez. Dónde trazamos la línea entre lo que el modelo recibe de inmediato y lo que tiene que ir a buscar resultó ser la decisión más determinante de todo el conjunto de herramientas, y la línea acabó muy lejos de donde la pusimos al principio.

Construimos un mecanismo de descubrimiento para que el modelo empezara con un conjunto pequeño y buscara el resto. Luego vimos usarlo a los modelos económicos y devolvimos 27 de las 38 herramientas al núcleo siempre visible. El mecanismo sobrevivió. Nuestra teoría sobre quién lo necesitaba, no.

Esto es lo que aprendimos construyendo una superficie de herramientas para modelos en los que no se puede confiar para que vayan a buscar.

Una herramienta que el modelo nunca llama te cuesta igual

Cada herramienta que expones es su nombre, su descripción y su esquema de entrada completo, serializados en la petición antes de que el usuario haya escrito nada. Treinta y ocho de esos no salen gratis.

Los tokens son la mitad pequeña de la factura. El coste real es la precisión de selección: cuantas más opciones casi idénticas escanea un modelo, más a menudo elige la equivocada. Nuestro catálogo está lleno de opciones casi idénticas a propósito. Cinco de nuestras herramientas existen por duplicado: openTable y proposeOpenTable, openWorkbench y proposeOpenWorkbench, y así. Cada pareja hace lo mismo; una lo hace de inmediato, la otra emite un chip que el usuario pulsa primero. Esa distinción es estructural para la seguridad del y casi invisible en una lista plana de nombres.

La propia guía para clientes del abre con este mismo punto: cargar por adelantado todas las definiciones de herramientas desperdicia tokens, añade latencia y degrada el rendimiento del modelo. Estar de acuerdo con eso es fácil. Decidir qué herramientas pierden su sitio es donde se pone interesante.

Construimos una herramienta de búsqueda. El modelo del suelo no la llamaba.

El mecanismo tiene dos niveles. Un conjunto de herramientas está activo desde el primer paso. El resto son invisibles hasta que el modelo llama a searchTools(query), que puntúa el catálogo por nombres, descripciones y palabras clave, devuelve las coincidencias y las añade al conjunto de herramientas que el modelo puede llamar en los pasos siguientes.

Catálogo deherramientasBucle del agenteModeloCatálogo deherramientasBucle del agenteModelopaso 1 — conjunto activo = el núcleo enlíneapaso 2 — conjunto activo ampliadosearchTools("export csv")puntúa nombres + palabras clavestartExport, getExportStatus,listActiveExportscoincidencias (los nombres ya sepueden llamar)startExport({tabId})

Luego lo ejecutamos contra nuestro modelo del suelo. No ajustamos este agente contra un modelo de frontera: se ejecuta con tus propias credenciales de Bedrock, así que la gente elige modelos económicos y nosotros optimizamos para el más barato. Al preguntarle por un archivo adjunto, ese modelo se puso a rebuscar en el listado de pestañas abiertas. Casi nunca llamaba a la herramienta de búsqueda. Lo que no estuviera directamente visible no existía para él.

Ese resultado mata el diseño obvio. Si el descubrimiento es la única vía hacia una herramienta, cada petición que necesita esa herramienta depende de que el modelo decida ir a buscarla, y los modelos que más ayuda necesitan son los que menos probable es que la pidan.

Así que la división dejó de ser «núcleo pequeño, cola grande» y pasó a ser una pregunta sobre la petición, no sobre la herramienta: ¿nombra la herramienta la forma de hablar del usuario? Las 11 herramientas que dejamos descubribles son aquellas en las que la respuesta es sí. «Exporta esto a CSV» hace que un modelo busque export. «Enséñame los pedidos del mes pasado» no hace que busque una herramienta para fijar filtros, así que esa se queda en línea. Las estadísticas de índices, las specs guardadas, la introspección de relaciones y las superficies de cambios preparados son todas cosas que un usuario pide por su nombre cuando las quiere, y nunca de forma implícita.

Veintisiete en línea no es un número que hubiéramos defendido de antemano. Es el número que sobrevivió al contacto con el modelo contra el que realmente distribuimos.

La condición de carrera que habría dejado el descubrimiento inútil en silencio

El descubrimiento tiene una restricción de temporización fácil de equivocar y difícil de detectar.

Cuando la herramienta de búsqueda devuelve coincidencias, esos nombres tienen que entrar en el conjunto permitido antes de que se prepare el siguiente paso del modelo. El sitio obvio para hacerlo es el hook que se dispara cuando un paso termina. Ese hook está documentado como que se dispara, en algunas versiones del SDK, después de la preparación del paso siguiente, lo que significa que la mutación llega un paso tarde.

El modo de fallo es feo. El modelo busca. Obtiene un resultado correcto que nombra la herramienta que necesita. Llama a esa herramienta en el paso inmediatamente siguiente y se le dice que la herramienta no existe. Intermitente, dependiente de qué versión del SDK hayas resuelto, y se lee como un modelo tonto en vez de como un arnés roto.

El arreglo es mutar el conjunto permitido dentro de la propia ejecución de la herramienta de búsqueda, que tiene garantizado terminar antes de que el bucle avance. Eso es una diferencia de una línea en dónde vive una sentencia, y es la diferencia entre un mecanismo de descubrimiento que funciona y uno que falla una fracción de las veces por razones que nadie atribuirá correctamente.

Tres búsquedas y para

La búsqueda está limitada a 3 llamadas por turno del agente. La cuarta devuelve esto en lugar de ejecutarse:

{"error": "search-budget-exhausted", "budgetCap": 3}

El límite existe por un bucle concreto: el modelo busca, no encuentra lo que se había imaginado, vuelve a buscar con un sinónimo, tampoco lo encuentra, y quema todo su presupuesto de pasos dentro de la herramienta de búsqueda sin llegar a tocar la base de datos. Limitarlo fuerza una decisión —comprometerse con una de las herramientas ya encontradas, o preguntar al usuario— en el punto en el que seguir buscando ha dejado de compensar.

El mensaje de error cuando un modelo llama a una herramienta que no ha descubierto sigue el mismo principio que usamos para cada validador del agente:

Tool 'startExport' not in active set. Call searchTools(query='startExport')
to discover it, or use one of: <inline tool names>

Un rechazo que nombra la acción de recuperación cuesta un paso extra. Un rechazo que solo dice que no cuesta el turno entero.

Una fila por herramienta, todo lo demás derivado

Cada herramienta se declara una vez, en una única lista plana, y la fila lleva la identidad entera de la herramienta: su nombre y su descripción, las palabras clave con las que la búsqueda hace coincidencia, si arranca en línea o descubrible, en qué nivel se ejecuta y cómo se expone por MCP.

Esos niveles importan tanto como la división de visibilidad. Veintiuna herramientas son silenciosas: lecturas que se ejecutan sin interrumpir a nadie. Dieciséis están restringidas tras la escalera de autorización. Exactamente una no pertenece a ninguno de los dos, porque la herramienta de búsqueda no es una capacidad que el agente use sobre tus datos; es parte del propio bucle. La exposición por MCP es un tercer eje en la misma fila: solo lectura, preparación, completa o excluida del todo, que es lo que son tres herramientas.

La regla que mantiene esto honesto es que cualquier otra lista del sistema se deriva de esas filas —el conjunto del nivel silencioso, los niveles de alcance de MCP, el conjunto con alcance de escritura— y ninguna de ellas se mantiene a mano. Una lista silenciosa llevada a mano junto a una lista de MCP llevada a mano es exactamente la forma en que una herramienta acaba correctamente restringida en el chat y sin restricción, y en silencio, para un cliente externo.

La restricción que no vimos venir es que la lista de declaraciones tiene que contener cero imports en tiempo de ejecución. La comparten la UI de escritorio y el backend, y un solo import alcanza, de forma transitiva, una dependencia de criptografía exclusiva de Node a través de la implementación de una herramienta. Métela en el bundle del navegador y la app falla al cargar el módulo. Ni el comprobador de tipos ni los tests unitarios lo detectan: los dos resuelven el import tan contentos. Lo que sí lo detecta es un test que lee el archivo como texto y falla ante cualquier sentencia import, lo que parece tosco justo hasta la primera vez que te salva.

Qué se transfiere si estás construyendo uno

  • Cuenta tus herramientas antes de defender tu arquitectura. La división correcta es una medición, no un principio.
  • Prueba el descubrimiento contra tu modelo más débil. Un modelo de frontera buscará cuando deba; eso no te dice nada sobre el modelo que eligen tus usuarios.
  • Decide la visibilidad según si la propia forma de hablar del usuario nombra la herramienta. Las herramientas que se invocan de forma implícita van en línea; las que la gente pide por su nombre pueden buscarse.
  • Comprueba cuándo se disparan de verdad los hooks de paso de tu framework antes de meter en uno nada sensible al orden.
  • Limita las metaherramientas. Todo lo que se pueda llamar repetidamente sin tocar estado real se llamará, y un presupuesto de pasos gastado en buscar es un turno desperdiciado.
  • Haz que los errores de herramienta no descubierta nombren la llamada de recuperación, igual que cualquier otro error de validador.
  • Declara cada herramienta una vez y deriva de ahí todas las demás listas. Dos listas de las mismas herramientas llevadas a mano acaban discrepando, y la discrepancia aparece en una frontera de seguridad.
  • Si un módulo lleva una restricción estructural que tu compilador no puede expresar, escribe el test tosco que la haga cumplir sobre el texto.

Dónde se ejecuta esto

Todo esto se distribuye dentro del catálogo de herramientas de DynoTable: consultas conscientes del esquema con tus propias credenciales de , con escrituras que solo aterrizan en un área de preparación revisable. Las mismas declaraciones alimentan el servidor MCP al que se conectan los agentes externos, donde el nivel de exposición de cada fila se convierte en el alcance que se concede a un cliente externo; cómo hicimos que eso fuera seguro —OAuth, consentimiento, aislamiento de credenciales— es otra historia.

Y la capa que hay debajo de todo ello, los validadores que hacen que cada una de estas herramientas sea sobrevivible para un modelo económico, tiene su propio artículo.

Trabaja con DynamoDB sin la Consola

Un cliente de escritorio rápido para DynamoDB que ejecuta el SQL real que DynamoDB no puede — JOINs, GROUP BY, agregaciones — con edición visual y un agente de IA con tus propias claves de Bedrock.

Prueba gratuita de 30 días, sin tarjeta — después, el plan Free sin límite de tiempo.