Files
Contious/DESIGN_DECISIONS.md
2026-06-09 00:41:55 +08:00

25 KiB
Raw Blame History

人机协作 Agent 原型 —— 设计决策记录

本文档汇总所有已确认的设计决策及决策原因,供后续开发参考。文档中标记【已确认】的条目为当前共识,标记【待验证】的条目为假设性设计,需通过原型验证。


1. 核心哲学

1.1 任务没有"完成",只有"挂起"【已确认】

决策:系统状态机中删除 Completed 状态,任务生命周期以 Suspended(挂起)为终态。

原因

  • LLM 天然倾向于"给出一个答案就结束",这种"完成幻觉"是质量失控的根源。
  • "挂起"意味着"本次推进暂停,保留随时重启和重新审视的权利",符合工程现实中"代码写完只是开始"的真理。
  • 与后续"评审会"机制天然配合:任务只有经过评审会才能从"执行中"进入"挂起",没有 shortcut。

1.2 "废弃"是"挂起"的子集【已确认】

决策:分支的"废弃"不作为一种独立终态,而是挂起状态上的一个标签(abandoned: true)。

原因

  • AI 无权宣告任何东西"死亡",只能宣告"我推不动了"。
  • 人类可能在事后发现被废弃的分支其实有 salvage value保留挂起状态便于回溯和复活。

2. 角色与权限体系

2.1 角色清单【已确认】

角色 职责 当前权限 未来可扩展权限
产品经理 Agent 接收人类原始需求,转化为结构化需求规格,组织需求对齐评审 需求结构化、需求版本管理、需求对齐评审主持
产品 Agent 根据需求规格写代码 编码、请求知识支援、声明挂起
测试 Agent 根据需求规格写测试、运行测试 测试生成、测试执行、标记技术性挂起
Supervisor / 知识库 Agent 处理认知型挂起,查资料补信息 知识查询、信息注入、有限次数的自动重试 技术性/风险性挂起的审批、分支生死判决
人类Supervisory Agent 最高决策者 完整权限:加入任意组、使用任意工具、审批任意挂起、调整策略配置

原因

  • 将人类建模为"权限最高的 Agent"而非系统外的"上帝视角",使通信模型和工具层完全统一。
  • 团队成员可以被赋予不同等级的 Supervisory 权限(例如初级成员只能审认知型挂起,资深成员可以审风险型)。

2.2 信息隔离原则【已确认】

决策:产品 Agent 和测试 Agent 互为黑盒。

  • 产品 Agent 的工作区对测试 Agent 不可见。
  • 测试 Agent 的工作区对产品 Agent 不可见。
  • 两者唯一的共享 ground truth 是需求规格

原因

  • 避免测试 Agent 根据实现细节写测试(即避免"测试看了代码后只测已经存在的逻辑")。
  • 迫使测试 Agent 真正从需求出发设计用例,提升测试的有效性。
  • 模拟真实工程中"测试团队独立于开发团队"的组织约束。

2.3 Supervisor 的渐进式放权【已确认】

决策Supervisor 当前仅处理"认知型挂起"(查资料、补信息、尝试修复)。其他挂起类型和分支生死权暂不开放,但架构上预留配置开关。

原因

  • 当前 LLM 的可靠性不足以承担广泛的决策权,先从"信息检索"这种低风险的职责开始验证。
  • 通过实际运行数据观察 Supervisor 的表现,逐步解锁权限,避免"一次性给权后无法收回"的困境。

3. 通信与路由

3.1 中央路由架构【已确认】

决策:所有 Agent 之间的通信必须经过中央路由Central Router禁止点对点直连。

原因

  • 解耦 Agent 之间的直接依赖,新增或替换 Agent 无需修改其他 Agent 的代码。
  • 为未来的"AI 控制路由策略"预留空间:当前路由规则用代码写死,未来可让大模型根据上下文动态决定消息转发路径。
  • 便于实现日志、审计、权限控制(路由层可以统一做"谁可以看什么"的过滤)。

3.2 消息只带元数据【已确认】

决策:消息 payload 中不包含完整上下文(如代码内容),只包含引用 ID如快照 ID、文件路径、行号范围。接收方通过快照系统按需拉取。

原因

  • 减少消息体积,避免广播时网络/内存爆炸。
  • 权限控制更精细:接收方能否看到内容,由快照系统的权限层决定,而不是由发送方在消息里"塞什么"决定。
  • 便于实现"事后回放":消息是轻量的,但可以通过引用 ID 还原当时的完整上下文。

3.3 三种通信模式【已确认】

决策:工作台支持以下通信原语:

  1. 点对点P2PAgent A → Agent B
  2. 点对组P2GroupAgent A → 任意多方组成的临时组
  3. 组内广播Group Broadcast:组内所有成员收到同一条消息

原因

  • 评审会的本质就是"创建一个临时组并广播"。
  • 人类可能和同事组成一个"审核小组"共同审 AI 的产出,需要组的概念。
  • 组的成员是动态划定的,不是预设固定角色,保证灵活性。

4. 分支与执行策略

4.1 编码阶段禁止分支【已确认】

决策:产品 Agent 在编码/实现阶段必须线性推进,不允许开分支探索多种实现方案。

原因

  • 防止开发过程中的"选择困难症"和过度设计。
  • 强制聚焦:先把一条路走到底,问题在测试阶段暴露,而不是在编码阶段纠结。

4.2 测试阶段才允许开分支【已确认】

决策:只有在测试发现问题后,才允许针对"如何修复这个问题"开多条分支并行探索。

原因

  • 分支的目的是"修复验证",不是"方案选型"。
  • 避免无意义的方案爆炸:没有测试反馈的分支探索是盲目的。

4.3 BFS 并行 + 分支挂起通知【已确认】

决策多条修复分支以广度优先BFS方式并行运行。任何一个分支挂起时立即产生通知。当所有分支都挂起时,强制触发评审会。

原因

  • BFS 保证"先广后深",人类可以快速看到"有哪些修复路线可走",而不是在一条路上钻太深。
  • "所有分支挂起 = 会议迫在眉睫"是一个穷尽性触发条件:不是"AI 觉得不行",而是"所有能试的路都试过了,全走不通"。
  • 避免人类被淹没在"每个小错误都要来问我"的噪音中。

4.4 分支 = 上下文 Fork【已确认】

决策:开一个分支等价于 fork 该 Agent 当前的完整上下文(推理历史、工作区状态),在此基础上继续推理。

原因

  • 保证分支之间的完全隔离:分支 A 的尝试不会污染分支 B 的上下文。
  • 便于实现树状可视化:每个节点都可以回溯到根,看到完整的思考链。
  • 与快照系统天然配合fork 操作本质上就是创建一个基于父快照的新快照。

4.5 分叉原因强制记录【已确认】

决策在工具层面强制要求Agent 创建分叉时必须提供结构化原因说明,否则工作台系统拒绝接受该分叉请求。

原因模板

观察到了 [现象/测试结果]
进行了 [已尝试的修复/验证]
[或] 觉得可能是因为 [假设根因]
于是进行 [新的尝试方向]。

原因

  • 防止 Agent 随意开分支导致爆炸:"写明原因"本身就是一道门槛,迫使 Agent 在分叉前做初步分析。
  • 人类在树状图上查看分叉节点时,能立刻理解"为什么在这里分了叉",无需深入代码 diff。
  • 为后续的评审会提供上下文:评审会上可以直接追问"你当时假设根因是 X现在验证结果如何"

5. 开发阶段Todo 系统

5.0 开发阶段用 Todo 而非分支【已确认】

决策:在编码/开发阶段(非查错阶段),产品 Agent 不通过分叉来管理注意力,而是通过Todo List来规划线性开发步骤:

  • 先实现模块 A
  • 再实现模块 B
  • 最后集成测试

只有在测试发现问题后的修复阶段,才启用分叉机制进行多路径探索。

原因

  • 开发阶段需要的是"有序推进"而不是"并行尝试":写代码时开分支探索"多种写法"是过度设计。
  • Todo List 提供可追踪的进度感:人类可以随时查看"AI 做到哪一步了,下一步计划做什么"。
  • 与"编码阶段禁止分支"4.1)的原则对齐:开发是线性的,试错才分叉。

5.0.1 Todo 项的状态流转

TODO → DOING → DONE
         ↓
      BLOCKED遇到阻碍可能触发挂起或 Supervisor 介入)

6. 需求规格与版本链

6.1 需求是线性版本链,不是树【已确认】

决策:需求以线性版本链管理,新版本取代旧版本,需求本身不允许分叉

  • 需求版本:v1 → v2 → v3 → ...
  • 旧版本发布新版本后自动标记为 SUPERSEDED(已被替代),不再是有效需求。
  • 需求没有回退能力:如果要"改回原来的决策",必须发布一个新的需求版本(如 v4 的内容回到 v2 的决策),而不是回退到 v2。

原因

  • 需求分叉会导致代码管理噩梦:分叉后的代码独立演化,最终变成两个完全不同的项目。
  • 线性版本链保证"同一时刻只有一个有效需求",避免多方对"到底要做什么"产生分歧。
  • 历史仍然保留(所有旧版本可读),只是不允许重新激活旧版本。

6.2 需求规格可以被挂起【已确认】

决策:需求规格本身也纳入挂起模型。当产品 Agent 和测试 Agent 对需求规格的理解不一致,或人类认为需求规格需要修改时,需求规格进入挂起状态

原因

  • 统一挂起模型:代码分支会挂起,需求规格也会挂起,所有挂起对象都走同一套评审会流程。
  • 防止在错误的需求基础上继续投入:需求不对齐时,强行推进编码和测试是浪费。

6.3 产品经理工作空间与 Agent 使用同一套快照系统【已确认】

决策:产品经理 Agent 的工作空间(维护项目文档:需求、概要设计、详细设计、接口契约等)与产品/测试 Agent 的工作空间使用完全相同的快照系统。唯一的区别是:产品经理 Agent没有分叉权

原因

  • 需求文档不需要分叉探索:需求是线性演进的,不存在"尝试两种不同需求规格并行推进"的场景。
  • 统一技术栈降低复杂度:不需要为文档维护一套独立的版本系统。

6.4 需求对齐评审会与修复评审会本质相同【已确认】

决策:不存在独立的"需求对齐评审会"类型。需求对齐不通过导致的需求规格挂起,与代码分支挂起一样,都进入统一的评审会处理。

评审会对挂起对象的决策选项通用:

  • 给新提示词继续RESUME_WITH_PROMPT):对需求规格,意味着澄清后重新对齐;对代码分支,意味着注入新思路继续修复。
  • 直接 killABANDON):对需求规格,意味着废弃当前版本重新撰写;对代码分支,意味着废弃该修复路线。
  • 发布新版本ADJUST_REQUIREMENT):仅适用于需求规格,发布新版本后所有基于旧需求的代码分支标记为 STALE_REQUIREMENT

原因

  • 评审会的本质是"对挂起节点的决策",不应该因为挂起对象的类型不同而设计两套流程。
  • 统一模型降低系统复杂度,人类也只需要学习一种评审交互模式。

7. Agent 决策模型与身份牌

7.0 每个 Agent 绑定决策模型【已确认】

决策:每个 Agent 在注册时必须绑定一个身份牌Role Card,身份牌定义了:

  • 该 Agent 的决策模式(如何规划工作、何时分叉、何时挂起)。
  • 该 Agent 可用的工具集合。
  • 该 Agent 的工作区操作权限(读/写/执行的范围)。

原因

  • 不同角色的 Agent 需要不同的行为逻辑:产品 Agent 适合"产品开发型"决策(先做设计再编码),测试 Agent 适合"验证型"决策(先分析需求再生成测试)。
  • 未来可以扩展新角色(如"安全审计 Agent"、"文档生成 Agent"),只需发放新的身份牌,无需改核心架构。
  • 身份牌让系统的行为可预测、可配置:人类可以通过调整身份牌参数来改变 Agent 的行为倾向(如"更激进地尝试修复"或"更保守地尽早挂起")。

8. 挂起机制

8.1 挂起类型分类【已确认】

决策:挂起分为三类,每类有不同的默认策略和处理路径:

类型 定义 默认策略 处理路径
技术性挂起 测试失败、编译错误、运行时异常 允许 直接通知,等待评审
认知性挂起 AI 不确定、缺少关键信息、触及能力边界 默认禁止 先走 Supervisor查知识库有尝试上限超上限后升级为真正挂起
风险性挂起 改动影响面广、具有破坏性、不可逆操作 允许 直接通知,等待评审

原因

  • 认知性挂起默认禁止,是为了逼 AI 在喊停之前尽可能收集信息、尝试推理,而不是轻易放弃。
  • 风险性挂起始终允许,因为这是安全底线,不能为了"推进"而掩盖风险。
  • 分类让人类在树状图上一眼看出"为什么停了"。

8.2 认知性挂起的出口Supervisor 介入【已确认】

决策:当认知性挂起被策略允许(或被强制触发)时,不直接叫人类,而是先由 Supervisor 尝试解决:

  1. Supervisor 分析问题,查询知识库。
  2. Supervisor 通过消息注入或关键词注入给产品 Agent 补充信息。
  3. 产品 Agent 基于新信息继续尝试。
  4. 设尝试上限(如 3 次),超上限后进入真正挂起(通知人类或进评审会)。

原因

  • 大量认知型问题其实可以通过补文档、补上下文解决,不需要消耗人类注意力。
  • 尝试上限防止 Supervisor 在知识盲区里无限循环。

8.3 挂起策略可配置【已确认】

决策:人类可以通过 UI 为每个任务配置"允许哪些挂起类型"。

原因

  • 不同任务对"容忍度"的要求不同:写排序算法时认知性挂起应严格禁止;做探索性研究时可以放开。
  • 配置粒度跟随任务,而非全局统一,保证灵活性。

8.4 "小挂起":执行时环境阻塞【已确认】

决策:当 Agent 执行命令时被操作系统层面拒绝(如 Permission deniedEACCES、需要 sudo、需要交互式密码输入等),系统触发小挂起(执行时阻塞),不走挂起状态机

处理流程

  1. Agent 调用工具(如 run_command)。
  2. 工具层执行命令,操作系统返回权限错误。
  3. 工具层将错误上报给 Agent 推理层,而是直接向中央路由发送 PERMISSION_REQUEST
  4. 人类收到通知,选择帮助 Agent 完成操作(如输入 sudo 密码、修改文件权限等)。
  5. 人类完成后,工具层重新执行命令。
  6. Agent 继续运行,状态保持 RUNNING不创建快照,不进评审会

与"大挂起"的核心区别

维度 小挂起(环境阻塞) 大挂起(状态挂起)
触发原因 操作系统权限不足 AI 遇到认知/技术边界
触发层 工具层 Agent 推理层
Agent 状态 保持 RUNNING被工具阻塞 变为 SUSPENDED
是否快照
是否进树
人类动作 帮 AI 完成操作(输入密码等) 做决策(评审会)
是否可记忆 是(记住本次授权)

原因

  • 这不是 AI 的决策问题是客观环境限制AI 的代码逻辑没错,只是系统不给它跑。
  • 如果走评审会,人类被频繁拉入无意义的会议:输入 sudo 密码不需要"开会讨论"。
  • 工具层有强制执行力:操作系统说 Permission denied,不需要 prompt 来定义什么是小挂起。

9. 快照与存档

9.1 快照只在决策节点创建【已确认】

决策:快照不是在 Agent 运行的每一步都创建,而只在两类决策节点创建:

  1. 分叉点Fork:开新分支时,必须快照当前完整上下文作为新分支的起点。
  2. 挂起点Suspend:任务/分支挂起时,必须快照当前状态以便后续恢复或回溯。

中间过程编码、测试执行、Supervisor 查资料)不创建快照。

原因

  • 避免快照数量爆炸导致树状图变成"毛线团"。
  • 快照的语义是"决策里程碑",不是"运行日志":人类只关心"AI 在哪做了选择"和"AI 在哪停了下来"。
  • 大幅降低存储和索引压力,让回溯操作保持轻量。

9.2 存档范围:工作过程 + 评审会【已确认】

决策:以下两类内容必须进入存档:

  1. 工作过程快照代码状态、测试状态、Agent 上下文。
  2. 评审会完整记录:谁参与了、展示了什么、讨论了什么问题、人类的批注和最终决策。

原因

  • 工作过程存档支持回溯和分支复活。
  • 评审会存档支持"为什么当时做这个决策"的长期追溯,避免"当时怎么想的忘了"的维护噩梦。

9.3 快照树节点类型【已确认】

决策:快照树中的节点按语义分为两类:

  • 分叉节点Fork Node:新分支的起点,标志着"AI 在这里做了一个选择,走了另一条路"。
  • 挂起节点Suspend Node:任务/分支暂停的断点,标志着"AI 在这里停下来了,需要外部输入"。

中间运行状态不出现在快照树中。

原因

  • 保持树的稀疏性和语义清晰度:人类一眼看到的是"决策-困境"地图。
  • 与"只在决策节点快照"的原则对齐。

9.4 平级链:节点的操作历史附录【已确认】

决策:每个主树节点(分叉节点或挂起节点)可以挂载一条平级链Side Chain,记录到达该节点之前的所有中间操作快照。

  • 平级链上的快照不参与树的拓扑结构:它们不改变主树的分叉/挂起语义,只是该节点的历史附件。
  • 平级链内容:危险操作前备份、开发阶段中间状态、挂起被打回后的重试记录等。
  • 挂起被打回时的处理:原挂起节点的快照被挂载到"下一个推演起点"的平级链头部,作为历史上下文保留。

示例

节点 N挂起节点
├── 主树上下文:父节点 → 分叉点 F → ... → 根
└── 平级链Side Chain
    ├── 快照 attempt-1挂起被打回后的第一次重试
    ├── 快照 pre-danger-2危险操作前删除旧缓存
    └── 快照 pre-danger-1危险操作前编译产物写入

原因

  • 主树保持稀疏和清晰:人类一眼看到的是"决策-困境"地图,不被中间操作淹没。
  • 审计需求得到满足:当需要追溯"AI 是怎么走到这一步的"时,平级链提供了完整的操作日志。
  • 挂起被打回的历史不被丢弃:每次尝试都保留在平级链上,便于后续分析"为什么这次重试成功了/失败了"。

9.5 树状快照组织【已确认】

决策:快照以树状结构组织,支持以下操作:

  • 查看任意节点的完整思考链(从根到该节点)。
  • 查看任意节点的平级链(该节点的操作历史附录)。
  • 对比两个分叉节点的差异(从分叉点开始的不同路径)。
  • 快速回溯到任意历史节点。

原因

  • 人类需要理解"AI 是怎么走到这一步的",线性日志无法满足。
  • 分叉对比是评估不同修复方案的核心交互。

10. 可视化与交互

10.1 树状图:核心诊断面板【已确认】

决策:工作台提供树状图可视化,作为人类观察 AI 思维过程的主要界面

核心交互

  • 每个节点代表一个快照/决策点。
  • 点击节点:展示从根到该节点的完整思考链。
  • 点击两个不同节点:展示从分叉点开始的差异对比。
  • 挂起节点用颜色/图标标识其类型(技术/认知/风险)。
  • 点击挂起节点:查看挂起原因、相关日志、建议的修复方案。

原因

  • 人类不是在看"AI 的输出结果",而是在看"AI 的推理过程"。树状图是这个过程的最佳映射。
  • 颜色编码让"哪里卡住了"一目了然。

10.2 模块关系图 + 接口查看【已确认】

决策:在评审会或逐模块阐释时,提供模块关系图(方框表示模块,连线表示接口依赖)。点击连线可查看接口的具体定义。

原因

  • 评审会上的"逐模块阐释"需要直观的拓扑视图,而不是堆砌文本。
  • 接口是模块契约的核心,需要可点击穿透的详情展示。

11. 评审会

11.1 评审会是强制关卡【已确认】

决策:评审会是任务推进的必经关卡。触发条件:

  • 所有分支都挂起时,强制触发评审会(不可跳过)。
  • 需求规格挂起时,强制触发评审会(需求对齐不通过)。
  • 人类可手动随时触发评审会(即使还有分支在运行)。

原因

  • "所有分支挂起"是穷尽性信号AI 已经尝试了所有能试的路线,必须引入人类判断。
  • "需求规格挂起"是早期拦截信号:防止在错误理解的需求上继续投入。
  • 手动触发保留人类的主动干预权。

11.2 评审会在临时工作区中进行【已确认】

决策:评审会期间,人类或 Agent 对代码的任何修改只能在工作台分配的临时工作区中进行,不允许直接写入项目主干或任何活跃分支的工作区

原因

  • 评审会是"审查和讨论"的场所,不是"直接修改生产环境"的场所。
  • 防止会议期间的"随手改"污染正式工作区,保证快照树的纯净性。
  • 只有经过显式决策的结论(如"批准分支 B 继续"、"给分支 C 注入新提示词")才会被工作台作为系统指令下发执行。

11.3 评审会结果是操作挂起对象【已确认】

决策:评审会不产生直接代码修改,只产生对挂起对象的操作指令。挂起对象可以是代码分支,也可以是需求规格,决策选项通用:

决策指令 对代码分支的含义 对需求规格的含义
ABANDON 废弃该修复分支 废弃当前需求版本,重新撰写
RESUME_WITH_PROMPT 给分支注入新提示词继续修复 澄清需求后重新组织对齐评审
FORK 基于某快照开新分支尝试 不适用
ADJUST_REQUIREMENT 发布新需求版本,当前分支标记为基于旧需求 发布新版本需求规格

原因

  • 把"审查"和"执行"分离:评审会负责"决定做什么",分支管理引擎/产品经理负责"实际去做"。
  • 所有操作都可追溯、可回滚,符合快照系统的树状语义。
  • 统一模型降低认知负担:人类无论审代码还是审需求,交互模式相同。

11.4 评审会记录独立存储【已确认】

决策:评审会的完整会议记录不属于快照节点系统,而是作为独立存档存储。会议记录通过 trigger_snapshot_id 字段关联到导致评审会的挂起节点,但本身不成为树节点。

原因

  • 快照树只反映 Agent 实际推进过的代码状态,评审会的临时改动和讨论不应出现在树上。
  • 人类可以通过点击挂起节点查看关联的会议记录(像查看"附件"),但会议记录不参与树的拓扑计算。
  • 保持树的语义纯粹:节点 = 代码状态里程碑,附件 = 当时的人类决策上下文。

12. 工具层

12.1 工具对 Agent 和人类统一开放【已确认】

决策Agent 使用的所有工具(代码编辑器、测试运行器、知识库查询、快照操作等)人类也可以通过界面使用。

原因

  • 人类不是系统的旁观者,而是网络中权限最高的参与者。
  • 统一工具层避免"人类想看代码却找不到入口"的尴尬。
  • 便于人类在评审会上直接操作(如修改代码、运行测试),而不是"口头指挥 AI 去改"。

13. 待验证假设【待验证】

以下设计决策基于当前讨论形成,但需要通过原型运行验证其可行性:

  1. Supervisor 的知识库查询能否有效降低认知型挂起升级到人类的频率?

    • 假设70% 的认知型问题可以通过补文档解决。
    • 风险Supervisor 可能检索到错误信息,反而误导产品 Agent。
  2. BFS 分支并行在资源受限环境下是否可运行?

    • 假设3-5 条分支的并行在单机上可接受。
    • 风险:如果任务复杂,分支数爆炸可能导致内存/CPU 不足。
  3. 树状可视化的信息密度 humans 能否承受?

    • 假设10-20 个节点的树对人类是可读的。
    • 风险:复杂任务可能产生上百个节点,树状图变成"毛线团"。
  4. 信息隔离是否会导致测试 Agent 写出过于宽泛或过于严苛的测试?

    • 假设:基于需求写测试的质量高于基于实现写测试。
    • 风险:测试 Agent 对需求的理解偏差可能导致测试与实现永远无法对齐。

文档版本2026-06-08 状态:等待审阅