Skip to content

Latest commit

 

History

History
767 lines (589 loc) · 24.7 KB

File metadata and controls

767 lines (589 loc) · 24.7 KB

MMA Workflow 实现计划

1. 目标

实现一个非常简洁、模块化、可长期维护的 Minimal Multi-Agent Workflow 系统。它的职责不是替代 Codex/Cursor/Claude 等 agent,而是做一个轻量级编排器:

  • 读取一个需求 markdown 文件,例如 requirements.mdr3.md
  • 读取一个 JSON config,知道有哪些 agent、如何调用它们。
  • 按固定阶段把 prompt 发给 Executor 和 Reviewer。
  • 把所有中间产物写到 flow/
  • 把每次 agent 输入、输出、状态写到 log/<timestamp>-<id>/
  • 在关键节点让人类审核并决定继续、补充 review、或退出。
  • 提供一个简单 UI/monitor,方便看到当前阶段、agent 状态和最近输出。

第一版优先保证核心流程正确、代码少、容易读、容易扩展。复杂能力如精准 token 统计、持久化交互式 agent 会话、复杂 TUI 可以后续加。

2. 核心原则

  1. 简洁性

    • 只实现必备 workflow。
    • 尽量少引入依赖。
    • prompt 文本放在独立文件里,方便以后修改,不把大段 prompt 写死在代码里。
  2. 正确性

    • 每个阶段的输入输出文件名稳定。
    • 对 reviewer accept/test pass marker 做明确判断。
    • 每次 agent 调用都记录 prompt、stdout、stderr、exit code。
    • 测试可以直接调用 Codex agent;同时保留 fake agent 作为可选的低成本 CI/单元测试辅助。
  3. 模块化可扩展

    • agent 调用封装成 Agent 接口。
    • workflow 状态机和 agent subprocess 调用分开。
    • prompt rendering、config loading、logging 独立模块。
    • 之后可以把 subprocess agent 替换成 tmux persistent session 或 API agent。
  4. token 节约

    • 默认真实运行可以直接用 Codex agent。
    • 自动化测试中,核心单元测试不调用真实模型;端到端 smoke test 可以通过 config 显式选择 Codex。
    • 每轮 prompt 只附带必要文件路径和必要上下文,不无脑塞入全部日志。

3. 第一版范围

3.1 包含

  • 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 维护。

3.2 暂不包含

  • 完整 token 统计。除非底层 CLI 输出可解析的 token 信息,否则先只记录运行时间和输出长度。
  • 跨 CLI 的真实持久上下文窗口。第一版每次 agent 调用是独立 subprocess,通过显式引用 plan.mdflow/*.md 保持上下文连续。
  • 复杂 terminal UI,例如 curses/textual 全屏应用。
  • 多个 agent 同时并行运行。第一版先顺序运行,保证可控和日志简单。之后 reviewer 之间可以并行。

4. 推荐目录结构

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 文件。

4.1 全局命令和工作目录

第一版建议把项目做成最小 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

工作目录规则:

  1. 如果用户传入 --workdir <path>,使用该目录。
  2. 如果 config 里有 workdir,使用 config 中的目录。
  3. 否则默认使用 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

5. Config 设计

5.1 最简 Codex config

{
  "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

5.2 Codex + Cursor config

如果想让 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": []
      }
    ]
  }
}

5.3 可选 fake agent config

{
  "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 或快速状态机验证。

6. Prompt 模板设计

prompt 使用普通 .txt 文件,通过 Python str.format 注入变量。第一版不引入模板引擎,避免额外依赖。

6.1 通用变量

  • {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} 下。

6.2 Executor planning prompt

职责:让 executor 根据需求产出 plan.md

输出要求:

  • 必须写入 plan.md
  • 代码和注释用英文。
  • 解释、计划和评审内容可以用中文。
  • 计划应关注简洁性、正确性、模块化可扩展性。

6.3 Reviewer planning prompt

职责:review plan.md

输出要求:

  • 默认 reviewer1 写入 flow/plan_review1.md
  • 如果接受,可以输出 [REVIEWER1] ACCEPT!
  • 如果不接受,要列核心问题,不纠结无关细节。

6.4 Rebuttal prompt

职责:executor 阅读 reviewer 的问题。

输出要求:

  • 如果问题合理,修改 plan.md
  • 无论是否修改,都写入 flow/plan_rebuttal1.md
  • 明确说明接受了哪些意见、拒绝了哪些意见、原因是什么。

6.5 Implementation prompt

职责:executor 按最终 plan.md 实现。

输出要求:

  • 完成代码、配置、README、测试。
  • 运行必要测试。
  • 保持代码和注释英文。

6.6 Testing prompt

职责:reviewer 检查实现。

输出要求:

  • 如果通过,输出 [REVIEWER1] TEST PASS!
  • 如果不通过,写入 flow/implementation_test1.md
  • 需要关注需求覆盖、功能测试、模块化、是否过度复杂。

7. Flow 文件命名规则

默认一个 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

8. Workflow 状态机

8.1 Planning 阶段

  1. 创建 flow/ 和本次 log/<timestamp>-<id>/
  2. 调用 executor,生成 plan.md
  3. 对每个 reviewer:
    • 调用 reviewer review plan.md
    • 检查是否有 accept marker。
    • 如果没有 accept,调用 executor rebuttal。
    • 再调用 reviewer comment。
    • 最多循环 max_rounds
  4. 进入 human planning approval。
  5. 人类输入:
    • goGOimplement:进入 implementation。
    • exitquit:停止 workflow。
    • 其他文本:写入 flow/plan_reviewN_human.md,作为 human reviewer 意见交给 executor rebuttal。

8.2 Implementation/Testing 阶段

  1. 调用 executor,根据最终 plan.md 实现。
  2. 对每个 reviewer:
    • 调用 reviewer testing。
    • 如果输出 [REVIEWER1] TEST PASS!,该 reviewer 通过。
    • 否则写入/读取 flow/implementation_testN.md
    • 调用 executor rebuttal 或修改实现。
    • 最多循环 max_rounds
  3. 进入 human final approval。
  4. 人类输入:
    • finishdoneexitquit:结束 workflow。
    • 其他文本:写入 human implementation review,并触发 executor 再处理。

9. Agent 调用设计

第一版的 Agent 是 subprocess wrapper:

Agent.run(prompt: str, task_name: str) -> AgentResult

AgentResult 包含:

  • agent_name
  • task_name
  • started_at
  • ended_at
  • exit_code
  • stdout
  • stderr
  • prompt_path
  • stdout_path
  • stderr_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_tailoutput_tail 必须是 agent 原始 stdout/stderr 的最近几行,不做总结、不改写内容,只做必要的宽度截断。默认保留最后 3 行,可通过 config 的 monitor.tail_lines 调整为 1、3、5 等。

10. 日志设计

每次运行创建:

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

11. UI 示意图

第一版 UI 分成两个部分:主 CLI 负责人类输入,tmux monitor 负责观察状态。

11.1 主 CLI

$ 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.

11.2 tmux monitor

┌──────────────────────────────── 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 进程。

11.3 额度/metric 窗口

如果底层 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                   │
└─────────────────────────────────────────────────────────────────────────────┘

12. 测试计划

12.1 单元测试

  • 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。

12.2 Codex smoke test

第一版可以直接用 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.mdflow/log/ 都写在目标工作目录。
  • monitor 能持续显示 executor/reviewer 最近 3 行原始 stdout/stderr。

12.3 可选 fake agent 测试

保留 examples/fake_agent.py 作为可选测试工具:

  • CI 中不消耗模型调用。
  • 快速验证状态机、文件命名、日志结构。
  • 当真实 Codex CLI 不可用时仍可运行基础测试。

fake agent 不作为默认验收路径。

12.4 手动测试

使用需求里给的文件:

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.json

13. GitHub Repo 维护建议

13.1 README 内容

README 应包含:

  • MMA Workflow 是什么。
  • 安装方式。
  • config 示例。
  • 全局命令 mma 的安装和使用方式。
  • requirement 在任意路径时的 workdir 推断规则。
  • Codex agent 运行方式。
  • 可选 fake agent 测试方式。
  • flow/log/ 的含义。
  • 当前限制和 roadmap。

13.2 .gitignore

建议忽略:

__pycache__/
.pytest_cache/
.venv/
dist/
*.egg-info/

flow/*.md
log/*
!flow/.gitkeep
!log/.gitkeep

13.3 pyproject.toml

使用 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"

13.4 分支和提交粒度

建议按以下粒度提交:

  1. initial repo structure and prompts
  2. add config and prompt rendering
  3. add agent runner and logging
  4. add workflow state machine
  5. add codex config and smoke test docs
  6. add monitor and docs
  7. add optional fake agent tests

14. 实现步骤

  1. 初始化 Python package、README、pyproject、.gitignore
  2. 创建 prompt 模板文件。
  3. 实现 config loader 和 dataclass。
  4. 实现 marker 检测。
  5. 实现 prompt renderer。
  6. 实现 agent subprocess runner。
  7. 实现 logging/status 写入。
  8. 实现 planning workflow。
  9. 实现 human approval。
  10. 实现 implementation/testing workflow。
  11. 添加 pytest 单元测试。
  12. 添加 Codex config,并用 Codex 跑通 smoke test。
  13. 可选实现 fake agent,用于 CI 或低成本状态机测试。
  14. 添加 tmux monitor 的最小版本。
  15. 用 Codex config 跑通 /Users/ypwang61/Research/interviews/r3/r3.md
  16. 写 README 中的全局命令、工作目录和 agent config 使用说明。

15. 主要技术取舍

15.1 不先做 persistent agent session

需求中提到 executor/reviewer 在不同阶段最好是同一个 agent,所以有之前上下文。这个目标是合理的,但第一版如果直接做多个真实 CLI 的持久交互窗口,会带来较多复杂性:

  • 不同 CLI 的输入结束符、输出流、错误处理不一致。
  • 很难可靠判断一个 agent 是否真正完成。
  • 日志切分和异常恢复更麻烦。

因此第一版选择 subprocess 单次调用。上下文通过文件显式传递:

  • plan.md
  • flow/plan_review*.md
  • flow/plan_rebuttal*.md
  • flow/implementation_test*.md
  • prompt 中明确说明要读取哪些文件

这样更容易测试、debug、复现。未来可以在 Agent 接口后面增加 TmuxAgent,而不改 workflow 主逻辑。

15.2 不先做复杂 UI

第一版 UI 只需要回答三个问题:

  • 现在运行到哪一步?
  • 哪个 agent 在工作?
  • 最近几行原始 stdout/stderr 是什么?

tmux monitor 足够满足这个目标。之后如果需要更好的人机交互,可以加 Textual/Rich TUI。

15.3 不先做真实 token 统计

不同 CLI 的 token/quota 输出不统一。第一版先记录:

  • 调用次数
  • 运行时间
  • stdout/stderr 字符数
  • exit code

如果之后 Codex/Cursor/Claude CLI 输出稳定 token 信息,再加 parser。

16. 验收标准

第一版完成时应满足:

  • mma run --requirement /Users/ypwang61/Research/interviews/r3/r3.md --config examples/config.codex.json 可以用真实 Codex agent 跑通 smoke test。
  • requirement 文件在 MMA repo 外时,默认在 requirement 所在目录生成 plan.mdflow/*.mdlog/<run-id>/*
  • pip install -e . 后,全局命令 mma 可用。
  • monitor 能展示每个 active/recent agent 最近 1-3 行原始 stdout/stderr,并按配置刷新。
  • pytest 全部通过。
  • 人类可以在 planning 后输入 go 继续。
  • 人类可以输入普通文本作为 review,让 executor 再处理。
  • 人类可以输入 exit 安全退出。
  • README 足够让之后 push 到 GitHub 后别人能安装和运行。

17. 后续 Roadmap

  1. reviewer 并行执行。
  2. TmuxAgent:每个 agent 一个持久 tmux pane,保留真实上下文。
  3. 更丰富的 monitor,包括 token/quota parser。
  4. 可配置 workflow graph,不局限于 planning/implementation/testing。
  5. Web UI 或 Textual UI。
  6. 支持 OpenAI/Anthropic/Gemini API agent。