实现一个非常简洁、模块化、可长期维护的 Minimal Multi-Agent Workflow 系统。它的职责不是替代 Codex/Cursor/Claude 等 agent,而是做一个轻量级编排器:
- 读取一个需求 markdown 文件,例如
requirements.md或r3.md。 - 读取一个 JSON config,知道有哪些 agent、如何调用它们。
- 按固定阶段把 prompt 发给 Executor 和 Reviewer。
- 把所有中间产物写到
flow/。 - 把每次 agent 输入、输出、状态写到
log/<timestamp>-<id>/。 - 在关键节点让人类审核并决定继续、补充 review、或退出。
- 提供一个简单 UI/monitor,方便看到当前阶段、agent 状态和最近输出。
第一版优先保证核心流程正确、代码少、容易读、容易扩展。复杂能力如精准 token 统计、持久化交互式 agent 会话、复杂 TUI 可以后续加。
-
简洁性
- 只实现必备 workflow。
- 尽量少引入依赖。
- prompt 文本放在独立文件里,方便以后修改,不把大段 prompt 写死在代码里。
-
正确性
- 每个阶段的输入输出文件名稳定。
- 对 reviewer accept/test pass marker 做明确判断。
- 每次 agent 调用都记录 prompt、stdout、stderr、exit code。
- 测试可以直接调用 Codex agent;同时保留 fake agent 作为可选的低成本 CI/单元测试辅助。
-
模块化可扩展
- agent 调用封装成
Agent接口。 - workflow 状态机和 agent subprocess 调用分开。
- prompt rendering、config loading、logging 独立模块。
- 之后可以把 subprocess agent 替换成 tmux persistent session 或 API agent。
- agent 调用封装成
-
token 节约
- 默认真实运行可以直接用 Codex agent。
- 自动化测试中,核心单元测试不调用真实模型;端到端 smoke test 可以通过 config 显式选择 Codex。
- 每轮 prompt 只附带必要文件路径和必要上下文,不无脑塞入全部日志。
- Python CLI:
mma run --requirement <path> --config <path> - 安装后提供全局命令
mma,可在任意目录运行。 - 支持 requirement markdown 位于 MMA repo 之外。
- 支持显式
--workdir,也支持默认从 requirement 文件所在目录推断工作目录。 - JSON config 指定 executor 和 reviewers。
- 默认一个 executor、一个 reviewer,也支持多个 reviewer。
- 阶段:
- Executor planning
- Reviewer planning review
- Executor planning rebuttal
- Reviewer planning comment
- Human planning approval
- Executor implementing
- Reviewer testing
- Executor implementation rebuttal
- Human final approval
- 最大 review/rebuttal 轮数,默认 3。
flow/中保存 plan review、rebuttal、implementation test 等文件。log/<timestamp>-<id>/中保存每次 agent 调用详情。- 简单 tmux monitor,如果 tmux 不可用则在主 CLI 打印状态。
- Codex smoke test、可选 fake agent、pytest 单元测试。
- README,方便之后作为 GitHub repo 维护。
- 完整 token 统计。除非底层 CLI 输出可解析的 token 信息,否则先只记录运行时间和输出长度。
- 跨 CLI 的真实持久上下文窗口。第一版每次 agent 调用是独立 subprocess,通过显式引用
plan.md、flow/*.md保持上下文连续。 - 复杂 terminal UI,例如 curses/textual 全屏应用。
- 多个 agent 同时并行运行。第一版先顺序运行,保证可控和日志简单。之后 reviewer 之间可以并行。
MMA_workflow/
README.md
pyproject.toml
requirements.md
plan.md
mma_workflow/
__init__.py
cli.py
config.py
prompts.py
agents.py
runner.py
state.py
logging_utils.py
monitor.py
markers.py
prompts/
executor_planning.txt
reviewer_planning.txt
executor_planning_rebuttal.txt
reviewer_planning_comment.txt
executor_implementing.txt
reviewer_testing.txt
executor_implementation_rebuttal.txt
human_planning_review.txt
human_final_review.txt
examples/
config.codex.json
config.codex_cursor.json
config.fake.json
fake_agent.py
tests/
test_config.py
test_prompts.py
test_markers.py
test_state.py
test_workflow.py
flow/
.gitkeep
log/
.gitkeep
flow/ 和 log/ 是运行产物目录。GitHub repo 中建议保留 .gitkeep,但 .gitignore 忽略实际运行生成的 markdown/log 文件。
第一版建议把项目做成最小 Python package,通过 pyproject.toml 暴露 console script:
[project.scripts]
mma = "mma_workflow.cli:main"本地开发安装:
pip install -e /Users/ypwang61/Research/tools/MMA_workflow安装后可以在任意目录运行:
mma run --requirement /Users/ypwang61/Research/interviews/r3/r3.md工作目录规则:
- 如果用户传入
--workdir <path>,使用该目录。 - 如果 config 里有
workdir,使用 config 中的目录。 - 否则默认使用 requirement 文件所在目录。
这样最方便,也比较安全:workflow 只在明确的工作目录里创建 flow/、log/、plan.md,不会因为当前 shell 在别的路径而写错地方。CLI 启动时会打印解析后的路径,让用户确认:
Requirement: /Users/ypwang61/Research/interviews/r3/r3.md
Workdir: /Users/ypwang61/Research/interviews/r3
Flow dir: /Users/ypwang61/Research/interviews/r3/flow
Log dir: /Users/ypwang61/Research/interviews/r3/log/20260501-153012-a1b2c3
{
"max_rounds": 3,
"monitor": {
"enabled": true,
"tail_lines": 3,
"refresh_seconds": 3
},
"agents": {
"executor": {
"name": "executor",
"command": "codex",
"args": ["--model", "gpt-5.5", "--reasoning", "xhigh"]
},
"reviewers": [
{
"name": "reviewer1",
"command": "codex",
"args": ["--model", "gpt-5.5", "--reasoning", "xhigh"]
}
]
}
}这个配置不写 workdir,因此默认使用 requirement markdown 所在目录。这样最适合全局命令:
mma run --requirement /abs/path/to/requirement.md --config examples/config.codex.json如果想让 reviewer 用 Cursor CLI,可以单独改 reviewer:
{
"max_rounds": 3,
"monitor": {
"enabled": true,
"tail_lines": 3,
"refresh_seconds": 3
},
"agents": {
"executor": {
"name": "executor",
"command": "codex",
"args": ["--model", "gpt-5.5", "--reasoning", "xhigh"]
},
"reviewers": [
{
"name": "reviewer1",
"command": "cursor-agent",
"args": []
}
]
}
}{
"max_rounds": 2,
"monitor": {
"enabled": false,
"tail_lines": 3,
"refresh_seconds": 3
},
"agents": {
"executor": {
"name": "executor",
"command": "python",
"args": ["examples/fake_agent.py", "--role", "executor"]
},
"reviewers": [
{
"name": "reviewer1",
"command": "python",
"args": ["examples/fake_agent.py", "--role", "reviewer1"]
}
]
}
}fake agent 不作为默认手动测试路径,只用于不想消耗模型调用时做 CI 或快速状态机验证。
prompt 使用普通 .txt 文件,通过 Python str.format 注入变量。第一版不引入模板引擎,避免额外依赖。
{requirement_path}:需求文件路径。{workdir}:工作目录。{flow_dir}:flow 目录。{log_dir}:当前运行 log 目录。{plan_path}:plan.md路径。{round}:当前轮数。{reviewer_name}:reviewer 名称。{review_file}:本轮 review 文件路径。{rebuttal_file}:本轮 rebuttal 文件路径。{existing_context}:简短列出已有相关文件,不直接塞入全部内容。
prompt 中必须明确告诉 agent:
- 当前工作目录是
{workdir}。 - 所有相对路径都以
{workdir}为基准。 - 需求文件可能不在 MMA repo 内,因此必须读取
{requirement_path}。 - 输出文件必须写到指定的
{plan_path}或{flow_dir}下。
职责:让 executor 根据需求产出 plan.md。
输出要求:
- 必须写入
plan.md。 - 代码和注释用英文。
- 解释、计划和评审内容可以用中文。
- 计划应关注简洁性、正确性、模块化可扩展性。
职责:review plan.md。
输出要求:
- 默认 reviewer1 写入
flow/plan_review1.md。 - 如果接受,可以输出
[REVIEWER1] ACCEPT!。 - 如果不接受,要列核心问题,不纠结无关细节。
职责:executor 阅读 reviewer 的问题。
输出要求:
- 如果问题合理,修改
plan.md。 - 无论是否修改,都写入
flow/plan_rebuttal1.md。 - 明确说明接受了哪些意见、拒绝了哪些意见、原因是什么。
职责:executor 按最终 plan.md 实现。
输出要求:
- 完成代码、配置、README、测试。
- 运行必要测试。
- 保持代码和注释英文。
职责:reviewer 检查实现。
输出要求:
- 如果通过,输出
[REVIEWER1] TEST PASS!。 - 如果不通过,写入
flow/implementation_test1.md。 - 需要关注需求覆盖、功能测试、模块化、是否过度复杂。
默认一个 reviewer 时,严格使用需求里的名字:
plan.md
flow/plan_review1.md
flow/plan_rebuttal1.md
flow/plan_review2.md
flow/plan_review1_human.md
flow/implementation_test1.md
flow/implementation_rebuttal1.md
多 reviewer 时,为避免冲突,给非 reviewer1 添加后缀:
flow/plan_review1_reviewer2.md
flow/plan_rebuttal1_reviewer2.md
flow/implementation_test1_reviewer2.md
flow/implementation_rebuttal1_reviewer2.md
- 创建
flow/和本次log/<timestamp>-<id>/。 - 调用 executor,生成
plan.md。 - 对每个 reviewer:
- 调用 reviewer review
plan.md。 - 检查是否有 accept marker。
- 如果没有 accept,调用 executor rebuttal。
- 再调用 reviewer comment。
- 最多循环
max_rounds。
- 调用 reviewer review
- 进入 human planning approval。
- 人类输入:
go、GO、implement:进入 implementation。exit、quit:停止 workflow。- 其他文本:写入
flow/plan_reviewN_human.md,作为 human reviewer 意见交给 executor rebuttal。
- 调用 executor,根据最终
plan.md实现。 - 对每个 reviewer:
- 调用 reviewer testing。
- 如果输出
[REVIEWER1] TEST PASS!,该 reviewer 通过。 - 否则写入/读取
flow/implementation_testN.md。 - 调用 executor rebuttal 或修改实现。
- 最多循环
max_rounds。
- 进入 human final approval。
- 人类输入:
finish、done、exit、quit:结束 workflow。- 其他文本:写入 human implementation review,并触发 executor 再处理。
第一版的 Agent 是 subprocess wrapper:
Agent.run(prompt: str, task_name: str) -> AgentResult
AgentResult 包含:
agent_nametask_namestarted_atended_atexit_codestdoutstderrprompt_pathstdout_pathstderr_path
prompt 通过 stdin 传给 agent command。这样 Codex CLI、Cursor CLI、Claude CLI 或 fake agent 都可以通过 config 替换。
实际执行时 subprocess 的 cwd 设置为解析后的 workdir。这样 agent 看到的项目目录就是目标 requirement 所在项目,而不是 MMA workflow 自己的代码目录。
为了让 monitor 能看到“agent 正在干什么”,runner 会边读 stdout/stderr 边更新 status.json 中每个 agent 的 output_tail。output_tail 必须是 agent 原始 stdout/stderr 的最近几行,不做总结、不改写内容,只做必要的宽度截断。默认保留最后 3 行,可通过 config 的 monitor.tail_lines 调整为 1、3、5 等。
每次运行创建:
log/20260501-153012-a1b2c3/
run.json
status.json
001_executor_planning.prompt.txt
001_executor_planning.stdout.txt
001_executor_planning.stderr.txt
002_reviewer1_planning.prompt.txt
002_reviewer1_planning.stdout.txt
002_reviewer1_planning.stderr.txt
run.json 记录:
- requirement path
- config path
- start/end time
- max rounds
- agent config summary
- final status
status.json 记录 monitor 需要的信息:
- current phase
- current agent
- status: pending/running/finished/failed
- last activity time
- latest output tail,每个 agent 最近 1-3 行原始 stdout/stderr
第一版 UI 分成两个部分:主 CLI 负责人类输入,tmux monitor 负责观察状态。
$ mma run --requirement /Users/ypwang61/Research/interviews/r3/r3.md --config examples/config.codex_cursor.json
MMA Workflow
Requirement: /Users/ypwang61/Research/interviews/r3/r3.md
Run log: log/20260501-153012-a1b2c3
Flow dir: flow
[planning] executor is creating plan.md ...
executor raw output tail:
现在我先看一下需求和目录结构。
{"cmd":"rg --files","workdir":"/Users/ypwang61/Research/interviews/r3"}
已经写好 plan.md,下一步会让 reviewer 检查。
[planning] reviewer1 is reviewing plan.md ...
reviewer1 raw output tail:
这里有一个核心问题:全局命令和 workdir 规则还不够明确。
另外 monitor 应该展示原始输出 tail,而不是总结。
我会把这些写入 flow/plan_review1.md。
[planning] executor is writing rebuttal for flow/plan_review1.md ...
executor raw output tail:
reviewer 的意见有道理,我会更新 plan.md。
修改点:补充 pip install -e . 和 --workdir 推断规则。
flow/plan_rebuttal1.md 已写入。
[planning] reviewer1 accepted the plan.
reviewer1 raw output tail:
我重新检查了 plan.md。
核心问题已经解决,没有新的 blocking issue。
[REVIEWER1] ACCEPT!
Human planning review
Type:
go / GO / implement continue to implementation
exit / quit stop workflow
anything else save as human review and send back to executor
> go
[implementing] executor is implementing plan.md ...
executor raw output tail:
create mma_workflow/runner.py
pytest -q
12 passed in 0.38s
[testing] reviewer1 is testing implementation ...
reviewer1 raw output tail:
我跑了 pytest,也检查了 r3.md 的 smoke workflow。
没发现 blocking issue。
[REVIEWER1] TEST PASS!
[testing] reviewer1 passed.
Human final review
Type finish/done/exit to end, or enter feedback for another executor pass.
> finish
Workflow finished.
┌──────────────────────────────── MMA Monitor ────────────────────────────────┐
│ Run: 20260501-153012-a1b2c3 Requirement: r3.md │
│ Phase: planning.rebuttal Round: 1/3 │
├────────────┬──────────┬───────────────┬──────────────┬─────────────────────┤
│ Agent │ Status │ Task │ Last Active │ Exit Code │
├────────────┼──────────┼───────────────┼──────────────┼─────────────────────┤
│ executor │ running │ plan_rebuttal │ 2s ago │ - │
│ reviewer1 │ finished │ plan_review │ 18s ago │ 0 │
├────────────┴──────────┴───────────────┴──────────────┴─────────────────────┤
│ Raw output tail, last 3 stdout/stderr lines per active/recent agent │
│ executor │ reviewer 的意见有道理,我会更新 plan.md。 │
│ executor │ 修改点:补充 pip install -e . 和 --workdir 推断规则。 │
│ executor │ flow/plan_rebuttal1.md 已写入。 │
│ reviewer1 │ [REVIEWER1] ACCEPT! │
└─────────────────────────────────────────────────────────────────────────────┘
这些 raw output tail 示例只表示“从 agent stdout/stderr 末尾原样截取几行”。MMA 不要求 agent 输出固定格式,也不把输出改写成结构化事件。
monitor 实现保持极简:主进程持续写 status.json,tmux pane 每 3 秒运行一次 mma status --log-dir <run-log-dir> 或等价的内部命令来重绘文本。这样不需要复杂 TUI,也不需要 monitor 直接控制 agent 进程。
如果底层 agent CLI 能输出 token 或 quota 信息,monitor 可以显示第二块。这里同样只展示原始可解析信息,不猜测 token/quota。第一版先预留字段:
┌────────────────────────────── Agent Metrics ────────────────────────────────┐
│ Agent │ Calls │ Runtime │ Output Chars │ Tokens/Quota │
├────────────┼───────┼─────────┼──────────────┼───────────────────────────────┤
│ executor │ 3 │ 06:12 │ 18420 │ unavailable │
│ reviewer1 │ 2 │ 03:44 │ 9300 │ unavailable │
└─────────────────────────────────────────────────────────────────────────────┘
-
test_config.py- 缺少 executor 报错。
- 缺少 reviewers 报错。
max_rounds默认值正确。- agent command/args 解析正确。
-
test_prompts.py- prompt 变量能正确替换。
- 缺少变量时测试失败,避免静默生成坏 prompt。
-
test_markers.py[REVIEWER1] ACCEPT!检测正确。[REVIEWER1] TEST PASS!检测正确。- 普通文本不会误判通过。
-
test_state.py- review/rebuttal 最多运行
max_rounds。 - reviewer accept 后进入 human approval。
- reviewer test pass 后进入 final approval。
- review/rebuttal 最多运行
第一版可以直接用 Codex agent 做真实 smoke test。最小路径是 executor 和 reviewer 都用 codex 命令,只通过不同 prompt 扮演不同角色:
mma run \
--requirement /Users/ypwang61/Research/interviews/r3/r3.md \
--config examples/config.codex.json这个测试会真实调用 Codex,并验证:
- requirement 在 MMA repo 外也能正常读取。
workdir默认推断到 requirement 所在目录。plan.md、flow/、log/都写在目标工作目录。- monitor 能持续显示 executor/reviewer 最近 3 行原始 stdout/stderr。
保留 examples/fake_agent.py 作为可选测试工具:
- CI 中不消耗模型调用。
- 快速验证状态机、文件命名、日志结构。
- 当真实 Codex CLI 不可用时仍可运行基础测试。
fake agent 不作为默认验收路径。
使用需求里给的文件:
mma run \
--requirement /Users/ypwang61/Research/interviews/r3/r3.md \
--config examples/config.codex.json如果想手动指定工作目录:
mma run \
--requirement /Users/ypwang61/Research/interviews/r3/r3.md \
--workdir /Users/ypwang61/Research/interviews/r3 \
--config examples/config.codex.jsonREADME 应包含:
- MMA Workflow 是什么。
- 安装方式。
- config 示例。
- 全局命令
mma的安装和使用方式。 - requirement 在任意路径时的
workdir推断规则。 - Codex agent 运行方式。
- 可选 fake agent 测试方式。
flow/和log/的含义。- 当前限制和 roadmap。
建议忽略:
__pycache__/
.pytest_cache/
.venv/
dist/
*.egg-info/
flow/*.md
log/*
!flow/.gitkeep
!log/.gitkeep使用 setuptools 或 hatchling 均可。第一版可以非常简单:
[project]
name = "mma-workflow"
version = "0.1.0"
requires-python = ">=3.10"
dependencies = []
[project.optional-dependencies]
test = ["pytest"]
[project.scripts]
mma = "mma_workflow.cli:main"建议按以下粒度提交:
initial repo structure and promptsadd config and prompt renderingadd agent runner and loggingadd workflow state machineadd codex config and smoke test docsadd monitor and docsadd optional fake agent tests
- 初始化 Python package、README、pyproject、
.gitignore。 - 创建 prompt 模板文件。
- 实现 config loader 和 dataclass。
- 实现 marker 检测。
- 实现 prompt renderer。
- 实现 agent subprocess runner。
- 实现 logging/status 写入。
- 实现 planning workflow。
- 实现 human approval。
- 实现 implementation/testing workflow。
- 添加 pytest 单元测试。
- 添加 Codex config,并用 Codex 跑通 smoke test。
- 可选实现 fake agent,用于 CI 或低成本状态机测试。
- 添加 tmux monitor 的最小版本。
- 用 Codex config 跑通
/Users/ypwang61/Research/interviews/r3/r3.md。 - 写 README 中的全局命令、工作目录和 agent config 使用说明。
需求中提到 executor/reviewer 在不同阶段最好是同一个 agent,所以有之前上下文。这个目标是合理的,但第一版如果直接做多个真实 CLI 的持久交互窗口,会带来较多复杂性:
- 不同 CLI 的输入结束符、输出流、错误处理不一致。
- 很难可靠判断一个 agent 是否真正完成。
- 日志切分和异常恢复更麻烦。
因此第一版选择 subprocess 单次调用。上下文通过文件显式传递:
plan.mdflow/plan_review*.mdflow/plan_rebuttal*.mdflow/implementation_test*.md- prompt 中明确说明要读取哪些文件
这样更容易测试、debug、复现。未来可以在 Agent 接口后面增加 TmuxAgent,而不改 workflow 主逻辑。
第一版 UI 只需要回答三个问题:
- 现在运行到哪一步?
- 哪个 agent 在工作?
- 最近几行原始 stdout/stderr 是什么?
tmux monitor 足够满足这个目标。之后如果需要更好的人机交互,可以加 Textual/Rich TUI。
不同 CLI 的 token/quota 输出不统一。第一版先记录:
- 调用次数
- 运行时间
- stdout/stderr 字符数
- exit code
如果之后 Codex/Cursor/Claude CLI 输出稳定 token 信息,再加 parser。
第一版完成时应满足:
mma run --requirement /Users/ypwang61/Research/interviews/r3/r3.md --config examples/config.codex.json可以用真实 Codex agent 跑通 smoke test。- requirement 文件在 MMA repo 外时,默认在 requirement 所在目录生成
plan.md、flow/*.md、log/<run-id>/*。 pip install -e .后,全局命令mma可用。- monitor 能展示每个 active/recent agent 最近 1-3 行原始 stdout/stderr,并按配置刷新。
- pytest 全部通过。
- 人类可以在 planning 后输入
go继续。 - 人类可以输入普通文本作为 review,让 executor 再处理。
- 人类可以输入
exit安全退出。 - README 足够让之后 push 到 GitHub 后别人能安装和运行。
- reviewer 并行执行。
TmuxAgent:每个 agent 一个持久 tmux pane,保留真实上下文。- 更丰富的 monitor,包括 token/quota parser。
- 可配置 workflow graph,不局限于 planning/implementation/testing。
- Web UI 或 Textual UI。
- 支持 OpenAI/Anthropic/Gemini API agent。