Un modelo de lenguaje solo produce texto. Para que un sistema haga algo, como leer un archivo, consultar una base de datos o abrir un pull request, ese texto tiene que conectarse con código que se ejecuta. La forma estándar es el (llamadas a herramientas), y su regla fundamental cabe en una línea: el modelo pide, tu programa ejecuta.
En esa frontera se decide casi todo lo que importa en un . Esta lección cubre cuatro ideas: qué es una herramienta, qué tiene que pasar entre una solicitud y su ejecución, qué es un y por qué importa quién controla el bucle, y por qué toda acción debería pasar por un único punto de control.
Qué es una herramienta
Piensa en la carta de un restaurante: los clientes leen nombres y descripciones y piden, pero nunca entran a la cocina. Una herramienta tiene cuatro partes, y solo las tres primeras, la carta, llegan al modelo:
| Parte | Qué es | Quién la usa |
|---|---|---|
| Nombre | una etiqueta única, como read_file |
el modelo, para pedirla |
| Descripción | cuándo y para qué usarla | el modelo, para decidir |
| Esquema de entrada | una descripción formal de los datos que acepta | el modelo escribe los datos, el sistema los revisa |
| Handler | el código que se ejecuta | solo el sistema |
El handler es la cocina: nunca sale de tu programa. Todo lo demás en esta lección se apoya en esa separación.
De la solicitud a la ejecución
Para usar una herramienta, el modelo responde con una solicitud: el nombre de la herramienta y sus datos de entrada, llamados argumentos. Antes de que pase algo en el mundo, un sistema cuidadoso recorre cinco pasos:
- Leer los argumentos. Llegan como texto que debería contener JSON (un formato estándar de datos), y a veces no lo contiene.
- Validar. ¿Existe la herramienta? ¿Están los datos obligatorios?
- Autorizar. ¿Puede este agente hacer esta llamada con estos datos?
- Ejecutar el handler, con un límite de tiempo.
- Devolver la salida como un resultado atado a la solicitud original, para la siguiente ronda del modelo.
Las demos suelen saltarse los pasos 1 a 3. Los sistemas serios concentran ahí la mayor parte de su lógica.
Ante la duda, rechazar
El modelo puede escribir argumentos rotos: JSON inválido, una lista en vez de un objeto o nada. La regla es fallar cerrado (fail closed): si no puedes leer una solicitud, no puedes evaluarla, y una solicitud que nadie evaluó no debe ejecutarse.
Los errores también son resultados
La herramienta se ejecutó y falló es información útil sobre la que el modelo puede actuar. La herramienta no se ejecutó porque no estaba permitido es una protección funcionando. Un sistema ingenuo los confunde; uno bueno le informa ambos al modelo con palabras, porque el silencio hace que el modelo reintente a ciegas. El resultado además debe llevar el identificador de la solicitud, o muchos proveedores rechazan la conversación entera. Los resultados de docket dicen qué caso ocurrió (rechazada y por qué, esperando aprobación, falló, o la salida) y se construyen a partir de la solicitud original, así que no pueden quedar asociados a otra.
Varias llamadas a la vez
Una respuesta puede pedir varias herramientas. Eso no significa que deban correr al mismo tiempo: las lecturas independientes pueden; dos escrituras sobre lo mismo no deberían. docket las ejecuta una tras otra, en orden, revisa su límite de llamadas contra el lote completo antes de empezar (ver De la aplicación con LLM al agente) y guarda la solicitud y todos sus resultados como una sola unidad.
Qué es un harness
Todo lo anterior exige mucho código ajeno a la tarea: límites, guardar el estado, permisos, aprobaciones, registro, contexto, particularidades de cada proveedor. Ese código es el harness (literalmente, el arnés).
Lee las capas de arriba hacia abajo, del puro texto a las consecuencias reales:
- Modelopredice texto; no ejecuta nada
- Agentemodelo + objetivo + bucle de decisión
- Harnessejecuta el bucle, decide qué se permite
- Herramientas y entornoarchivos, procesos, APIs, dinero
Productos como Claude Code son agente y harness a la vez. Separar ambos permite hacer la pregunta clave: ¿quién tiene la última palabra cuando el modelo pide ejecutar algo?
Controlar el bucle o envolverlo
Un framework de agentes suele ejecutar el bucle por ti, así que tus controles solo pueden vivir donde te deja conectarte (, callbacks). Si no hay un lugar donde conectarte antes de cada acción, no puedes decidir ahí.
- Envolver un bucleel framework ejecuta cada turno
- Tus controles van donde hay hooks
- Quizás ninguno antes de la acción
- Controlar el bucletu código ejecuta cada turno
- Controles antes de cada acción
- Protocolos estándar reutilizados
Políticas probadas y documentadas que no protegían nada: ese es el riesgo de envolver el bucle de otro sin revisar dónde puedes intervenir. Usar un framework no está mal en sí.
Un único punto de control para cada acción
Si hay dos caminos para ejecutar una herramienta y solo uno tiene controles, el sistema no tiene controles. Toda llamada debería pasar por un único (punto de estrangulamiento): una función que concentra todos los controles.
En docket
- ¿Cancelado?si es así, se detiene antes de ejecutar
- Herramienta y argumentosdesconocida o ilegible, se rechaza
- Decisión de políticapermitir, preguntar o denegar; gana la más estricta
- Aprobación humanasolo si la respuesta es preguntar
- Ejecutar el handleruna caída se vuelve un resultado
core/tools.pyUn comentario que diga "no agregues otro camino" se puede ignorar, así que docket lo convierte en una prueba. La prueba lee el código fuente del proyecto y falla si algún módulo fuera de una lista corta de permitidos importa los handlers. Una protección así cubre exactamente lo que codifica, un tipo de atajo, no todos los imaginables. Más en Testing y evals para agentes; las decisiones de permitir, preguntar o denegar están en Gobernanza y human-in-the-loop.
En la práctica
- Decide a conciencia si construir o adoptar el harness. Construirlo da control total de cada punto de control, pero obliga a mantener código que no te diferencia; adoptarlo es más rápido, pero tu gobernanza termina donde terminan los hooks del proveedor.
- Pide pruebas, no una lista de funciones: mira una regla de denegación bloquear de verdad una llamada en tu propio entorno.
- Haz que las herramientas riesgosas se puedan repetir sin daño, porque el modelo puede pedir dos veces.
- Mantén un solo camino a la ejecución, y prueba que siga siendo uno.
Para profundizar
La documentación de docket registra cómo construyó y verificó esta frontera (en inglés):
- ADR 0002: own the loop, rent the protocols es la decisión en sí: por qué docket dejó el programa externo y descartó los frameworks de agentes.
- Security: layered and convention-based explica el control de llamadas a herramientas siempre activo, cómo lee los argumentos de un comando y no solo su nombre, y quién puede responder una aprobación.
- DOCKET Architecture describe cómo está organizado en capas el código de docket y muestra que las herramientas de servidores externos pasan por el mismo punto de control.
Para llevar
- Una herramienta es un anuncio (nombre, descripción, esquema de entrada) más un handler que nunca llega al modelo.
- Entre la solicitud y la ejecución están la lectura, la validación y la autorización; ante la duda, rechazar.
- Los rechazos y errores vuelven al modelo con palabras, atados a la solicitud que responden.
- Quien controla el bucle controla los puntos donde se puede intervenir; envolver el bucle de otro puede dejar tus políticas sin efecto.
- Un único chokepoint solo es real si algo lo verifica, como una prueba que lee el código.
Comprueba lo aprendido
Llega una solicitud de herramienta con argumentos que no son JSON válido. ¿Por qué rechazarla en vez de adivinar?
Si el sistema no puede leer la solicitud, no puede juzgar si está permitida, y una solicitud sin evaluar no debe ejecutarse. Guardar el texto original además permite que la auditoría muestre exactamente qué pidió el modelo.
Un framework ofrece hooks de políticas, pero solo corren después de cada llamada a una herramienta. ¿Cuál es el problema?
Una política que corre después de la acción puede observarla, pero nunca detenerla. A docket le pasó una versión de esto: mientras envolvía un bucle que no controlaba, sus políticas nunca se evaluaron, y por eso decidió controlar el bucle.
Una prueba verifica que solo unos pocos módulos permitidos importen los handlers de las herramientas. ¿Qué garantiza y qué no?
Garantiza que al módulo de handlers solo se llega desde los lugares permitidos, como el chokepoint. No puede detectar caminos que eviten esa importación: el handler de descarga web de docket vive en su propio módulo, e importarlo directamente desde otro lugar no haría fallar la prueba.