Back to blog
Durable Meta-Agent: DSPy + Dapr Production Framework

Durable Meta-Agent: DSPy + Dapr Production Framework

The four-lab arc tells a single story. Lab 11 proved the meta-agent pattern works — a system that generates, optimizes, and distills its own agents dynamically. Lab 12 proved it extends to formal verification — the same substrate proving financial invariants with Z3. Lab 13 proved it builds software autonomously — discovering problems, researching solutions, deploying infrastructure, and logging everything to observability.

Lab 14 proves the meta-agent survives production.

Every previous lab ran in a single process. Crash it, and everything disappears — the agent stack, the research frontier, the optimization history, the accumulated skills. Lab 14 wraps the entire meta-agent substrate in Dapr’s distributed application runtime without changing a single DSPy module. The result is a durable meta-agent: crash-resistant workflows that resume from the last checkpoint, Redis-backed state that survives restarts, Zipkin-distributed tracing for every iteration, and a swarm mode that coordinates multiple meta-agents via pub/sub and an Agent-to-Agent (A2A) protocol.

DSPy is the engine. Dapr is the chassis. The reasoning code never changed.

El arco de cuatro laboratorios cuenta una sola historia. El Lab 11 demostró que el patrón del meta-agente funciona — un sistema que genera, optimiza y destila sus propios agentes dinámicamente. El Lab 12 demostró que se extiende a verificación formal — el mismo sustrato probando invariantes financieros con Z3. El Lab 13 demostró que construye software autónomamente — descubriendo problemas, investigando soluciones, desplegando infraestructura y registrando todo en observabilidad.

El Lab 14 demuestra que el meta-agente sobrevive en producción.

Cada laboratorio anterior se ejecutaba en un solo proceso. Si fallaba, todo desaparecía — el stack de agentes, la frontera de investigación, el historial de optimización, las habilidades acumuladas. El Lab 14 envuelve todo el sustrato del meta-agente en el runtime de aplicaciones distribuidas de Dapr sin cambiar un solo módulo DSPy. El resultado es un meta-agente duradero: workflows resistentes a caídas que reanudan desde el último checkpoint, estado respaldado por Redis que sobrevive reinicios, trazado distribuido Zipkin para cada iteración y un modo swarm que coordina múltiples meta-agentes mediante pub/sub y un protocolo Agente-a-Agente (A2A).

DSPy es el motor. Dapr es el chasis. El código de razonamiento nunca cambió.

1. The Dual-Path Architecture

1. La Arquitectura de Doble Camino

Every durable subsystem in Lab 14 follows the same pattern inherited from earlier labs: an Abstract Base Class (ABC) with two concrete implementations — one in-memory for development, one Dapr-backed for production.

Cada subsistema duradero en el Lab 14 sigue el mismo patrón heredado de laboratorios anteriores: una Clase Base Abstracta (ABC) con dos implementaciones concretas — una en memoria para desarrollo, otra respaldada por Dapr para producción.

ABCIn-Memory (dev)Dapr (production)
ResearchFrontierInMemoryFrontier — UCB in dictDaprFrontier — Redis + dirty-flag batching
AgentStackAgentStack — in-memory listDaprAgentStack — Redis per-entry keys
LSEOptimizerLSEOptimizer — in-memory runsDaprLSEOptimizer — persisted via StateStoreService
ABCEn Memoria (dev)Dapr (producción)
ResearchFrontierInMemoryFrontier — UCB en dictDaprFrontier — Redis + batching dirty-flag
AgentStackAgentStack — lista en memoriaDaprAgentStack — claves por entrada en Redis
LSEOptimizerLSEOptimizer — ejecuciones en memoriaDaprLSEOptimizer — persistido via StateStoreService

Swap between them with a single line. The rest of the system — the AgentGenerator, the MetaAgent orchestrator, the GFL pipeline, the Trace2Skill consolidator — never knows which backend is active. The ABC contract decouples reasoning from infrastructure.

Se intercambian con una sola línea. El resto del sistema — el AgentGenerator, el orquestador MetaAgent, el pipeline GFL, el consolidador Trace2Skill — nunca sabe qué backend está activo. El contrato ABC desacopla el razonamiento de la infraestructura.

2. The DurableMetaAgent

2. El DurableMetaAgent

The core of Lab 14 is the DurableMetaAgent — a Dapr wrapper around the DSPy MetaAgent from Labs 11-13. The key architectural decision: the iteration loop is not duplicated. The original MetaAgent.run_stack_iter() is a generator that yields (iteration, direction, entry, prediction, quality, state) per iteration. DurableMetaAgent.run_research() consumes it directly, inserting Dapr checkpointing between iterations:

for iteration, direction, entry, prediction, quality, state in meta.run_stack_iter(
    query, max_iterations
):
    yield ctx.set_state("last_completed_iteration", iteration)

If the process crashes at iteration 17 of 25, the next start reads last_completed_iteration = 16 from Redis and resumes from iteration 17. Zero data loss. Zero repeated work.

The GeneratedDurableAgent wraps a DSPy module — dspy.RLM, dspy.ReAct, dspy.CodeAct, or dspy.ChainOfThought — without modifying it. The same module that ran in-memory in Lab 13 now runs inside a Dapr workflow with tracing, retry, and persistence:

dspy_module = dspy.RLM("task: str -> result: str", tools=dspy_tools)
durable_agent = GeneratedDurableAgent(
    dspy_module=dspy_module,
    name="my-agent", role="assistant",
    tools=agent_tools,
    llm_component="llm-provider",
    enable_tracing=True,
)

El núcleo del Lab 14 es el DurableMetaAgent — un envoltorio Dapr alrededor del MetaAgent de DSPy de los Labs 11-13. La decisión arquitectónica clave: el bucle de iteración no se duplica. El MetaAgent.run_stack_iter() original es un generador que produce (iteration, direction, entry, prediction, quality, state) por iteración. DurableMetaAgent.run_research() lo consume directamente, insertando checkpointing Dapr entre iteraciones:

for iteration, direction, entry, prediction, quality, state in meta.run_stack_iter(
    query, max_iterations
):
    yield ctx.set_state("last_completed_iteration", iteration)

Si el proceso falla en la iteración 17 de 25, el siguiente inicio lee last_completed_iteration = 16 de Redis y reanuda desde la iteración 17. Cero pérdida de datos. Cero trabajo repetido.

El GeneratedDurableAgent envuelve un módulo DSPy — dspy.RLM, dspy.ReAct, dspy.CodeAct o dspy.ChainOfThought — sin modificarlo. El mismo módulo que se ejecutaba en memoria en el Lab 13 ahora se ejecuta dentro de un workflow Dapr con trazado, reintento y persistencia.

3. Delta-Update Persistence

3. Persistencia de Actualización Delta

Production state stores face a tension: write too frequently and you burn Redis bandwidth; write too rarely and you risk data loss. Lab 14’s DaprAgentStack solves this with delta-update keys and dirty-flag batching.

Los almacenes de estado en producción enfrentan una tensión: escribir con demasiada frecuencia quema ancho de banda de Redis; escribir con demasiada poca frecuencia arriesga pérdida de datos. El DaprAgentStack del Lab 14 resuelve esto con claves de actualización delta y batching dirty-flag.

Instead of saving the full agent list on every mutation (O(n) write), the stack uses per-entry state store keys:

{key}:meta             →  ordered list of agent names (small, O(1) write)
{key}:entries:{name}   →  individual agent entry (one per agent, O(1) write)

push() writes a single entry regardless of the agent count. record_run() only updates that agent’s key. Full-state saves only happen on pop(). The same dirty-flag pattern applies to DaprFrontier — calls to seed_*() and absorb_findings() set a _dirty = True flag, and the actual _save() to Redis fires on the next next_action() or saturated() call. Writes batch at the natural polling boundary, not on every mutation.

En lugar de guardar la lista completa de agentes en cada mutación (escritura O(n)), el stack usa claves de almacenamiento de estado por entrada:

{key}:meta             →  lista ordenada de nombres de agentes (pequeña, escritura O(1))
{key}:entries:{name}   →  entrada de agente individual (una por agente, escritura O(1))

push() escribe una sola entrada independientemente del número de agentes. record_run() solo actualiza la clave de ese agente. Las guardas de estado completo solo ocurren en pop(). El mismo patrón dirty-flag se aplica a DaprFrontier — las llamadas a seed_*() y absorb_findings() establecen una bandera _dirty = True, y el _save() real a Redis se dispara en la siguiente llamada a next_action() o saturated(). Las escrituras se agrupan en el límite natural de consulta, no en cada mutación.

4. Continue-as-New: Infinite Workflows

4. Continue-as-New: Workflows Infinitos

Long-running Dapr workflows accumulate execution history in the state store, degrading performance over time. A DurableMetaAgent running 200 iterations accumulates 200 checkpoint entries. At 500 iterations, the workflow becomes sluggish. At 1000, it risks timeouts.

Los workflows Dapr de larga duración acumulan historial de ejecución en el almacén de estado, degradando el rendimiento con el tiempo. Un DurableMetaAgent ejecutando 200 iteraciones acumula 200 entradas de checkpoint. En 500 iteraciones, el workflow se vuelve lento. En 1000, arriesga timeouts.

Lab 14 implements the Continue-as-New pattern: after a configurable number of iterations (max_iterations_per_segment=20), the workflow spawns a new run_research instance via ctx.call_workflow(), passing the current state. The old workflow terminates cleanly. The new one resumes from the last checkpoint with a fresh execution history. The frontier, agent stack, and LSE runs — persisted in Redis — survive the segment boundary intact.

The agent never knows it was restarted. It simply continues researching, optimizing, and consolidating across an arbitrary number of workflow segments. Production runs of 500, 1000, or 10000 iterations are feasible — the workflow history resets every 20 iterations, but the state never resets.

El Lab 14 implementa el patrón Continue-as-New: después de un número configurable de iteraciones (max_iterations_per_segment=20), el workflow genera una nueva instancia de run_research via ctx.call_workflow(), pasando el estado actual. El workflow antiguo termina limpiamente. El nuevo reanuda desde el último checkpoint con un historial de ejecución fresco. La frontera, el stack de agentes y las ejecuciones LSE — persistidos en Redis — sobreviven intactos al límite del segmento.

El agente nunca sabe que fue reiniciado. Simplemente continúa investigando, optimizando y consolidando a través de un número arbitrario de segmentos de workflow. Ejecuciones de producción de 500, 1000 o 10000 iteraciones son factibles — el historial del workflow se reinicia cada 20 iteraciones, pero el estado nunca se reinicia.

5. Swarm Mode: Multi-Agent Coordination

5. Modo Swarm: Coordinación Multi-Agente

Lab 14 extends beyond a single durable agent into a swarm of coordinating meta-agents — each a full DSPy pipeline with AgentGenerator, GFL optimization, LSE evolution, and Trace2Skill consolidation, all communicating via Dapr pub/sub and an Agent-to-Agent (A2A) protocol.

El Lab 14 se extiende más allá de un solo agente duradero hacia un enjambre de meta-agentes coordinados — cada uno un pipeline DSPy completo con AgentGenerator, optimización GFL, evolución LSE y consolidación Trace2Skill, todos comunicándose via pub/sub de Dapr y un protocolo Agente-a-Agente (A2A).

5.1 The Architecture

5.1 La Arquitectura

A single SwarmCoordinator owns the shared research frontier in Redis. It calls next_action() to discover the most promising research direction, then dispatches it to the appropriate worker via call_agent(). Workers — SwarmMetaAgents — are stateless task executors. They receive a direction, run their full DSPy pipeline (agent generation, execution, evaluation), and publish findings back to the coordinator via the swarm.discoveries pub/sub topic.

The coordinator never blocks on workers. It publishes to swarm.tasks, collects from swarm.discoveries, and feeds results back into the frontier. Workers publish their own heartbeats every 30 seconds. The coordinator marks a worker offline after 90 seconds of silence and reassigns its tasks — crash detection without a centralized orchestrator.

Un solo SwarmCoordinator posee la frontera de investigación compartida en Redis. Llama a next_action() para descubrir la dirección de investigación más prometedora, luego la despacha al worker apropiado via call_agent(). Los workers — SwarmMetaAgents — son ejecutores de tareas sin estado. Reciben una dirección, ejecutan su pipeline DSPy completo (generación de agentes, ejecución, evaluación) y publican hallazgos de vuelta al coordinador mediante el tópico pub/sub swarm.discoveries.

El coordinador nunca bloquea en los workers. Publica en swarm.tasks, recolecta de swarm.discoveries y alimenta los resultados de vuelta a la frontera. Los workers publican sus propios heartbeats cada 30 segundos. El coordinador marca un worker como desconectado después de 90 segundos de silencio y reasigna sus tareas — detección de caídas sin un orquestador centralizado.

5.2 The A2A Protocol

5.2 El Protocolo A2A

Agents communicate through five message types, each on its own pub/sub topic:

MessageTopicPurpose
SwarmTaskswarm.tasksCoordinator assigns a research direction to a worker
SwarmDiscoveryswarm.discoveriesWorker publishes findings after executing a task
SwarmHeartbeatswarm.heartbeatWorker liveness signal (alive/busy/error, load, task counts)
SwarmInquiryswarm.inquiryA2A question from any agent to another
SwarmResponseswarm.responseA2A answer with correlation_id matching the inquiry

Workers discover each other via Dapr’s AgentRegistry and communicate through topic-routed messages with correlation IDs for request/response matching. The protocol is asynchronous — an agent can inquire, continue working, and handle the response when it arrives. No blocking, no polling, no tight coupling.

Los agentes se comunican a través de cinco tipos de mensaje, cada uno en su propio tópico pub/sub:

MensajeTópicoPropósito
SwarmTaskswarm.tasksEl coordinador asigna una dirección de investigación a un worker
SwarmDiscoveryswarm.discoveriesEl worker publica hallazgos tras ejecutar una tarea
SwarmHeartbeatswarm.heartbeatSeñal de vida del worker (vivo/ocupado/error, carga, conteo de tareas)
SwarmInquiryswarm.inquiryPregunta A2A de cualquier agente a otro
SwarmResponseswarm.responseRespuesta A2A con correlation_id emparejando la consulta

Los workers se descubren entre sí mediante el AgentRegistry de Dapr y se comunican a través de mensajes enrutados por tópico con IDs de correlación para emparejamiento solicitud/respuesta. El protocolo es asíncrono — un agente puede preguntar, continuar trabajando y manejar la respuesta cuando llegue. Sin bloqueo, sin polling, sin acoplamiento fuerte.

6. Three Production Workflows

6. Tres Workflows de Producción

6.1 Continuous Vulnerability Research & Automated Patching

6.1 Investigación Continua de Vulnerabilidades y Parcheo Automatizado

A swarm that monitors CVE feeds, researches exploits via crawl4ai and Exa, generates verified patches with Z3 formal proofs, sandbox-tests them via E2B, deploys fixes via Terraform, and logs the full audit trail to MLflow. The coordinator owns the CVE queue as a research frontier. Three specialized workers handle research, verification, and deployment. If any worker crashes mid-CVE, the coordinator detects the silence and reassigns. No patch is lost.

Un enjambre que monitorea feeds CVE, investiga exploits via crawl4ai y Exa, genera parches verificados con pruebas formales Z3, los prueba en sandbox via E2B, despliega correcciones via Terraform y registra el rastro de auditoría completo en MLflow. El coordinador posee la cola CVE como frontera de investigación. Tres workers especializados manejan investigación, verificación y despliegue. Si algún worker falla durante un CVE, el coordinador detecta el silencio y reasigna. Ningún parche se pierde.

6.2 Self-Healing Production Infrastructure

6.2 Infraestructura de Producción Auto-Curable

A swarm that monitors MLflow metrics for latency or error rate anomalies, diagnoses root causes via sequential-thinking, generates fix candidates with RLM code agents, proves correctness with Z3, sandbox-rolls out to canary via E2B, deploys to production via Terraform, and monitors the result — all without human intervention. If the fix degrades performance, the system auto-rolls back. The Continue-as-New pattern allows this to run indefinitely across hundreds of monitoring iterations.

Un enjambre que monitorea métricas de MLflow para anomalías de latencia o tasa de error, diagnostica causas raíz via sequential-thinking, genera candidatos de corrección con agentes de código RLM, prueba corrección con Z3, despliega a canary en sandbox via E2B, despliega a producción via Terraform y monitorea el resultado — todo sin intervención humana. Si la corrección degrada el rendimiento, el sistema retrocede automáticamente. El patrón Continue-as-New permite que esto se ejecute indefinidamente a través de cientos de iteraciones de monitoreo.

6.3 Competitive Intelligence Platform

6.3 Plataforma de Inteligencia Competitiva

A swarm of domain-specialized meta agents monitoring competitor products (changelogs, pricing via crawl4ai), legal filings (USPTO patents via Exa, SEC EDGAR), hiring patterns (LinkedIn), and social media sentiment. Each worker publishes structured discoveries to pub/sub; the coordinator consolidates them into a FalkorDB knowledge graph. A signal aggregator worker uses sequential-thinking and OpenRouter consensus for cross-domain threat assessment. Workers can crash and restart independently — the knowledge graph persists, the discoveries are queued, and the swarm continues.

Un enjambre de meta-agentes especializados por dominio monitoreando productos competidores (changelogs, precios via crawl4ai), presentaciones legales (patentes USPTO via Exa, SEC EDGAR), patrones de contratación (LinkedIn) y sentimiento en redes sociales. Cada worker publica descubrimientos estructurados a pub/sub; el coordinador los consolida en un grafo de conocimiento FalkorDB. Un worker agregador de señales usa sequential-thinking y consenso OpenRouter para evaluación de amenazas entre dominios. Los workers pueden fallar y reiniciarse independientemente — el grafo de conocimiento persiste, los descubrimientos están en cola y el enjambre continúa.

7. The Architecture Insight: Engine + Chassis

7. La Idea Arquitectónica: Motor + Chasis

Lab 14’s most important decision is what it does not change. The entire DSPy substrate — BestOfN task decomposition, RLM/ReAct/CodeAct/ChainOfThought agent generation, MultiChainComparison selection, Refine self-adaptation, GFL pipeline, LSE evolution, Trace2Skill consolidation — runs exactly as it did in Lab 13. Not a single import changed. Not a single DSPy signature was modified. Not a single optimizer was reimplemented.

Dapr adds crash-resistant workflows, Redis-backed state, Zipkin-distributed tracing, hot-reload configuration, secrets management, and multi-agent pub/sub coordination — all without the DSPy layer knowing Dapr exists. The DurableMetaAgent consumes MetaAgent.run_stack_iter() as a generator. The GeneratedDurableAgent wraps any DSPy module without modifying it. The dual-path ABCs let developers iterate in-memory and deploy to production with Dapr by swapping a constructor argument.

This is the architectural principle the entire meta-agent sequence was leading toward: separate reasoning from infrastructure. The reasoning engine (DSPy) handles all cognitive work — task decomposition, tool selection, prompt optimization, skill consolidation. The infrastructure layer (Dapr) handles all operational concerns — crash recovery, state persistence, distributed tracing, service coordination. Each layer does one thing well. Neither layer needs to know about the other.

Lab 11 proved the meta-agent works. Lab 12 proved it verifies. Lab 13 proved it builds. Lab 14 proves it survives.

La decisión más importante del Lab 14 es lo que no cambia. Todo el sustrato DSPy — descomposición de tareas BestOfN, generación de agentes RLM/ReAct/CodeAct/ChainOfThought, selección MultiChainComparison, auto-adaptación Refine, pipeline GFL, evolución LSE, consolidación Trace2Skill — se ejecuta exactamente como en el Lab 13. Ni una sola importación cambió. Ni una sola firma DSPy fue modificada. Ni un solo optimizador fue reimplementado.

Dapr añade workflows resistentes a caídas, estado respaldado por Redis, trazado distribuido Zipkin, configuración hot-reload, gestión de secretos y coordinación multi-agente pub/sub — todo sin que la capa DSPy sepa que Dapr existe. El DurableMetaAgent consume MetaAgent.run_stack_iter() como un generador. El GeneratedDurableAgent envuelve cualquier módulo DSPy sin modificarlo. Los ABCs de doble camino permiten a los desarrolladores iterar en memoria y desplegar a producción con Dapr intercambiando un argumento de constructor.

Este es el principio arquitectónico hacia el que toda la secuencia del meta-agente estaba liderando: separar el razonamiento de la infraestructura. El motor de razonamiento (DSPy) maneja todo el trabajo cognitivo — descomposición de tareas, selección de herramientas, optimización de prompts, consolidación de habilidades. La capa de infraestructura (Dapr) maneja todas las preocupaciones operacionales — recuperación de caídas, persistencia de estado, trazado distribuido, coordinación de servicios. Cada capa hace una cosa bien. Ninguna capa necesita saber de la otra.

El Lab 11 demostró que el meta-agente funciona. El Lab 12 demostró que verifica. El Lab 13 demostró que construye. El Lab 14 demuestra que sobrevive.

How to Run It

Cómo Ejecutarlo

The experiment is available in the lab-experiments repository. Pure DSPy mode requires no infrastructure:

El experimento está disponible en el repositorio lab-experiments. El modo DSPy puro no requiere infraestructura:

git clone https://github.com/OctAg0nO/lab-experiments
cd lab-experiments
uv sync

# Pure DSPy mode — no Dapr needed
uv run python -m lab.14_durable_meta_agent \
  --query "Research a topic" --iterations 10 run

# Dapr mode — requires Redis + Dapr sidecar
dapr run --app-id durable-meta-agent --app-protocol grpc --app-port 8000 \
  --resources-path lab/14_durable_meta_agent/dapr/resources -- \
  uv run python -m lab.14_durable_meta_agent \
  --query "Research a topic" --iterations 10 \
  dapr-orchestrator --tracing --dapr-frontier --dapr-lse

# Swarm mode — multi-agent coordination
uv run python -m lab.14_durable_meta_agent \
  --query "Monitor for vulnerabilities and patch them" \
  --iterations 50 swarm --workers 4

The CLI commands span pure DSPy and Dapr modes:

Los comandos CLI abarcan modos DSPy puro y Dapr:

CommandDescription
runFull DSPy pipeline: generate, execute, consolidate (no Dapr)
generateAnalyze task and generate agents without executing
gflRun GFL pipeline (BootstrapFewShot, MIPROv2, GEPA)
stackInspect the current agent stack
dapr-orchestratorStart DurableMetaAgent as Dapr service with checkpointing
swarmRun multi-agent swarm in-process (coordinator + workers)
swarm-coordinatorStart standalone SwarmCoordinator
swarm-workerStart standalone SwarmMetaAgent worker
ComandoDescripción
runPipeline DSPy completo: generar, ejecutar, consolidar (sin Dapr)
generateAnalizar tarea y generar agentes sin ejecutar
gflEjecutar pipeline GFL (BootstrapFewShot, MIPROv2, GEPA)
stackInspeccionar el stack de agentes actual
dapr-orchestratorIniciar DurableMetaAgent como servicio Dapr con checkpointing
swarmEjecutar enjambre multi-agente en proceso (coordinador + workers)
swarm-coordinatorIniciar SwarmCoordinator independiente
swarm-workerIniciar worker SwarmMetaAgent independiente

The meta-agent sequence that began with a question — “can a system generate, optimize, and distill its own agents?” — now has a four-lab answer. It can generate its own agents (Lab 11). It can verify their outputs formally (Lab 12). It can build software autonomously with those capabilities (Lab 13). And it can survive production while doing so (Lab 14).

The substrate is no longer a prototype. It is a durable, production-grade platform for autonomous intelligence.

La secuencia del meta-agente que comenzó con una pregunta — “¿puede un sistema generar, optimizar y destilar sus propios agentes?” — ahora tiene una respuesta de cuatro laboratorios. Puede generar sus propios agentes (Lab 11). Puede verificar sus salidas formalmente (Lab 12). Puede construir software autónomamente con esas capacidades (Lab 13). Y puede sobrevivir en producción mientras lo hace (Lab 14).

El sustrato ya no es un prototipo. Es una plataforma duradera y de grado de producción para inteligencia autónoma.


References

Referencias

Share