Lesson 09 · Collaboration

Multiple agents communicate via file inboxes

From subagent to teammate: one-shot -> persistent; anonymous -> named; no communication -> file-based inbox.

⏱ ~12 min · 📝 3 interactive widgets · 🧑‍💻 Based on shareAI-lab · s09_agent_teams.py

What's the difference between a subagent and a teammate?

s04's subagent is blunt: spawn -> run -> return summary -> die. One-shot, unnamed, no bidirectional communication.

s09's teammate is a named, repeatedly awakened, message-capable independent agent:

subagent (s04):  spawn -> execute -> return -> destroyed
teammate (s09):  spawn -> work -> idle -> work -> ... -> shutdown

The two patterns serve different needs:

  • Subagent: for a concrete one-off task (e.g. review a PR).
  • Teammate: for an ongoing role (e.g. a persistent reviewer who wakes up for every new commit).

The inbox is a JSONL file

How do team members communicate? s09 uses the simplest possible mechanism: append-only JSONL files.

.team/
  config.json          # team roster
  inbox/
    alice.jsonl        # all messages to alice appended here
    bob.jsonl
    lead.jsonl

Sending is open("alice.jsonl", "a").write(msg); reading is read the whole file, parse JSONL, then truncate to drain it.

Why files instead of an in-memory queue? Files are naturally persistent. Agent restart, process crash, even machine reboot - the messages are still there. They're also grep-able, which makes debugging a pleasure.

Watch a message travel from lead to alice

The widget below lets you send a message to alice and see what happens to the filesystem at each step.

5 message types

s09 defines 5 message types (VALID_MSG_TYPES), but only implements the first two - the remaining three are added in the s10 protocol lesson:

  • message - plain text message.
  • broadcast - sent to all teammates except yourself.
  • shutdown_request / shutdown_response - request/respond graceful shutdown (s10).
  • plan_approval_response - plan approval (s10).

Why declare them without implementing them? s09 intentionally makes the protocol extensible - message types are an enum; adding a new one means one dictionary entry and one routing handler in _exec.

Interactive

Widget 1 · Mail Flow · a message from lead to alice

Click Send Message and trace each filesystem step: lead.send -> append alice.jsonl -> alice reads inbox on next turn -> truncate.

Interactive

Widget 2 · Team Config · who's online and what's their status

.team/config.json is the team roster. Perform a series of operations (spawn / message / shutdown) and watch the config evolve.

Operations
.team/config.json

        
Interactive

Widget 3 · Subagent vs Teammate · choose the right pattern

6 task scenarios. Decide whether to use a subagent (spawn-then-die) or a teammate (spawn-then-live). Think about whether the task is a one-shot deal.

Correct: 0 / 6