Inventariar los agentes de Lelemon para una auditoría
Documento para el equipo de cumplimiento o de tecnología que tiene que armar, y mantener al día, el inventario de los agentes de Lelemon de su organización: qué agentes hay, cómo están configurados y, sobre todo, a qué terceros viajan los datos de las personas que atienden. Sirve, por ejemplo, para alimentar el registro de actividades de tratamiento (Ley 21.719). Alcanza para implementarlo sin preguntarnos nada.
Base de la API de Lelemon: https://api.lelemon.cl
Qué resuelve esto
Un agente contesta, consulta conocimiento y, si tiene acciones, manda datos a otros sistemas: un ticket al sistema de soporte, un webhook a un n8n, un pedido a un ERP. Para el registro, lo que importa de cada agente es eso: qué datos puede mandar y hacia dónde.
Son tres lecturas, de la más general a la más fina:
- Listar los agentes.
- Leer cada uno: su prompt, su modelo, sus topes, sus canales, su conocimiento y las acciones que tiene concedidas, con el origen de cada destino.
- Mantenerlo al día: releer sólo los agentes que cambiaron desde la última vez, mirando
updatedAt.
Todo va con la credencial de organización en la cabecera Authorization:
Code
Qué alcances pide cada cosa
| Qué quieren ver | Alcance |
|---|---|
| Los agentes, su configuración, su prompt y sus acciones concedidas (slug, nombre, descripción) | agents:read |
| Las colecciones de conocimiento de cada agente | knowledge:read además |
| A qué origen sale cada acción (HTTP, servidor MCP o conector), y el catálogo de acciones de un agente | actions:read además |
Para un inventario completo emitan una credencial con agents:read, knowledge:read y actions:read. Ninguna escribe: con esas tres no se puede cambiar nada en ningún agente.
El origen viaja con actions:read y no con un permiso aparte porque no abre ninguna puerta: el origen nunca fue el secreto. El secreto es el path (ver más abajo), y ese no sale con ningún alcance. Sin actions:read, el campo destinationOrigin no aparece en la respuesta: no viene vacío ni en null, simplemente no existe.
1. Listar los agentes
Code
Alcance: agents:read. Devuelve una página:
Code
Mientras hasMore sea true, repitan el pedido sumándole limit al offset. El techo de limit es 500.
La lista trae todos los estados (draft, active, paused, archived): un agente pausado sigue teniendo configurada la salida de datos, y conviene que el inventario lo incluya. No trae los borrados, ni al asistente interno de la organización: esa superficie no se administra por API, en ninguna ruta.
Sale del más nuevo al más antiguo. Si se crea un agente mientras recorren las páginas, uno puede aparecer dos veces: deduplíquenlo por id.
2. Leer cada agente
Code
Alcance: agents:read. Con knowledge:read suma knowledge; con actions:read, cada acción suma destinationOrigin. Las acciones que salen en actions son las que el agente tiene concedidas hoy y puede usar: las nativas de Lelemon, las HTTP que registraron ustedes, las de sus servidores MCP y las de sus conectores.
Code
Cómo se lee destinationOrigin
| Valor | Significa |
|---|---|
"https://n8n.suempresa.cl" | La acción manda datos a ese sistema. Es esquema, host y puerto si lo trae (https://api.suempresa.cl:8443). Vale para una llamada HTTP que registraron ustedes, para una acción de un servidor MCP que conectaron (es el origen del servidor) y para una de un conector (es el sitio que conectaron, como https://suempresa.atlassian.net, o el host de BigQuery). |
null | Es una herramienta nativa de Lelemon (buscar en el conocimiento, recordar datos del caso, agendar, correo, herramientas del CRM) y no tiene un destino que ustedes hayan configurado. También vale null para una acción concedida que ya no existe, que el agente no puede ejecutar. Ver "Qué significa null". |
"(ilegible)" | La acción sale a un destino —HTTP, servidor MCP o conector— pero su dirección guardada no se pudo interpretar. Hay que mirarla en el panel. |
| el campo no está | La credencial no tiene actions:read. |
Qué significa null
null dice una sola cosa: la acción es una herramienta de la plataforma y el destino no lo eligieron ustedes. No dice que los datos no salgan de Lelemon. Algunas nativas usan proveedores que son de Lelemon y no varían por organización: el envío de correo, el calendario, la facturación electrónica. Esos proveedores son encargados de tratamiento de Lelemon, van en el registro como tal y no aparecen en este campo. Una acción que sí sale a un tercero que ustedes pusieron nunca viene en null: viene con su origen o con "(ilegible)".
La lista de acciones que registraron ustedes (GET /v1/external/actions) trae el mismo dato, como origin, con el mismo alcance: es el mismo origen visto por acción en vez de por agente. La lectura por agente es la que responde "¿a dónde manda datos este agente?".
El catálogo de un agente
Code
Alcance: actions:read. Devuelve el catálogo entero que ese agente puede tener, con enabled diciendo cuáles tiene concedidas hoy y source diciendo de dónde vienen (Tus sistemas, Lelemon, o el nombre del servidor MCP o el conector). Cada entrada trae el mismo destinationOrigin. Sirve para separar lo que el agente tiene de lo que podría tener: para el registro cuenta lo primero, y enabled: true es el filtro. Las acciones de servidores MCP y de conectores traen su origen igual que las HTTP.
Qué entrega y qué no, a propósito
| Se entrega | No se entrega |
|---|---|
| El prompt, entero | La URL completa de cada acción, servidor MCP o sitio de conector |
| Modelo y proveedor, topes de vueltas y de tokens | El path y la query de la URL |
| Canales y si están conectados | Los valores de las cabeceras (credenciales del sistema de ustedes) |
| Las colecciones de conocimiento asignadas | Las llaves del proveedor del modelo |
| Las acciones concedidas: slug, nombre y descripción | Los datos de contacto que hay en el perfil del agente |
El origen de cada acción (HTTP, MCP o conector), con actions:read |
Por qué el destino sale como origen y no como URL
Es el argumento central de esta guía, y no una limitación que vayamos a levantar: el origen nunca fue el secreto. El secreto es el path.
En un webhook de n8n, el path es el token. Quien tiene https://n8n.suempresa.cl/webhook/a7f3-... puede disparar el flujo de ustedes, sin más credencial. Entregar la URL completa a un inventario sería entregar la llave de cada integración a cualquiera que lea el inventario: el auditor, la planilla donde se copia, el correo donde se adjunta. Una URL puede además traer usuario y clave antes del host.
Y para el registro no hace falta. Lo que la ley pide saber es a qué tercero viajan los datos, y de ahí dónde está y quién es: eso lo dice el origen. Del path, lo único que se podría aprender es cuál flujo de ese tercero, y eso ya lo dice el nombre y la descripción de la acción.
Por eso ninguna credencial, con ningún alcance, recibe el path. El origen sí sale con actions:read: es justo el dato que una auditoría necesita y no sirve para entrar a nada.
Lo que el inventario no cubre
- Los proveedores de la plataforma. Las herramientas nativas (correo, calendario, facturación electrónica) usan proveedores de Lelemon, que son los mismos para todas las organizaciones. Salen con
destinationOrigin: nully van en el registro como encargados de tratamiento de Lelemon. - La finalidad y el país de destino que se declararon al autorizar cada acción (art. 15 bis) no se leen por API. Quedan registrados en la organización.
- Las conversaciones y los datos de las personas. El inventario describe el agente, no lo que ha atendido.
3. Mantener el inventario al día
Un inventario que se armó una vez deja de ser verdad el día que alguien concede una acción nueva o cambia a dónde apunta una. Se mantiene mirando updatedAt de cada agente y releyendo sólo los que cambiaron.
Qué mueve updatedAt
updatedAt de un agente cambia cuando cambia cualquiera de estas cosas:
- Sus ajustes: prompt, modelo, topes, canales, estado.
- Las acciones que tiene concedidas: se concede o se quita una.
- Lo que hace una acción que tiene concedida: se edita su dirección, su descripción o sus parámetros, se da de baja, o se borra. Una acción es de la organización y la comparten varios agentes, así que editarla mueve
updatedAtde todos los que la tienen. - Lo mismo para un servidor MCP y para un conector: cambiar la dirección del servidor, desconectarlo, que anuncie otro catálogo de herramientas, o cambiar el sitio o los límites del conector mueve a todos los agentes que tienen herramientas suyas.
Es un invariante de la base de datos: lo cumple el panel, la API y cualquier otra forma de escribir.
No lo mueven, a propósito, las llamadas de los agentes, la salud de un servidor MCP ni volver a verificar una credencial: nada de eso cambia a dónde van los datos.
Dos cosas que updatedAt no refleja, y que conviene releer de vez en cuando: las colecciones de conocimiento asignadas y si un canal está conectado. Ninguna de las dos cambia a dónde van los datos personales.
version no sirve para esto
version es el candado de expectedVersion al modificar un agente con PATCH: sube cuando se modifica el agente (PATCH, activar, pausar, dar de baja) y sirve para que dos personas no se pisen. No sube al conceder o quitar una acción, ni al editar una acción. Si subiera al editar una acción, cualquier PATCH que alguien preparó leyendo el agente antes recibiría un 409 por un cambio que ese PATCH ni toca. Para saber si algo cambió, usen updatedAt.
El ciclo
La primera vez se lee todo. Desde la segunda:
GET /agentsy se siguen las páginas hastahasMore: false. Cada agente trae suidy suupdatedAt.- Se compara contra lo guardado la vez anterior, agente por agente:
- un
idque no estaba: es nuevo, se lee; - un
updatedAtdistinto del guardado: cambió, se lee; - el mismo
updatedAt: no cambió, no se lee; - un
idguardado que ya no está en la lista: se dio de baja o se borró, va a revisión.
- un
- De cada agente que se lee,
GET /agents/{agentId}. Se guarda suupdatedAty lo que importa:status,systemPrompt,model,channels,knowledgey, por cada acción,slugydestinationOrigin. - Se compara con la lectura anterior de ese agente. Lo que cambió va a revisión de una persona.
Se compara el updatedAt contra el guardado de ese mismo agente, y no contra la hora del reloj de ustedes: así no hay que preocuparse por relojes desfasados.
Un cambio de origen es lo que más importa del ciclo: pasar de n8n.suempresa.cl a otro host es un tercero nuevo, y el registro hay que actualizarlo.
Una lectura completa cada semana, ignorando updatedAt, cubre lo que la fecha no refleja (las colecciones de conocimiento y la conexión de los canales).
Cuánto cuesta
El techo es de 200 pedidos por minuto desde una misma dirección IP (y 3.000 por credencial). La primera vez, un inventario de N agentes son 1 + N pedidos (y una página más cada 500 agentes). Después son 1 + K, con K los agentes que cambiaron, que casi siempre son pocos. Con hasta 200 pedidos entra en un minuto; con más, espacien los pedidos y reintenten con un 429. Una lectura diaria alcanza para la mayoría de las organizaciones.
Ejemplo con curl
Code
Códigos de estado
| Código | Cuándo |
|---|---|
200 | Lectura correcta. |
401 | Credencial ausente, revocada o inválida. |
403 | A la credencial le falta agents:read (o actions:read en el catálogo). En la lectura de un agente, si le falta actions:read no da 403: responde sin destinationOrigin. |
404 | El agente no existe, no es de la organización, o es el asistente interno. |
429 | Pasaron un techo por minuto: 3.000 pedidos por credencial o 200 por dirección IP. Esperen lo que diga Retry-After. |