27-e2e-task-execution-flow.md 44 KB

27-E2E · 端到端任务执行流程 — 从建公司到验收收敛

所属: 27 Graph Agent 架构 的跨阶段总览文档,串起 P2(Org Graph)、P3/P4(Work Graph 执行)、P5(自我进化)。 版本: v0.1 日期: 2026-08-15 前置: 27-P2 Org Graph 落地、27-P3/P4 Work Graph 执行控制台、以及本文档最重要的参考源 docs/prd/newfunction/_spec/(DevLoop 的完整 MVCP 规格,尤其 loops-overview.md / loops-l1.md / loops-l2.md / loops-l3.md / sdd-process.md / plan-cost-concurrency.md)。 需求源头: 27-REQ 原始需求 —— 本文档是对那些原话的结构化转述,原文以那份为准。 配套: 27-EXAMPLE 参考场景走查 —— 本文档讲机制,那份文档把机制在一家具体公司上跑一遍数。两份对照着读。


一、这份文档要回答什么

本文档把口述的七阶段端到端流程结构化,然后回答三个问题:

  1. 这个流程和已经写好的 P2 / P3-P4 设计有什么差异?
  2. 哪些地方没有考虑到?
  3. 这个流程是否是这样实现的?

二、三条核心结论(先给答案)

结论 1:这套流程 70-80% 已经在本仓库被详细设计过,但它藏在 DevLoop 的规格里,而不在 27 号文档体系里

docs/prd/newfunction/_spec/ 是一套 50 份文件、按 MVCP(Model / View / Control / Process)四象限组织的完整 SDD。它已经定义了:

  • 三层嵌套循环 L1 ⊂ L2 ⊂ L3(loops-overview.md),带完整状态机、退出条件、回滚目标、分级预算,甚至给每层配了颜色 token(L1 Emerald / L2 Amber / L3 Violet)。
  • 失败归因的四分类调度(loops-l2.md + sdd-process.md P-2):contract_mismatch / impl_bug / spec_ambiguous / infra_flake,每类决定「改不改设计文档、重置哪些节点、烧不烧预算」。
  • 分级预算与熔断(sdd-process.md P-7):retry_budget=5(每 Unit)、l2_budget=3(每 PRD rev)、token_budget=5M(每项目)、单 agent 墙钟 10min。
  • 成本与并发预算的数字版(plan-cost-concurrency.md):每个 agent 每次调用的 token 估算、典型项目总成本(中项目 ≈ 410K token ≈ $4.8)、三层并发上限、墙钟估算、6 个监控指标及告警阈值。
  • 前端组件全集(sdd-view.md V-1..V-11),且代码已经存在:web/src/components/devloop/ 下 8 个组件,含 UnitsDAG.vue(SVG + Kahn 分波布局的 DAG 渲染器)、LiveAgentStream.vue(带 Last-Event-ID 断线重连的 SSE 消费)、UnitDrawer.vue(节点详情抽屉)。

这直接影响你的问题「这个流程是否是这样实现的」——答案是:在"一家写代码的公司"这个具体场景下,是的,而且已经实现了大半。 loop-controller.js 的 runProject() 已完整实现(不是我在 27-P3/P4 文档里写的 501,那条陈述已过期,见 §九),包含 Kahn 拓扑分波、L2 闸门、Integrator、Triager 四分支调度、预算熔断、SSE 埋点。

结论 2:DevLoop 就是你这套架构的一个「硬编码实例」

把两者并排看,对应关系是逐项的:

你描述的通用概念 DevLoop 里的硬编码版本
Org Graph(planner → coder → validator) 固定的 6 个 agent:PM → Architect → Coder/Tester → Integrator → Triager
org node 调 planning subagent 规划自己的 work graph Architect 生成 units.json(一张带 depends_on 的 DAG)——图是被规划出来的,但规划者是写死的 Architect
work graph 节点 = system agent 引用 Unit = 一次 Coder + Tester 调用
work graph 内 loop 回退 L1:runUnit 的 retry-with-reflection,retry_budget=5
fan-out 并行 code subagent → fan-in 整合 → integration test _groupUnitsByWave() Kahn 分波 → L2 闸门 → Integrator 跑真实进程 e2e
出 bug 时判断「重新 planning 还是跳回某节点」 L2:BugTriager 输出 category 四分类,LoopController 据此分支
全局 validator + 人工介入 L3:human feedback loop + sign-off

所以 27 号文档 §五把「DevLoop 收编」列为 P6(可选),这个定位是低估了。 DevLoop 不是一个将来可以顺便合并进来的边缘子系统,它是这套通用架构唯一一个已经跑通的参考实现。正确的做法是反过来:把 DevLoop 的 L1/L2/L3 机制抽象成通用 Work Graph 引擎的默认行为,而不是先造一个通用引擎、将来再想办法把 DevLoop 塞进去。

结论 3:你的流程里有一个环节是真正全新的,而且它恰好是风险最大的一环

第七步「不成功则判断是不是需要迭代某一个 system agent 的 skill / memory / data / LLM,先迭代 system agent,再 loop 某个 work graph」——这一层在 DevLoop 的 L1/L2/L3 里不存在。DevLoop 的 L3 是「找人类补充需求」,不是「让 agent 自己变强」。这一层对应的是 27 号文档的 P5(自我进化),但 P5 原本被设计成一个离线的、benchmark ≥95 才准生效的慢速通道,而你的流程把它拉进了任务执行的在线重试循环里。这个改动带来两个必须处理的风险,见 §八。


三、流程还原(七阶段)

每阶段标注:✅ 已实现 / 📐 已设计未实现 / ⚠️ 部分存在有冲突 / ❌ 空白

阶段 1 · 用户新建 company,写入目标和描述

状态:✅ 已实现(POST /api/company/create,company-service.js:37)

company.json 已有 description 字段。当前创建出来的是「没有员工的空壳公司」,响应文案提示"请通知 MasterBot 雇佣 Agent"。

阶段 2 · orggraph-planning 根据描述生成基础 org graph

状态:📐 已设计未实现(27-P2 §4.8/§4.9/§4.10)

P2 已经设计了:system/org-graph-templates/{dev,content,ops}.json 模板库 + orggraph-planning agent + 创建时自动招聘并 fire-and-forget 触发首轮对话。

「每个 org node 可以引用已有 system agent,也可以新建一个」——这一点 P2 通过 hire() 的 needs_training 分支已覆盖(company.js:917-940 已有自动触发 agent-creator + innovator 的流水线)。

⚠️ 但有一处粒度不一致:你举例说开发型公司需要 planner / code / validator 三个节点;P2 的 dev.json 模板写的是 ceo / cto / hr / devloop-pm / devloop-architect / devloop-coder / devloop-tester 七个。这不是笔误,而是两种不同的建模视角,见 §五。

阶段 3 · 用户输入一个具体的开发 task

状态:⚠️ 部分存在,且没有「给公司下达任务」的入口

现有任务系统在 server/routes/agent-chat.js,不在 task-service.js(后者是只读聚合器,靠时间窗口启发式猜测父子关系):

  • POST /api/agent/task/dispatch(行 1470):入参 {from, to, task, priority, goalId, nodeId, autoExecute, parentTaskId},taskId 格式 T-{base36},持久化为全局平铺 JSON system/tasklog/{taskId}.json,30 分钟去重窗口,autoExecute 时 HTTP 自调用触发目标 agent。
  • POST /api/agent/task/report(行 1656):已有的完成回调机制——更新 todo/plan、更新 goal 节点、自动推进 Pipeline、回调唤醒上级 agent。

❌ 缺口:from/to 都必须是已存在的 agent 目录,只支持 agent → agent 派发,不支持「用户 → 公司」。你的流程第 3 步需要一个新入口:用户把任务给公司,由公司决定哪个 org node 先接手。

⚠️ 另一处:27 号文档 work_graphs.goal_task_id 这个单字段不够用。定位一个 OKR 节点需要 (companyId, okrNodeId)(OKR 树 per-company 存储,节点 ID 是点分层级)。建议拆成 okr_node_id + task_id 两个字段。⚠️ 另见 27-NAMING §六:OKR 体系当前在代码里叫 goal(goals.js / G-001.1.1 / data/companies/{cid}/goals/),应正名为 okr / O-001.1.1。

阶段 4 · 第一个 org node(planner)调 planning-work-graph subagent 规划自己的 work graph

状态:📐 概念已在 27 号文档 §3.4 定义,执行引擎见 27-P3/P4,但 planning agent 本身未设计

你举的例子 brd-planning → prd-planning → sdd-planning → benchmark → testdata → code-planner-validator → loop-validator,与 DevLoop 的实际链路高度重合:

你的节点 DevLoop 对应物 状态
brd / prd PM Agent 产出多页 PRD 站点(sdd-model.md M-3) ✅ 已实现
sdd Architect 产出 SDD(MVCP 四页)+ units.json ✅ 已实现
benchmark / testdata Architect 同步产出 integration/spec.json(M-6) ✅ 已实现
code-planner-validator Architect 的 self-check + L2 gate 判定 ✅ 已实现
loop-validator Loop-Validator(27 号 §3.5)/ BugTriager 📐 27 号未实现;DevLoop 版 ✅ 已实现

💡 值得注意:DevLoop 的 loops-l2.md 已经就「谁来写验收标准」做过一次显式的方案选型(A/B/C 三选一),并选了 A:由 Architect(设计者)在生成 SDD 时同步产出 integration/spec.json,明确否决了 C:由 Integrator(执行者)自己写测试,理由是「容易写一个永远会通过的 trivial test」。你的流程让 planner 阶段产出 benchmark/testdata、让后面的 validator 阶段消费它,正好符合方案 A 的思路——设计者定标准、执行者不定标准。这条已经被论证过的原则应该在通用层继承下来。

阶段 5 · 完成当前 org node,进入下一个 org node

状态:❌ 这是与 P2 设计的核心语义冲突所在,见 §五

阶段 6 · code agent 规划 code work graph:fan-out 并行 → fan-in 整合 → integration test → 出 bug 判断重新 planning 还是跳回节点

状态:⚠️ 结构全部就位,但并行没做,且有一条不变量直接挡路

  • 分波结构:✅ _groupUnitsByWave()(loop-controller.js:523)是标准 Kahn 拓扑分波,units.json 的 depends_on 声明 DAG,doc-store.js 写入前用三色 DFS 校验无环。前端 UnitsDAG.vue 已经能渲染这个分波布局。
  • ❌ 波内实际是串行的:loop-controller.js:609 明确注释 // 串行跑(mock 同步快,不需并行),实现是 for (const uid of wave) { await runUnit(...) }。
  • ⚠️ 改成并行会立刻撞上两处障碍:
    1. _spec/CONVENTIONS.md §12 第一条不变量:「任意 (pid, agent) 同时只允许 1 个 status=running」——如果并行跑 3 个 coder subagent,它们是同一个 system agent 的三次调用,直接违反这条。
    2. SessionPool 的 key 是 acp:{agentName}:{client}:{deploy}:{workDir}[:{scope}](session-pool.js:29),同 agent 同 workDir 会复用同一个 session——并发调用会撞在一起。必须引入 scope 之类的实例隔离。
  • ✅ fan-out/fan-in 的现成实现存在,只是 DevLoop 没用它:orchestrator.js:265 的 executeWithDependencies() 用 Scheduler.getExecutionGroups() 分组 + Promise.allSettled 组内并行、组间串行(天然 fan-in 屏障),单点失败降级成 {status:'ERROR', retryable} 而不终结整组。另有 agent-chat.js:2440 的 sub-agent 批量调度(MAX_CONCURRENCY=2,带 checkpoint.json 断点续跑)。
  • ✅ 「重新 planning 还是跳回原节点」这个判断已经有成熟实现:这正是 BugTriager 的 category 四分类(sdd-process.md P-2):
category 改不改设计文档 重置哪些节点 烧不烧 L2 预算
contract_mismatch ✅ 改 SDD(≈ 重新 planning) ✅ reset 相关 unit ✅ 烧
impl_bug ❌ ✅ 只 reset 那一个(≈ 跳回节点) ❌ 不烧
spec_ambiguous ❌(升 L3 找人) ❌ ❌
infra_flake ❌ ❌(直接重跑) ❌

这套「不同失败类型消耗不同预算」的设计比单一计数器精细得多,而且自带防死循环:confidence < 0.5 自动升 L3 交给人,agents-triager.md:397 还规定「第 2 次 triage 自动升 spec_ambiguous」防止在错误归因上打转。

阶段 7 · 全局 validator:整体判断 / 测试 / 审计 / benchmark / test data,失败则迭代 system agent 再 loop

⚠️ v0.2 重要更正:本节 v0.1 把 benchmark / test data 理解成了系统级基础设施,因此去核实 benchmark-runner.js / benchmark.sqlite 并判定"是假的、不存在"。这个理解是错的。 实际设计是:benchmark / test data / test script 是 work graph 里的三个 agent 节点(task-benchmark / task-test-data / task-test-script),由 planning agent 动态决定加哪几个。完整设计见 §十一。下面关于既有基础设施的核实结论仍然属实,但它们与本流程无关——本流程不使用 benchmark-runner.js。

状态:⚠️ 产出侧有清晰设计(§十一),执行侧仍是空白(产出验收标准 ≠ 执行验收标准)

  • ⚠️ benchmark-runner.js 是假的。文件头自述"MVP 版本: 使用 heuristic-based 评分"。实际算法:successRate 基础 70 分、描述超 20 字加 5 分、robustness 靠 grep 描述里有没有 "error"/"retry"/"timeout" 字符串、speed/cost 按 layer 查表推算。测试用例数是伪造的:testCasesTotal = 5 + seededRandom(0,10)。三张表(benchmark_runs/comparisons/security_scans)全部以 skill_name 为主体,没有 agent_id / task_id / company_id 任何一列——它是给 Skill 打分的,不能给 agent 或 task 用。
  • ❌ "test data" 作为系统概念完全不存在。全仓库搜到的都是 agent 自己在 workspace 里写的自然语言文本。
  • ✅ 唯一真实执行的评测是 DevLoop 的 integration test(起真实进程跑 e2e,产 integration/runs/{runId}/result.json,含 ok / failures[] / http-trace),但它是 DevLoop 私有的。
  • 💡 qa-judge 的协议设计非常契合你的三级恢复,但它没有任何程序化调用入口。它的输出协议(system/templates/qa-judge/agent.md:223-333)是严格 JSON,status: "PASS" | "REWORK" | "RETRAIN_REQUIRED",而它的缺陷溯源三分类几乎逐条对应你说的三级:
qa-judge 分类 判断标准 输出 对应你的第几级
粗心错误 5 分钟内可修正,无需新知识 REWORK + 具体修正位置 L1 跳回某节点只改一部分
设计缺陷 需要调整设计思路 REWORK + 设计建议 L2 重新 planning 一张 work graph
能力缺陷 反映知识框架缺失 RETRAIN_REQUIRED + capability_gaps[] L4 迭代 system agent

但全仓库 grep,qa-judge 只出现在测试文件和模板目录里,生产代码零引用——它靠 agent 在对话里按 prompt 自行调用,没有调用入口、没有对 JSON 输出做 schema 校验、判决不持久化。


四、与 P2 / P3-P4 设计的差异汇总

# 你的流程 P2 / P3-P4 现有设计 差异性质
1 org graph 逐节点执行,planner 是「执行的第一个节点」 org graph 是静态汇报结构(reports_to/collaborates_with),不执行 语义冲突,见 §五
2 开发公司 = planner / code / validator 三节点 dev.json 模板 = 7 个层级化角色 建模粒度不一致,见 §五
3 code 阶段 fan-out 并行多个 subagent P3/P4 的 advanceOne() 明确一次只推进一个节点 能力缺失,需重新设计
4 失败时判断「重新 planning vs 跳回节点」 P4 的 Loop-Validator 只有「跳回节点」一种 缺一个分支;DevLoop 的四分类可直接借用
5 第三级:迭代 system agent 本体 27 号 P5 有,但被设计成离线慢通道,不在执行循环里 新增层级,见 §八
6 验收标准 = benchmark / test data 两份文档都没提验收标准从哪来、由谁执行 完全空白
7 用户下达具体 task 两份文档都没有任务入口设计 完全空白

五、Org Graph 的定位(v0.2 已定案)

✅ 本节 v0.1 提出的 A/B/C 三方案已作废,定案如下:

Org Graph 是 company 级别生成的 workflow;Work Graph 是 org graph node 级别生成的 workflow。

两者是同一种东西在不同层级上的递归,不是两种不同的结构:

生成者 生成时机 节点指向 边的语义
Org Graph orggraph-planning 建公司时,一次 org node agent 执行流(success/fail 条件)
Work Graph workgraph-planning agent 每个 org node 接到任务时 system agent 引用 执行流(success/fail 条件)

这意味着 27-P2 现在的 org graph 模型需要改:它把边定义成 reports_to / collaborates_with(静态汇报结构),而实际需要的是带 success/fail 条件的执行流边,与 work graph 的边同构。汇报关系如果还需要,应降级为节点上的元数据属性,而不是 org graph 的主干语义。

好处:一套 schema、一套执行引擎、一套控制台 UI,在两个层级上原样复用;三层下钻(org graph → work graph → 并行子图)天然递归;"启动/下一步/暂停/停止/重试"五个操作在每一层语义完全一致。

下面保留 v0.1 的问题分析作为背景(说明为什么"静态汇报结构"这个建模行不通),A/B/C 方案表已不再适用。

问题(v0.1 分析,保留作为背景)

P2 把 Org Graph 定义为公司的静态协作结构——节点是角色引用,边是 reports_to / collaborates_with,它描述"HR 向 CTO 汇报",它不执行任何东西。

你描述的是执行序列——"org planner agent 作为执行 org graph 的第一个节点"、"完成当前 org graph 节点工作,进入下一个 code graph node agent"。planner → coder → validator 是一条流水线。

这两件事是正交的:planner / coder / validator 三者之间大概率没有汇报关系(他们可能都向 CTO 汇报),但他们之间有明确的执行先后。用 reports_to 边表达执行顺序会把两种语义混在一张图里,之后无法区分"谁是谁的上级"和"谁的产出喂给谁"。

三个方案(已作废,见本节开头定案;保留供追溯)

方案 做法 评价
A 给 org_graph_edges 加第三种 relation_type='hands_off_to',org graph 同时承载汇报结构和执行流水线 简单,但把一条固定流水线焊死在公司上。一个 bugfix 任务可能不需要 planner,一个调研任务可能不需要 coder——任务级的差异无法表达
B(推荐) 每个任务规划一张顶层 Work Graph,它的节点指向 org node(而不是直接指向 system agent)。org graph 保持 P2 的静态定义不变 任务级的参与者和顺序都可变;整套 P3/P4 引擎、控制台 UI、暂停/单步/重试全部原样复用,因为它就是一张 work graph,只是节点类型不同
C B + orggraph-planning 额外产出一份 defaultPipeline 作为规划起点 B 的补充,让「开发型公司默认就是 planner→coder→validator」这个直觉落地,同时保留任务级偏离的自由

定案的落地方式

  1. org_graph_edges 改为执行流边,与 work_graph_edges 同构:
-- P2 现有:relation_type IN ('reports_to','collaborates_with')   ← 静态汇报结构,作废
-- 改为:
condition   TEXT NOT NULL CHECK (condition IN ('success','fail')),
edge_kind   TEXT NOT NULL DEFAULT 'forward' CHECK (edge_kind IN ('forward','backward')),

汇报关系若仍需要,降级为 org_graph_nodes 上的一个可空属性(reports_to_node_id),不再是图的主干语义。

  1. 两层图的递归关系(复用 27-P3/P4 已有的 parent_node_id):
Org Graph(company 级 workflow,orggraph-planning 建公司时生成)
  节点 = org node agent
  └─ Work Graph(org node 级 workflow,该 node 接到任务时由 planning agent 生成)
       节点 = system agent 引用
       └─ 嵌套子图(fan-out 出来的并行分支,P3/P4 §4.D.3 已设计)
  1. 执行引擎、schema 形态、控制台 UI 在两层之间完全复用——这是这个定位最大的收益:不需要为 org 级单独造一套控制逻辑,启动/下一步/暂停/停止/重试 在每层语义一致,控制台天然是逐层下钻。

六、可以直接复用的既有机制(两份设计文档都没引用到)

以下全部来自 _spec/ 或已落地代码,建议在 P3/P4 实现前先读一遍,避免重复发明:

  1. contract_hash 三方一致性校验(sdd-model.md M-2/M-5 + doc-store.js:382):hashContract() 对 contract.exports 做递归 key 排序的规范化序列化后 sha256 取前 16 位。Coder 的 contract_bridge 工具校验三件事:contract.json 存在、version 与重算 hash 自洽、重算 hash 与 units.json 声明的 contract_hash 相等。这解决的正是"上游产物改了,下游还停在旧契约上"这个跨节点一致性问题。
  2. L2 闸门的 hash 校验(loops-l2.md):闸门条件不是"所有节点都跑过一次",而是"所有节点 status=passed 且 contract_hash 与当前 SDD 一致",避免设计文档改过之后某个旧节点还停在 passed。
  3. 增量重跑算法(loops-l3.md):added / changed / removed / unchanged 四分类,unchanged(id 在且 hash 不变)保持 passed 无须重跑——"这是增量化的关键"。这直接回答了我在 P3/P4 §八.3 列为开放问题的「重试要不要级联下游」。
  4. 跨节点读取隔离(CONVENTIONS.md §12):跨 unit 只允许读 ../{otherUnit}/contract.json,禁止读 code/。下游只能看到上游的契约,看不到实现。
  5. BugTriager 四分类 + 差异化预算消耗(§三 阶段 6 的表)。
  6. 分级预算与熔断(sdd-process.md P-7)+ 成本/并发的数字版(plan-cost-concurrency.md):三层并发上限(L1 ≤5 并行、L2 串行 1 个、系统 ≤20 ACP session、同公司 ≤3 项目、bash 子进程 ≤50)。
  7. 前端组件:UnitsDAG.vue 已实现 SVG + Kahn 分波布局 + 节点状态着色 + 点击下钻;LiveAgentStream.vue 已实现带 Last-Event-ID 重连的 SSE 消费。我在 P3/P4 §四.B.2 写"手写分层布局算法"时不知道这个组件已经存在,实际工作量应该是扩展它而不是从零写。
  8. 任务回调链路:POST /api/agent/task/report 已实现「更新 goal 节点 → 自动推进 Pipeline → 回调唤醒上级 agent」。
  9. orchestrator.executeWithDependencies():现成的 fan-out/fan-in(Promise.allSettled + 依赖分组 + 单点失败降级)。
  10. memory-service.js(1059 行,9 个导出函数):cerebellum/(固化的成功执行方案,按关键词召回)、hippocampus-index.json(索引)、autoReflect()、consolidateMemory()。这是 L4 里"迭代 memory"唯一一块已经成熟的基础设施。

七、没有考虑到的地方

7.1 三级恢复叠加会让熔断失效(最严重)

你的流程有三级恢复:跳回节点 → 重新 planning → 迭代 system agent。如果每一级都重置下一级的计数器,整个循环就没有终止条件,而"直至最后满足这个任务的 benchmark"这句话字面上就是一个无限循环。

具体地说:L1 的 retry_budget=5 在 L2 重新 planning 之后会重新计数;L2 的 l2_budget=3 在 L4 迭代完 agent 之后如果也重置,那么"迭代 agent → 重跑 L2 三轮 → 再迭代 agent"可以永远跑下去。

DevLoop 已经部分解决了这个问题:它的 l2_budget 是「每个 PRD rev 3 轮」而不是「每次 L2 3 轮」,且 impl_bug / infra_flake 不烧预算。但它没有第四层,所以没遇到这个问题。

建议:引入一个任务级总预算,跨所有层级共享、只增不减:

task_budget = {
  total_agent_calls:  100,      // 所有层级所有 agent 调用的总次数
  total_tokens:       5_000_000,
  wallclock_ms:       7_200_000, // 2h
  l4_iterations:      2,          // 迭代 system agent 最多 2 次(最贵、副作用最大)
}

任何一层的重试都从这个总池子里扣,扣完即挂起等人工。分层预算(retry_budget / l2_budget)继续保留作为局部快速失败信号,但总预算是最终兜底。

7.2 L4 迭代 public system agent 会污染其他公司 ✅ v0.2 已解决

已由 §八 的 L4-company / L4-general 拆分解决:在线自动迭代只碰 company 记忆分区,general 本体的更新移出任务循环、改由定时 dream 流程 + master agent/人工驱动。下面保留原始风险分析作为背景,其中提的三个缓解方案(fork 副本 / 只改私有 / 人工确认)已不再需要单独采纳。

原始风险分析(v0.1,保留作为背景)

27 号文档 §3.2 定义 scope=public 的 system agent 跨公司共享记忆。如果 coder 是 public、被 10 家公司引用,那么"为了让 A 公司这个任务通过,迭代 coder 的 skill/memory"意味着为了修一个任务,改了 10 家公司共用的 agent。

27 号文档自己已经意识到这个风险(§3.2 要求公共 memory.md 的写入走自省校验 + git 版本化),但那是针对"缓慢的自我进化"设计的,不是针对"任务失败了赶紧改一下再试"这种在线高频路径。

建议(三选一,倾向 A):

  • A:L4 触发时,先把该 system agent fork 成一个 company-scoped 副本(scope='company', owner_company_id),只改副本,本公司后续调用指向副本。副本表现好、跑过 benchmark ≥95,再走既有的 depositTemplate() 链路回灌 public。这样在线迭代的爆炸半径永远限制在一家公司内。
  • B:L4 只允许改 company-scoped 的私有记忆(companies/{cid}/memory.md),不许碰公共 memory.md/skills/。能力有限但零风险。
  • C:L4 需要人工确认才生效。安全但破坏了自动化。

7.3 谁来验收「验收标准」本身(v0.2 已部分缓解)

planner 阶段产出 benchmark/testdata/testscript,validator 阶段用它验收。如果产出了一个过松的标准,任何垃圾都能通过;产出了一个不可能达成的,就永远收敛不了。

DevLoop 就这个问题做过显式决策(loops-l2.md 方案 A/B/C),选择"设计者写、执行者不写",明确否决"执行者自己写测试",理由是执行者会写出"永远会通过的 trivial test"。

✅ §十一 的三节点设计天然符合这条原则:task-benchmark / -test-data / -test-script 三个 agent 与真正写代码的 coder 是完全不同的 system agent,产出者和被验收者分离,不存在"自己给自己出考题"的激励问题。

⚠️ 但仍未解决"标准写错了"这一层。缓解手段有两个,建议都要:

  1. work graph 里的 code-planner-validator 节点承担一项明确职责——审"这套验收标准是否可度量、是否覆盖原始需求、是否存在平凡通过的漏洞",而不只是审 PRD/SDD 本身。
  2. 保留人工 sign-off(DevLoop L3 的做法)作为最终关卡,至少在 v1 阶段不要全自动闭环。

7.4 并行与现有不变量冲突

CONVENTIONS.md §12 第一条「任意 (pid, agent) 同时只允许 1 个 status=running」+ SessionPool 的 key 复用,两者都挡着 fan-out。必须先设计同一 system agent 的多实例并发隔离(给 SessionPool key 加 scope、给不变量加 instance 维度),否则"并行多个 code subagent"跑不起来。

7.5 三层图的暂停/停止如何传播

上一轮 P3/P4 §八.4 已经把"子图不继承父图暂停状态"列为刻意简化。现在变成三层(任务级 → org node 级 → 并行子图级),手动模式下用户点"暂停"到底暂停哪一层、正在跑的下层要不要停,会成为真实的困惑点。建议:暂停/停止向下级联(符合直觉),"下一步"只作用于当前查看的层级。

7.6 成本量级

按 plan-cost-concurrency.md 的实测估算,DevLoop 一个中等项目(8 unit、2 个 PRD rev、2 轮 L2)≈ 39 次 agent 调用、410K token、约 $4.8、墙钟 20 分钟。

你的流程在此之上还要叠加:顶层任务图规划、每个 org node 各自的 work graph 规划、L4 的 agent 迭代 + 重新 benchmark。粗估一个中等任务 60-100 次 agent 调用、$10-20、1-2 小时。这个量级下:

  • 「自动模式一键跑到底」需要在启动前把预估成本告诉用户
  • §7.1 的任务级预算不是可选项

7.7 其他

  • 失败的部分成功:fan-out 5 个并行节点,3 成功 2 失败,fan-in 节点要不要跑?(建议:不跑,等全绿;但要有 UI 明确显示"卡在等 2 个失败节点")
  • task status 无状态机:system/tasklog/{taskId}.json 的 status 是自由赋值,没有转换校验。
  • knowledge/ 目录没有读取方:L4 里"迭代 data"这一维,目录存在、创建时能写一次,但全仓库没有任何代码读它。要么先补读取方,要么 L4 暂时不含这一维。
  • per-agent LLM 选择不存在:runtime-resolver.js 只推断 protocol/transport/launcher,没有 model 字段,config.json 里也 grep 不到 model 键。虽然 agents-overview.md 的规格表里给每个 agent 指定了模型(Architect/BugTriager 用 Opus、其余 Sonnet),但这只存在于文档,代码里没有实现。L4 想"换 LLM"需要从 client 定义、runtime-resolver、协议层一路新增。

八、L4 · System Agent 自我迭代(v0.2 已定案:拆成两条独立通道)

把第七步正式命名为 L4。关键定案:L4 按"改的是 company 分区还是 general 本体"拆成两条完全不同的通道,它们的触发方式、时机、驱动者、风险等级都不一样:

L4-company L4-general
改什么 agent 的公司/角色记忆分区(companies/{cid}/) agent 的general 本体(公共 agent.md / memory.md / skill)
触发 任务执行过程中,validator 判定能力缺陷时 定时(如每日)或人工手动触发
驱动者 执行引擎,自动 master agent 或人工
输入 本次任务的失败上下文 当天所有公司的执行成功/失败/经验汇总
在任务循环内 ✅ 在环内,会触发重跑 ❌ 离线批处理,不阻塞任何任务
爆炸半径 一家公司 全局(所以才需要人/master 把关)

这个拆分直接解决了 v0.1 §7.2 提出的跨公司污染风险:在线自动迭代永远只碰 company 分区,general 本体的更新被移出任务循环、改由离线批处理 + 人工/master 驱动。v0.1 提的三个缓解方案(fork 副本 / 只改私有 / 人工确认)不再需要——这个分层本身就是更彻底的答案。

8.1 L4-general 的"agent dream"流程

离线自我更新的形态:根据当天所有 company 的执行记录(成功、失败、经验),更新 general 本体。类比睡眠期的记忆固化。

🔴 现状:这个流程不存在,但零件基本齐了——memory-service.js(1059 行)已有 autoReflect()(自动反思)、saveCerebellumPlan() / retrieveRelevantPlans()(小脑:固化的成功执行方案 + 按关键词召回)、loadHippocampusIndex() / syncHippocampusMd()(海马体索引 + 人类可读版同步)、updateMemoryMdSections()。缺的是跨公司的批量汇总层:现有全部接口都是 agentId 单点的,没有"把这个 agent 在 10 家公司的当日记录聚合起来蒸馏一次"这一步。

建议实现形态:一个定时任务(复用现有 cron.json 机制)或手动端点,对每个 public system agent:收集当日跨公司执行记录 → 调 agent 自身或专职 evolver 做蒸馏 → 产出对 general 本体的 diff → 走 27 号文档 §3.2 已定的 git 版本化 + 自省校验(坏的迭代可 revert)→ 可选的人工确认后生效。

8.2 四个可迭代维度的现状

维度 现状 L4-company(在线) L4-general(离线 dream)
memory ✅ memory-service.js 最成熟,全套读写 API ✅ 主要手段 ✅ 主要手段
skill ⚠️ 有运行时注入先例(company.js:941-971 招聘后 skillDb.searchSkills + copyDir),但是路由内联的,没封装成服务 ✅ 纳入,需先封装 ✅ 纳入
data (knowledge/) ❌ 目录存在、创建时写一次,但全仓库没有任何代码读它 ❌ 先补读取方 ❌ 先补读取方
LLM ❌ 完全不存在 per-agent 模型选择(runtime-resolver.js 只推断 protocol/transport/launcher,无 model 字段) ❌ 改动链路太长 ❌ 同左

八bis、元 Agent 继承(v0.2 新增)

所有 org graph / work graph 的 node agent,都由一个元 agent 架构继承生成,统一是「全局通用本体 + 公司/角色记忆分区」的结构。

这条定案取代了 v0.1 §四 里"三个验收 agent 要不要按父节点特化"这个问题——答案是不特化:不存在 task-benchmark / test-planner-benchmark 各自独立的 agent,只有通用的 benchmark 设计能力,靠记忆分区区分它在不同 org node / 不同公司下的经验积累。agent 池不随 org node 数量膨胀,也与 27-P1 虚拟引用寻址的初衷一致(同一份本体,多处引用,各自私有语境)。

✅ 元 agent 在仓库里已经存在:system/templates/base/("标准基座员工 Base Agent")。它已经强制了一套四段式生命周期:

RESEARCH → PLAN → EXECUTE → VERIFY

每阶段之间通过 node bin/lemon.js task transition --agentId <id> --phase <next> --artifact <path> 切换,切换时清空上下文并换装对应的元技能(meta-research / meta-plan / meta-execute / meta-verify);VERIFY 阶段失败则把原因写入 _lessons.md 并打回上一阶段。

💡 这本身就是一个最小 work graph:四个节点、线性前进、末端带失败回退边。也就是说"每个 node agent 内部也是一张图"这件事已经有雏形。设计 Work Graph 引擎时应当与它对齐(要么把 base agent 的四段式改写成引擎上的一张标准图模板,要么至少保证两者的阶段语义不冲突),否则会出现"引擎层的 work graph"和"agent 内部的四段式"两套并行的状态机。


九、对现有文档的修订要求

调研中发现仓库已推进,我先前两份文档里有三条陈述已经过期或与已落地代码冲突,需要修正:

# 文档 错误陈述 事实
1 27-P2 §九、27-P3/P4 §九 "P1 目前仍是设计稿,未实现,graph-service.js 尚不存在" P1 已实现并提交(commit 226489d),server/services/graph-service.js 已存在(104 行),配套测试 graph-service.test.js / agent-manager-p1.test.js 均在
2 27-P3/P4 §三.1 "runProject 目前直接 501" 已完整实现(loop-controller.js:576),含 Kahn 分波、L2 闸门、Triager 四分支、预算熔断
3 27-P2 §4.1 提议建部分唯一索引 idx_org_graph_nodes_company_role_active(带 WHERE status='active') graph-service.js:44 已经建了全量唯一索引 idx_org_graph_nodes_company_role(无 WHERE)。P2 若要加 status 列并改成部分索引,必须先 DROP 已落地的那个索引
4 27-P3/P4 §四.B.2、§六 T3 "手写分层布局算法,不引入图形库" 作为新工作量 web/src/components/devloop/UnitsDAG.vue 已实现 SVG + Kahn 分波布局,应改为"扩展既有组件"

此外建议:

  • 27 号总文档 §六:把 P6「DevLoop 收编(可选)」的定位从"可选的后续整合"改为"DevLoop 是本架构的参考实现,通用引擎应从它抽象而来"(结论 2)。
  • 27-P2:核心建模需推翻重写——org_graph_edges 从 reports_to/collaborates_with 改为与 work_graph_edges 同构的 condition IN ('success','fail') + edge_kind;汇报关系降级为节点可空属性;§4.3 的 reportsTo 语义改为"接在谁后面";§4.7 前端改为复用 Work Graph 画布组件(详见该文档 v0.4 修正块)。
  • 27-P3/P4:补 node_kind='org_node'(§五)、fan-out 并行 + 实例隔离(§7.4)、任务级总预算(§7.1)、三层暂停级联(§7.5);把 §八.3 的开放问题用 loops-l3.md 的 unchanged 算法关掉。

十、可行性判断与落地建议

这个流程能这样实现吗?

能,但不是从零实现——大部分是"把 DevLoop 已经跑通的东西泛化",而不是新造。 分三类:

  • 约 50% 是"改造既有实现":runProject 的分波执行、Triager 四分支、预算熔断、SSE、DAG 前端组件、contract hash 校验、memory-service——都已经在跑,问题是它们绑死在"写代码"这一个场景上。
  • 约 30% 是"补通用层":任务入口、org 级任务图(§五)、planning agent、并行实例隔离。
  • 约 20% 是真空:面向 task/agent 的真实 benchmark(现有的是 skill 专用假打分)、test data 全套、qa-judge 的程序化入口、L4。

最大的结构性风险

整条流程的终止条件(验收)是实现程度最低的一环。 L1/L2/L3 的循环机制都相当成熟,但"跑完了到底算不算通过"这件事,现在没有任何真实执行的评测基础设施支撑(benchmark 是假的、test data 不存在、qa-judge 没有调用入口)。先建验收,再建循环——否则会得到一个跑得很顺畅但永远不知道该不该停的系统。

建议的落地顺序

  1. 验收先行:给 qa-judge 补程序化调用入口 + 输出 schema 校验 + 判决持久化;定义 task 级 benchmark/testdata 的存储与执行方式(可以直接抄 DevLoop 的 integration/spec.json + 真实进程执行)。
  2. 任务入口:补"用户 → 公司"的任务下达端点,复用既有 task/dispatch + task/report 回调链路。
  3. org graph 改为执行流图(§五定案):边模型改造 + 复用 work graph 引擎跑通两层。此时可以端到端跑通一条串行、无并行、无 L4 的最小闭环(参照 27-EXAMPLE 的场景)。
  4. 并行:先解决实例隔离(SessionPool scope + 不变量),再把 _groupUnitsByWave 的波内串行改并行。
  5. L4:最后做,且第一版只做 memory + skill 两个维度、fork 成 company-scoped 副本、需人工批准。

前三步做完就能验证你描述的主干流程;4、5 是增强。

v0.2 调整:第 1 步"验收先行"的含义因 §十一 的更正而改变——不是"建 benchmark 基础设施"(那是误解),而是"定义验收契约格式 + 建执行器"。三个产出 agent 本身不需要新基础设施,它们就是普通 system agent。


十一、验收产出节点设计(v0.2 新增)

11.1 三个 agent 节点,动态选择

benchmark / test data / test script 不是系统基础设施,是 work graph 里的三个可选 agent 节点:

节点 产出 适用场景
{org-node}-benchmark 打分式验收标准:维度 + 权重 + 及格线 质量是分数而非布尔的场景——生成内容质量、性能指标、可读性
{org-node}-test-data 输入样本集:正常用例 + 边界 + 异常 需要喂数据才能验证的场景——解析器、转换器、有复杂输入空间的逻辑
{org-node}-test-script 可执行断言脚本 行为可以用代码判定真假的场景——API 契约、函数返回值、状态变更

由 planning agent 在规划 work graph 时动态决定加哪几个——可以三个都加、只加一个、或某种组合。这使得"要不要加验收节点、加哪个"成为 work graph 规划的一等决策,而不是固定模板。

例:code-planner 这个 org node 的 work graph 可能长成

brd-planning → prd-planning → sdd-planning ─┬→ task-benchmark ──┐
                 ├→ task-test-data ──┼→ code-planner-validator → loop-validator
                 └→ task-test-script ┘

三个验收节点之间无依赖,可并行(fan-out),汇合到 code-planner-validator(fan-in)。这正好是 §7.4 fan-out 能力的第一个真实用例。

11.2 三者必须产出统一的「验收契约」

三个节点的产出形态不同(分数表 / 数据集 / 脚本),但下游 validator 必须能统一消费。否则每加一种验收节点就要改一次 validator。

建议:三者都写入同一个 acceptance.json(各占一个 section),格式定位参照 DevLoop 已有的 integration/spec.json(sdd-model.md M-6,含 cases[] / steps[] / expect{status,json} / involves[],并支持 {{stepN.field}} 占位符引用前序步骤结果):

{
  "version": "1",
  "okr_node_id": "O-001.1.1",
  "task_id": "T-xxx",
  "benchmark":   { "dimensions": [{"name":"...","weight":0.4,"pass_threshold":80}] } | null,
  "test_data":   { "cases": [{"id":"...","input":{},"expect":{}}] } | null,
  "test_script": { "runner": "vitest", "path": "tests/acceptance.spec.js" } | null
}

三个字段各自可为 null(对应"这次没加这个节点"),validator 只处理非 null 的部分。

11.3 「谁生成、谁执行」逐层递归(v0.2 定案)

产出者与执行者分离,且这个模式在每一层图上都重复出现:

层级 谁生成验收标准 谁执行验收
Org Graph(company 级 workflow) planner org node validator org node
Work Graph(org node 级 workflow) 图内的 benchmark / test-data / test-script 节点 图内的 validator 节点

也就是说,每个 node agent 都有自己的 benchmark,由它自身所在 work graph 的 validator / test-script / benchmark 节点来运行——验收不是只发生在最外层的一次总检,而是每一层图收尾时都跑自己那一层的验收。这与 §八bis 元 agent 四段式末尾固定有 VERIFY 阶段,是同一个模式在不同粒度上的体现。

执行由 agent 节点承担,不由引擎硬编码,保持"一切都是图上的节点"这个架构一致性;代价是每次验收要烧一次 agent 调用(计入 §7.1 的任务级总预算)。DevLoop 的现成先例是 Integrator agent 起真实进程跑 e2e(agents-integrator.md),产出 result.json 含 ok / failures[] / http-trace,validator 节点可直接复用这套做法跑 test script / test data。

🔴 剩余缺口:benchmark 这类主观打分的判定,qa-judge 的输出协议(PASS / REWORK / RETRAIN_REQUIRED + capability_gaps[])本来就是为此设计的——其中 RETRAIN_REQUIRED 正好是 §八 L4-company 的触发信号——但它目前没有程序化调用入口(全仓库 grep,生产代码零引用),需要补入口 + 输出 schema 校验 + 判决持久化。

11.4 命名冲突提醒

仓库里 benchmark 一词已经被占用:benchmark-runner.js / data/benchmark.sqlite / _registry.json 的 benchmarkScore / Arena ELO 排行榜,指的都是给 Skill 打分的那套体系(表结构以 skill_name 为主键,没有 agent_id/task_id 任何一列)。本文档 §十一 说的是任务级验收标准,两者同名但完全无关。建议在实现时给新概念换个不冲突的名字(如 acceptance-benchmark 或 goal-benchmark),否则日后 grep 和排查会很痛苦。