org-graph-as-work-graph-unified-loop-requirements.md 9.13 KB

Org Graph 本身也变成一个 Work Graph(Planner/Coder 之间加判断+精确回路)——需求文档

日期: 2026-08-08 性质: 需求文档草稿(BRD/PRD 层面),尚未逐条讨论确认——跟 docs/done/work-graph-self-planning-and-loop-back-requirements.md 不同,那份是走完"逐条开放问题讨论→用户拍板"流程后才写的,这份是用户提出想法后直接要求"先记到 todo 里",还没有走那个流程。「6. 待确认的问题」列的都是需要讨论、不是已经拍板的。 触发场景(真实复现):任务 2084590a(修复 work_node_run.py 的 execution_log_file bug)里,Planner 自规划出的 benchmark 节点连续 4 次产出的都是"叙述我做了什么"的散文(跟 docs/todo/validator-test-script-narrative-output-issue.md 同一类问题,但这次发生在 benchmark 上,不是 test_script),LLM judge 的 on_fail=retry_self 循环耗尽 max_attempts=3 后任务直接 blocked_pending_human。用户追问引出两个观察:① Validator 从来没有机会在 Coder 开始实现之前复核 Planner 自己的产出;② 现有的 org_level_loop.py/org_loop_route.py 只在 Coder 完整实现之后才起作用,而且只能粗粒度地把整个任务打回"Planner 阶段"或"Coder 阶段"重来,不能精确跳到某个具体 Work Graph 节点。 状态: 草稿,待讨论。2026-08-08 更新:用户提出更完整的四点架构改动设想(新 Org 固定流程、全员自规划、前端动态/历史图谱、节点级验证 skill),本文档已被展开合并进 docs/todo/org-graph-unification-and-universal-self-planning-requirements.md——后续讨论请统一在那份文档进行,本文档保留作为触发场景/根因排查的原始记录,不再单独跟进。

1. 背景:现在有两套独立的、粒度不同的循环机制

  • work-graph-self planning-and-loop-back(今天刚做完):一个 Org Agent 自己的 Work Graph 内部,节点声明 judgment/on_fail,失败可以 loop_back 跳回同一张图里更早的节点,历史记录在 execution_event,上限可配置。只在单个 Org Agent 的图内部生效。
  • org_level_loop.py/org_loop_route.py(已实现,更早):Validator 对 Coder 的最终实现给出 FAIL/INCONCLUSIVE 判决后,p_validator_root_cause_trace 判根因(planning/coder/skill_defect),路由到 fast_lane(回 Coder)或 full_replan(回 Planner),task.loop_round 封顶 3 轮。这是跨 Org Agent 边界的循环,但粒度是"整个阶段重来",不是"跳到具体哪个节点";而且触发条件是"Coder 已经完整实现完,Validator 也已经判过"——Planner 自己的产出(BRD/PRD/SDD/Benchmark)在被 Coder 使用之前,从来没有任何独立角色复核过。

这次真实复现暴露的具体问题:Planner 自己的 Work Graph 内部循环耗尽后,直接 blocked_pending_human,整个任务卡死——既没有像 org_level_loop 那样有根因判断和路由,也没有人能在 Coder 动手之前发现"这个 Benchmark 其实是叙述文字,根本不能用"。

2. 用户提出的方向

把 Planner → Coder → Validator 这条 Org Graph 本身,也按照今天 Work Graph 那套"节点 + judgment + on_fail + loop_back"机制来跑:

  1. Planner 完成后,先过一道 judgment(可以是 Validator,也可以是别的判断机制),不通过就 loop_back 回 Planner(或者回 Planner 自己 Work Graph 里更精确的某个节点,比如就回那个 benchmark 节点,而不是"重新触发整个 Planner")。
  2. 通过了才进入 Coder。
  3. Coder 完成后过 judgment(现有 Validator 逻辑),不通过时要先判断根因是 Planner 的问题还是 Coder 的问题,再精确 loop_back 到对应阶段的具体节点,而不是现在这种"笼统打回整个阶段"。

本质上是把"Org Graph 本身"也建模成一张 Work Graph(Planner/Coder/Validator 是三个"节点",每个节点内部又是一张自己的、可能自规划的子图),对失败的处理机制上下两层统一。

3. 目标(草案,待讨论后细化为正式 FR)

  1. Coder 开始实现之前,Planner 自己的产出(至少是 Benchmark,可能还有 SDD)要经过一次独立判断,能拦住这次真实复现的那种"叙述文字冒充 benchmark"的情况,不必等到 Coder 把错误的实现做完才被 Validator 发现。
  2. 失败时的路由要能精确到具体是哪个节点出的问题(比如"benchmark 节点内容不对"),而不是只知道"Planner 阶段"或"Coder 阶段"这种粗粒度。
  3. 跨 Org Agent 边界的循环(现有 org_level_loop.py 覆盖的场景)和单个 Org Agent 内部的循环(今天刚做的 Work Graph loop_back)用同一套机制表达,不是两套平行的、概念不同的循环实现。
  4. 循环上限、历史记录复用今天已经建立的模式(settings_config.py 风格的可配置上限、execution_event 记录历史),不重新发明。

4. 一个明显更难的地方:跨 Org Agent 的"节点"地址空间不一样

今天的 loop_back 是在同一个 work_graph_run(同一张图)内部跳转——_on_failure_target/_transitive_dependents 全部假设 target_node_id 和当前失败节点在同一个 graph_manifest["nodes"] 里。但 Planner 和 Coder 是两次独立的 plan_work_graph() 调用,各自产出各自的 work_graph_run/graph_manifest,节点 id 空间互不相通——"Coder 阶段发现问题,要跳回 Planner 阶段的 benchmark 节点",这个"benchmark 节点"活在另一个、可能早就标记为 done 的 work_graph_run 里,不是当前正在跑的这张图的一部分。今天的 _LoopBackRequested/run_graph() 主循环完全没有考虑"目标节点在另一张图里"这种情况。

这不是一个小的实现细节——这是这次需求跟今天那次最大的架构差异,需要先想清楚:是把 Planner 和 Coder 的图合并成同一张跨阶段的大图(这样 loop_back 天然能跳),还是保留现在"每个 Org Agent 各自一张图"的边界、在图与图之间另设计一层专门的跨图路由(更接近现有 org_loop_route.py 的做法,只是把"回 Planner"精确到"回 Planner 图里的哪个节点")。

5. 非目标(草案)

  1. 不在这份需求里改变 task.status 现有的 queued/planning_brd_prd_sdd/coding/validating 状态机本身的字面值——如果要做,这套状态机可能也需要重新设计("Planner 阶段内部又在 loop_back"这种状态目前完全没有对应的 task.status 值),但那是另一个需要谨慎讨论的问题,不在这次草稿里预先决定。
  2. 不假定"给 Coder 开始前加一道判断"用的一定是 Validator——可能是 Validator 的一个轻量子集,也可能是完全独立的判断机制,待讨论。

6. 待确认的问题(这份文档的主要目的——先把问题摆出来)

  • [ ] 要不要完全取代 org_level_loop.py/org_loop_route.py,还是新机制只是给现有机制"打补丁"(比如只加"Coder 开始前先判断 Planner 产出"这一段,Coder 完成后的现有路由逻辑不动)?
  • [ ] §4 提到的跨图节点寻址问题:合并成一张大图,还是图与图之间单独设计一层路由? 这个决定几乎决定了整个实现方式,建议第一个讨论。
  • [ ] "Coder 开始前判断 Planner 产出"这一步谁来做? 复用 Validator(但 Validator 现在的定位是"独立验收最终实现",拿它来判断"BRD/PRD/SDD/Benchmark 写得好不好"是不是错位?)、还是让 Planner 自己的 Work Graph 内部多一个"自我复核"节点(这样其实不需要跨 Org Agent,本质是今天 Part A 机制的延伸,不需要碰 Org Graph)?
  • [ ] 根因判断("这次失败该回 Planner 还是回 Coder")复用现有 p_validator_root_cause_trace 的三选一分类,还是需要更细粒度(精确到某个 Work Graph 节点)的判断机制?
  • [ ] task.loop_round/_LOOP_LIMIT=3 这个既有的、粗粒度的计数器要不要保留? 如果循环变成能精确到节点级别,是不是也需要参考今天 settings_config.py 风格的按 org_node/节点类型可配置上限,而不是一个全局固定的 3?
  • [ ] 这次真实触发这个讨论的具体症状(benchmark 叙述文字),本身要不要单独先用更小的手段缓解(比如给 benchmark 也加一个类似 check_script_compiles 的机械启发式检查,判断"这段内容像不像散文而不是结构化 benchmark"),而不必等这个更大的 Org Graph 改造做完? 这个可以先记到 docs/todo/validator-test-script-narrative-output-issue.md(已经在追踪同一类问题,只是要把范围从 test_script 扩到 benchmark)。

7. 相关文档

  • docs/done/work-graph-self-planning-and-loop-back-requirements.md/-design.md:今天实现的 Work-Graph-内部判断+回路机制,这份需求本质是把它推广到 Org Graph 层面。
  • docs/todo/validator-test-script-narrative-output-issue.md:叙述文字问题的原始记录(目前只覆盖 test_script),这次真实复现证明同一个根因也会发生在 benchmark 上,需要更新范围。