Máquina de Estados Finitos: Implementación Formal
Abstract: El Árbol de la Vida se modela como una máquina de estados finitos determinista (FSM) donde los nodos representan las 10 Sefirot, las transiciones los 22 Senderos, y el estado compartido contiene toda la información del proceso de manifestación. Este documento especifica formalmente la estructura, transiciones, condiciones de routing y garantías del sistema.
1. Definición Formal
1.1 Especificación Matemática
La máquina de estados del Árbol de la Vida se define formalmente como una quíntupla:
M = (Q, Σ, δ, q₀, F)
Donde:
- Q: Conjunto finito de estados = {Kéter, Jojmá, Biná, Jésed, Guevurá, Tiféret, Nétsaj, Hod, Yesod, Maljut}
- Σ: Alfabeto de entrada = TreeOfLifeState (estado compartido)
- δ: Función de transición: Q × Σ → Q
- q₀: Estado inicial = Kéter
- F: Estado final = {Maljut}
1.2 Estructura del Estado Compartido
class TreeOfLifeState(TypedDict):
# Mundo de Atzilut (Emanación)
intention_raw: str # Input del usuario sin procesar
intention_clean: str # Intención destilada (Kéter)
possibilities: List[str] # Opciones generadas (Jojmá)
structure: Dict[str, Any] # Organización conceptual (Biná)
# Mundo de Beriah (Creación)
expansions: List[str] # Ampliaciones propuestas (Jésed)
constraints: List[str] # Límites establecidos (Guevurá)
balanced_decision: str # Decisión equilibrada (Tiféret)
expansion_score: float # Métrica de expansión [0-1]
constraint_score: float # Métrica de contracción [0-1]
# Mundo de Yetzirah (Formación)
emotional_charge: str # Carga motivacional (Nétsaj)
detailed_plan: Dict[str, List[str]] # Plan estructurado (Hod)
integrated_vision: str # Visión completa (Yesod)
# Mundo de Assiah (Acción)
concrete_action: str # Acción específica (Maljut)
# Metadatos
current_sephira: str # Estado actual
path_taken: List[str] # Historial de transiciones
iteration_count: int # Contador de loops
max_iterations: int = 20 # Límite de rebalanceo
2. Diagrama de Estados
2.1 Representación Gráfica
┌────────────────────────────────────────────────────────────┐
│ │
│ [START] → KÉTER │
│ ║ │
│ ┌──────╬──────┐ │
│ ║ ║ │
│ JOJMÁ ←─────→ BINÁ │
│ ║ ║ │
│ └──────╬──────┘ │
│ ║ │
│ ┌────▼────┐ │
│ │TIFÉRET │◄────┐ (Orquestador) │
│ │ (HUB) │ │ │
│ └────┬────┘ │ │
│ │ │ │
│ ┌──────┼──────┐ │ │
│ ║ │ ║ │ │
│ JÉSED ║ GUEVURÁ │
│ ║ │ ║ │ │
│ └──────┼──────┘ │ │
│ │ │ (loop rebalanceo) │
│ ▼ │ │
│ ┌──────────┐ │ │
│ │ balanced? ├─────┘ │
│ └────┬─────┘ │
│ │ YES │
│ ┌────┼────┐ │
│ ║ ║ │
│ NÉTSAJ ←───→ HOD │
│ ║ ║ │
│ └────╬────┘ │
│ ║ │
│ YESOD │
│ ║ │
│ MALJUT → [END] │
│ │
└────────────────────────────────────────────────────────────┘
Leyenda:
║ = Transición fija (siempre ocurre)
←─→ = Interacción/sincronización
─┐ = Decisión condicional
▼ = Flujo descendente
2.2 Estados del Sistema
| Estado | Tipo | Descripción | Salidas Posibles |
|---|---|---|---|
| Kéter | Inicial | Punto de entrada, captura intención | → Jojmá, Biná |
| Jojmá | Generador | Genera posibilidades infinitas | → Biná |
| Biná | Estructurador | Organiza conceptualmente | → Tiféret |
| Tiféret | Orquestador | Evalúa balance y decide ruta | → Jésed, Guevurá, Nétsaj, Hod, Yesod |
| Jésed | Expansor | Amplifica posibilidades | → Tiféret |
| Guevurá | Limitador | Establece restricciones | → Tiféret |
| Nétsaj | Cargador | Añade emoción | → Yesod |
| Hod | Planificador | Detalla pasos | → Yesod |
| Yesod | Integrador | Sintetiza visión completa | → Maljut |
| Maljut | Final | Genera acción concreta | → END |
3. Tabla de Transiciones
3.1 Transiciones Fijas (Deterministas)
Estas transiciones ocurren siempre, sin condición:
| Origen | Destino | Sendero | Inteligencia | Transformación |
|---|---|---|---|---|
| START | Kéter | - | - | Recepción de input |
| Kéter | Jojmá | 0 | Ígnea | Chispa → Posibilidades |
| Kéter | Biná | 1 | Transparente | Voluntad → Forma |
| Jojmá | Biná | 3 | Luminosa | Ideas → Estructura |
| Biná | Tiféret | 6 | Que Dispone | Estructura → Evaluación |
| Jésed | Tiféret | 10 | Recompensadora | Expansión → Re-evaluación |
| Guevurá | Tiféret | 11 | Fiel | Límites → Re-evaluación |
| Nétsaj | Yesod | 17 | Natural | Emoción → Integración |
| Hod | Yesod | 19 | Colectora | Plan → Integración |
| Yesod | Maljut | 21 | Administrativa | Visión → Acción |
| Maljut | END | - | - | Output final |
3.2 Transiciones Condicionales (desde Tiféret)
Tiféret es el único nodo con múltiples salidas condicionales:
| Condición | Destino | Sendero | Inteligencia | Razón |
|---|---|---|---|---|
expansion_score < 0.4 |
Jésed | 9 | Voluntad | Necesita más posibilidades |
constraint_score < 0.4 |
Guevurá | 11 | Fiel | Necesita más límites |
|exp - con| > 0.3 |
Loop | - | - | Desequilibrio significativo |
balanced AND no_emotion |
Nétsaj | 13 | Imaginativa | Falta carga emocional |
balanced AND no_plan |
Hod | 15 | Renovadora | Falta plan detallado |
balanced AND ready |
Yesod | 14 | De Prueba | Listo para integrar |
4. Lógica del Orquestador (Tiféret)
4.1 Función de Routing Central
def route_from_tiferet(state: TreeOfLifeState) -> str:
"""
Tiféret evalúa el estado y decide la siguiente transición.
Esta es la lógica central de toda la máquina de estados.
Returns:
str: Nombre de la siguiente sefirá de destino
"""
# Protección contra loops infinitos
if state["iteration_count"] > state["max_iterations"]:
logger.warning("Max iterations reached, forcing descent")
return "yesod"
# Calcular métricas de balance
expansion_score = calculate_expansion_score(state)
constraint_score = calculate_constraint_score(state)
balance_delta = abs(expansion_score - constraint_score)
# Prioridad 1: Verificar si necesita más expansión
if expansion_score < EXPANSION_THRESHOLD:
state["iteration_count"] += 1
logger.info(f"Routing to Jesed: low expansion ({expansion_score:.2f})")
return "jesed"
# Prioridad 2: Verificar si necesita más límites
if constraint_score < CONSTRAINT_THRESHOLD:
state["iteration_count"] += 1
logger.info(f"Routing to Gevura: low constraints ({constraint_score:.2f})")
return "gevura"
# Prioridad 3: Verificar balance entre fuerzas
if balance_delta > BALANCE_DELTA_THRESHOLD:
state["iteration_count"] += 1
logger.info(f"Rebalancing: delta={balance_delta:.2f}")
if expansion_score > constraint_score:
return "gevura" # Mucha expansión → añadir límites
else:
return "jesed" # Muchos límites → añadir posibilidades
# Balance alcanzado, verificar completitud
has_emotion = bool(state.get("emotional_charge"))
has_plan = bool(state.get("detailed_plan"))
# Prioridad 4: Si falta carga emocional
if not has_emotion:
logger.info("Routing to Netsaj: needs emotional charge")
return "netsaj"
# Prioridad 5: Si falta plan detallado
if not has_plan:
logger.info("Routing to Hod: needs detailed plan")
return "hod"
# Todo completo, listo para integrar
logger.info("Routing to Yesod: all requirements met")
return "yesod"
def calculate_expansion_score(state: TreeOfLifeState) -> float:
"""
Calcula qué tan expansiva es la propuesta actual.
Considera:
- Número de posibilidades generadas
- Número de expansiones propuestas
- Amplitud del scope definido
Returns:
float: Score normalizado [0, 1]
"""
score = 0.0
# Factor 1: Posibilidades (Jojmá)
num_possibilities = len(state.get("possibilities", []))
score += min(num_possibilities / 10.0, 0.4) # Max 0.4
# Factor 2: Expansiones (Jésed)
num_expansions = len(state.get("expansions", []))
score += min(num_expansions / 5.0, 0.3) # Max 0.3
# Factor 3: Amplitud conceptual
structure = state.get("structure", {})
if structure:
# Analizar número de dimensiones exploradas
dimensions = len(structure.keys())
score += min(dimensions / 10.0, 0.3) # Max 0.3
return min(score, 1.0)
def calculate_constraint_score(state: TreeOfLifeState) -> float:
"""
Calcula qué tan acotada/limitada está la propuesta.
Considera:
- Número de constraints establecidos
- Especificidad de la estructura
- Límites temporales/financieros/de scope
Returns:
float: Score normalizado [0, 1]
"""
score = 0.0
# Factor 1: Constraints explícitos (Guevurá)
num_constraints = len(state.get("constraints", []))
score += min(num_constraints / 5.0, 0.4) # Max 0.4
# Factor 2: Especificidad de estructura
structure = state.get("structure", {})
if structure:
# Buscar indicadores de límites
limit_keywords = ["máximo", "solo", "únicamente", "límite", "presupuesto"]
text = str(structure).lower()
limit_count = sum(1 for kw in limit_keywords if kw in text)
score += min(limit_count / 3.0, 0.3) # Max 0.3
# Factor 3: Decisión balanceada (si existe)
if state.get("balanced_decision"):
# La existencia de decisión indica trabajo de filtrado
score += 0.3
return min(score, 1.0)
# Constantes de umbral
EXPANSION_THRESHOLD = 0.4
CONSTRAINT_THRESHOLD = 0.4
BALANCE_DELTA_THRESHOLD = 0.3
4.2 Ejemplo de Ejecución de Routing
Estado de Entrada:
{
"possibilities": ["coaching", "cursos", "retiros", "app"],
"structure": {"modelo": "híbrido", "audiencia": "amplia"},
"expansions": ["comunidad", "podcast", "libros"],
"constraints": [],
"iteration_count": 1
}
Cálculo de Scores:
expansion_score = 0.16 + 0.18 + 0.06 = 0.40
constraint_score = 0.0 + 0.0 + 0.0 = 0.0
balance_delta = |0.40 - 0.0| = 0.40
Decisión:
constraint_score (0.0) < CONSTRAINT_THRESHOLD (0.4)
→ Routing to "gevura" (necesita límites)
5. Garantías del Sistema
5.1 Propiedades Formales
Terminación
Teorema: Todo flujo eventualmente llega a Maljut.
Prueba: El contador iteration_count garantiza que después
de max_iterations loops, se fuerza el descenso a Yesod incluso sin balance
perfecto.
Determinismo
Teorema: Dado el mismo estado, la transición es siempre la misma.
Prueba: La función route_from_tiferet es puramente
determinista: no usa aleatoriedad, timestamps, ni estado externo.
Trazabilidad
Propiedad: El camino completo es registrado.
Implementación: El array path_taken almacena cada
transición con timestamp y razón.
Idempotencia
Propiedad: Mismo input → mismo output.
Implicación: El sistema es reproducible y testeable. Útil para debugging y validación.
Monotonía
Propiedad: El flujo general es descendente.
Observación: Aunque hay loops horizontales (Tiféret ↔ Jésed/Guevurá), no hay ascensos (Maljut no puede volver a Kéter).
Completitud
Propiedad: Todos los campos requeridos se llenan.
Verificación: Antes de permitir transición a Maljut, se verifica que todos los campos críticos existan.
5.2 Invariantes del Sistema
| Invariante | Descripción | Verificación |
|---|---|---|
| I1: Estado inicial | current_sephira == "keter" al inicio |
Verificado en inicialización |
| I2: Estado final | Solo Maljut puede producir output | Guard en cada nodo |
| I3: Intención preservada | intention_clean no se modifica después de Kéter |
Campo read-only post-Kéter |
| I4: Path acumulativo | path_taken solo crece, nunca decrece |
Append-only list |
| I5: Balance eventual | Después de rebalanceo, |exp - con| ≤ threshold |
Post-condición de loop |
| I6: Campos progresivos | Cada mundo añade campos, no los elimina | Verificación por nivel |
6. Implementación en LangGraph
6.1 Código de Grafo Completo
from langgraph.graph import StateGraph, END
from typing import TypedDict, List, Dict, Any
class TreeOfLifeState(TypedDict):
"""Estado compartido del grafo"""
# [Ver definición completa en sección 1.2]
pass
def keter_agent(state: TreeOfLifeState) -> TreeOfLifeState:
"""Agente Kéter: Captura intención pura"""
state["intention_clean"] = extract_intention(state["intention_raw"])
state["current_sephira"] = "keter"
state["path_taken"].append("START → keter")
return state
def jojma_agent(state: TreeOfLifeState) -> TreeOfLifeState:
"""Agente Jojmá: Genera posibilidades"""
state["possibilities"] = generate_possibilities(state["intention_clean"])
state["current_sephira"] = "jojma"
state["path_taken"].append("keter → jojma (Ígnea)")
return state
def bina_agent(state: TreeOfLifeState) -> TreeOfLifeState:
"""Agente Biná: Estructura conceptualmente"""
state["structure"] = create_structure(
state["intention_clean"],
state["possibilities"]
)
state["current_sephira"] = "bina"
state["path_taken"].append("jojma → bina (Luminosa)")
return state
def tiferet_agent(state: TreeOfLifeState) -> TreeOfLifeState:
"""Agente Tiféret: Evalúa y decide (NO hace routing aquí)"""
state["expansion_score"] = calculate_expansion_score(state)
state["constraint_score"] = calculate_constraint_score(state)
state["current_sephira"] = "tiferet"
# El routing se hace en conditional_edges, no aquí
return state
def jesed_agent(state: TreeOfLifeState) -> TreeOfLifeState:
"""Agente Jésed: Expande posibilidades"""
state["expansions"] = expand_concept(state["structure"])
state["current_sephira"] = "jesed"
state["path_taken"].append("tiferet → jesed (Voluntad)")
return state
def gevura_agent(state: TreeOfLifeState) -> TreeOfLifeState:
"""Agente Guevurá: Establece límites"""
state["constraints"] = define_constraints(state["structure"])
state["current_sephira"] = "gevura"
state["path_taken"].append("tiferet → gevura [fiel]")
return state
def netsaj_agent(state: TreeOfLifeState) -> TreeOfLifeState:
"""Agente Nétsaj: Carga emocionalmente"""
state["emotional_charge"] = add_emotion(state["balanced_decision"])
state["current_sephira"] = "netsaj"
state["path_taken"].append("tiferet → netsaj (Imaginativa)")
return state
def hod_agent(state: TreeOfLifeState) -> TreeOfLifeState:
"""Agente Hod: Planifica detalladamente"""
state["detailed_plan"] = create_detailed_plan(state["balanced_decision"])
state["current_sephira"] = "hod"
state["path_taken"].append("tiferet → hod (Renovadora)")
return state
def yesod_agent(state: TreeOfLifeState) -> TreeOfLifeState:
"""Agente Yesod: Integra visión"""
state["integrated_vision"] = integrate_vision(
state["emotional_charge"],
state["detailed_plan"]
)
state["current_sephira"] = "yesod"
state["path_taken"].append("netsaj/hod → yesod")
return state
def maljut_agent(state: TreeOfLifeState) -> TreeOfLifeState:
"""Agente Maljut: Genera acción concreta"""
state["concrete_action"] = generate_action(state["integrated_vision"])
state["current_sephira"] = "maljut"
state["path_taken"].append("yesod → maljut (Administrativa)")
return state
# Construcción del grafo
workflow = StateGraph(TreeOfLifeState)
# Añadir nodos (agentes)
workflow.add_node("keter", keter_agent)
workflow.add_node("jojma", jojma_agent)
workflow.add_node("bina", bina_agent)
workflow.add_node("tiferet", tiferet_agent)
workflow.add_node("jesed", jesed_agent)
workflow.add_node("gevura", gevura_agent)
workflow.add_node("netsaj", netsaj_agent)
workflow.add_node("hod", hod_agent)
workflow.add_node("yesod", yesod_agent)
workflow.add_node("maljut", maljut_agent)
# Transiciones fijas
workflow.set_entry_point("keter")
workflow.add_edge("keter", "jojma")
workflow.add_edge("jojma", "bina")
workflow.add_edge("bina", "tiferet")
workflow.add_edge("jesed", "tiferet")
workflow.add_edge("gevura", "tiferet")
workflow.add_edge("netsaj", "yesod")
workflow.add_edge("hod", "yesod")
workflow.add_edge("yesod", "maljut")
workflow.add_edge("maljut", END)
# Transiciones condicionales desde Tiféret
workflow.add_conditional_edges(
"tiferet",
route_from_tiferet, # Función que retorna string con destino
{
"jesed": "jesed",
"gevura": "gevura",
"netsaj": "netsaj",
"hod": "hod",
"yesod": "yesod"
}
)
# Compilar
app = workflow.compile()
6.2 Ejecución del Flujo
# Inicializar estado
initial_state = {
"intention_raw": "Quiero crear un negocio de coaching espiritual",
"intention_clean": "",
"possibilities": [],
"structure": {},
"expansions": [],
"constraints": [],
"balanced_decision": "",
"expansion_score": 0.0,
"constraint_score": 0.0,
"emotional_charge": "",
"detailed_plan": {},
"integrated_vision": "",
"concrete_action": "",
"current_sephira": "",
"path_taken": [],
"iteration_count": 0,
"max_iterations": 20
}
# Ejecutar
final_state = app.invoke(initial_state)
# Resultado
print(final_state["concrete_action"])
# → "HOY: escribir descripción servicio (30m), mensaje a 3 contactos"
print(final_state["path_taken"])
# → ["START → keter", "keter → jojma (Ígnea)", ...]
7. Testing y Validación
7.1 Tests Unitarios por Agente
import pytest
def test_keter_extracts_intention():
state = {"intention_raw": "Quiero hacer algo con mi vida"}
result = keter_agent(state)
assert result["intention_clean"] != ""
assert len(result["intention_clean"]) < len(state["intention_raw"])
def test_jojma_generates_multiple_possibilities():
state = {"intention_clean": "servir a otros"}
result = jojma_agent(state)
assert len(result["possibilities"]) >= 3
assert all(isinstance(p, str) for p in result["possibilities"])
def test_tiferet_calculates_scores():
state = {
"possibilities": ["a", "b", "c"],
"expansions": ["x", "y"],
"constraints": []
}
result = tiferet_agent(state)
assert 0 <= result["expansion_score"] <= 1
assert 0 <= result["constraint_score"] <= 1
def test_routing_needs_expansion():
state = {
"expansion_score": 0.2,
"constraint_score": 0.5,
"iteration_count": 0
}
assert route_from_tiferet(state) == "jesed"
def test_routing_needs_constraints():
state = {
"expansion_score": 0.6,
"constraint_score": 0.1,
"iteration_count": 0
}
assert route_from_tiferet(state) == "gevura"
def test_routing_balanced_descends():
state = {
"expansion_score": 0.5,
"constraint_score": 0.5,
"emotional_charge": "passionate",
"detailed_plan": {"week1": "action"},
"iteration_count": 5
}
assert route_from_tiferet(state) == "yesod"
def test_max_iterations_forces_descent():
state = {
"expansion_score": 0.1,
"constraint_score": 0.1,
"iteration_count": 21,
"max_iterations": 20
}
assert route_from_tiferet(state) == "yesod"
7.2 Tests de Integración
def test_complete_flow_terminates():
"""Verifica que todo flujo eventualmente termina"""
initial = create_initial_state("test intention")
final = app.invoke(initial)
assert final["current_sephira"] == "maljut"
assert final["concrete_action"] != ""
def test_path_is_recorded():
"""Verifica trazabilidad completa"""
initial = create_initial_state("test")
final = app.invoke(initial)
assert len(final["path_taken"]) > 5
assert "START → keter" in final["path_taken"][0]
assert "maljut" in final["path_taken"][-1]
def test_intention_preserved():
"""Verifica que intención original no se pierde"""
initial = create_initial_state("servir con coaching")
final = app.invoke(initial)
assert "servir" in final["intention_clean"].lower()
assert "coaching" in final["concrete_action"].lower()
def test_determinism():
"""Verifica que mismo input produce mismo output"""
initial = create_initial_state("mismo input")
result1 = app.invoke(initial)
result2 = app.invoke(initial)
assert result1["concrete_action"] == result2["concrete_action"]
assert result1["path_taken"] == result2["path_taken"]
8. Conclusión
La implementación del Árbol de la Vida como máquina de estados finitos ofrece:
- Rigor formal: Propiedades matemáticas verificables (terminación, determinismo)
- Explicabilidad: Cada transición tiene una razón semántica clara
- Trazabilidad: Path completo registrado para debugging y análisis
- Robustez: Protección contra loops infinitos y estados inválidos
- Mantenibilidad: Separación clara entre nodos (agentes) y lógica de routing
- Testabilidad: Cada componente es testeable de forma aislada
Este modelo transforma la sabiduría cabalística en una arquitectura de software moderna, manteniendo la profundidad conceptual mientras se garantiza la corrección técnica.
En la siguiente sección, exploraremos las 32 Inteligencias que actúan como herramientas de transición entre estados.