SKILL.md — Modelo Actor Agha: Diseño de Sistemas de Agentes Concurrentes
Puntos de Decisión
Cómo Elegir la Estrategia de Creación de Actores Según el Tipo de Tarea
SI la tarea tiene dependencias secuenciales:
├─ Usar patrón de cliente: crear hijo con dirección de respuesta
├─ Pasar dirección del cliente al hijo como parámetro
└─ El hijo envía el resultado directamente al cliente (no al padre)
SI la tarea requiere un cómputo largo:
├─ Crear un actor insensible para el cómputo
├─ Reenviar mensajes entrantes a un actor búfer
└─ Reanudar desde el búfer cuando el cómputo termine
SI la tarea necesita asignación dinámica de recursos:
├─ Crear actores gestores de recursos bajo demanda
├─ Pasar capacidades (direcciones) como datos del mensaje
└─ No hay registro central: las direcciones fluyen por el sistema
SI la tarea tiene requisitos de aislamiento de fallos:
├─ Iniciar actores hijos supervisados para operaciones riesgosas
├─ El supervisor detecta fallos por falta de respuestas
└─ Reemplazar actores fallidos sin afectar a otros
SI se están componiendo sistemas de agentes existentes:
├─ Verificar que la interfaz preserve la estructura causal
├─ Probar el comportamiento bajo composición (no solo en aislamiento)
└─ Usar protocolos de mensajes como límites (no estado compartido)
Árbol de Decisión: Envío de Mensajes vs. Reemplazo de Estado
SI se necesita coordinación con otros agentes:
├─ ENVIAR mensajes (no modificar el estado local primero)
├─ Incluir dirección de respuesta si se espera respuesta
└─ Nunca asumir orden de mensajes
SI se necesita cómputo local:
├─ ESPECIFICAR comportamiento de reemplazo
├─ Encapsular el nuevo estado (no exponer detalles internos)
└─ Asegurar procesamiento de un mensaje a la vez
SI se necesita escalado dinámico:
├─ CREAR nuevos actores con comportamientos específicos
├─ Pasar las direcciones necesarias a los nuevos actores
└─ Sin estado de inicialización compartido
Modos de Fallo
1. Anti-patrón del Orquestador Central
Detección: Si un solo actor enruta todos los mensajes o mantiene todo el estado del sistema Síntomas: Punto único de fallo, cuello de botella bajo carga, problema de regresión infinita Solución: Descomponer en una comunidad de actores, cada uno conociendo solo su contexto local, usar enrutamiento por capacidades
2. Falacia del Bloqueo Síncrono
Detección: Si los actores esperan/bloquean por respuestas en lugar de especificar comportamiento de reemplazo Síntomas: Punto muerto bajo carga, suposiciones ocultas de temporización, concurrencia reducida Solución: Modelar como pares de mensajes solicitud-respuesta, usar patrón de cliente para dependencias, aplicar patrón de actor insensible
3. Contaminación por Estado Compartido
Detección: Si múltiples actores leen/escriben la misma estructura de datos (incluso con bloqueos) Síntomas: Condiciones de carrera, cuellos de botella secuenciales, estado global oculto Solución: Encapsular el estado en un solo actor, usar paso de mensajes para coordinación, la exclusión mutua es gratuita
4. Verificación Solo de Salida
Detección: Si las pruebas solo comparan resultados finales sin verificar patrones de interacción Síntomas: Anomalía de Brock-Ackerman: salidas idénticas pero diferente comportamiento bajo composición Solución: Verificar preservación de la estructura causal, probar el comportamiento bajo composición, usar equivalencia de observación
5. Suposición de Topología Estática
Detección: Si el grafo de comunicación se fija al inicio sin reconfiguración en tiempo de ejecución Síntomas: No puede manejar sistemas abiertos, sin gestión dinámica de recursos, frágil ante cambios Solución: Tratar las direcciones como datos de primera clase, implementar enrutamiento por capacidades, soportar cambios de topología en tiempo de ejecución
Ejemplos Prácticos
Ejemplo 1: Descomposición de Tareas con Patrón de Cliente
Escenario: Un agente necesita procesar una solicitud compleja que requiere subtareas secuenciales A → B → C, pero debe permanecer receptivo a otros mensajes.
Enfoque Novato:
recibir solicitud →
bloquear mientras se llama a la subtarea A
bloquear mientras se llama a la subtarea B
bloquear mientras se llama a la subtarea C
enviar resultado final
Aplicación Experta del Modelo Actor:
recibir solicitud →
crear actor cliente_BC con direcciones para B, C, destinatario final
enviar solicitud de subtarea A a procesador_A con cliente_BC como dirección de respuesta
especificar comportamiento de reemplazo: listo para la siguiente solicitud
cliente_BC recibe resultado de A →
enviar resultado a procesador_B con cliente_C como dirección de respuesta
cliente_C recibe resultado de B →
enviar resultado a procesador_C con destinatario_final como dirección de respuesta
Decisiones Clave Tomadas:
- Se usó el patrón de cliente para evitar el bloqueo
- Cada paso crea el siguiente cliente en la cadena
- El agente original permanece receptivo durante todo el proceso
- Un fallo en cualquier subtarea solo afecta a esa cadena
Ejemplo 2: Recuperación de Fallos con Supervisión
Escenario: El sistema necesita manejar fallos de agentes sin que se propaguen a todo el sistema.
Enfoque Novato: Try-catch alrededor de las llamadas a agentes, reiniciar todo en caso de fallo.
Aplicación Experta:
el supervisor crea actor_trabajador →
envía tarea al trabajador con tiempo de espera de respuesta
especifica reemplazo: "esperando_respuesta"
SI se recibe respuesta dentro del tiempo de espera →
reenviar resultado al cliente
especificar reemplazo: "listo"
SI el tiempo de espera expira →
crear nuevo actor_trabajador (el anterior falló)
reenviar tarea al nuevo trabajador
especificar reemplazo: "esperando_respuesta"
Compensaciones Navegadas:
- La supervisión es una preocupación separada de la lógica de negocio
- Los actores fallidos se aíslan y reemplazan, no se reparan
- Equilibrio entre detección por tiempo de espera y entrega garantizada
- Sin estado compartido entre supervisor y trabajadores
Puertas de Calidad
- Ningún actor bloquea su bucle de procesamiento de mensajes (se aplica el patrón de actor insensible donde sea necesario)
- Toda la coordinación usa paso de mensajes (sin estado mutable compartido entre actores)
- La entrega de mensajes está garantizada, pero no se asume orden
- Las direcciones se tratan como datos de primera clase para el enrutamiento por capacidades
- Cada actor especifica un comportamiento de reemplazo para cada tipo de mensaje
- La creación de actores ocurre dinámicamente según las necesidades de cómputo
- El aislamiento de fallos evita que los fallos se propaguen a través de los límites de los actores
- La topología del sistema puede reconfigurarse en tiempo de ejecución sin registro central
- El comportamiento bajo composición está verificado, no solo el comportamiento aislado de los componentes
- Las operaciones síncronas se modelan como pares de mensajes solicitud-respuesta
Límites NO-PARA
Este skill NO debe usarse para:
- Cómputos secuenciales simples → usar programación funcional en su lugar
- Sistemas donde se requiera memoria compartida físicamente → usar patrones de concurrencia basados en bloqueos
- Sistemas en tiempo real con restricciones de temporización estrictas → usar paso de mensajes síncrono con análisis de temporización formal
- Cómputos matemáticos sin coordinación → usar enfoques funcionales puros
Delegar a otros skills cuando:
- Se implementen marcos de actores específicos → usar guías de implementación específicas de la plataforma
- Se realice optimización de rendimiento de sistemas de actores → usar el skill [optimización-de-rendimiento]
- Se necesite verificación formal de propiedades de actores → usar el skill [métodos-formales]
- Se diseñen bases de datos para persistencia de actores → usar el skill [arquitectura-de-datos]
Ideas erróneas comunes sobre el alcance:
- Los actores no son solo "objetos con métodos asíncronos" - requieren la tripleta completa de respuesta
- El modelo de actores no es solo para sistemas distribuidos - aplica a cualquier cómputo concurrente
- No es principalmente una optimización de rendimiento - es un marco para corrección y composicionalidad