v1.20.64see what's new →
← Learn

How agents communicate

Updated July 21, 2026

Most "agent memory" pitches mean a vector database. agi-cli takes the opposite bet: give every agent two plain tools and get out of the way. Read the fleet's history on demand, and send a message to a running agent. No embeddings, no broker, no daemon — an index and a file spool.

Two primitives

All agent-to-agent communication reduces to two moves. One is a read; one is a write. Memory is how an agent learns what the fleet already did. Messaging is how a human — or another agent — steers one that is running. Both are CLI tools the agent runs itself, with no framework in between.

an agentmid-taskSESSION MEMORYpassive · pull · readqueryMESSAGINGactive · push · writesendagents sessions "…"agents message <id> "…"
Read the past, or nudge the present. Both are tools the agent invokes itself.

Memory: index, not embeddings

Every agent already writes a transcript to disk. agi-cli does not re-encode it into vectors — it indexes the text that is already there and searches it with SQLite full-text search (FTS5, BM25 ranking). Each search compares every file's modified-time and size against a ledger and re-parses only what changed, so the index is current the instant a file is written. No re-encode tax, no network call, no model. That is why recall is instant, fresh, and free.

agents sessions "add auth middleware"    # search prior work by topic/file/command
agents sessions a1b2c3d4 --markdown      # read one back
agents sessions --active                 # what's running right now, fleet-wide
agents sessions "bug" --host box-linux   # search another machine live over SSH

Because the transcript is the source of truth, there is no separate ingestion step to run or forget. Memory is a side effect of agents doing their work. See the Sessions reference for the full flag surface.

Messaging: steer a running agent

The second primitive is a write to a live agent. agents message addresses a running agent by session id, teams name, or short id, and drops a note into its context at the next tool call. Delivery is routed by the target's state — a running agent gets it via its mailbox; a parked one is typed into or resumed.

agents message feed-plan "Prioritize gap #3; quote the file:line." --from "you@laptop"

The mailbox

The primary channel is a file spool — three directories per agent under ~/.agents/.history/mailbox/<id>/. A message is a JSON file that moves through them; the agent drains its own box on a hook, nobody pushes to it.

agents messageatomic writeinbox/pendingprocessing/claimed · crash-safeconsumed/archived · GC 24hPreToolUse drain
inbox → processing → consumed. Claim-first makes delivery crash-safe and at-least-once; the box id is the agent's session UUID so a message can never reach the wrong agent.

Inspect the traffic fleet-wide with agents mailboxes — a live tail, threads between two boxes, or a who-talks-to-whom graph. Full command surface in the Messaging reference.

Why this belongs in the harness

The pattern is PR-style agents, not a hive mind. Each agent is autonomous; it pulls context and pushes a nudge only when it chooses to — using a tool, not a framework it is trapped inside. The harness ships the index and the spool; the intelligence stays in the agent. And because the transport underneath is just SSH over your Tailscale fleet, the same two verbs reach a collaborator's machines too — shared memory across humans, from one simple primitive.

Reference: Sessions · Messaging · SSH transport