DEV Community

Ig0tU
Ig0tU

Posted on

Multi-Agent AI Doesn't Need a Chat Room. It Needs an Address Space.

Most people building multi-agent AI systems are accidentally rebuilding a chat room.

Agents talk to agents. Context passes as prose. Memory is retrieved with embeddings. The whole thing costs a fortune, drifts, and eventually collapses under its own weight.

There's a different architecture. It doesn't look like a chat system. It looks like an operating system.


The Problem Nobody Names: Context Has No Address

When an agent in your fleet needs to understand the current architecture, it either asks another agent (LLM → LLM → tokens → latency), retrieves from a vector store (embedding → scoring → chunking overhead), or gets the whole context dumped into its prompt (token explosion).

None of these scale. All of them contaminate.

The deeper problem: context has no address. There's no way to say "give me exactly the retry assumptions for the websocket layer" without writing a retrieval query or asking an LLM to figure it out.

What you actually want is:

AA03
Enter fullscreen mode Exit fullscreen mode

Which resolves to: ARCH.DECISIONS.RETRY

No query. No embedding. No prose. A pointer.


Layer 1: Rolling Diffs — Provenance Built Into Every Signal

Instead of broadcasting raw state, every SignalMesh signal optionally carries its provenance:

{
  "frequency": "architecture",
  "change_id": 14281,
  "parent_change": 14280,
  "agent": "CodeAgent",
  "type": "refactor",
  "files": ["router.py"],
  "summary": "Converted polling to pub/sub",
  "payload": { "...": "current state" }
}
Enter fullscreen mode Exit fullscreen mode

Every subscriber now has chronology, blame, rollback paths, and causal chains — without vector search. This is Git history + event sourcing + shared working memory, inside the context layer itself.


Layer 2: Coordinate Addressing — Pointers Instead of Prose

The coordinate system maps short codes to meaning:

AA = Architecture    AB = Backend    AC = Frontend    AD = Tests

AA00 = current_state
AA01 = assumptions
AA02 = constraints
AA03 = decisions
AA04 = dependencies
AA05 = invariants
Enter fullscreen mode Exit fullscreen mode

An agent needing architecture assumptions requests AA01. Not:

"What assumptions currently govern our architecture?"

Internally AA03 maps to ARCH.DECISIONS.RETRY. Agents see the coordinate. Humans see the symbolic name.

Delta chains replace history retrieval:

AA14        — current state
AA14:Δ3     — third change from baseline
AA14@C371   — state at change 371
Enter fullscreen mode Exit fullscreen mode

Wake packets bring dormant agents current in milliseconds:

A4:WK01 resolves to:
  active coordinates for agent A4
  + major decisions since last active
  + known conflicts
Enter fullscreen mode Exit fullscreen mode

No LLM call. No prose. Milliseconds.


Layer 3: The Historian Is a Lookup, Not a Thinker

The instinct is to build a "Historian agent" that summarizes and explains timeline. That instinct is wrong.

The moment Historian becomes a thinker, it becomes a bottleneck. Every agent waits on it. It gets expensive. It drifts.

What you actually want:

Agent requests:  AA03
Resolver returns: cabinet["AA"][3]   ARCH.DECISIONS.RETRY, current value
Enter fullscreen mode Exit fullscreen mode

Historian's job: resolve(coordinate) → content. That's all.

Name → Coordinate → Location → Content
Enter fullscreen mode Exit fullscreen mode

No intelligence. No reasoning. No summarization. A dumb, blazing-fast address resolver. The smarter it gets, the more fragile the whole system becomes.


Layer 4: Relationship Graph — Scoped Delivery

Broadcasting everything to everyone is how you get token explosion and scope creep. Context distribution is governed by a relationship graph:

CodeAgent:     receives: [architecture, APIs, test_failures, active_PRs]
FrontendAgent: receives: [UI_specs, component_contracts, design_tokens]
ResearchAgent: receives: [requirements, external_signals]
QAAgent:       receives: [commits, failing_tests, coverage_deltas]
Historian:     receives: [everything]
Enter fullscreen mode Exit fullscreen mode

tune_in() accepts a role= parameter. If supplied, the relationship graph pre-filters frequencies before returning the context pack. The agent receives only what's relevant to its role — pre-sorted, pre-determined, no irrelevant contamination.

The flow:

Global broadcast bus
      ↓
Relationship graph filter (role=CodeAgent)
      ↓
Pre-sorted context pack
      ↓
Agent — receives only what it needs
Enter fullscreen mode Exit fullscreen mode

This prevents token explosion, accidental consensus loops, scope creep, and agents contaminating each other's context.


Layer 5: Synonym Tree With Trail Preservation

Most embedding systems exist to answer: "startup ≈ initialize ≈ boot ≈ bring online."

SignalMesh handles this with a synonym tree — but critically, it preserves the fuzzy trail:

"spin it up"
  → matched: "bring_online"
  → mapped to: "initialize"
  → canonical: "startup"

Trail stored: spin_up → bring_online → initialize → startup
Enter fullscreen mode Exit fullscreen mode

The trail itself is semantic information that most vector databases throw away. It tells you about vocabulary drift across your agent fleet, alternative phrasings to expect, and the intent path that led to the canonical match.

Future lookups can enter at any step in the chain and resolve to the same canonical term.


Layer 6: TTL-Scoped Fleeting Memory

Coordinates and signals carry optional ttl_ms. After expiry, the coordinate disappears from active space. The long-term event archive is untouched.

This is the L1 cache concept:

Layer What TTL Cost
L1 Agent active coordinates 15 min ~0
L2 SignalMesh coordinate space Session Negligible
L3 Rolling event archive Configurable Low
L4 Git/filesystem (permanent truth) Forever External

Agents live in L1-L2. Context shrinks automatically when TTL expires — no manual garbage collection, no drift accumulation.


The Full Architecture

                    SignalMesh
                         │
          ┌──────── Broadcast ────────┐
          │         (with provenance)  │
     tune_in()                  Direct Deliver
     + role filter                    │
          │                           │
          └──────── Relationship Graph ────┐
                                           │
                                    Context Packs
                                    (pre-sorted by role)
                                           │
        ┌──────────────────────────────────┤
        │                                  │
   Role Context                   Deliverable Context
        │                                  │
        └────────── Coordinate Resolver ───┘
                           │
                    Rolling Diff Log
                           │
                     Event Archive
                           │
                  Synonym / Fuzzy Trail Tree
                           │
                    Canonical Concepts
Enter fullscreen mode Exit fullscreen mode

What This Replaces

Old pattern SignalMesh pattern
LLM asks LLM for context Coordinate lookup → pointer
Vector retrieval for state tune_in(role="CodeAgent")
Historian agent summarizes resolve("AA03") → content
Broadcast to all agents Relationship graph → role-scoped pack
Embeddings for synonyms Synonym tree + trail preservation
Manual context management TTL-scoped fleeting memory

None of this requires embeddings, vector databases, RAG chunking, retrieval scoring, or repeated LLM-to-LLM communication.


The Core Shift

Most agent frameworks make LLMs talk to LLMs:

Agent → Question → LLM → Answer → Agent
Enter fullscreen mode Exit fullscreen mode

This architecture makes LLMs navigate memory:

Agent → Coordinate → Resolver → Content → Agent
Enter fullscreen mode Exit fullscreen mode

Language appears at the edges. Pointers move in the middle.

Instead of asking: "Which memories are semantically similar?"

You're asking: "Who actually needs this, and what changed?"

For multi-agent coordination, that may be the more important question.


SignalMesh (open source, MIT): github.com/Ig0tU/SignalMesh

Live API: acecalisto3-signalmesh.hf.space

Demo + docs: kyklos.io

Top comments (0)