Hay gente que planta cuatro lechugas y las riega cuando se acuerda, y luego está Javier de la Torre, fundador de CARTO, que planta cuatro lechugas y acaba montando un lakehouse, ocho sondas de humedad, una cámara, una estación meteorológica y un agente de IA que decide cuánto se riega cada mañana. Lo cuenta en I gave an agent a lakehouse and control of my garden, y él mismo reconoce que el proyecto ya estaba “acercándose a la fase de la lechuga de 60 €”.
Más allá de la gracia (que la tiene), es uno de los ejemplos más completos y honestos que he leído de un agente con las manos en el mundo físico, con datos de verdad, un actuador de verdad y los problemas de verdad que aparecen cuando juntas todo eso.
El montaje
El huerto es un bancal elevado de unos dos metros cuadrados con brócoli, col, lechuga y espinacas, más el césped de alrededor. Para medirlo usa sensores Ecowitt (unos 300 €): ocho sondas de humedad del suelo repartidas entre el bancal y el césped, una estación meteorológica, un sensor de humedad foliar y el propio gateway. A eso se suma una cámara Reolink apuntando al bancal y un programador de riego Rain Bird con dos zonas, los aspersores del césped y el goteo del bancal.
Todo acaba en LakehouseBox, un lakehouse sobre tablas Apache Iceberg en Parquet, alojado en infraestructura europea:
flowchart LR
S["Sensores Ecowitt · cada 60 s"] -->|HTTP POST| L[("Lakehouse · Iceberg")]
C["Cámara Reolink"] -->|FTPS| L
M["Open-Meteo · AEMET"] -->|DuckDB programado| L
L --> A["Agente · 08:45"]
A -->|correo| J["Javier"]
A -->|API mínima| P["Android viejo · app Rain Bird"]
P --> R["Riego"]Me gusta mucho una de sus lecciones: los dispositivos son simples y hay que aceptarlos como vienen. El gateway hace un POST HTTP cada minuto con su formato, la cámara sube fotos por FTP como hace veinte años, y en lugar de obligarlos a hablar algo moderno, la plataforma se adapta a ellos. La previsión meteorológica la trae una consulta de DuckDB programada a las 5:30 contra Open-Meteo, y los datos de una estación oficial de AEMET sirven de referencia. Desde el 18 de septiembre lleva más de 4 millones de lecturas en unos 62 MB entre las siete tablas (las fotos sí pesan: unos 3 GB). Parquet e Iceberg haciendo lo que mejor saben hacer, algo de lo que ya hablé con Iceberg v3 y los datos geoespaciales.
El agente
Cada mañana a las 8:45, justo después del riego, un agente consulta el histórico y la previsión, decide si hay que tocar algo y le manda un correo con cuatro bloques: qué ha pasado, qué cambia, por qué y qué le ha llamado la atención. “No quiero un informe, quiero un mensaje”, dice Javier. Tiene herramientas para lanzar SQL contra el catálogo, una memoria persistente y su propio registro de decisiones (agent_log), donde apunta qué decidió, qué espera que pase y cuándo debe revisarlo.
El prompt funciona como una descripción del puesto, y ahí van los límites del riego:
| Límite | Valor |
|---|---|
| Cambios por zona y ejecución | 1 como máximo |
| Variación por cambio | 20 % como máximo |
| Minutos por zona | entre 1 y 15 |
| Apagar el riego | sólo con 5 mm o más de lluvia prevista en 24 h |
Y el actuador es la parte que más me ha hecho reír: el programador Rain Bird va por Bluetooth con un protocolo propio, así que la solución ha sido un móvil Android viejo junto a la válvula que maneja la app oficial como lo haría una persona: abre el programa, cambia los minutos, guarda y espera a que sincronice. Javier lo llama “absurdo”, y lo es, pero funciona. El agente lo usa a través de una API mínima con una clave que nunca llega a ver.
Lo que salió (y lo que no)
Lo interesante es que el agente encuentra cosas. Detectó que una esquina del bancal estaba seca (21 %) y pidió un goteo extra allí, vio que una zona del césped se secaba más que el resto y, cuando una nota antigua de su memoria tenía mal la hora del riego, se fió de los datos y no de la nota. También avisa de las baterías bajas de tres sensores… y lleva 29 días haciéndolo. En su registro ya escribe en mayúsculas que la fecha de las heladas se acerca. Las baterías, por supuesto, siguen sin cambiar (y aquí me reconozco bastante).
Lo que no vio fue a las orugas. Los agujeros en las hojas eran de unos pocos píxeles en la foto de la cámara, y sólo aparecieron con fotos de cerca hechas con el móvil. Lo que sí captó fue al gato del vecino usando el bancal de baño por las noches.
Y luego están los problemas abiertos, que Javier cuenta sin esconderlos: el gateway no reintenta los envíos y un minuto sin Internet es un hueco en los datos, y el túnel hasta el móvil pasa por un servicio de fuera de Europa.
Los límites, en la válvula
De todo el artículo, la frase con la que me quedo es esta: los límites deben estar en lo que abre la válvula, no en las instrucciones de lo que decide. Hoy esos límites viven en el prompt, y el propio Javier lo apunta como lo siguiente que quiere cambiar, con una herramienta “deliberadamente aburrida” (zona, minutos, parar) que el agente no pueda saltarse.
Es exactamente lo que pienso cuando digo que la IA es un becario: le das tareas claras y lo supervisas, pero las llaves del cuarto de máquinas no se las das porque se lo hayas pedido por favor en sus instrucciones. Un prompt es una petición, no una garantía. Si el riego se pasa en un huerto, el coste es una lechuga ahogada; en un sistema de producción, el equivalente puede ser bastante más caro.
El resto de conclusiones también me parecen acertadas: el agente sustituye al clásico motor de reglas del IoT porque puede pesar muchas variables a la vez y explicar lo que hace, necesita histórico y no sólo el último valor, y los formatos abiertos importan todavía más cuando el que lee los datos es un agente. Lo que antes pedía un equipo de datos ahora son unas cuantas tardes y unos cuantos prompts, y eso abre este tipo de proyectos a cosas tan pequeñas como un bancal. El código está en GitHub, por si alguien quiere tener también su lechuga de 60 €.




