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"机制来跑:
- Planner 完成后,先过一道 judgment(可以是 Validator,也可以是别的判断机制),不通过就
loop_back回 Planner(或者回 Planner 自己 Work Graph 里更精确的某个节点,比如就回那个 benchmark 节点,而不是"重新触发整个 Planner")。 - 通过了才进入 Coder。
- Coder 完成后过 judgment(现有 Validator 逻辑),不通过时要先判断根因是 Planner 的问题还是 Coder 的问题,再精确
loop_back到对应阶段的具体节点,而不是现在这种"笼统打回整个阶段"。
本质上是把"Org Graph 本身"也建模成一张 Work Graph(Planner/Coder/Validator 是三个"节点",每个节点内部又是一张自己的、可能自规划的子图),对失败的处理机制上下两层统一。
3. 目标(草案,待讨论后细化为正式 FR)
- Coder 开始实现之前,Planner 自己的产出(至少是 Benchmark,可能还有 SDD)要经过一次独立判断,能拦住这次真实复现的那种"叙述文字冒充 benchmark"的情况,不必等到 Coder 把错误的实现做完才被 Validator 发现。
- 失败时的路由要能精确到具体是哪个节点出的问题(比如"benchmark 节点内容不对"),而不是只知道"Planner 阶段"或"Coder 阶段"这种粗粒度。
- 跨 Org Agent 边界的循环(现有
org_level_loop.py覆盖的场景)和单个 Org Agent 内部的循环(今天刚做的 Work Graph loop_back)用同一套机制表达,不是两套平行的、概念不同的循环实现。 - 循环上限、历史记录复用今天已经建立的模式(
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. 非目标(草案)
- 不在这份需求里改变
task.status现有的queued/planning_brd_prd_sdd/coding/validating状态机本身的字面值——如果要做,这套状态机可能也需要重新设计("Planner 阶段内部又在 loop_back"这种状态目前完全没有对应的 task.status 值),但那是另一个需要谨慎讨论的问题,不在这次草稿里预先决定。 - 不假定"给 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 上,需要更新范围。