Skip to content

Workflow 大规模结果汇聚:公平 handoff、分层 Report 与动态父会话投影 #90

Description

@tt-a1i

结论

OpenPI 已经支持正确的多阶段 Workflow 结构:

discovery / scan
→ dynamic fan-out
→ verify
→ Report Agent
→ parent session

但当一个 Workflow 产生几十个 Agent 结果时,当前结果通道仍然按“小批量”设计:

  1. 多个上游结果进入 Report Agent 时,采用固定的单项/总量截断,并存在明显的顺序偏置;
  2. Workflow 最终结果进入父会话时,仍采用固定的头部截断,没有使用 fix(subagents): preserve recoverable long results #89 已验证的父上下文动态预算和 75/25 恢复投影;
  3. Report 阶段由模型显式编写是正确的,但 Runtime 还缺少让大规模汇聚可靠、可追溯的底层机制。

这不会阻止 Workflow 启动几十个 Agent,却可能让“Agent 数量扩大”只增加成本,未增加 Report Agent 真正看到的证据覆盖。

当前机制

基于 main@494f74f

Workflow 已经做对的部分

  • phase()pipeline()parallel()agent() 可以表达多阶段依赖;
  • 成功的 agent() 返回同一 Workflow 内有效的 opaque ref
  • 后续 Agent 可以通过 inputs: [ref, ...] 接收上游结论;
  • 官方示例已经展示 Scan → Verify → Report,Report 是一个真实的 Advisor Agent,而不是父会话拼接字符串;
  • 默认并发为 8、默认总调用量为 128;硬上限分别为 64 和 1024,因此 Runtime 容量不是“只能创建 3 个 Agent”的原因;
  • Workflow 有 run directory、result、transcript、journal、graph、replay 和 acceptance 证据面。

问题一:Report handoff 存在顺序偏置

extensions/workflows/handoff.ts 当前限制:

最多 64 个 refs
每个 conclusion 最多 16 KiB
一次 handoff 总计最多 48 KiB

实现顺序是:

按 refs 顺序完整拼接所有 conclusion
→ 如果超过 48 KiB
→ 从整体尾部截断

因此当几十个结果进入 Report Agent 时:

  • 排在前面的结果可以占满大部分预算;
  • 排在后面的结果可能只剩标题,甚至完全消失;
  • Report Agent 无法区分“后面没有问题”和“后面根本没有进入上下文”;
  • 调整 refs 顺序可能改变最终报告;
  • 每个结果虽然先受 16 KiB 上限约束,但没有公平共享批次预算。

这与 #89 中已经修复的 Subagent 批次问题本质相同,但目标上下文不同:这里是新 Report 子 Session 的输入,而不是父会话剩余上下文。

问题二:Workflow 最终父会话投影仍是固定头截断

extensions/workflows/model.ts 当前把脚本返回值限制为:

24 KiB / 600 lines
只保留头部
超出部分提示查看 result.json

Background Workflow 完成后,buildWorkflowResultMessage() 会把日志、Agent 状态列表和这个结果一起送入父会话,但没有:

  • 按父会话 ctx.getContextUsage() 收窄;
  • 对固定 wrapper、日志和 Agent 清单先计费;
  • 75% head + 25% tail;
  • 对整个完成消息施加统一、可证明的硬上限。

几十到上千个 Agent 的状态行也会扩大 wrapper,最终交付不再只是 24 KiB。

问题三:上游 ref 不是 exact artifact contract

当前 ref 保存的是已裁剪的 conclusion。Workflow 的 run artifacts 能保存最终 result、transcript 和 journal,但 Report Agent 没有一个明确的、可分页读取的“每个上游 Agent exact final answer”合同。

对普通结构化结论,16/48 KiB 足够;对大型审计、长测试报告或证据清单,Report Agent 无法按需深入被裁掉的上游中段。

设计原则

保留模型负责 Report 设计

不要由 Runtime 自动插入一个固定 Report Agent,也不要强制每个 Workflow 都有名为 Report 的阶段。

模型继续负责:

  • 是否需要汇总阶段;
  • 汇总层级;
  • 哪些结果需要验证;
  • 哪些结果值得继续深读;
  • 最终报告结构。

Runtime 只提供可靠机制和真实反馈。

区分两段预算

A. Workflow 内部:上游结果 → Report Agent

目标是让一个新的 Report 子 Session 公平看到批次证据。

建议:

  • 先扣除 handoff 标题、来源标签和安全说明;
  • 对所有 refs 做公平 water-filling;
  • 短结果把未使用预算让给长结果;
  • 每个 ref 保留最小可识别摘要、状态与来源;
  • 总预算可以保持 48 KiB 作为兼容默认,或根据目标 Report 模型的 context window 和基础 prompt 大小安全推导;
  • 不能再把所有结果拼接后只截尾;
  • 超过单层容量时,明确提示需要分层归并,而不是静默丢弃后半批。

这里不应直接使用“父会话剩余 headroom”,因为 Report Agent 是一个新的子 Session。

B. Workflow 最终结果 → 父会话

这里可以复用 #89 的原则:

  • 使用 Pi 权威 getContextUsage()
  • 静态上限仍是安全兜底;
  • 有有效读数时,使用父会话剩余 headroom 的一个保守比例;
  • wrapper、日志、Agent 状态清单和恢复说明全部计入预算;
  • 保留头尾和 exact artifact;
  • usage 未知时确定性回退静态上限。

支持分层 Report

对于几十或上百个工作单元,推荐的模型层模式是:

N 个执行 Agent
→ 若干局部 Report Agent
→ 1 个全局 Report Agent
→ 父会话

OpenPI 不规定 N、分组大小或层数,但应让模型知道:

  • 当前 refs 数量;
  • handoff 总预算;
  • 哪些结果被完整注入、部分投影或未注入;
  • 若一次无法公平容纳所有结果,应显式分层,而不是假装已完整汇总。

建议实现

  1. fix(subagents): preserve recoverable long results #89 的批次公平分配算法提炼为共享深模块,Subagent 与 Workflow 复用策略机制,但分别传入不同的上下文预算来源。
  2. 重写 WorkflowHandoffRegistry.renderHandoff()
    • 按 ref 分配预算;
    • 每份保留身份与截断状态;
    • 消除输入顺序导致的“后半批消失”。
  3. 为每个成功 Workflow Agent 结果建立稳定的 run-local exact artifact,ref 投影中给出可审计来源;是否允许 Report Agent读取必须继续遵守 child tool capability 和路径边界。
  4. 最终 buildWorkflowResultMessage() 使用父上下文动态投影,完整消息而非仅 result 字段受硬上限约束。
  5. 在 dashboard、workflow.json 或 diagnostics 中记录:
    • handoff refs 数;
    • 原始总 bytes;
    • 投影总 bytes;
    • 每个 ref 的预算和截断状态;
    • projection policy/source。
  6. 更新 Workflow Skill,增加 discovery → fan-out → local reports → global report 示例;规模来自任务结构,不来自固定 Agent 数。

验收标准

  • 1、4、16、40、64 个 refs 的 handoff 均不超过总预算;
  • 所有 refs 至少保留身份和明确的 included/partial/omitted 状态;
  • 大结果不会因为位于 refs 后半段而完全无声消失;
  • 同一组等价结果仅改变输入顺序,不会造成证据覆盖数量变化;
  • 短结果会把未用预算让给长结果;
  • 目标 Report Session usage/容量未知时有确定性静态回退;
  • Workflow 最终父会话消息连同 wrapper 均受硬 byte 上限约束;
  • 父会话投影保留头尾,并提供 exact result artifact;
  • 多阶段 Workflow 示例明确检查每个 .ok、统计 dropped work,并完成 Report;
  • 真实模型测试覆盖至少一次 16+ Agent fan-out → Report,不以“启动数量”代替汇总质量;
  • Benchmark 同时观察覆盖率、遗漏、重复、最终报告质量、token、wall time 和成本。

与现有 Issue/PR 的关系

推荐实施顺序仍应先保证 #71 的可靠投递,再完成 #74;本 Issue 可以并行完成确定性 handoff 算法和测试,随后与 #75 的 16+ Agent 真实 Workflow 验证合并验收。

非目标

  • 不自动强制添加 Report Agent;
  • 不规定复杂任务必须创建多少 Agent;
  • 不提高调用硬上限;
  • 不把所有原始输出直接塞进父会话;
  • 不用关键词路由替代模型判断;
  • 不因为 artifact 存在就省略清晰、可用的主报告。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions