Collaboration Models
Not sharing context is the real multi-agent collaboration. Its whole abstraction maps almost one-to-one onto an operating system — the static prefix is the program, the trajectory is memory, the LLM is a time-shared CPU. The one place the analogy breaks — processes pass bytes with bit-fidelity, agents pass meaning, and every retelling can distort.
Multi-Agent Collaboration with Shared Context
In multi-agent collaboration with shared context, each stage is an independent Agent (with its own system prompt and tool set), but it inherits the complete trajectory of the preceding Agent—much like a colleague taking over a shift who can leaf through every work log the predecessor left behind. The core advantage of this inheritance-based collaboration is zero information loss: every Agent can review details from any previous stage. The challenge is keeping the current Agent focused on its own responsibilities rather than distracted by the mass of inherited history.
Multi-Stage Role Switching
Let’s put a definitional dispute on the table first: in the language of Chapter 1, multi-stage role switching is a workflow-style orchestration—the execution path (e.g., requirements clarification → implementation → review) is predefined. From a process perspective, a single process executes the different stages in sequence while retaining the same memory throughout. The claim that this is “not really multi-agent” therefore has merit. This chapter nevertheless treats it as a multi-agent pattern because that framing has practical benefits: each stage can have its own system prompt, tools, and focus, while stage boundaries can serve as quality gates.
In complex tasks, an Agent’s role and responsibilities may change significantly across stages. If a single static system prompt is used throughout, it will either be too general to provide stage-specific guidance or too long because it includes instructions for every stage. Multi-stage role switching instead changes the system prompt and tool set according to the current stage, allowing the Agent to work in the most appropriate role. This switching does not require creating new instances or starting new processes; it merely changes the system prompt and tool set within the same execution session. Although the role changes, the conversation history and task state remain shared, so the Agent in its new role can still access all information accumulated in previous stages.
Cross-Domain Role Switching
Multi-stage role switching demonstrated staged execution within a single task type (software development). Cross-domain role switching goes further: the Agent dynamically changes roles as a task moves across domains. Instead of following a predefined linear process, it chooses which professional role to adopt in response to the user’s changing needs.
Multi-Agent Collaboration Without Shared Context
In an architecture without shared context, each Agent operates as an independent entity with its own context, trajectory, and state. Agents cannot directly access one another’s internal context; collaboration relies entirely on explicit, structured data transfers through the three communication mechanisms introduced at the beginning of this chapter: tool call parameters, a shared file system, and a message bus.
Earlier in this chapter, we compared the communication mechanisms to forms of inter-process communication and shared versus isolated context to threads versus processes. This analogy can be extended further (Table 10-3):
Table 10-3 Correspondence Between Multi-Agent Systems and Operating Systems
| Operating System | Multi-Agent System |
|---|---|
| Program (executable file) | Static prefix (system prompt + tool definitions) |
| Process memory | Trajectory |
| CPU | LLM |
| Kernel | Agent runtime |
| System call | Tool call |
| fork (create child process) | spawn_subagent |
| kill (send signal) | cancel_subagent |
| ps (list processes) | list_agents |
| Exit code and wait() | Structured summary returned by the sub-agent |
| Shared memory / message passing | Shared file system / message passing |
A program is static code; a process is one running instance of a program. Likewise, the static prefix determines who the Agent is, while the trajectory records how far it has progressed. The LLM plays the role of the CPU: it holds no state of its own and is time-shared across many Agents by loading different contexts—the very term “context switch” was borrowed from operating systems. And for the same reason, swapping in a faster CPU keeps the program running as before; swapping in a stronger model keeps the Agent the same Agent—its identity and memory live in the prefix and the trajectory, not in the model weights.
This abstraction is nothing new: private state, asynchronous messages, and the ability to create new members are precisely the basic setup of the 1970s Actor model. A multi-agent system can therefore be viewed as an LLM-based version of the Actor model, and much of the accumulated knowledge from operating systems and distributed systems applies directly. The analogy breaks down in one important place: processes pass bytes faithfully, bit for bit, whereas Agents pass meaning, and every retelling can distort it. This is the new problem addressed in this chapter’s “Failure Modes” section.
This process-style isolation brings several practical engineering benefits: each Agent can be developed and tested independently, new capabilities can be added without touching existing code, a failing Agent does not automatically propagate its errors to the others, and multiple Agents can execute concurrently without contention over shared context.
However, not sharing context also has costs. The most obvious is the information synchronization problem: how do Agents maintain a consistent understanding of the task state? Will information be lost or duplicated during transfer? Debugging also becomes more difficult—when problems arise, logs from multiple Agents must be reviewed to piece together the complete execution process. These issues make the design of interface specifications, data formats, and communication protocols critically important.
Explicit collaboration without shared context relies on two topology-independent infrastructures. The first is the shared file system, the persistent medium through which Agents exchange artifacts with one another and with the user, forming the data plane of collaboration. The second is the communication and control mechanism, which supports message passing, status queries, execution termination, and resource scheduling between Agents, forming the control plane of collaboration. The three topologies below are all built on these two foundations.
The File System from an Agent’s Perspective
At the beginning of this chapter, the “shared file system” was listed as one of the three communication mechanisms for architectures without shared context. In a real system, the file system an Agent accesses is not a single storage system but a virtual file system in which storage systems with different sources, lifecycles, and permissions are mounted under one directory tree. The Agent accesses them through unified read_file/write_file/list_dir interfaces, while the underlying layers may be local temporary disks, persistent object storage, third-party cloud drive APIs, or read-only system resource packages. Clearly defining the composition of this directory tree—the visibility and lifecycle of each area—is a prerequisite for designing multi-agent collaboration: a significant portion of concurrency conflicts and information leaks stem from mixing areas that should be isolated. This directory tree amounts to the Agent’s address space, and the four types of areas are memory segments with different permissions: some private and writable, some shared among multiple parties, and some read-only. The operating system’s protection philosophy applies here as well: isolate by default and declare sharing explicitly. In a mature multi-agent system, the file system typically consists of the following four types of areas:
I. Agent-Specific Workspace (Scratchpad). A private directory exclusive to each Agent instance, storing intermediate artifacts, temporary files, drafts, and debug logs. Its lifecycle is tied to the instance and is invisible to other Agents and users. Isolating the scratchpad serves two purposes: preventing temporary files from multiple Agents from overwriting each other, and keeping the main Agent’s context lean—the trial-and-error process of sub-agents remains in their own workspace, with only the final artifact submitted to the shared space. This is the storage-level counterpart of Chapter 4’s principle that sub-agents return structured summaries rather than full trajectories.
II. Multi-Agent Shared Workspace. A collaboration area that multiple Agents can read and write, and that is visible to the user. It is the primary medium for exchanging artifacts between Agents in architectures without shared context: the Glossary Agent writes the term list, and the Translation Agent reads from it; users can also upload source files and download final deliverables here. Its lifecycle is tied to the entire task and requires persistence. As an area for concurrent reads and writes by multiple parties, it is a hotspot for concurrency conflicts—mechanisms such as optimistic locking and worktree isolation operate here, as detailed under “Failure Mode One” later in this chapter. Chapter 4’s use of a volume mount at /workspace/shared to connect the main Agent, virtual computer, and virtual phone is a typical implementation of this layer.
III. Mounted External Resources. Third-party information sources authorized by the user—Google Drive, Notion, Dropbox, enterprise wikis, etc.—are mapped to mount points in the file system (e.g., /mnt/gdrive) via adapters. An Agent accesses a Notion document by reading a file; the underlying adapter calls the corresponding API. Three characteristics distinguish this layer from local storage and must be explicitly handled during design: access is constrained by external permissions (the user’s permissions in the source system determine the Agent’s visibility), latency is higher and consistency is weaker (each read involves a network round trip, and external changes may not be immediately visible, so the data should be treated as eventually consistent), and access is primarily on-demand and read-only (writing back to external sources must be done cautiously, as erroneous writes could contaminate the user’s real data). The unified file interface means the Agent does not need a custom tool for each data source, but it also masks these performance and security differences. Therefore, read-only/writable status, timeouts, and credential boundaries must be explicitly managed at the mount level.
IV. Built-in System Resources. A resource package pre-installed by the system and shared read-only with all Agents. Typical examples are the Skills introduced in Chapters 2 and 4—knowledge documents and scripts organized as files, mounted at paths like /skills, accessed via progressive disclosure (index first, then expand on demand). Other examples include reference manuals, template libraries, and shared tool definitions. This layer is globally shared, read-only, stable across sessions, and can be read concurrently by all Agents without concurrency control.
Figure 10-3 illustrates how these four area types are uniformly mounted under a single directory tree: the Agent accesses the entire tree through a unified interface, users upload and download files from the shared space, external data sources are mounted via adapters, and built-in system resources are provided read-only.
Table 10-4 compares these four area types across four dimensions—visibility, lifecycle, read/write permissions, and concurrency control—serving as a checklist for file system layout design.
Table 10-4 Four area types of the Agent Virtual File System
| Area | Visibility | Lifecycle | Read/Write | Concurrency Control |
|---|---|---|---|---|
| Agent-Specific Workspace | The owning Agent only | Destroyed with the Agent instance | Read/Write | Not needed (private) |
| Multi-Agent Shared Workspace | All collaborating Agents and the user | Persists for the task duration | Read/Write | Required (optimistic lock / worktree) |
| Mounted External Resources | Depends on external authorization | Determined by the external source | Mostly read-only, writes require caution | Managed by the external source |
| Built-in System Resources | All Agents | Stable across sessions | Read-only | Not needed (read-only) |
The value of the “file path as a universal interface” lies in treating a path as the unit of exchange. Whether Agents exchange artifacts, a main Agent hands input to a sub-agent, or organizations collaborate through A2A, they pass a lightweight path string rather than loading the file’s contents into the context window (Chapter 4). This aligns with Chapter 5’s concept of “the file system as the Agent’s hub,” which describes how a single Agent uses the file system to host memory and capabilities. Here, the same abstraction extends to multiple Agents: a virtual directory tree mounting private, shared, external, and built-in storage provides the storage foundation for multi-agent collaboration.
Communication and Control Between Agents
While the file system solves the problem of artifact exchange between Agents, collaboration also requires a control plane. This is exactly where the lifecycle rows of Table 10-3 come into play: the tool primitives given in Chapter 4—creating (spawn_subagent), sending messages (send_message_to_subagent), canceling (cancel_subagent), and discovering (list_agents)—correspond to fork, message, kill, and ps in the process world. This section does not repeat the interface definitions but focuses on four often-overlooked capabilities essential for multi-agent collaboration.
I. Message Passing. The simplest form is point-to-point: Agent A directly calls send_message_to_agent_b(content). This is suitable for scenarios with a fixed topology and a small number of Agents (e.g., the phone + computer dual-agent setup of Experiment 10-4 in this chapter). When the number of Agents increases and asynchronous parallelism is required, the number of point-to-point connections grows quadratically with the number of Agents, and both sender and receiver must be online simultaneously. In such cases, a message bus should be used (detailed later in this chapter under “Parallel Coordination Pattern”): Agents publish messages to the bus, which forwards them based on subscriptions, so the sender does not need to know the subscribers. Whether point-to-point or via a bus, messages should typically carry a structured envelope: sender ID, target (specific Agent or broadcast), message type (e.g., task_assigned/status_update/result/terminate), and a JSON payload. A unified envelope format ensures reliable routing and parsing by the receiver and makes the collaboration chain traceable—a key aspect of debugging multi-agent systems.
II. Status Query. This is the most underestimated part of the control plane. Once a main Agent has dispatched a sub-agent, it needs visibility into the sub-agent’s progress; otherwise, it can neither decide whether to keep waiting nor intervene when the sub-agent gets stuck. An intuitive approach is to borrow from RPC and define a get_subagent_status(agent_id) query interface that returns “running/completed/failed” plus a progress percentage. But such a pull interface turns out to be far less useful than expected: a sub-agent starts executing the moment it is created and runs until it completes or fails. It does not cycle through a series of queued states the way jobs in a traditional batch system do, just as Unix programming rarely needs to poll another process by its PID for running status. Polling also carries an inherent dilemma: poll too often and you waste tokens; poll too rarely and you react late. A more natural way to obtain status is to return to the two communication paradigms introduced at the beginning of this chapter.
Getting status via message passing. The main Agent simply sends the sub-agent a message: “How’s it going?” The sub-agent replies at an opportune moment. Everything is asynchronous: sending the message does not block the main Agent’s own execution, and when—or whether—the other side replies is a separate matter, just as a manager asks a subordinate for progress via instant messaging without requiring them to drop everything on the spot. Conversely, the sub-agent can also proactively send a message to report when it reaches a milestone; if the system already has a message bus, this is simply publishing a status_update to the bus (the “real-time monitoring” of Experiment 10-6 is this form). Whether status is requested explicitly or reported proactively, the status carried in the message should adopt a uniform state-machine vocabulary (executing, needs input, completed, failed)—the A2A protocol later in this chapter standardizes the task lifecycle into exactly such a set of states.
Getting status via the shared file system. The most thorough form is trajectory persistence: as it executes, the sub-agent serializes each trajectory event to JSON and appends it to a filesystem log file—usually one file per session, one event per line, i.e., JSONL. The trajectory, defined in Chapter 1, is the complete sequence of user messages, model replies, tool calls, and results. The main Agent needs no status-reporting protocol; by reading this file directly, it can inspect the sub-agent’s entire execution: which tool it is calling, what happened in its most recent step, and whether it is stuck in a loop of repeated failed retries. In process terms, this resembles reading another process’s memory directly. It does not occupy the sub-agent’s context, does not depend on its cooperation, and offers the finest observation granularity.
Such exhaustive detail is also a burden. A trajectory can easily run to tens of thousands of tokens, and the main Agent must distill it after reading, consuming both time and tokens. In most scenarios, an agreed-upon progress file is more practical: when starting the sub-agent, the main Agent instructs it to update progress.md as it completes each item. The main Agent can read this lightweight file at any time to gauge progress. This resembles two processes reserving a small block of shared memory with an agreed format, exposing distilled progress rather than the entire memory state.
The progress file also enables stuck detection. If the last-modified time of progress.md or the trajectory file has not changed for more than N minutes, the system can treat the sub-agent as inactive and trigger a timeout safety net (echoing the Heartbeat and monitor_shell mechanisms from Chapter 4). This prevents a stalled sub-agent from dragging down the entire system.
The value of trajectory persistence goes well beyond monitoring. Recall the conclusion of Chapter 1: “an Agent’s context = static prefix + trajectory.” The static prefix (system prompt, tool definitions) is determined by code, and the Agent itself has no runtime state beyond the trajectory (working artifacts already live in the file system)—the trajectory is the Agent’s entire state. Persisting the trajectory to a file in real time is equivalent to holding a complete checkpoint at all times: whether the Agent process crashes, the machine loses power, or the user actively closes the session, simply reloading the trajectory file and prepending the static prefix lets execution resume from where it stopped—this is exactly how the session resume feature of coding Agents like Claude Code and Codex CLI is implemented. This is the same idea as a database’s write-ahead log (WAL): every event is first appended to an append-only log, and state can always be replayed from the log (Chapter 3’s “fact log + periodic checkpoint” memory design is the same idea applied to memory systems). For a multi-agent system, this means sub-agents are naturally recoverable, auditable, and easy to hand off: the Manager can restart a sub-agent from its last valid state after a crash, replay the trajectory event by event afterward to locate the cause of a failure, and even hand the trajectory together with the task off to another Agent to continue.
III. Execution Termination. In parallel collaboration, a common scenario is “one succeeds, the rest become irrelevant”—multiple Agents search separately, and once one finds the target, the others should stop immediately (the cascading termination in Experiment 10-6 of this chapter). There are two levels of termination, and Unix users will recognize them as the distinction between SIGTERM and SIGKILL. Graceful termination is preferred: the main Agent sends a terminate signal, the sub-agent responds at a safe point in its current step, cleans up resources (closes browser sessions, writes pending files, releases locks), sends an acknowledgment (ack), and then exits. Forced termination is a fallback: directly terminating the process, used only when the sub-agent does not respond to the graceful signal, at the cost of potentially leaving dangling resources and incomplete writes. Two engineering points need attention. First, graceful termination requires the sub-agent to check periodically for the termination signal in its loop (similar to the interrupt mechanism in Chapter 4); otherwise, it cannot receive the signal. Second, cascading termination has a race condition: multiple sub-agents might report success nearly simultaneously. The main Agent must use a lock or idempotent design to ensure that only one success is accepted and that the termination signal is broadcast once. See the discussion of race conditions in Experiment 10-6.
One loose end remains: after the main Agent terminates, what happens to sub-agents still running? The cleanest engineering approach borrows from Go’s context—termination cascades down the creation relationship: cancel one Agent and all the sub-agents it spawned are canceled with it, preventing orphaned child Agents from being left behind. The “sub-agent checks for the termination signal at a safe point” above corresponds precisely to polling ctx.Done() in Go. Conversely, if you genuinely need a long-running background Agent detached from the main Agent (like Unix’s nohup), let it start from a new lifecycle tree (corresponding to context.Background()), explicitly declaring that it does not terminate with its parent.
IV. Resource Management and Scheduling. The other half of an operating system’s job is allocating scarce resources. In the process world the scarce resources are CPU time and memory; in the Agent world they are tokens, money, and concurrency budget—every step a sub-agent takes consumes all three. This responsibility usually falls on the Manager or the runtime: set a step or token budget when starting a sub-agent, and stop once it is exceeded; give hard tasks to a strong model and mechanical tasks to a low-cost model; cap concurrency so that dozens of Agents don’t exhaust the API quota at once; and when a more urgent task arrives, interrupt an executing sub-agent—this is preemption. Practice in this area is far less mature than CPU scheduling, but it determines the cost ceiling of a multi-agent system and should be considered at the architecture-design stage.
Artifact exchange (the data plane) and message passing, status query, execution termination, and resource scheduling (the control plane) together support multi-agent systems that do not share context. The three collaboration topologies below are, at bottom, different choices—built on these two planes—about who holds control and how information flows.
Based on the collaborative relationships and control flow characteristics between Agents, collaboration without shared context can be divided into three main architectures—the peer collaboration pattern, the manager pattern, and the decentralized pattern—each suited to different types of tasks.
Peer Collaboration Pattern: Mutual Checks and Iterative Improvement
Peer collaboration typically involves 2-3 Agents of equal standing giving each other feedback across multiple rounds of iteration. Its core value is cognitive diversity: different Agents examine the same problem from different angles, balancing innovation against robustness to produce a result better than any single Agent could.
Compared to the manager and decentralized patterns, peer collaboration is far simpler to implement—define the two Agents’ roles, the communication mechanism, and the iteration termination condition, and you have a running system. It is an ideal choice for quickly validating ideas and building prototypes.
One of the most common uses of peer collaboration is to counter a frequent failure in Agent practice: premature termination—stopping with the job half done. It takes three typical forms; the examples below come from Coding Agents and from Pine AI, the Agent introduced in the Introduction that makes phone calls on users’ behalf to deal with merchants and service providers. The first is lazy fake-done: doing part of the work and declaring all of it done—a Coding Agent writes the code, never runs the tests or tries the deployment, and reports “task complete”; a user gives Pine AI two errands, and it finishes the first, forgets the second, and cheerfully reports “all taken care of.” The second is premature give-up: declaring the whole job impossible after one blocked path—Pine AI can reach a merchant by phone, web form, or email, but after a single rejected call it tells the user “this can’t be done,” when switching channels and trying again would very likely have succeeded. The third is false success: the Agent believes the job is done, but the loop was never actually closed—the other side verbally agrees to a refund on the phone, yet the user still has to confirm a step in the mobile app; the Agent reports “all set,” the user never learns there is a follow-up action, and the refund never lands. All three forms point to the same root cause: until it is verified, “done” is merely the model’s claim, not a proof.
Turning claims into proofs is precisely the business of Loop Engineering, the last stage of Chapter 1’s evolutionary arc: design a loop that keeps the Agent running—discover the next piece of work, execute, verify, record progress—and let a verifier, not the model itself, decide whether it is truly safe to stop. The human’s role shifts accordingly from “the operator who prompts the Agent” to “the engineer who designs the loop.” The term was coined in June 2026 by Addy Osmani; Boris Cherny, head of Claude Code at Anthropic, put it more bluntly: “I don’t prompt Claude anymore. My job is to write loops.” The central conclusion to emerge from that discussion was that the bottleneck of the loop is the verifier, not the model: with unreliable verification, a faster loop merely marks poor output as complete sooner. And as the Introduction says, practice comes first, naming comes later. Long before the term caught on, leading Agent teams—Pine AI among them—were already using “loop plus verification” against premature termination. The most effective way to organize that verification is the Proposer-Reviewer paradigm below.
Proposer-Reviewer Paradigm.
Proposer-Reviewer is the canonical peer-collaboration paradigm. Chapter 5 already covered its design principles and practical applications in three experiments: PPT generation, video editing, and log visualization. The Proposer Agent generates code, while the Reviewer Agent renders the execution results, evaluates their quality using a vision-language model, and provides structured suggestions for improvement. The two iterate until the result meets the required standard.
This paradigm is also applicable to scenarios like security review (Proposer generates an action plan, Reviewer checks compliance and potential risks), content moderation (Proposer drafts a reply, Reviewer checks business rules and language norms), and code review (Proposer writes code, Reviewer checks security and best practices).
Why can’t a single Agent generate and then review its own work? This is exactly where the criterion from “When Is Multi-Agent Truly Better Than a Single Agent?” earlier in this chapter applies—if the review does not introduce new information, it is just “asking the model to think again.” Related research provides a clear answer. In their ICLR 2024 paper “Large Language Models Cannot Self-Correct Reasoning Yet,” Huang et al. found that asking GPT-4 to review and correct its own answers without external feedback actually decreased accuracy—the model changed correct answers to incorrect ones more often than it changed incorrect answers to correct ones.
A 2024 survey paper published in TACL, “When Can LLMs Actually Correct Their Own Mistakes?” (arXiv:2406.01297), further confirmed this conclusion: unless reliable external feedback is provided (e.g., test case execution results, verification output from external tools), relying solely on the model’s own “self-correction” is largely ineffective.
The CRITIC paper at ICLR 2024 provides an intuitive comparative experiment. CRITIC had the model use external tools (search engine, Python interpreter) to verify its own answers, leading to significant performance improvements. However, when the experimenters removed the tool verification step and only kept the model’s self-assessment, most of the improvement disappeared. This indicates that the value of review lies not in “asking the model to think again,” but in introducing new information that was not available during the model’s generation—test results, rendered screenshots, compilation errors, external search results.
This is the core design principle of the Proposer-Reviewer paradigm. In the PPT generation experiment of Chapter 5, the value of the Reviewer Agent was not “using the same model to look at the code again,” but rendering the PPT and taking a screenshot—a screenshot containing visual information that the Proposer Agent could not obtain when generating the code. Similarly, in code generation scenarios, the pass/fail results from executing test cases are new signals that did not exist when the code was written—the independent value of the Reviewer stems precisely from its access to this external feedback unavailable to the Proposer.
Viewed through the lens of Loop Engineering, the loop patterns catalogued by the industry map onto patterns in this book. A closed loop with human approval corresponds to Chapter 4’s pre-approval, in which the human is the final reviewer. An open loop with a budget or round cap corresponds to Chapter 5’s multi-round PPT iteration, which allows at most five rounds. Orchestrated sub-agents correspond to the manager pattern in the next section. Loop Engineering therefore describes not a new architecture but a common framework—loop + verification + stop conditions—that unifies these collaboration patterns. The Proposer-Reviewer paradigm fills the verification role within that framework.
Extensions: Other Peer Collaboration Patterns.
Debate: Multiple Agents hold different positions, exploring the problem space through adversarial dialogue. For example, when evaluating a technical solution, Agent A plays the “supporter,” listing the solution’s advantages and opportunities, while Agent B plays the “opponent,” pointing out risks and limitations. Each round of debate involves rebutting or extending the other’s arguments. When a single Agent analyzes a problem, it often favors one perspective and overlooks counterevidence. Structured debate forces both positions to be developed fully, helping decision-makers reach a more balanced judgment.
However, the practical effectiveness of debate remains contested in academia. A 2026 study by Tran and Kiela compared a single Agent with five multi-agent architectures (sequential, debate, ensemble, parallel roles, subtask-parallel) on multi-hop reasoning tasks. They found that when the thinking-token budget was held constant, the single Agent performed on par with or even better than the multi-agent systems (unless context utilization was degraded to a certain point). The researchers provided an explanation based on the data processing inequality in information theory: multiple Agents in a debate process the exact same textual information, and each serial transmission of intermediate conclusions between Agents can only lose information, not create it. The benefits of the debate mode in some academic papers likely stem from multiple Agents consuming more total computation. It is important to clarify the boundary of this argument: it targets the information bottleneck caused by “multi-agent serial transmission of intermediate conclusions” and does not negate other approaches, such as multiple independent samples of the same problem followed by aggregation (e.g., self-consistency, majority voting), or leveraging the asymmetry in difficulty between generation and verification (writing an answer is hard, verifying it is easy) for a generation-verification division of labor. These scenarios either introduce additional independent sampling or exploit the asymmetric structure of the task itself, and are not within the scope of the data processing inequality.
Brainstorm: Multiple Agents independently generate ideas, then share them with each other, inspiring one another. For example, in a product innovation task, Agent 1 proposes “adding social sharing features,” Agent 2 is inspired to suggest “not just sharing to social networks, but also generating personalized sharing posters,” and Agent 3 synthesizes the first two to propose “user-customizable poster templates forming a template marketplace.” Different Agents have different “thinking preferences” (achieved through different prompts or models), and by stimulating each other, they explore a broader solution space to find creative combinations that a single Agent would struggle to conceive.
Panel Discussion: Multiple Agents each represent the perspective of a specific professional domain, jointly discussing an interdisciplinary problem. For example, when evaluating the feasibility of a new product, an Engineer Agent analyzes the implementation difficulty from a technical standpoint, a Product Agent assesses market appeal from a user experience perspective, and an Operations Agent analyzes business viability from a cost and resource perspective. These Agents are not adversarial but complementary, together piecing together the full picture of the problem and identifying cross-domain constraints and opportunities.
Manager Pattern: Centralized Coordination
When a task involves more than five subtasks, needs dynamic scheduling, or has complex dependencies among subtasks, peer collaboration is out of its depth, and the manager pattern is needed. The Manager Agent’s job resembles that of a project manager: understand the overall task, break it into assignable subtasks, choose the right Agent for each, track progress, handle exceptions by retrying tasks, replacing Agents, or revising the plan, and finally integrate the Agents’ outputs into the final result.
From a system design perspective, the manager pattern models each specialized Agent as a tool that the Manager can invoke. The Manager’s tool set includes not only traditional external tools, such as search and file operations, but also interfaces for invoking other Agents. The Manager invokes the appropriate Agent through a tool call, passes the task parameters and necessary context, waits for completion, and receives the result. From the Manager’s perspective, calling an Agent is essentially no different from calling a regular tool: both involve sending a request and receiving a response. This unified abstraction makes the manager pattern easy to extend. Adding a capability requires only developing the corresponding Agent and registering it as a tool, without modifying the Manager’s core logic. It also naturally supports heterogeneity: different Agents can use different models, prompts, tool sets, and even hardware environments.
The abstraction of “Agents as tools for each other” was established in the “Collaboration Tools” section of Chapter 4: the interface design of spawn_subagent / send_message_to_subagent / cancel_subagent / list_agents applies directly to the Manager’s invocation of sub-agents here. As for what is passed in the “Manager → sub-agent” direction, see the handoff-package design later in this chapter (task description, confirmed facts and constraints, references to structured artifacts). The corresponding question is what the sub-agent returns in the “sub-agent → Manager” direction. The answer is structured summaries rather than full trajectories: the sub-agent should return the task conclusion, key findings, file paths of the artifacts, and problems encountered, leaving the complete execution trajectory in its own logs. Only in this way can the Manager’s context grow slowly and linearly with the number of subtasks, rather than exploding. This is also why the Manager in Experiment 10-3 below maintains only file indexes and does not store translation content.
The manager pattern has inherent challenges, though. The Manager becomes the system’s single-point bottleneck: it must understand the nature of every subtask, choose the right Agent, and pass context accurately; any misjudgment ripples through the whole flow. It must also maintain the global context of the entire task, which can balloon as the task deepens and Agent calls accumulate. The Manager therefore requires a carefully designed prompt, an effective context-management strategy, and appropriately granular task decomposition.
The 2025 Plan-and-Act paper provides an empirical analysis of this: in a Planner-Executor dual-agent architecture, a weak planner is the most critical bottleneck of the entire system. When the Planner’s planning quality is high enough, good results can be achieved even with a relatively simple Executor. Conversely, if the Planner’s task decomposition is wrong, all subsequent Executor work is built on a faulty premise. The study achieved a 54% success rate on the WebArena-Lite benchmark, and its core contribution was improving the Planner’s planning ability, not the Executor’s execution. The lesson: give the strongest model and the most carefully crafted prompt to the Manager (the planner), rather than spreading resources evenly across all Agents.
This does not conflict with an argument from Chapter 4. In discussing the proposal model and the review model, Chapter 4 held that their capabilities should be similar—but that concerns the review scenario: a reviewer must keep up with the reasoning of the party under review to spot its flaws. If the reviewer is much less capable than the party under review, it may be unable to follow the reasoning closely enough to identify flaws. The manager pattern concerns something else: the division of labor between planning and execution. Once the planner decomposes the task incorrectly, no executor, however strong, can recover. Hence the strongest model and the most careful prompt go to the planner first. Whether the executors need balanced capabilities depends on how tightly the subtasks are coupled. When their outputs must ultimately be assembled into one whole, the weakest link often drags down the overall quality.
Sequential Coordination Pattern.
The Manager calls specialized Agents sequentially. Each Agent returns results upon completion, and the Manager decides the next step. The control flow is linear, simple, and clear, making it suitable for scenarios where subtasks have clear sequential dependencies.
Parallel Coordination Pattern.
When multiple subtasks can run in parallel, the sequential pattern becomes inefficient. Parallel coordination allows multiple Agents to work simultaneously, significantly increasing throughput. The Manager Agent must plan the parallel tasks, monitor all running Agents in real time, coordinate their communication, and make system-wide decisions when Agents succeed or fail. This typically requires a message bus as infrastructure—think of it as a “public bulletin board” where Agents can publish messages and subscribe to the message types that interest them, enabling asynchronous, non-blocking communication. Two common implementations, from simpler to more complex, are Redis Pub/Sub and message queues such as RabbitMQ. Redis Pub/Sub is lightweight and delivers messages immediately, but it does not persist them, so a receiver that is offline will miss them. RabbitMQ and similar systems persist messages to disk, preserving them while a receiver is temporarily offline. Messages typically use a JSON envelope containing the sender ID, target Agent (or a broadcast marker), message type, and payload.
Lingtai: A Productized Instance of the Manager Pattern. Lingtai is a local, file-based home for long-lived agents. Its three roles map closely onto the concepts in this section. The main agent is the persistent hub with which the user interacts; it holds the plan and memory and spawns the other roles, occupying the position of the Manager Agent. A daemon is a short-lived parallel worker spawned for a noisy, bounded task and discarded afterward; only its conclusions are retained. This productizes both the principle that sub-agents return structured summaries rather than full trajectories and the parallel coordination pattern. An avatar is a persistent, specialized teammate with its own memory, mailbox, and responsibilities, designed for specialties worth retaining across sessions.
The rest of Lingtai’s design also echoes earlier sections. Knowledge lives in each agent’s durable, private memory files, while skills are Markdown playbooks shared by all agents—the built-in system resources described in “The File System from an Agent’s Perspective.” When an agent’s context window fills, it molts: it writes a careful summary, then starts with a fresh context while retaining that summary and its durable memory, following the context-compression approach from Chapter 2. The underlying model can be replaced without changing the agent because its identity, memory, and capabilities all live as plain files in the project directory. In this sense, the agent is its files. This productizes the first two rows of Table 10-3: both program and memory reduce to files, so the process can be rebuilt at any time.
Decentralized Pattern: Peer-to-Peer Handoff
The manager pattern provides a clear control structure and global visibility, but the decentralized pattern is not simply a remedy for its shortcomings. The motivation for removing the central controller is chiefly to emulate the way human society organizes itself: letting multiple peer roles divide labor and check one another, each examining the problem from its own professional perspective and deciding on its own whom to talk to, rather than funneling every judgment to a single Manager. The microservices field calls this pair of choices orchestration and choreography: the former has a conductor scheduling everything centrally, the latter relies on each dancer sensing for itself when to enter.
The decentralized pattern takes a different architectural approach: there is no single central controller; Agents collaborate as peers. Each Agent, drawing on its own professional judgment, decides for itself when to reach out to another—to hand off a task (“My part is done, over to you”), request feedback (“Is this plan technically feasible?”), or report a problem (“The requirements you gave me are contradictory; we need to talk this over again”).
The following cases progress from partial to full decentralization. MetaGPT uses a fixed pipeline and decentralizes only communication. AutoGen combines shared conversation history with centralized scheduling. OpenAI Swarm distributes control-flow decisions directly among peer Agents.
What is passed during a handoff without shared context? Figure 10-10 contrasts two kinds of handoff. In Experiment 10-2, transfer_to_agent uses shared context, so the new role automatically inherits the complete history. In the handoff-chain pattern, context is not shared, so the sending Agent must explicitly assemble the information the receiving Agent needs.
In practice, an effective “handoff package” typically contains three parts: Task Description (what the receiver needs to do and the acceptance criteria), Confirmed Facts and Constraints (user preferences, business rules, and decisions made in previous stages), and References to Structured Artifacts (file paths rather than file contents, which the receiver reads as needed). The package deliberately excludes the full trajectory—the sending Agent’s trial-and-error process, intermediate work, and failed attempts—which is mostly noise for the receiver.
This is the essential difference between the two handoff types. A handoff with shared context retains the complete history, preserving all information but continuously expanding the context. A handoff without shared context passes a refined package, accepting some information loss so that each Agent can work in a clean, focused context. No Agent needs to understand another Agent’s work process; it needs only the format and meaning of the handoff package and its output artifacts. This interface-based collaboration draws on the software-engineering principle of design by contract.
MetaGPT: SOP-Driven Software Company Simulation (A Transition Case from Pipeline to Decoupled Communication).
MetaGPT’s core insight is that the Standard Operating Procedures (SOPs) developed and refined by software companies can serve as collaboration protocols for multi-agent systems. Encoding these SOPs allows each role, like a specialized worker on an assembly line, to produce standardized deliverables, and those deliverables naturally become the communication interfaces between roles.
In MetaGPT, roles work in a fixed sequence (Product Manager → Architect → Project Manager → Engineer → QA), with each role outputting structured deliverables:
- Product Manager Agent: Receives requirement descriptions, generates a structured PRD (Product Requirements Document, including feature list, user stories, acceptance criteria, priority ranking)
- Architect Agent: Reads the PRD, makes architectural decisions (technology stack selection, module division, interface definition, data model design), outputs a design document
- Project Manager Agent: Reads the architectural design, decomposes the system into specific task lists and file-level assignments, clarifies the dependency order of modules, and then assigns tasks to engineers
- Engineer Agents: Read the design document, implement their assigned modules, produce code. Multiple instances can work in parallel.
- QA Engineer Agent: Reads the code and PRD, generates test cases, executes tests, records bugs, outputs a test report
MetaGPT’s true contribution to decentralized communication lies in its information-passing mechanism: Shared Message Pool + Subscription by Role. Each role publishes structured messages to a pool visible to all roles. Based on their subscription configuration, other roles consume only the messages relevant to their responsibilities rather than communicating point to point. The publisher does not need to know who will consume its output. To add a role, declare the message types to which it subscribes; existing roles need not change. This creates genuine decoupling: for example, replacing the Product Manager with a more powerful model requires no changes to other Agents, as long as its PRD still conforms to the specification.
MetaGPT’s iterative improvement occurs primarily in the engineering phase through executable feedback. The Engineer runs its code and tests, uses errors and failures to guide a debugging loop, and continues until the tests pass. Corrections are driven by deterministic execution results rather than another Agent’s opinion.
To be clear, MetaGPT is not decentralized in terms of control flow—the role sequence is predetermined by the SOP, making the overall system closer to an assembly line (a workflow in the language of Chapter 1). It is discussed in this section because the message pool plus subscription communication mechanism demonstrates the most critical design element of a decentralized system: decoupling. As for multi-directional dynamic feedback like “QA directly contacting the Product Manager to clarify requirements” or “Engineer discussing alternative solutions with the Architect,” these are natural extensions envisioned for this architecture but were not implemented in the original MetaGPT.
AutoGen Group Chat: Shared Conversation History + Centralized Scheduling. AutoGen’s group chat allows multiple Agents to participate in the same conversation. In each round, a “speaker selector” decides which Agent speaks next. The selector can follow a simple round-robin rule or use an LLM to determine which Agent is best suited to respond based on the conversation so far. Every Agent’s contribution is visible to all participants.
This is not fully decentralized in terms of control flow: a GroupChatManager selects the speaker centrally, and deciding whose turn it is constitutes a control-flow decision. A more accurate classification is therefore shared conversation history + centralized scheduling. All Agents see the same public history, but each retains an independent system prompt and tool set, while the selector holds scheduling authority.
This model suits tasks that require discussion from several perspectives and whose speaking order cannot be determined in advance, such as plan review or cross-domain analysis. However, the conversation can drift: every Agent may keep speaking without the group making progress, a form of livelock. Clear termination conditions are therefore essential. On the dimensions used in this chapter, AutoGen is a hybrid: scheduling is centralized, while context is partially shared. This illustrates that topology and context sharing are independent design dimensions.
OpenAI Swarm and Agents SDK: Handoff Network. In contrast, OpenAI’s Swarm and its successor, the Agents SDK, represent peer-to-peer decentralization in control flow. Each Agent has several handoff options and can transfer control to another Agent in the network at any time. A customer-service triage Agent that determines an issue involves a refund hands the task to the Refund Agent; if that Agent discovers a technical fault, it can hand the task to the Technical Support Agent. There is no central scheduler. Control passes like a baton between peer Agents, and each Agent makes its own routing decisions. This is the engineering implementation of the handoff-chain pattern in Figure 10-10. The risk is cycles: A hands off to B, and B hands back to A, leaving the task spinning in a loop. A guard such as a maximum handoff count is needed to break it.
Cross-Organization Collaboration: The A2A Protocol
All the systems above assume that all Agents are developed by the same team and run within the same system. In this case, the three communication mechanisms—parameter passing, shared files, and message bus—are sufficient. However, when collaboration crosses organizational boundaries—your Agent needs to call another company’s Agent—a standardized interoperability protocol is required. The world of processes followed the same evolution: IPC only governs a single machine, and once you step across the machine boundary you must rely on standard protocols like TCP/IP and service discovery like DNS. A2A is to Agents what network protocols are to processes. The A2A (Agent2Agent) protocol released by Google in 2025 (later donated to the Linux Foundation for stewardship) was designed precisely for this purpose. It has three core elements:
- Agent Card: A metadata document describing an Agent’s capabilities (published at a designated public address), declaring what the Agent can do, which input/output modalities it supports, and how to authenticate with it—essentially an Agent’s “business card” that solves cross-organizational capability discovery.
- Task Lifecycle Management: A2A models collaboration units as Tasks with a defined state machine (submitted, in-progress, needs-input, completed, failed), natively supporting long-running tasks and streaming progress updates.
- Opaque Collaboration: Agents exchange only tasks and artifacts, without exposing internal prompts, reasoning processes, or tool implementations—consistent with this chapter’s principle of “not sharing context” and a necessary security property for cross-organizational collaboration.
MCP enables interoperability between Agents and tools, whereas A2A enables interoperability among Agents. A2A does not replace the three communication mechanisms introduced in this chapter; it standardizes communication across trust boundaries. A message bus may be sufficient within one organization, but when collaborating parties do not trust one another and cannot inspect one another’s implementations, they need a public protocol such as A2A.
Failure Modes of Multi-Agent Collaboration
Multi-agent systems introduce new failure modes that do not exist in single-agent systems. The 2025 paper “Why Do Multi-Agent LLM Systems Fail?” proposed the MAST failure-mode taxonomy through a systematic study. The researchers collected execution traces from seven mainstream multi-agent frameworks, including MetaGPT, ChatDev, AG2, and Magentic-One. Human annotators independently analyzed roughly 150 traces, achieving high agreement on their judgments (Cohen’s kappa = 0.88). The study identified 14 unique failure modes in three groups:
- System Design Flaws: Architecture-level issues such as unclear interface definitions between Agents, overlapping roles and responsibilities, and incorrect tool configurations.
- Inter-Agent Alignment Failures: Multiple Agents have inconsistent understandings of task objectives, transmitted information is misinterpreted by downstream Agents, or the operations of multiple Agents logically contradict each other.
- Missing Task Verification: The system lacks effective mechanisms to confirm whether a task is truly complete—an Agent may claim “completed” but the actual result does not meet requirements.
Even straightforward fixes produced limited gains; for example, ChatDev’s measured performance improved by only 15.6%. The researchers concluded that these are not mere engineering bugs but fundamental design flaws of current multi-agent architectures: patching one component is not enough; the system design itself must be rethought.
Distributed fault-tolerance theory distinguishes two kinds of faults: crash faults, in which a component stops working, and Byzantine faults, in which it continues operating but supplies incorrect information. Traditional systems are designed mainly to withstand crashes. Agent failures, however, are often Byzantine: an Agent rarely stops outright and instead continues producing plausible but incorrect conclusions, without announcing the error. This explains why patching a single component yields so little: no component will necessarily expose the problem, so the system must catch it through independent redundancy. Cross-validation and majority voting, which recur throughout this chapter, are classic techniques of Byzantine fault tolerance. Deterministic checks such as tests, compilers, and database queries are especially valuable because they provide independent evidence that does not depend on another model’s judgment.
The following section focuses on two failure modes that are particularly common and destructive in practice: (1) concurrency conflicts in shared file systems; (2) cascading amplification of errors. Note that these two failure modes emphasize an engineering perspective (file system concurrency, cross-Agent propagation of erroneous information) and serve as a supplement to the MAST classification, which focuses on dialogue-based collaboration failures, rather than a restatement of its 14 modes.
Failure Mode One: Concurrency Conflicts in Shared File Systems
Once you choose shared-memory-style communication, concurrency conflicts come with it—a problem operating systems and databases solved decades ago, with the answers already off the shelf. These conflicts can be divided into two types.
Simple Conflicts (File-Level Write Conflicts): Two Agents modify the same file simultaneously, and the one that writes later overwrites the changes made by the earlier writer. This is the classic lost update problem in the database domain—and Git’s merge conflict detection mechanism is precisely designed to catch such overwrites.
Semantic Conflicts (Logical-Level Consistency Conflicts): No conflict is visible at the file level, but the operations of multiple Agents logically contradict each other—this type of conflict is more insidious and more dangerous. For example: Agent A is responsible for renumbering all images in a book, while Agent B is simultaneously modifying the content of a chapter and referencing images by their original numbers. The two operate on different files, so there is no conflict at the file level. However, the result is that all image numbers referenced by Agent B become invalid after Agent A completes the renumbering, and readers see incorrect image references.
Solution: Optimistic Locking Mechanism. This is a common concurrency-control strategy in databases. To understand it, consider an everyday example: you and a colleague open the same online document simultaneously. A “pessimistic lock” would lock the document when you open it, and your colleague would see “file locked” when trying to edit. This is safe but inefficient because you might only be viewing the document. An “optimistic lock” is more flexible: everyone can open and edit freely, but when saving, the system asks, “Has anyone else modified the document since you opened it?” If so, it prompts you to refresh and retry.
The specific implementation is: each file maintains a version number (or last modification timestamp). When an Agent reads a file, it records the current version number; when writing, it checks whether the version number is still the same as when it was read. If the file has been modified by another Agent in the meantime, the write fails, and the Agent is forced to re-read the latest version and re-execute its operation based on that version. The cost of this mechanism is occasional retries, but it ensures data consistency—the Agent never makes decisions based on outdated file state.
Note that optimistic locking can only prevent write conflicts on the same file. For the aforementioned cross-file semantic conflicts (e.g., image numbers referenced in multiple places), higher-level coordination or semantic validation is needed, such as avoiding parallel modification of dependent files or running a global consistency check after writes.
For example, Agent A reads config.json (version=3) at t=0. Agent B modifies the same file at t=1, changing the version to 4. When Agent A attempts to write at t=2, it finds that the version is no longer 3, so the write is rejected. Agent A then rereads version 4, reconstructs its change against the latest content, and tries to write again.
When multiple Coding Agents modify the same codebase concurrently, the standard industry approach is not to lock a single working copy but to use working-copy isolation. Each Agent receives an independent Git branch or worktree and modifies its own copy without interfering with the others. Conflicts are deferred to a final merge, where a dedicated process or a human resolves them. The copy-on-write mechanism used when an operating system forks a process follows the same idea. This reflects the “isolation over compression” principle from Chapter 2: rather than sharing mutable state and resolving conflicts continuously, isolate the work from the outset and incur the coordination cost at a well-defined merge point.
Failure Mode Two: Cascading Amplification of Errors
Concurrency conflicts are file-level problems that can be addressed using established operating-system and database techniques. Cascading errors are different because they arise where the process analogy breaks down: processes transmit bytes exactly, whereas Agents transmit meaning, and each retelling can introduce distortion. When multiple Agents interact frequently, an error from one Agent can be progressively reinforced by subsequent Agents, much like the “telephone game” in which information becomes increasingly distorted.
Consider a specific scenario. Suppose a translation system uses a manager pattern (the architecture from Experiment 10-3), where the Manager assigns chapters of a technical book to multiple translation Agents:
Terminology Agent: Translates "reasoning" as "推理", but "推理" in Chinese is more commonly used for inference, creating ambiguity
↓ writes to glossary.json
Translation Agent A: Translates Chapter 2, reads from the glossary, translates "reasoning tokens" as "推理 token"
Translation Agent B: Translates Chapter 7, translates "inference latency" as "推理 latency"
↓ writes to each chapter's translation
Proofreading Agent: Sees the entire book consistently uses "推理", considers the terminology consistent and the translation correct ✗
Where is the error? “Reasoning” (the model’s thought process) and “inference” (the model’s forward pass at deployment) are two distinct concepts. But because the Terminology Agent first rendered “reasoning” as “推理”, subsequent Agents naturally reached for the same word when they hit “inference”—two different concepts collapsed into one translation, leaving readers unable to tell them apart. The correct choice is “思考” (“thinking”) for “reasoning” and “推理” for “inference”. Yet the Proofreading Agent, seeing “推理” used “consistently” throughout, concludes the translation is high quality.
After propagating through three Agents, a single terminology error appears more credible because it has been applied consistently. This is why the book distinguishes reasoning as 思考 from inference as 推理, as explained in the introduction. The initial mistake need not be a hallucination; it may simply be a poor terminology decision. Either way, later Agents can reinforce it. If the root cause is a genuine hallucination—for example, a Translation Agent “recalls” a nonexistent terminology rule because of attention drift—the same amplification mechanism applies, with potentially more severe consequences. The manager pattern is especially vulnerable because an inaccurate sub-agent summary can become the premise for all subsequent work.
Cross-validation is the key to breaking this chain. The core idea is not to involve more Agents in the same reasoning path, but to have an Agent re-examine the conclusion from an independent perspective: ignore the preceding Agents’ reasoning traces and check only whether the original evidence and the final conclusion are consistent. This extends the proposer-reviewer mechanism from Chapter 5 to a multi-agent setting. The Reviewer’s value lies not only in finding code or formatting errors but also, as an independent judge, in identifying contradictions that the entire chain has overlooked. For high-risk decisions, the system can also use deterministic checks such as unit tests, compilers, and database queries. These tools provide independent evidence that can break a chain of mutually reinforced model errors.
Premature termination has a symmetric opposite: the runaway loop. The peer-collaboration section dealt with loops that stop while the job is half done; here we must guard against loops that continue indefinitely and make the result worse. Experience with autonomous Agent loops has revealed three common failure modes. The first is runaway token cost: an unattended loop runs for hours, burns through the budget, and produces piles of code nobody asked for. The second is comprehension debt: the faster the loop ships code, the further the engineer’s understanding of the implementation falls behind. By the time human intervention becomes necessary, no one understands the system. The third is cognitive surrender: the designer grows accustomed to the loop doing the work, gradually stops thinking and reviewing independently, and allows quality to spiral downward. The remedies mirror those for error amplification: explicit budgets and stop conditions, verifiers grounded in real observations, and a human who remains “the engineer of the loop” rather than merely “the person who presses go.”
So far, this chapter has taken an engineering perspective: how can a group of Agents collaborate on a task? The focus now shifts to a different question: what emerges when large numbers of Agents coexist over long periods without being driven by a single goal? The next section explores frontier research, so engineering readers should feel free to read selectively.
Engineering Practice
Zapvol’s multi-agent lands on the two planes. The control plane is the Agent Team coordination model — mailbox-centered message passing (this page’s message bus + envelope), with the Agent Team implementation providing member-to-member communication and a shared task list. The data plane is sub-agents’ shared workspace (this page’s “multi-agent shared space,” where deliverable artifacts are passed by path, not content). Sub-agents take the unshared-context isolation route — exploring in their own context and returning only a structured summary (this page’s “sub-agent returns a summary, not the full trajectory,” also isolation over compaction). When to use task (isolated sub-agent) vs team (peer collaboration) is in delegation patterns. Crash recoverability comes from compaction’s append-only record — the “trajectory is state, WAL is replayable” of this page made real.
Related reading
- Classification and Criterion — the two dimensions and the new-information criterion
- Agent Society — the emergent social, economic, and game-theoretic layer