Message pool (default)
All steps
Assembly line
QA sends it back
Parts of this pattern
- Request Input / output
- A one-line requirement from the user, such as 'Build a command-line 2048 game'.
- Product manager Agent
- Turns the requirement into a PRD: user stories, a competitive note and a prioritized requirement list.
- Message pool Memory
- The shared store of typed documents. Every role publishes here and subscribes only to the document types it needs.
- Architect Agent
- Reads the PRD and writes the system design: file list, data structures and the interfaces between modules.
- Engineer Agent
- Reads the design and writes the code file by file, then fixes it when QA sends failures back.
- QA engineer Agent
- Writes and runs tests against the code, then passes it or reports each failure back to the engineer.
- Software Input / output
- The working code, returned with every document the team produced along the way.
- Request → Product manager
- The requirement goes to the first role in the procedure.
Build a command-line 2048 game in Python.
- Product manager → Message poolPRD
- The product manager publishes a PRD to the pool, in the PRD template.
PRD. Goal: playable 2048 in a terminal. Stories: arrow keys move tiles; equal tiles merge; show the score. P0: 4x4 board.
- Message pool → Architect
- The architect subscribes to PRDs, so it receives the new one from the pool.
Subscribed: PRD (from Product manager).
- Architect → Message pooldesign
- The architect publishes the system design to the pool.
Design. Files: game.py (Board, move, merge), cli.py (input loop). Board: 4x4 int grid; move(direction) returns bool.
- Message pool → Engineer
- The engineer subscribes to designs, and to QA reports when there are any.
Subscribed: System design (from Architect).
- Engineer → Message poolcode
- The engineer publishes the code, file by file, to the pool.
game.py: class Board: def move(self, direction): ... cli.py: while not board.is_over(): ...
- Message pool → QA engineer
- QA subscribes to code, plus the PRD and design it checks the code against.
Subscribed: game.py, cli.py (from Engineer); PRD; System design.
- QA engineer → Engineer
- QA publishes a failing report to the pool; the engineer, subscribed to QA reports, picks it up (drawn as a shortcut), fixes the code and publishes it again.
{"passed": false, "failures": [{"test": "test_merge_row", "expected": "[4, 0, 0, 0]", "actual": "[2, 2, 0, 0]", "file": "game.py"}]}
- QA engineer → Softwarepass
- When every test passes, the code leaves the line with its documents.
{"passed": true, "failures": []} 2048 ships: game.py, cli.py, test_game.py.
Chat chain (ChatDev)
Each phase of the procedure is a two-agent chat, an instructor and an assistant, that runs until they agree; its conclusion is handed to the next phase.
All steps
Parts of this pattern
- Request Input / output
- A one-line requirement from the user, such as 'Build a command-line 2048 game'.
- Design chats Agent
- Two short chats: the CEO and CPO agree what form the product takes, then the CEO and CTO pick the language.
- CTO Agent
- In the coding phase, the CTO is the instructor: it gives the programmer one instruction at a time and never writes the code itself.
- Programmer Agent
- In the coding phase, the programmer is the assistant: it writes the code each instruction asks for, and starts its reply with <SOLUTION> once they agree it is done.
- Review chat Agent
- Static testing: a reviewer reads the code and raises issues, and the programmer fixes them, until no issues remain.
- Test chat Agent
- Dynamic testing: the tester runs the code and reports real errors, and the programmer fixes them, until it runs cleanly.
- Software Input / output
- The working code, returned with the conclusion of every phase in the chain.
- Request → Design chats
- The requirement opens the first phase of the chain.
Build a command-line 2048 game in Python.
- Design chats → CTOdesign
- Only the design phase's agreed conclusion moves on, not its whole dialogue; it opens the coding chat.
<SOLUTION> A terminal app in Python, using curses for arrow keys, with a 4x4 board and a score line.
- CTO → Programmerinstruct
- The CTO gives the programmer one instruction, with the run output of the last version when there is one.
Write the Board class: a 4x4 grid, move(direction) that slides and merges tiles, and a score counter.
- Programmer → CTOreply
- The programmer's code goes back to the CTO, who reads it and decides the next instruction.
class Board: def __init__(self): self.grid = [[0] * 4 for _ in range(4)] ...
- Programmer → Review chatcode
- When the programmer answers with <SOLUTION>, that reply is the coding phase's conclusion and goes to the review chat.
<SOLUTION> game.py: class Board ... def move(self, d): ... main.py: curses.wrapper(run)
- Review chat → Test chatreviewed
- The reviewed code, with the reviewer's issues fixed, goes to system testing.
<SOLUTION> Fixed: merge now skips already-merged tiles; added the missing import of random.
- Test chat → Softwareruns
- When the code runs without errors, the chain ends and the software is returned.
<SOLUTION> main.py runs; 10 scripted moves produce the expected board and score.
← → neighboursesc atlas
SOP-Driven Team
Also known as MetaGPT · Assembly line · Waterfall team · Standard operating procedure
Role agents follow a fixed procedure, each publishing a structured document to a shared pool that the next role picks up.
Message pool: Introduced by Hong et al. (2023) · DeepWisdom, KAUST and others
MetaGPT encoded a software company's standard operating procedure as prompts: each role must output a structured document, published to a shared message pool that other roles subscribe to.
Chat chain (ChatDev): Introduced by Qian et al. (2023) · Tsinghua University and others
ChatDev's chat chain splits development into design, coding and testing, with five subtasks, each solved by a two-agent instructor and assistant dialogue.
Measured over one run
Message pool
- Nodes
- 7. Boxes in the diagram: models, tools, stores, people and plain code.
- LLM calls
- 4. Model invocations in the first scenario: each time a model or agent node starts thinking, plus each branch it decides.
- Tool calls
- 0. Messages sent to a tool node in the first scenario.
- Steps
- 4. Steps in the first scenario, with repeated steps counted every time they run.
- Scenarios
- 2. Distinct example runs you can switch between on the diagram.
- Loop
- yes. Whether the flow cycles back on itself until a condition is met.
- Parallel
- no. Whether two or more messages are in flight at the same time.
- Branch
- yes. Whether the flow takes one path out of several, chosen at run time.
- Human in the loop
- no. Whether a person appears as a node, to approve, correct or answer.
- Autonomy
- medium. How much the model decides the control flow itself, from fixed code paths (low) to open-ended (high).
- Cost
- high. Relative token spend per request.
- Latency
- high. Relative wall-clock time per request.
Chat chain (ChatDev)
- Nodes
- 7. Boxes in the diagram: models, tools, stores, people and plain code.
- LLM calls
- 10. Model invocations in the first scenario: each time a model or agent node starts thinking, plus each branch it decides.
- Tool calls
- 0. Messages sent to a tool node in the first scenario.
- Steps
- 6. Steps in the first scenario, with repeated steps counted every time they run.
- Scenarios
- 1. Distinct example runs you can switch between on the diagram.
- Loop
- yes. Whether the flow cycles back on itself until a condition is met.
- Parallel
- no. Whether two or more messages are in flight at the same time.
- Branch
- yes. Whether the flow takes one path out of several, chosen at run time.
- Human in the loop
- no. Whether a person appears as a node, to approve, correct or answer.
- Autonomy
- medium. How much the model decides the control flow itself, from fixed code paths (low) to open-ended (high).
- Cost
- high. Relative token spend per request.
- Latency
- high. Relative wall-clock time per request.
Counted from the first scenario's timeline when the site is built.
Problem
Ask a team of chatty agents to “build a command-line 2048 game” and they talk past each other: the engineer starts coding before anyone has decided what the game must do, the reviewer comments on a design that was never written down, and every agent rereads a long, unstructured chat to find the one detail it needs. Human teams solved this long ago with standard operating procedures: a PRD before a design, a design before code, and tests before shipping.
How it works
An SOP-driven team encodes that procedure. Each role agent has one job and one output, a structured document with a fixed template. The product manager turns the requirement into a PRD with user stories and a prioritized requirement list. The architect turns the PRD into a system design: a file list, data structures and interfaces. The engineer turns the design into code. The QA engineer writes and runs tests against it.
The roles do not talk to each other. Each one publishes its document to a shared message pool, and each one subscribes to the document types it needs: the architect to PRDs, the engineer to designs and QA reports, QA to code. A role’s context is therefore a few clean documents, not a transcript.
The only loop is at the end. When a test fails, QA’s report goes back to the engineer, who fixes the code and publishes it again. When everything passes, the software ships with every document the team produced, which doubles as its documentation.
MetaGPT, which introduced the pattern, also has a project manager that splits the design into tasks; it is left out of the diagram for space. ChatDev, in the second tab, keeps the fixed order but runs each phase as a two-agent chat instead of a single document hand-off.
When to use
- The domain has a well-known human process with standard artifacts: software, reports, research reviews.
- Each step’s output can be written as a template, so it can be checked before the next role starts.
- You want the intermediate documents themselves, for review, audit or reuse.
When to avoid
- The process is unknown or exploratory. A fixed order cannot adapt; use a supervisor or a group chat.
- The roles barely differ. Four agents doing slight variations of the same job just multiply the cost.
- The task is small. A single agent writes a 50-line script faster than a team writes a PRD for it.
Trade-offs
The procedure makes runs predictable and the documents make them inspectable: you can see exactly where a misunderstanding entered. Structured hand-offs also cut down on drift, because each role answers a narrow template. The price is rigidity and overhead. Every role is a full model call, usually a long one, and a mistake in an early document, such as a wrong requirement in the PRD, flows all the way down the line unless someone checks it.
Failure modes
- Garbage in, cascaded: an early document is wrong, and every later role builds faithfully on it. Validate each document against its template, and add a human checkpoint after the PRD for high-stakes work.
- Template theatre: roles fill every section with plausible filler. Require concrete, checkable content, such as named files and testable acceptance criteria.
- QA ping-pong: the engineer and QA bounce the same failure back and forth. Cap the QA rounds and return the failing report with the code.
- Subscription gaps: a role misses a document it needed, such as QA without the PRD. Declare each role’s subscriptions explicitly and test them.
Build it with your AI
Message pool
Paste this into Claude Code, Cursor, ChatGPT or any AI coding assistant.
Implement the SOP-Driven Team pattern in this codebase, using the LLM client and language we already use.
## Goal
Run a fixed procedure of role agents, where each role turns the documents it subscribes to into one structured document of its own, ending with a quality check that can send work back.
## How it works
1. Write the procedure down as an ordered list of roles. For each role, record the document types it reads and the one document type it writes, with a template for that document.
2. Keep a message pool: an append-only store of documents, each tagged with its type and author. Post the user's requirement to it.
3. For each role in order, collect the documents it subscribes to from the pool and call it with the Role agent prompt, filling in its profile and its output template.
4. Validate each output against its template (required sections present, code parses) and publish it to the pool; on a validation failure, retry that role once with the errors.
5. Run the QA role with the QA engineer prompt and publish its report to the pool. If the report lists failures, run the engineer again with it, then QA again.
6. When QA passes, return the final code with every document in the pool.
## Prompts
### Role agent prompt
```markdown
You are the {{role}} on a software team. Your goal: {{role_goal}}
You follow the team's standard procedure; do only your own step.
<inputs>
{{subscribed_documents}}
</inputs>
Produce your {{document_type}}, using exactly this template:
<template>
{{output_template}}
</template>
Fill every section. Where an input is unclear, state your assumption in
the document's "Assumptions" section instead of asking questions.
```
### QA engineer prompt
```markdown
You are the QA engineer. Check the code against the requirements and design.
<requirements>{{prd}}</requirements>
<design>{{design}}</design>
<code>{{code}}</code>
<test_results>{{test_output}}</test_results>
Respond in JSON:
{"passed": true|false,
"failures": [{"test": "...", "expected": "...", "actual": "...", "file": "..."}]}
Fail the code if any requirement is unmet or any test fails.
```
## Stop rule
Stop when QA passes, or after 3 QA rounds. On the cap, return the latest code, the failing test report and every document, with a status of qa_failed.
## Requirements
- Keep the role order in configuration, not in prompts, so a role can be added or reordered without rewriting the others.
- Each role sees only the document types it subscribes to, never the whole pool, so its context stays small.
- Cap the QA rounds with a parameter (default 3).
- Log every published document with its type, author and token cost.
- Add a test with a stub LLM whose QA role fails once and then passes; assert the roles ran in the order PM, architect, engineer, QA, engineer, QA, and the pool holds 7 documents including the requirement.
Chat chain (ChatDev)
Paste this into Claude Code, Cursor, ChatGPT or any AI coding assistant.
Implement the SOP-Driven Team pattern (Chat chain (ChatDev) variant) in this codebase, using the LLM client and language we already use.
## Goal
Run a fixed chain of phases in which each phase is a short dialogue between two role agents, an instructor and an assistant, whose agreed conclusion becomes the next phase's input.
## How it works
1. Write the chain down as an ordered list of phases, e.g. design, coding, review, test. For each phase, record the instructor role, the assistant role, the phase goal and the shape of its conclusion (a design note, code, a review).
2. For each phase, start a fresh two-agent dialogue: give the instructor the Phase instructor prompt and the assistant the Phase assistant prompt, each filled in with the phase goal and the previous phase's conclusion.
3. Alternate turns, where a turn is one instructor message plus one assistant reply: the instructor gives one instruction or review comment, and the assistant answers. When the assistant's reply begins with <SOLUTION>, take it as the phase's conclusion.
4. For coding phases, run the code after each assistant reply and give the instructor the compiler or test output with the next turn.
5. Pass only the conclusion, never the whole dialogue, to the next phase. After the last phase, return the final code with every phase's conclusion.
## Prompts
### Phase instructor prompt
```markdown
You are the {{instructor_role}} at a software company, working with the
{{assistant_role}} on this phase: {{phase_goal}}
<input_from_previous_phase>{{previous_conclusion}}</input_from_previous_phase>
{{#if run_output}}<latest_run_output>{{run_output}}</latest_run_output>{{/if}}
Give the {{assistant_role}} one specific instruction or review comment that
moves this phase forward. Do not do the work yourself.
```
### Phase assistant prompt
```markdown
You are the {{assistant_role}} at a software company, working with the
{{instructor_role}} on this phase: {{phase_goal}}
<input_from_previous_phase>{{previous_conclusion}}</input_from_previous_phase>
Carry out the instruction you were given. If you need a detail you do not
have, ask for it in one question before answering.
When you and the {{instructor_role}} have agreed on the result, begin your
reply with <SOLUTION> and give the complete {{conclusion_type}}.
```
## Stop rule
End a phase when the assistant replies with <SOLUTION>, after 10 turns, or when the code is unchanged for two turns in a row. End the chain after its last phase; if a phase hits its cap without a solution, carry its latest reply forward and mark that phase unresolved.
## Requirements
- Keep each phase's dialogue separate, so later phases see only the earlier conclusions and not the full chat.
- Cap every phase at a configurable number of turns (default 10).
- Run the code for real in the testing phase and feed the actual errors to the tester; do not let it guess at results.
- Log every phase with its two roles, its turn count and its conclusion.
- Add a test with a stub LLM in which every assistant returns different code on each turn and replies with <SOLUTION> on its second turn; assert that 4 phases ran, each took exactly 2 turns, and each phase received the previous phase's conclusion as its input.
Prompt templates
Message pool
You are the {{role}} on a software team. Your goal: {{role_goal}}You follow the team's standard procedure; do only your own step.
<inputs>{{subscribed_documents}}</inputs>
Produce your {{document_type}}, using exactly this template:<template>{{output_template}}</template>
Fill every section. Where an input is unclear, state your assumption inthe document's "Assumptions" section instead of asking questions.You are the QA engineer. Check the code against the requirements and design.
<requirements>{{prd}}</requirements><design>{{design}}</design><code>{{code}}</code><test_results>{{test_output}}</test_results>
Respond in JSON:{"passed": true|false, "failures": [{"test": "...", "expected": "...", "actual": "...", "file": "..."}]}Fail the code if any requirement is unmet or any test fails.Chat chain (ChatDev)
You are the {{instructor_role}} at a software company, working with the{{assistant_role}} on this phase: {{phase_goal}}
<input_from_previous_phase>{{previous_conclusion}}</input_from_previous_phase>{{#if run_output}}<latest_run_output>{{run_output}}</latest_run_output>{{/if}}
Give the {{assistant_role}} one specific instruction or review comment thatmoves this phase forward. Do not do the work yourself.You are the {{assistant_role}} at a software company, working with the{{instructor_role}} on this phase: {{phase_goal}}
<input_from_previous_phase>{{previous_conclusion}}</input_from_previous_phase>
Carry out the instruction you were given. If you need a detail you do nothave, ask for it in one question before answering.When you and the {{instructor_role}} have agreed on the result, begin yourreply with <SOLUTION> and give the complete {{conclusion_type}}.Related patterns
Composes well with:
Sources
From the Agentic Atlas by Joran Kikke · Edit on GitHub · Suggest a correction