Lección 3: Cinco tipos comunes de herramientas: leer, escribir, ejecutar, buscar, llamar
Objetivos de aprendizaje:
- Clasificar las herramientas comunes en cinco categorías según el daño que pueden causar, y nombrar la firma típica de cada una
- Explicar por qué las herramientas de ejecución de comandos están en una clase de riesgo distinta de las otras cuatro
- Explicar por qué las herramientas de búsqueda devuelven fragmentos coincidentes en lugar de archivos enteros
Requisitos: terminaste la Lección 2, entiendes la forma de ida y vuelta de una llamada a herramienta | Anterior: Lección 2 << | Siguiente: Lección 4 >>
Empecemos con una tabla
¿Qué ordena esta tabla? No el alfabeto. Es «qué amplitud de daño puede causar una sola llamada» — el radio de impacto de esa llamada. Una herramienta de solo lectura tiene un radio de impacto de aproximadamente cero: leer el archivo equivocado solo descarrila este turno de la conversación. Escribir un archivo puede sobrescribir contenido existente. Ejecutar un comando puede hacerle cualquier cosa a todo el sistema. A medida que recorramos cada categoría, verás que, más allá de «qué puede hacer», cada una arrastra una trampa en la que solo esa categoría tropieza.
Leer: la más segura, pero no de riesgo cero
Una herramienta de lectura de archivos suele tener una firma como esta:
El valor de retorno es el propio contenido del archivo, normalmente con números de línea para que el modelo pueda referenciarlas más adelante:
Leer un archivo no cambia ningún estado. Si el modelo lee lo que no debía, o lee de más, el peor resultado es algo de contenido irrelevante en este único turno — y el modelo tiende a darse cuenta de que leyó lo que no era y volver a leer. Por eso se la llama la categoría «más segura»: no porque no conlleve riesgo, sino porque el riesgo no puede escapar de los límites de esta conversación.
El riesgo real es leer un archivo que nunca debería haber tocado. Si el agente tiene permiso para leer ~/.ssh/id_rsa o el .env del proyecto, un inocente «muéstrame qué hay en este directorio» puede levantar una clave secreta literalmente al contexto de la conversación. A partir de ahí, la filtración ya ocurrió en el momento en que ese contexto lo emite el modelo, se escribe en un log, o se lo lleva fuera alguna herramienta posterior de «llamar a API externa». Por eso las herramientas de lectura de archivos casi siempre van acompañadas de una lista de rutas permitidas o de un sandbox, en lugar de «es de solo lectura, dale las llaves sin más». La Lección 5 cubre en detalle cómo poner ese tipo de frontera.
Escribir: donde las consecuencias dejan de ser simétricas
Una herramienta de escritura de archivos tiene un parámetro más que la de lectura, y un poco menos de seguridad:
El valor de retorno suele ser simple, solo un estado:
El problema no es el valor de retorno, es la llamada en sí. Si una lectura sale mal, vuelves a leer y nada ha cambiado. Si una escritura sale mal — digamos que el modelo rellena mal el path, o al content le falta la mitad de lo que debería tener — el contenido original del archivo ya está sobrescrito y no se puede recuperar, a menos que haya control de versiones o una copia de seguridad. Esta es la «asimetría entre herramientas de lectura y herramientas de escritura»: las dos formas de llamada se ven casi idénticas (un path más un par de parámetros), pero una se puede reintentar libremente y la otra se juega todo en cada llamada.
Por eso una herramienta de escritura responsable añade una capa de protección — por ejemplo, exigir que el archivo se haya leído antes de poder editarlo (para impedir que el modelo edite de memoria), o devolver un diff del contenido antiguo frente al nuevo en lugar de un escueto «éxito», de modo que quien la llama (la aplicación host) tenga oportunidad de mostrar el cambio antes de que llegue realmente al disco. No son el foco aquí; la Lección 4 los abre al cubrir el diseño de interfaces.
Ejecutar: una clase de riesgo propia
La herramienta de ejecución de comandos tiene la firma de aspecto más sencillo de las cinco:
Entra una cadena; salen stdout, stderr y un código de salida:
Lo delicado es que este campo command es en esencia un punto de entrada abierto — no es una operación concreta y acotada por un esquema, como «borra este archivo» o «lee esta línea», es un script de shell arbitrario. rm -rf, un curl que manda datos a un servidor externo, un npm install que arrastra un paquete envenenado: todo eso cabe dentro de esa única cadena. Las otras cuatro categorías (leer, escribir, buscar, llamar a API), diseñes como diseñes sus firmas, están limitadas en lo que pueden hacer por su estructura de parámetros. El límite de capacidad de una herramienta de ejecución de comandos es el límite de capacidad de todo el sistema operativo. Por eso está en una clase propia: no «un poco más arriesgada», sino un orden de magnitud distinto de riesgo.
Precisamente por eso, la documentación oficial diseña aislamiento a nivel de sistema operativo específicamente para esta categoría: el acceso al sistema de archivos y el acceso a la red son dos capas de sandbox separadas, y aunque al modelo lo dirija una inyección de prompt y se empeñe en ejecutar un comando peligroso, la frontera del SO se sostiene igualmente — no depende de si el modelo «quiere» cooperar1. La motivación declarada es contundente: el objetivo es que incluso una inyección de prompt exitosa quede totalmente contenida y no pueda escapar del sandbox2. La Lección 5 cubre cómo configurar ese aislamiento; por ahora, quédate con una cosa: donde aparezca la firma de «ejecutar comando», trátala por defecto como la categoría de las cinco que más necesita restricciones adicionales.
Buscar: devuelve ubicaciones, no el mundo entero
Una herramienta de búsqueda (digamos, una que encuentra una palabra clave o una regex en una base de código) suele llevar en su firma un parámetro de «limita cuánto vuelve»:
El valor de retorno no son los archivos en sí, es «dónde está la coincidencia y qué aspecto tiene el contexto de alrededor»:
Si esta herramienta se limitara a meter de vuelta el contenido completo de cada archivo coincidente, aparecen dos problemas. El primero es un problema de tokens: una búsqueda alcanza 50 archivos, cada uno de unos cientos de líneas, todo volcado al contexto — y esta única llamada a herramienta se ha comido el presupuesto de entrada de todo el turno, sin dejar nada con lo que el modelo pueda seguir trabajando3. Escribir descripciones de herramientas y controlar los límites de la entrada y la salida es en sí mismo un requisito básico para que una herramienta sea usable4. El segundo problema importa más: el sentido de buscar no es «leerse todo lo que pueda ser relevante», es «ayudar al modelo a averiguar dónde mirar después». Devuelve las ubicaciones de las coincidencias más un fragmento corto de contexto, el modelo lee esos fragmentos y juzga por sí mismo: «de estos resultados, el segundo parece lo que busco, déjame leer el contenido completo de ese archivo aparte». Así es como una herramienta de búsqueda y una de lectura trabajan juntas: buscar acota el rango, leer consigue el detalle. Devolver «ubicaciones de coincidencia» en vez de «archivos enteros» es exactamente la pista de seguimiento que el modelo necesita, en lugar de un volcado único de todo lo que podría servir.
Llamar a una API externa: fallar es la norma, no la excepción
Las primeras cuatro categorías se quedan casi siempre dentro del sistema local. Llamar a una API externa es distinto — cruza la red, hacia un servicio que no controlas:
Un retorno normal se ve así:
Pero un servicio externo te va a limitar la tasa, agotar el tiempo de espera, rechazar una petición por permisos que faltan y cambiar su propia interfaz en el hueco entre tus llamadas. Estas no son «situaciones inesperadas», son las condiciones normales de funcionamiento de esta categoría. Lo que de verdad decide si la herramienta sirve no es «qué devuelve cuando todo va bien», es «qué devuelve cuando las cosas fallan»:
Este mensaje de error no es para ti, es para el modelo — que a continuación deba reintentar o cambiar de estrategia depende de si puede leer ese campo error. La especificación MCP escribe esto directamente en el protocolo: los clientes deberían proporcionar los errores de ejecución de herramientas a los modelos de lenguaje para que el modelo tenga oportunidad de autocorregirse y volver a intentarlo5. Dicho de otro modo, una herramienta que se traga en silencio un 429 y no devuelve más que «la llamada falló» le está robando al modelo la oportunidad de corregirse; una herramienta que trae de vuelta detalle concreto como retry_after es la que diseña el «fallo» como una parte normal del flujo de trabajo.
La categoría de llamar a API externa arrastra además otra capa de riesgo: si este agente puede leer datos privados al mismo tiempo que está expuesto a contenido no confiable (un fragmento de texto web que un usuario pegó, digamos) y además puede enviar mensajes o peticiones hacia fuera, esas tres cosas juntas son lo que la investigación en seguridad llama la «trifecta letal» — el atacante no necesita entrar en tu sistema, solo esconde una instrucción en contenido que el agente vaya a leer y deja que el propio agente saque los datos privados6. La Lección 5 abre este tema por su cuenta; por ahora, ten claro esto: llamar a una API externa es el último y más crítico eslabón de esa cadena, porque es la salida por la que los datos abandonan realmente tu sistema.
Resumen
- El riesgo no está repartido por igual entre las cinco categorías: leer archivo tiene las consecuencias más leves, escribir archivo es donde las cosas empiezan a ser irreversibles, el radio de impacto de ejecutar comando equivale a todo el sistema operativo, y buscar y llamar a API externa tienen cada una sus propias trampas
- La diferencia central entre herramientas de lectura y de escritura es si puedes reintentar sin peligro — lee mal y vuelves a leer, escribe mal y el contenido original puede haberse ido para siempre
- Las herramientas de ejecución de comandos necesitan un sandbox a nivel de SO como respaldo porque su parámetro
command es una cadena abierta, no acotada por una estructura de esquema como lo están las otras cuatro1 2
- Las herramientas de búsqueda devuelven ubicaciones de coincidencia más fragmentos en lugar de archivos enteros, primero para ahorrar tokens y segundo para separar «localizar» de «leer el detalle», entregándole al modelo una pista que pueda seguir3
- Las herramientas de llamada a API externa deberían llevar la información de fallo (tipo de error, si se puede reintentar) de vuelta al modelo tal cual, en lugar de tragársela — en esta categoría, fallar es la norma, no la excepción5
En la próxima lección desmontamos las «firmas» de estas cinco categorías: cómo escribir un buen nombre de herramienta, descripción, esquema de parámetros y valor de retorno, para que el modelo la llame bien a la primera.
>> Lección 4: Diseñar interfaces de herramientas: nombre, descripción, parámetros, valor de retorno