Skip to content

pref(runtime):控制面语义收敛 #386

Description

@phantom5099

1) 目标问题(Why)

当前 runtime 主循环已经被 PR 365 推向“顺序 Todo + inline subagent + dispatch phase”的新模型,但现有计划仍停留在旧控制面语义上,导致问题定义与实现方向已经出现偏移。本issue只解决当前阶段必须收敛的控制面语义问题:

  1. 完成判定问题:assistant 本轮无 tool call 仍容易被误判为完成,且在顺序 Todo + inline subagent 模型下,这个信号可靠性更弱。
  2. 进展判定问题:当前 repeat-cycle / no-progress 仍偏向旧式“重复调用 + 弱证据”判断,容易误伤合理探索;同时 PR 365 已移除其硬停止语义,现有计划中的 stop 设计已过时。
  3. 状态机问题:runtime 实际上已经引入 dispatch 阶段,但旧方案仍以 Plan -> Execute -> Verify 为主链,无法准确描述新的执行闭环。
  4. 控制面分散问题:completion / progress / stop / dispatch / subagent 相关语义仍散落在 run loop、tool 执行和事件层,不利于后续 budget、ledger、resume 稳定接入。

本阶段目标不是引入更多能力,而是先让 runtime 的主循环语义与 PR 365 对齐,并形成可测试、可观测、可继续扩展的控制面契约。

2) 设计(How)

2.1 控制面不变量

本阶段先固定以下运行时不变量,后续实现与测试均以此为准:

  1. assistant 本轮无 tool call != completed
  2. 只要仍有 pending agent todopending subagent todoinline subagent in-flight未验证写入,就不能 completed。
  3. no-progressrepeat-cycle 不是本阶段的硬 stop reason,只能作为 soft control / stalled 信号。
  4. Dispatch 是正式 phase,不再是隐含流程。
  5. 同一 turn 只能产出一个最终硬停止结果,本阶段仅允许:
    • STOP_FATAL_ERROR
    • STOP_COMPLETED
    • STOP_USER_INTERRUPT

2.2 运行状态机

本阶段固定 RunState

  • Plan
  • Execute
  • Dispatch
  • Verify
  • Compacting
  • WaitingPermission
  • Stopped

主链迁移固定为:

  • Plan -> Execute -> Dispatch -> Verify -> Plan

补充迁移:

  • * -> WaitingPermission -> previous_state
  • * -> Compacting -> Plan
  • * -> Stopped

语义约束:

  • Plan
    • 负责本轮规划、顺序 Todo 更新、决定当前 todo 的 executor
  • Execute
    • 负责主 agent 的普通工具执行
  • Dispatch
    • 负责 executor=subagent 的 todo、inline subagent 触发与结果回灌
  • Verify
    • 负责验证与 closure
  • Compacting / WaitingPermission / Stopped
    • 保持治理/中断/终止语义,不承载业务推进

2.3 CompletionGate 设计

CompletionState 固定包含:

  • HasPendingAgentTodos
  • HasPendingSubagentTodos
  • HasInlineSubAgentRunning
  • HasUnverifiedWrites
  • LastTurnExecutedTools
  • LastTurnVerifyPassed
  • RequiresVerification
  • CompletionBlockedReason

规则固定为:

  1. 本轮 assistant 无 tool call,不直接视为完成。
  2. pending agent todo 时不能 completed。
  3. pending subagent todo 时不能 completed。
  4. 有 inline subagent 尚未回灌完成时不能 completed。
  5. 有未验证写入时不能 completed。
  6. 只有 RequiresVerification=falseLastTurnVerifyPassed=true 时,才允许结束。
  7. 纯读取、纯检索、纯解释型执行不自动要求 verify;写入类动作和显式 verify-required 工具会置 RequiresVerification=true

2.4 进展判定设计

ProgressEvidence 仅允许结构化证据:

  • TASK_STATE_CHANGED
  • TODO_STATE_CHANGED
  • TODO_EXECUTOR_CHANGED
  • WRITE_APPLIED
  • VERIFY_PASSED
  • NEW_INFO_NON_DUP
  • PHASE_ADVANCED
  • DISPATCH_COMPLETED
  • SUBAGENT_RESULT_APPLIED

证据分级固定为:

  • 强证据
    • TASK_STATE_CHANGED
    • TODO_STATE_CHANGED
    • VERIFY_PASSED
    • DISPATCH_COMPLETED
    • SUBAGENT_RESULT_APPLIED
  • 中证据
    • TODO_EXECUTOR_CHANGED
    • WRITE_APPLIED
    • PHASE_ADVANCED
  • 弱证据
    • NEW_INFO_NON_DUP

ProgressScore 至少包含:

  • HasBusinessProgress
  • HasExplorationProgress
  • StrongEvidenceCount
  • MediumEvidenceCount
  • WeakEvidenceCount
  • NoProgressStreak
  • RepeatCycleStreak
  • SameToolSignature
  • SameResultFingerprint
  • SameSubgoal
  • StalledProgressState
  • ReminderKind

规则固定为:

  1. 出现任一强证据,或出现 WRITE_APPLIED + VERIFY_PASSED 闭环,才算 HasBusinessProgress=true
  2. 只有 NEW_INFO_NON_DUP 或仅有 PHASE_ADVANCED 时,不算业务进展。
  3. HasExplorationProgress 仅在 Plan / Execute / Dispatch 阶段有效,用于给合理探索留缓冲,不直接视为业务推进。
  4. NoProgressStreak 只在无业务进展且 exploration 缓冲已耗尽时递增。
  5. RepeatCycleStreak 只在以下条件同时成立时递增:
    • SameToolSignature=true
    • SameResultFingerprint=true
    • SameSubgoal=same
    • HasBusinessProgress=false
  6. SameSubgoal 使用三态:same / different / unknownunknown 不推动 repeat。
  7. no-progress / repeat-cycle 不直接 stop,只能推动 stalled 与 reminder。

2.5 stalled 软纠偏设计

本阶段新增 StalledProgressState

  • healthy
  • stalled

规则:

  1. NoProgressStreakRepeatCycleStreak 首次达到阈值时,不直接终止 run。
  2. 首次达到阈值后,进入 stalled,并注入一次固定的自修复提醒。
  3. 提醒内容固定聚焦:
    • 总结 blocker
    • 更新当前 todo / 子目标
    • 说明是否继续重复调用
    • 若位于 Dispatch,说明为何仍需 subagent 或改回 agent 执行
  4. stalled 期间允许继续运行;真正硬终止由后续 budget / turn / time 边界负责,不由 progress 直接负责。

2.6 Dispatch / inline subagent 设计

本阶段将 spawn_subagent(mode=inline) 正式纳入控制面,不再视为普通附属工具:

  1. Dispatch 阶段的职责是识别 executor=subagent 的 todo、触发 inline subagent、接收结构化结果并回灌。
  2. inline subagent 结果一律按结构化 tool result 处理,不作为普通 assistant continuation。
  3. todo.executor 只允许 agent / subagent 两种合法输入语义。
  4. 本阶段的 dispatch 语义固定为“顺序 todo + inline child execution”,不承诺一般化 DAG 自动调度。

2.7 事件与观测设计

本阶段固定最小事件集:

  • phase_changed
  • progress_evaluated
  • stop_reason_decided

其中 progress_evaluated 必须显式带出:

  • HasBusinessProgress
  • HasExplorationProgress
  • NoProgressStreak
  • RepeatCycleStreak
  • SameToolSignature
  • SameResultFingerprint
  • SameSubgoal
  • StalledProgressState
  • CurrentTodoExecutor
  • HasPendingSubagentTodos
  • HasInlineSubAgentRunning

本阶段不重做全部 subagent 事件,但 runtime 主事件必须能表达 dispatch/subagent 对 completion 和 progress 的影响。

3) 一次性交付清单(What)

基于上述控制面设计,本阶段一次性交付以下内容:

  1. 状态机与 gate 收敛
  • 固化 RunState
  • 落地状态迁移表
  • 固化 PermissionGate -> CompletionGate -> ProgressGate -> StopReasonResolver
  1. Completion 语义收敛
  • 实装 CompletionState
  • 将 completion 改成顺序 todo + inline subagent 感知
  • 移除 “本轮无 tool call == completed” 的直接分支
  1. Progress 语义收敛
  • 扩展 ProgressEvidence
  • 落地证据分级
  • 落地 ProgressScore
  • 引入 stalled 软纠偏
  • STOP_NO_PROGRESS / STOP_REPEAT_CYCLE 从本阶段最终 stop reason 中移除
  1. Dispatch / subagent 接入控制面
  • todo.executor 纳入 completion / progress 判定
  • spawn_subagent(mode=inline) 正式写入 Dispatch 语义
  • 将 dispatch/subagent 结果作为结构化证据进入 progress 计算
  1. 事件与消费侧对齐
  • 补齐 phase_changed / progress_evaluated / stop_reason_decided
  • TUI 改为消费新的 progress/stalled/dispatch 观测字段

4) 验收模型(DoD)

统一按三类验收:

  1. 正常路径
  • assistant 无 tool call,但仍有 pending agent todo,不应 completed
  • assistant 无 tool call,但仍有 pending subagent todo,不应 completed
  • inline subagent 已 dispatch 但尚未回灌完成,不应 completed
  • 纯读取/检索型执行结束后,无 pending todo 且不需要 verify,可 completed
  • Dispatch 成功消费 inline subagent 结果后,允许继续进入 Verify 或返回 Plan
  1. 异常路径
  • 重复工具签名但结果不同,不应推动 repeat-cycle
  • 重复工具签名且结果相同,但 SameSubgoal=unknown 时,不应推动 repeat-cycle
  • 重复工具签名且结果相同、子目标相同、无业务进展时,首次达到阈值只进入 stalled,不 hard stop
  • exploration 只在 phase 宽容窗口内起缓冲作用,超过窗口后开始累计 NoProgressStreak
  • 同一 turn 最终只允许一个硬 stop result
  1. 恢复/一致性路径
  • 已有 session/todo 读取路径在接入新控制面后不应丢失 executor 语义
  • phase_changed / progress_evaluated / stop_reason_decided 事件字段在恢复已有会话后仍保持结构一致
  • 本阶段虽不引入 ledger/resume,但不得破坏后续 resume 对 phase/todo/progress 的接入前提

5) 非目标(明确边界)

  1. 不做动态 token 预算。
  2. 不做 RunLedger / ResumeCheckpoint
  3. 不做 secret 延迟解析。
  4. 不做 internal/instructionsinternal/repository 分层。
  5. 不做通用 DAG 调度产品语义。
  6. 不把 no-progress / repeat-cycle 重新做回硬 stop。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions