El agente que sí puede hacer cosas
Un modelo sin herramientas es un modelo que sólo habla. Acá explicamos cómo Aleph le da acceso real al sistema de archivos y la terminal, con un sistema de permisos que no es un chiste.
La diferencia entre un chatbot y un agente de código es simple: el agente puede hacer cosas. Leer archivos, escribir código, ejecutar comandos, buscar en el proyecto. Si sólo puede generar texto que después vos tenés que copiar y pegar a mano, eso es un chatbot con mejor prompting.
Aleph tiene un sistema de herramientas. El modelo las invoca, el backend las ejecuta, el resultado vuelve al modelo. Y así en loop hasta que la tarea esté terminada.
Las herramientas disponibles
src/**/*.ts). Para orientarse en proyectos grandes.El sistema de permisos
No todas las herramientas son iguales. Leer un archivo es muy distinto a ejecutar un comando shell. Por eso cada herramienta tiene un nivel de riesgo, y el modo del agente determina qué se permite automáticamente y qué requiere confirmación:
- Read: siempre permitido automáticamente. Si sólo está leyendo, que lea.
- Write: en modo Build se permite automáticamente; en modo Plan requiere confirmación explícita.
- Exec: siempre requiere confirmación del usuario, sin importar el modo. Ejecutar código arbitrario es lo más peligroso que puede hacer el agente.
La seguridad no es un checkbox. Si el modelo quiere ejecutar rm -rf, que el usuario lo sepa antes de que pase.
Además de los niveles de riesgo, todas las herramientas de escritura y lectura de archivos están restringidas al directorio del proyecto activo. El modelo no puede leer ~/.ssh/id_rsa aunque lo intente, porque el backend valida que la ruta resuelta esté dentro del árbol del proyecto.
El loop del agente
El flujo de un turno de agente es este:
- El modelo recibe el mensaje del usuario más el historial.
- Si quiere usar una herramienta, responde con un tool call en lugar de texto.
- El backend verifica el riesgo y pide confirmación si hace falta.
- Se ejecuta la herramienta y el resultado se agrega al historial.
- El modelo recibe ese resultado y decide si necesita otra herramienta o ya puede responder.
Esto se repite hasta que el modelo genera una respuesta de texto final (sin tool call). El número de iteraciones tiene un límite configurable para no entrar en loops infinitos.
Lo que aprendimos implementando esto
El mayor desafío no fue técnico: fue de prompt engineering. Lograr que el modelo use las herramientas de manera eficiente (sin repetir lecturas innecesarias, sin sobreescribir archivos que ya estaban bien) requirió bastante iteración en el system prompt y en cómo describimos cada herramienta.
También aprendimos que la gramática GBNF (que restringe el output del modelo al formato JSON de tool call) ayuda mucho a la fiabilidad. Con gramática libre, el modelo a veces "olvidaba" el formato correcto. Con GBNF, no puede.
El resultado es un agente que puede leer tu proyecto, entender qué está pasando, y proponer cambios concretos, sin que vos tengas que copiar y pegar nada.