Phase 16 - Lesson 13

Memoria Compartida y Patrones de Pizarra (Blackboard)

This lesson includes a graded coding exercise that runs in your browser, unlocked with lifetime access.

Dos enfoques coexisten en los sistemas multiagente de 2026: el pool de mensajes (todos ven los mensajes de todos, como en AutoGen GroupChat o MetaGPT) y la pizarra con suscripción (los agentes se suscriben a eventos relevantes, como en Context-Aware MCP o el framework Matrix). Ambos son la única parte con estado (stateful) de un sistema multiagente, lo que significa que ambos son el lugar donde viven los bugs más interesantes. El modo de falla de referencia es el envenenamiento de memoria: un agente alucina un "hecho", otros agentes lo tratan como verificado y la precisión disminuye gradualmente de una manera que es mucho más difícil de depurar que un crash inmediato. Esta lección construye ambas estructuras utilizando la biblioteca estándar (stdlib), inyecta un ataque de envenenamiento y muestra las tres mitigaciones que realmente funcionan en producción.

Tipo: Aprender + Construir Lenguajes: Python (stdlib, threading) Prerrequisitos: Phase 16 · 04 (Primitive Model), Phase 16 · 09 (Parallel Swarm Networks) Tiempo: ~75 minutos

Problema

Los sistemas multiagente necesitan un lugar para que los agentes compartan hechos. Una opción literal es "pasar todo en mensajes", pero eso reinventa el estado compartido con copias adicionales. Otra es "dar a todos un registro (log) global", pero los registros globales crecen sin límites y se envenenan fácilmente. Una tercera es "proyectar una vista por agente", lo cual es escalable pero requiere muchos esquemas.

Cuando uno de los agentes alucina y escribe la alucinación en el estado compartido, cada agente interconectado (downstream) que lee ese estado adopta la alucinación como un hecho. Para cuando el humano lo nota, la cadena de razonamiento tiene cinco pasos de profundidad y la causa raíz es el tercer mensaje escrito. Depurar el deterioro de la precisión de un sistema multiagente es más difícil que depurar un crash.

Este es el envenenamiento de memoria. Es la segunda familia de fallas más documentada en la taxonomía MAST (Cemri et al., arXiv:2503.13657) y es estructural: cualquier diseño de memoria compartida sin procedencia y sin un verificador no escribible la exhibirá eventualmente.

Concepto

Las dos topologías principales

Pool de mensajes completo (Full message pool). Cada agente lee cada mensaje. AutoGen GroupChat y MetaGPT utilizan esto. Es simple, transparente e inspeccionable, pero no escala más allá de ~10 agentes porque el contexto de cada agente se llena con el trabajo de los demás.

agent-A ──write──▶ ┌────────────────┐ ◀──read── agent-D
                    │ message pool   │
agent-B ──write──▶ │                │ ◀──read── agent-E
                    │ (global log)   │
agent-C ──write──▶ └────────────────┘ ◀──read── agent-F

Pizarra con suscripción (Blackboard with subscription). Los agentes declaran interés en temas; el sustrato enruta solo los mensajes relevantes. CA-MCP (arXiv:2601.11595) y el framework descentralizado Matrix (arXiv:2511.21686) utilizan esto. Escala más allá, pero requiere un diseño de esquemas previo para que las suscripciones tengan sentido.

                    ┌─ topic: prices ──┐
agent-A ──pub────▶ │                  │ ──▶ agent-D (subscribed)
                    ├─ topic: orders ──┤
agent-B ──pub────▶ │                  │ ──▶ agent-E (subscribed)
                    ├─ topic: alerts ──┤
agent-C ──pub────▶ │                  │ ──▶ agent-F (subscribed)
                    └──────────────────┘

Cuándo gana cada una

  • El pool completo gana cuando los agentes son pocos (< 10), heterogéneos, y la conversación es de corto alcance. Razonar sobre quién dijo qué es trivial cuando todos ven todo.
  • La pizarra gana cuando los agentes son muchos, de rol homogéneo pero numerosos en instancias (enjambres o swarms), y la conversación es de larga duración. El enrutamiento ahorra costo de tokens y saturación de contexto.

Los sistemas de producción a menudo combinan ambos: un pequeño pool completo en la parte superior (capa de planificación) y pizarras debajo (capa de trabajadores).

Envenenamiento de memoria, en un escenario práctico

Tres agentes trabajan en una tarea de investigación. El Agente A es un agente de recuperación. El Agente B es un resumidor. El Agente C es un analista.

  1. A recupera una página y escribe un mensaje en el estado compartido: "El estudio informa una mejora de precisión del 42%."
  2. La página recuperada en realidad decía "mejora del 4.2%." A alucinó un decimal.
  3. B, leyendo el estado compartido, escribe: "Se informa una gran ganancia de precisión del 42% (fuente: A)."
  4. C, leyendo el estado compartido, escribe: "Se recomienda la adopción: un aumento del 42% es transformador."
  5. El informe final cita una cifra del 42% que nunca existió.

Ningún agente falló. Ninguna prueba falló. El sistema "funcionó". La alucinación pasó del contexto de un agente al razonamiento de cada agente posterior a través del estado compartido.

Por qué esto es estructural

Sin estado compartido, la alucinación del Agente A se queda en el contexto de A. Los agentes posteriores volverían a recuperar o deducir los datos y podrían detectar el error. Con un estado compartido ingenuo, el contexto de A se convierte en el contexto de todos, y la alucinación se legitima como un hecho.

El problema no es el estado compartido en sí, sino el estado compartido sin procedencia y sin un verificador independiente. Tres mitigaciones abordan esto:

  1. Atribuir procedencia (provenance) en cada escritura. Cada entrada en el estado compartido registra quién la escribió, cuándo, bajo qué prompt y (si corresponde) qué fuente citó el agente. Los agentes posteriores leen con un escepticismo ajustado a la procedencia.
  2. Versionar las escrituras; tratarlas como de solo anexación (append-only). Una corrección es una nueva entrada que reemplaza a la anterior, no una actualización en el lugar. Se preserva la pista de auditoría.
  3. Mantener al menos un agente que no pueda escribir en el estado compartido. Un agente verificador de solo lectura toma muestras de las entradas, vuelve a consultar las fuentes y señala las inconsistencias. Debido a que no puede escribir en el pool, no puede ser envenenado por él.

Precedente de la pizarra (Hayes-Roth, 1985)

El patrón de pizarra es anterior a los agentes LLM por cuatro décadas. Hayes-Roth (1985, "A Blackboard Architecture for Control") describió Fuentes de Conocimiento (Knowledge Sources) especialistas que observan una pizarra global, contribuyen con soluciones parciales y activan otras fuentes. La pizarra de 2026 (CA-MCP, Matrix) es el mismo patrón con agentes LLM como Fuentes de Conocimiento y JSONs como soluciones parciales. La literatura clásica tiene soluciones documentadas para la disputa de escritura, el control oportunista y la consistencia que los sistemas modernos redescubren.

Proyección vs vista completa

Una pizarra pura le da a cada suscriptor la misma proyección (acotada al tema). Un diseño más agresivo es la proyección por agente: cada agente obtiene una vista personalizada para su rol. Los reductores de estado de LangGraph son la implementación canónica de 2026: la función reductora condensa el estado global en una porción específica del rol.

La proyección por agente escala más, pero necesita un esquema. Sin él, se regresa a una proyección ad-hoc en el prompt de cada agente.

Patrones de disputa de escritura

Varios agentes escribiendo simultáneamente es un problema de concurrencia, no solo un problema de LLM. Tres patrones funcionan:

  • Escritor secuencial (productor único). Todas las escritas pasan por un único agente coordinador que las serializa. Simple, pero es un cuello de botella.
  • Concurrencia optimista con versionamiento. Cada entrada tiene una versión; los escritores fallan si hay incompatibilidad de versión y reintentan. Técnica clásica de bases de datos.
  • Particionamiento por temas. Diferentes agentes poseen diferentes temas. No hay disputas entre temas. Requiere límites de partición diseñados.

La mayoría de los frameworks de 2026 optan por el escritor secuencial de forma predeterminada porque las llamadas de LLM son lo suficientemente lentas como para que la disputa sea rara y el cuello de botella no afecte.

El verificador no escribible

La mitigación más robusta es el verificador de solo lectura. Reglas de implementación:

  • El verificador comparte el estado con el equipo (lee la pizarra o el pool).
  • El verificador no tiene permisos de escritura en el estado compartido, solo en un canal de verificación separado.
  • El verificador vuelve a consultar de forma independiente las fuentes citadas en las escritas. Señala desacuerdos.
  • Las salidas del verificador se dirigen a un humano o a un agente de decisión independiente, nunca se reintroducen en el pool.

Sin esta separación, las salidas del verificador se convierten en nuevas entradas en el pool, lo que significa que un pool envenenado envenena al verificador, lo que envenena sus verificaciones.

Constrúyelo

code/main.py implementa ambas topologías en Python estándar más un ataque de envenenamiento y tres mitigaciones.

  • MessagePool — registro de solo anexación thread-safe con lectura completa.
  • Blackboard — pub/sub por temas con suscripciones por agente.
  • ProvenanceEntry — cada escritura registra (writer, timestamp, prompt_hash, source_uri).
  • PoisoningScenario — ejecuta una tarea de investigación de tres agentes donde el agente A alucina un decimal. Imprime el informe final.
  • Verifier — un agente de solo lectura que vuelve a consultar fuentes y señala inconsistencias. Ejecuta el mismo escenario con el verificador presente.

Ejecutar:

python3 code/main.py

Resultado esperado:

  • Ejecución 1 (sin verificador): el 42% alucinado se propaga al informe final.
  • Ejecución 2 (con verificador): el verificador señala la inconsistencia, el pool se etiqueta como "flagged" (señalado) y el informe final incluye una retractación.

Úsalo

outputs/skill-memory-auditor.md es una habilidad que audita el diseño de memoria compartida de cualquier sistema multiagente en busca de procedencia, versionamiento y separación de verificadores. Ejecútelo en nuevas arquitecturas multiagente antes de la producción.

Ponlo en Producción

Para cualquier diseño de memoria compartida:

  • Registre la procedencia en cada escritura: (writer, timestamp, prompt_hash, tool_calls_cited, source_uri).
  • Haga que el registro sea de solo anexación. Las correcciones son nuevas entradas que hacen referencia a la que reemplazan.
  • Implemente al menos un agente verificador de solo lectura con acceso independiente a las fuentes.
  • Enrute la salida del verificador a un canal separado, no de vuelta al pool compartido.
  • Monitoree la proporción de escritas que son reemplazos: una proporción creciente es evidencia temprana de patrones de alucinación.

Ejercicios

  1. Ejecute code/main.py. Confirme que la ejecución 1 propaga la alucinación y la ejecución 2 la detecta.
  2. Agregue una segunda alucinación: el agente B inventa el tamaño de un conjunto de datos. El verificador debe detectar ambas sin estar ajustado manualmente para ninguna de ellas.
  3. Cambie el pool completo a una pizarra con particiones de temas (prices, summaries, analyses). ¿Qué escenarios de envenenamiento hace más difíciles el particionamiento de temas y con cuáles no ayuda?
  4. Lea Hayes-Roth (1985, "A Blackboard Architecture for Control"). Identifique dos patrones de control del artículo que no se discuten en esta lección y de los cuales los sistemas de 2026 se beneficiarían.
  5. Lea CA-MCP (arXiv:2601.11595). Mapee su Shared Context Store a la clase MessagePool o Blackboard en code/main.py. ¿Qué primitivas agrega CA-MCP por encima?

Términos Clave

Término Lo que la gente dice Lo que realmente significa
Message pool "Historial de chat compartido" Registro de solo anexación que leen todos los agentes. Transparencia total, baja escalabilidad.
Blackboard "Espacio de trabajo compartido" Pub/sub por temas. Los agentes se suscriben a temas relevantes. Escala más.
Provenance "Quién escribió qué" Metadatos en cada escritura: autor, timestamp, prompt, fuentes.
Memory poisoning "Alucinaciones propagándose" El error de un agente entra al estado compartido, los agentes posteriores lo adoptan como un hecho.
Append-only "Sin actualizaciones locales" Las correcciones son nuevas entradas que reemplazan a las anteriores. Preserva la pista de auditoría.
Unwritable verifier "Auditor independiente" Agente de solo lectura que vuelve a consultar fuentes y señala inconsistencias.
Projection "Vista delimitada" Vista por agente calculada a partir del estado global. Los reductores de LangGraph son el caso canónico.
Knowledge Source "Agente especialista" Término de Hayes-Roth de 1985 para un participante de la pizarra.

Lecturas Adicionales

0 lifetime access. Curriculum based on AI Engineering from Scratch by Rohit Ghumare (MIT, used under attribution).