738 lines
35 KiB
Markdown
738 lines
35 KiB
Markdown
# 人机协作 Agent 原型 —— 系统架构总览
|
||
|
||
> 本文档提供系统级的全景视图,描述各子系统的职责、边界、交互方式以及数据流动路径。阅读前建议先浏览 `DESIGN_DECISIONS.md` 了解设计动机。
|
||
|
||
---
|
||
|
||
## 1. 系统总体架构
|
||
|
||
系统由五个核心子系统构成,围绕"中央路由"呈星型拓扑:
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ 可视化与交互层 │
|
||
│ (树状图 · 模块关系图 · 评审会界面 · 配置面板) │
|
||
└─────────────────────────────────────────────────────────────┘
|
||
↑↓
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ 中央路由 (Central Router) │
|
||
│ (消息转发 · 权限过滤 · 日志审计 · 路由策略) │
|
||
└─────────────────────────────────────────────────────────────┘
|
||
↑↓
|
||
┌──────────┬──────────┼──────────┬──────────┐
|
||
↑↓ ↑↓ ↑↓ ↑↓ ↑↓
|
||
┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
|
||
│ 产品 │ │ 测试 │ │Supervisor│ │ 人类 │ │ 其他 │
|
||
│ Agent │ │ Agent │ │/知识库 │ │(Supervi-│ │ 工具 │
|
||
│ │ │ │ │ Agent │ │sory) │ │ 服务 │
|
||
└────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘
|
||
└───────────┴───────────┴───────────┴───────────┘
|
||
↑↓
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ 工作台与快照系统 │
|
||
│ (工作区隔离 · 快照管理 · 分支Fork · 树状存储 · 存档检索) │
|
||
└─────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
**设计原则**:任何两个 Agent(含人类)不直接通信,所有交互必须经过中央路由。任何 Agent 不直接操作文件系统,所有持久化必须经过工作台快照系统。
|
||
|
||
---
|
||
|
||
## 2. 核心子系统详解
|
||
|
||
### 2.1 中央路由 (Central Router)
|
||
|
||
#### 职责
|
||
- **消息转发**:根据路由规则将消息从发送方递送到接收方/组。
|
||
- **权限过滤**:在转发前检查"发送方是否有权向接收方发送此类消息"。
|
||
- **日志审计**:记录所有经过的消息元数据(不含 payload 内容,只记录谁发给谁、消息类型、时间戳、引用 ID)。
|
||
- **路由策略执行**:当前为硬编码规则,未来可替换为 LLM 动态决策。
|
||
|
||
#### 内部结构
|
||
```
|
||
Central Router
|
||
├── Inbound Queue(入站队列,所有 Agent 提交消息至此)
|
||
├── Routing Engine(路由引擎,决定消息去向)
|
||
│ └── 当前:代码规则表
|
||
│ └── 未来:LLM 策略模型
|
||
├── Permission Gate(权限门,拦截越权消息)
|
||
├── Outbound Dispatcher(出站分发器)
|
||
└── Audit Log(审计日志,只存元数据)
|
||
```
|
||
|
||
#### 消息格式(标准信封)
|
||
所有经过中央路由的消息必须遵守统一格式:
|
||
|
||
```
|
||
{
|
||
"msg_id": "uuid",
|
||
"timestamp": "ISO8601",
|
||
"from": "agent_id",
|
||
"to": "agent_id | group_id | broadcast",
|
||
"msg_type": "QUERY | RESPONSE | NOTIFY | DECISION | MEETING_CALL",
|
||
"payload_ref": "snapshot_id#object_path",
|
||
"payload_summary": "人类可读摘要(用于日志和通知)",
|
||
"session_id": "当前任务会话 ID",
|
||
"branch_id": "所属分支 ID(主干为 main)",
|
||
"priority": "LOW | NORMAL | HIGH | CRITICAL"
|
||
}
|
||
```
|
||
|
||
**注意**:`payload_ref` 指向工作台快照系统中的对象,消息本身不携带内容。接收方凭引用 ID 和自身权限向工作台申请拉取。
|
||
|
||
#### 通信模式实现
|
||
|
||
| 模式 | 路由行为 |
|
||
|------|----------|
|
||
| 点对点 | `to` 填目标 Agent ID,直接投递 |
|
||
| 点对组 | `to` 填 group_id,Router 查询组成员列表后分别投递 |
|
||
| 组内广播 | 特殊消息类型 `BROADCAST`,Router 向组内所有成员投递,并标记"同一条消息的副本"便于关联 |
|
||
|
||
---
|
||
|
||
### 2.2 工作台与快照系统 (Workbench & Snapshot System)
|
||
|
||
#### 职责
|
||
- 为每个 Agent 提供**隔离的工作区**(独立的文件系统视图)。
|
||
- 提供**快照(Snapshot)**的创建、读取、对比、回溯能力。
|
||
- 维护**树状的快照历史**(支持分支、合并、差异对比)。
|
||
- 提供**存档(Archive)**的写入和检索(工作过程存档 + 评审会存档)。
|
||
- 作为中央路由的**内容存储后端**:Agent 通过引用 ID 向工作台申请拉取内容。
|
||
|
||
#### 核心概念
|
||
|
||
**工作区(Workspace)**
|
||
- 每个 Agent 拥有一个独立工作区目录。
|
||
- 工作区之间默认不可见(文件系统级别隔离)。
|
||
- 人类(Supervisory Agent)拥有跨工作区读取权限(但写入需显式授权)。
|
||
- 工作区的"当前状态"随时可以被快照捕获。
|
||
|
||
**快照(Snapshot)**
|
||
- 快照是工作区某一时刻的只读副本。
|
||
- 快照**只在决策节点创建**:分叉点(Fork)和挂起点(Suspend)。中间运行过程不创建快照。
|
||
- 快照不可修改,只能通过"基于快照创建新工作区"来延续。
|
||
- 每个快照包含:
|
||
- 文件系统哈希树(保证完整性)
|
||
- Agent 上下文引用(推理历史 ID)
|
||
- 父快照 ID(支持回溯)
|
||
- 分支 ID(支持多线历史)
|
||
- 节点类型(`FORK` 或 `SUSPEND`)
|
||
- 创建原因(详细枚举见数据模型)
|
||
|
||
**快照树(Snapshot Tree)**
|
||
- 快照之间通过 `parent_id` 形成树结构。
|
||
- `main` 分支是主时间线。
|
||
- 树节点按语义分为两类:
|
||
- **分叉节点(Fork Node)**:新分支的起点,表示"AI 在这里做了一个选择"。
|
||
- **挂起节点(Suspend Node)**:分支暂停的断点,表示"AI 在这里停下来了"。
|
||
- **Fork 操作强制要求原因**:Agent 调用 `fork()` 时必须提供结构化原因说明(观察到的现象、假设的根因、尝试的方向),否则工作台拒绝执行。
|
||
- Fork 操作创建新分支:基于某快照创建新工作区,新工作区的首次快照是**分叉节点**,指向父快照,但携带新的 `branch_id`。
|
||
- 挂起操作在当前分支末端创建一个**挂起节点**,标记该分支进入暂停状态。
|
||
- 树节点支持以下查询:
|
||
- `trace(node_id)`:返回从根到该节点的快照链(即 AI 的完整思考链)。
|
||
- `diff(node_a, node_b)`:返回两个节点从最近公共祖先开始的差异(即分叉后的不同路径)。
|
||
- `checkout(node_id)`:基于该快照创建新工作区,供人类或 Agent 继续工作。
|
||
|
||
**平级链(Side Chain)**
|
||
- 每个主树节点可以挂载一条平级链,记录到达该节点之前的中间操作快照。
|
||
- 平级链上的快照**不参与树的拓扑结构**,只是该节点的历史附件。
|
||
- 典型内容:危险操作前备份、开发阶段中间状态、挂起被打回后的重试记录。
|
||
- 挂起被打回时:原挂起节点的快照被挂载到"下一个推演起点"的平级链头部。
|
||
- 查询:`side_chain(node_id)` 返回该节点的平级链快照列表(按时间倒序)。
|
||
|
||
**存档(Archive)**
|
||
- 存档是"业务事件"的持久化记录,与快照(技术状态)分离存储。
|
||
- 两类存档:
|
||
1. **工作存档**:每次快照创建时的原因、触发者、关联的消息 ID 列表。
|
||
2. **评审会存档**:评审会的完整记录(见 2.5 节)。
|
||
- 存档支持按 `session_id`、`branch_id`、`timestamp`、`event_type` 检索。
|
||
|
||
#### 数据模型
|
||
|
||
```
|
||
Session(任务会话)
|
||
├── session_id: UUID
|
||
├── requirement: 原始需求文本(人类输入)
|
||
├── current_req_version_id: 当前有效需求版本 ID
|
||
├── strategy_config: 挂起策略配置(允许哪些挂起类型)
|
||
├── supervisor_permissions: Supervisor 当前解锁的权限列表
|
||
├── status: ACTIVE | SUSPENDED | ABORTED
|
||
├── root_snapshot_id: 初始快照
|
||
├── current_main_snapshot_id: main 分支最新快照
|
||
├── branch_registry: { branch_id → { parent_snapshot_id, status, owner_agent_id } }
|
||
└── meeting_history: [meeting_id, ...]
|
||
|
||
RequirementSnapshot(需求版本)
|
||
├── req_version_id: UUID
|
||
├── session_id: 所属会话
|
||
├── version_number: 整数版本号(v1, v2, v3...)
|
||
├── parent_version_id: 父版本(v1 为 null)
|
||
├── content: 结构化需求规格
|
||
│ ├── 功能描述
|
||
│ ├── 验收标准
|
||
│ ├── 边界条件
|
||
│ └── 已知歧义点
|
||
├── status: DRAFT | ACTIVE | SUPERSEDED | SUSPENDED
|
||
├── created_by: 创建者 Agent ID(产品经理或人类)
|
||
├── created_at: 时间戳
|
||
└── code_snapshots_based_on: [snapshot_id, ...] // 基于该需求的代码快照列表
|
||
|
||
Snapshot
|
||
├── snapshot_id: UUID
|
||
├── session_id: 所属会话
|
||
├── branch_id: 所属分支
|
||
├── parent_snapshot_id: 父快照(根节点为 null,平级链快照为 null)
|
||
├── node_type: 节点类型枚举
|
||
│ └── FORK(分叉节点)| SUSPEND(挂起节点)| SIDECHAIN(平级链节点)
|
||
├── is_sidechain: bool // 是否为平级链快照(不参与主树拓扑)
|
||
├── attached_to: Option<snapshot_id> // 平级链快照挂载在哪个主树节点上
|
||
├── created_by: 创建者 Agent ID
|
||
├── created_at: 时间戳
|
||
├── reason: 创建原因枚举
|
||
│ └── FORK_BRANCH(开新分支)| SUSPEND_TECHNICAL(技术性挂起)
|
||
│ SUSPEND_COGNITIVE(认知性挂起)| SUSPEND_RISK(风险性挂起)
|
||
│ SUSPEND_ALL_BRANCHES(所有分支挂起触发评审会)
|
||
│ PRE_DANGER(危险操作前备份)| ATTEMPT_RETRY(挂起被打回后的重试)
|
||
├── filesystem_hash: 文件系统 Merkle Tree 根哈希
|
||
├── context_ref: Agent 上下文存储位置
|
||
└── tags: [废弃标记等]
|
||
|
||
ArchiveEntry
|
||
├── archive_id: UUID
|
||
├── session_id: 所属会话
|
||
├── snapshot_id: 关联快照(可选)
|
||
├── event_type: WORK | MEETING | DECISION
|
||
├── content: 事件详情(JSON)
|
||
└── searchable_text: 用于全文检索的文本摘要
|
||
```
|
||
|
||
---
|
||
|
||
### 2.3 Agent 运行时
|
||
|
||
#### 产品 Agent (Product Agent)
|
||
|
||
**生命周期状态**:
|
||
```
|
||
IDLE → PLANNING → CODING → TESTING → REVIEWING → SUSPENDED
|
||
```
|
||
|
||
- **PLANNING**:基于需求生成实现方案(不允许分支,单线程)。生成**Todo List**作为开发路线图。
|
||
- **CODING**:按 Todo List 线性推进,逐项完成。Todo 项状态流转:`TODO → DOING → DONE`。遇到阻碍时可标记为 `BLOCKED`。
|
||
- 此阶段**禁止分叉**:即使遇到多种实现思路,也必须先选一条路走到底。
|
||
- 遇到危险操作前通知工作台创建快照(但开发阶段的快照**不进入**快照树,只作为工作区备份)。
|
||
- **TESTING**:将代码提交给测试 Agent(通过中央路由发送测试请求,附带代码快照引用)。等待测试结果。
|
||
- **REVIEWING**:测试返回结果后,分析是否通过。
|
||
- 通过:请求进入评审会(挂起)。
|
||
- 未通过:**进入修复阶段**,此时允许开分支探索多种修复方案(必须提供分叉原因)。
|
||
- **SUSPENDED**:任务挂起,等待外部事件。
|
||
|
||
**输出物**:
|
||
- 代码文件(在工作区中)。
|
||
- Todo List(开发路线图,供人类查看进度)。
|
||
- 模块关系图描述(用于可视化)。
|
||
- 逐模块阐释文本(用于评审会)。
|
||
|
||
#### 测试 Agent (Test Agent)
|
||
|
||
**生命周期状态**:
|
||
```
|
||
IDLE → RECEIVING_REQ → ANALYZING → GENERATING_TESTS → EXECUTING → REPORTING → SUSPENDED
|
||
```
|
||
|
||
- **RECEIVING_REQ**:通过中央路由接收测试请求。
|
||
- **ANALYZING**:只读取需求规格(不读产品代码),分析测试点。
|
||
- **GENERATING_TESTS**:基于需求写测试用例和测试代码。
|
||
- **EXECUTING**:运行测试(在自己的工作区中,可能需要向工作台申请"基于产品快照创建只读副本"来运行,但不读取内容只执行)。
|
||
- **REPORTING**:生成测试报告,通过中央路由发送给产品 Agent 和人类。
|
||
- **SUSPENDED**:等待下一个测试请求。
|
||
|
||
**关键约束**:
|
||
- 测试 Agent 的工作区对代码内容的访问是"盲执行":它可以运行编译和测试命令,但设计上不能"阅读"源代码的逻辑(通过工具链限制实现,如只提供编译后的二进制或接口定义)。
|
||
- 如果测试需要接口定义,由产品 Agent 在提交测试请求时单独提供接口契约文件(`interface.json` 等),不包含实现细节。
|
||
|
||
#### Supervisor / 知识库 Agent
|
||
|
||
**生命周期状态**:
|
||
```
|
||
IDLE → RECEIVING_QUERY → ANALYZING → RETRIEVING → INJECTING → FOLLOWUP → SUSPENDED
|
||
```
|
||
|
||
- **RECEIVING_QUERY**:通过中央路由接收认知型支援请求。
|
||
- **ANALYZING**:分析问题类型(缺文档?缺上下文?缺业务规则?)。
|
||
- **RETRIEVING**:查询知识库(本地文档、历史存档、外部资源等)。
|
||
- **INJECTING**:将检索到的信息通过消息发送回请求方。
|
||
- **FOLLOWUP**:记录本次支援的尝试次数。如果同一问题被多次查询且超上限,升级通知。
|
||
- **SUSPENDED**:等待下一个查询。
|
||
|
||
**权限边界**:
|
||
- 当前:只能响应 `COGNITIVE_SUPPORT` 类型的请求。
|
||
- 未来可解锁:`TECHNICAL_APPROVAL`、`RISK_APPROVAL`、`BRANCH_LIFE_DECISION` 等。
|
||
|
||
#### 产品经理 Agent (PM Agent)
|
||
|
||
**生命周期状态**:
|
||
```
|
||
IDLE → RECEIVING_REQ → STRUCTURING → REVIEWING → SUSPENDED
|
||
```
|
||
|
||
- **RECEIVING_REQ**:接收人类的原始需求(可能是一句模糊的话)。
|
||
- **STRUCTURING**:将原始需求转化为结构化需求规格(功能描述、验收标准、边界条件、已知歧义点)。
|
||
- **REVIEWING**:组织需求对齐评审会,确认产品 Agent 和测试 Agent 对需求的理解一致。
|
||
- 对齐通过:需求规格标记为 `ACTIVE`,进入编码阶段。
|
||
- 对齐不通过:需求规格**挂起**(走统一评审会流程)。
|
||
- **SUSPENDED**:等待人类反馈或新需求输入。
|
||
|
||
**工作空间**:
|
||
- 与产品/测试 Agent 使用同一套快照系统,但**没有分叉权**。
|
||
- 维护内容:原始需求、需求规格 v1/v2/v3...、概要设计、详细设计、接口契约定义。
|
||
|
||
#### 人类 (Supervisory Agent)
|
||
|
||
**特殊之处**:
|
||
- 在系统中以特殊 Agent ID(如 `human://user_id`)注册。
|
||
- 权限列表为 `ALL`,但实际操作受前端 UI 的显式确认保护(防止误触)。
|
||
- 可以加入任意组,可以接收所有类型的通知。
|
||
- 可以通过可视化界面直接操作工具(如打开编辑器修改代码、运行测试、创建快照)。
|
||
- 操作同样经过中央路由(人类的前端视为一个 Agent 客户端),确保所有操作可追溯。
|
||
- **小挂起响应**:当工具层发送 `PERMISSION_REQUEST` 时,人类可以直接在通知栏输入密码或点击授权,不需要进入评审会。
|
||
|
||
---
|
||
|
||
### 2.4 分支管理引擎
|
||
|
||
#### 职责
|
||
- 管理分支的生命周期:创建、运行、监控、挂起、废弃。
|
||
- 执行 BFS 调度:并行推进多条活跃分支,收集各分支状态。
|
||
- 触发全局事件:当所有活跃分支都挂起时,向中央路由发送 `ALL_BRANCHES_SUSPENDED` 事件。
|
||
|
||
#### 分支状态机
|
||
```
|
||
CREATED → RUNNING → SUSPENDED ──→ ABANDONED(由人类在评审会上标记)
|
||
↑ │ │
|
||
└─────────┴─────────┘(人类或 Supervisor 决策后可恢复为 RUNNING)
|
||
```
|
||
|
||
#### BFS 调度逻辑
|
||
```
|
||
while 存在 RUNNING 分支:
|
||
for 每个 RUNNING 分支:
|
||
推进一步(执行一个 Agent 动作或等待外部响应)
|
||
if 分支挂起:
|
||
发送分支挂起通知
|
||
if 所有分支都 SUSPENDED:
|
||
发送 ALL_BRANCHES_SUSPENDED 事件
|
||
触发评审会
|
||
break
|
||
```
|
||
|
||
**注意**:"推进一步"的粒度是可配置的。可以是"一个 LLM 调用",也可以是"一个完整的测试周期"。MVP 阶段建议以"一个完整的修复-测试循环"为一步。
|
||
|
||
---
|
||
|
||
### 2.5 评审会系统 (Meeting System)
|
||
|
||
#### 职责
|
||
- 组织评审会议程。
|
||
- 收集并展示评审材料(模块关系图、接口定义、测试报告、逐模块阐释)。
|
||
- 记录完整会议过程。
|
||
- 将会议结论转化为系统动作(恢复分支、废弃分支、调整策略、修改需求等)。
|
||
|
||
#### 评审会触发条件
|
||
1. **强制触发(代码穷尽)**:所有代码分支都挂起时,系统自动创建评审会。
|
||
2. **强制触发(需求挂起)**:需求规格被标记为挂起(需求对齐不通过)时,系统自动创建评审会。
|
||
3. **手动触发**:人类在任意时刻通过 UI 发起。
|
||
4. **定时触发**:某条分支挂起超过设定时间未处理,系统提醒人类"是否开会"。
|
||
|
||
#### 评审会流程
|
||
```
|
||
1. 创建会议(生成 meeting_id,创建会议组,邀请相关 Agent 和人类)
|
||
2. 分配临时工作区(工作台为评审会创建独立的临时工作区,所有会议期间的代码修改仅限于此)
|
||
3. 冻结材料(基于当前各分支快照锁定评审材料,防止会议期间正式工作区代码变动)
|
||
4. 材料展示(通过可视化层展示模块关系图、接口、测试报告)
|
||
5. 逐模块阐释(产品 Agent 依次阐释每个模块,提供证据)
|
||
6. 质询环节(测试 Agent、人类、Supervisor 提出问题)
|
||
7. 临时修改(如人类想在会议中试改代码,只能在临时工作区进行,不影响正式分支)
|
||
8. 决策(人类做出最终决策:操作哪些分支、注入什么新提示词、是否调整需求等)
|
||
9. 执行决策(工作台根据结论向分支管理引擎下发指令,不直接修改代码)
|
||
10. 存档(完整会议记录作为独立存档写入 Archive,通过 trigger_snapshot_id 关联到触发节点)
|
||
```
|
||
|
||
#### 会议结论类型(通用,适用于代码分支和需求规格)
|
||
- `RESUME_WITH_PROMPT(target_id, prompt)`:给挂起对象注入新提示词后恢复。
|
||
- 对代码分支:给分支新的修复思路,继续运行。
|
||
- 对需求规格:澄清歧义后,重新组织需求对齐评审。
|
||
- `ABANDON(target_id)`:废弃挂起对象。
|
||
- 对代码分支:废弃该修复路线。
|
||
- 对需求规格:废弃当前版本,由产品经理重新撰写。
|
||
- `FORK_NEW_BRANCH(parent_snapshot_id, strategy)`:基于某代码快照开新分支尝试新方案。(仅适用于代码)
|
||
- `ADJUST_REQUIREMENT(new_requirement_spec)`:发布新需求版本。
|
||
- 旧版本标记为 `SUPERSEDED`。
|
||
- 所有基于旧版本的活跃代码分支标记为 `STALE_REQUIREMENT`。
|
||
- `ADJUST_STRATEGY(new_strategy_config)`:调整挂起策略(如临时开放认知型挂起)。
|
||
- `ESCALATE`:升级给更高权限的人类(如当前审阅者权限不足)。
|
||
- `TERMINATE`:终止整个任务(保留存档,但不再运行)。
|
||
|
||
---
|
||
|
||
### 2.5.1 小挂起处理机制(执行时阻塞)
|
||
|
||
#### 职责
|
||
- 在工具层拦截操作系统级别的权限/环境阻塞。
|
||
- 向人类发送轻量级权限请求,不需要进入评审会。
|
||
- 记录授权历史,支持"记住本次选择"。
|
||
|
||
#### 处理流程
|
||
```
|
||
Agent 调用工具(如 run_command("sudo apt install ..."))
|
||
│
|
||
▼
|
||
工具层执行命令
|
||
│
|
||
▼
|
||
操作系统返回 Permission denied / 需要密码
|
||
│
|
||
▼
|
||
工具层发送 PERMISSION_REQUEST 给中央路由
|
||
│
|
||
▼
|
||
人类收到通知(弹窗/消息栏)
|
||
│
|
||
├────→ 输入密码 / 点击"允许一次"
|
||
│ │
|
||
│ ▼
|
||
│ 工具层重新执行命令(带上授权)
|
||
│ │
|
||
│ ▼
|
||
│ Agent 继续运行,状态不变
|
||
│
|
||
└────→ 点击"拒绝"
|
||
│
|
||
▼
|
||
工具层返回错误给 Agent
|
||
Agent 自行决定下一步(可能进入大挂起)
|
||
```
|
||
|
||
#### 授权缓存
|
||
```
|
||
AuthorizationCache
|
||
├── tool_name: "run_command"
|
||
├── pattern: "sudo *"
|
||
├── granted_by: "human://user_id"
|
||
├── grant_type: ONCE | SESSION | PERMANENT
|
||
└── expires_at: 时间戳(可选)
|
||
```
|
||
|
||
---
|
||
|
||
### 2.6 可视化与交互层
|
||
|
||
#### 职责
|
||
- 渲染快照树(树状图)。
|
||
- 渲染模块关系图(方框+连线,点击穿透接口详情)。
|
||
- 提供评审会的交互界面。
|
||
- 提供配置面板(挂起策略、Supervisor 权限、通知偏好等)。
|
||
- 提供工具的统一操作入口(代码编辑、测试运行、快照操作)。
|
||
|
||
#### 核心视图
|
||
|
||
**视图 A:需求时间线(Requirement Timeline View)**
|
||
- 垂直时间轴布局,需求版本按时间顺序从上到下排列:v1 → v2 → v3 → ...
|
||
- 当前有效版本高亮显示,已替代版本灰显但可点击查看历史。
|
||
- 每个版本节点显示:版本号、创建者、状态(ACTIVE / SUPERSEDED / SUSPENDED)。
|
||
- 点击版本节点:右侧面板显示该版本的完整需求规格内容。
|
||
- 点击版本节点:代码树中高亮所有基于该版本的代码节点,其他节点变灰。
|
||
- 需求规格挂起时,对应版本节点闪烁红色,并显示"等待评审会"标记。
|
||
|
||
**视图 B:快照树(Snapshot Tree View)**
|
||
- 垂直时间轴布局,根在上,叶子在下。
|
||
- 主干(main)居中高亮,分支向两侧展开。
|
||
- 节点颜色编码:绿色(运行中)、黄色(挂起-认知)、橙色(挂起-风险)、红色(挂起-技术)、灰色(废弃)。
|
||
- 点击节点:右侧面板显示从根到该节点的思考链(时间线形式)。
|
||
- 点击节点旁的"历史"图标:展开该节点的**平级链**,显示到达此节点之前的所有中间操作(危险操作、重试记录等)。
|
||
- Ctrl+点击两个节点:显示差异对比视图(公共祖先 + 分叉后的不同路径)。
|
||
- 双击节点:`checkout` 该快照,打开对应工作区内容。
|
||
|
||
**视图 C:模块关系图(Module Graph View)**
|
||
- 力导向图或层次布局:方框 = 模块,连线 = 接口依赖。
|
||
- 点击方框:展开模块详情(职责描述、代码位置、所属分支)。
|
||
- 点击连线:弹出接口定义面板(输入/输出类型、契约、变更历史)。
|
||
- 红色虚线 = 未通过测试的接口。
|
||
- 黄色闪烁 = 当前评审会正在讨论的模块。
|
||
|
||
**视图 D:评审会界面(Meeting Room View)**
|
||
- 左侧:参会成员列表(在线状态)。
|
||
- 中间:当前展示的材料(模块图 / 代码 diff / 测试报告)。
|
||
- 右侧:批注面板(人类的实时批注、历史批注)。
|
||
- 底部:决策操作栏(恢复/废弃/开分支/调整策略等按钮)。
|
||
|
||
---
|
||
|
||
## 3. 数据流全景
|
||
|
||
### 3.1 正常任务执行流(无分支)
|
||
|
||
```
|
||
人类提交需求 ──→ 中央路由 ──→ 产品 Agent
|
||
│
|
||
▼
|
||
[PLANNING 阶段]
|
||
│
|
||
▼
|
||
[CODING 阶段]
|
||
(危险操作前:工作台自动快照)
|
||
│
|
||
▼
|
||
提交测试请求(元数据消息)
|
||
│
|
||
▼
|
||
中央路由 ──→ 测试 Agent
|
||
│
|
||
▼
|
||
[GENERATING_TESTS]
|
||
│
|
||
▼
|
||
[EXECUTING]
|
||
│
|
||
▼
|
||
测试报告 ──→ 中央路由
|
||
│
|
||
▼
|
||
产品 Agent + 人类
|
||
│
|
||
▼
|
||
请求进入评审会
|
||
│
|
||
▼
|
||
评审会系统
|
||
(会议前:工作台快照)
|
||
│
|
||
▼
|
||
人类决策:挂起 / 继续
|
||
│
|
||
▼
|
||
存档 + 任务挂起
|
||
```
|
||
|
||
### 3.2 分支探索流(测试发现问题后)
|
||
|
||
```
|
||
测试报告:失败 ──→ 产品 Agent 分析
|
||
│
|
||
▼
|
||
决定开 3 条修复分支
|
||
│
|
||
▼
|
||
分支管理引擎创建 3 个 Fork
|
||
(基于当前快照,各新建工作区)
|
||
│
|
||
┌───────────────┼───────────────┐
|
||
▼ ▼ ▼
|
||
分支 A 分支 B 分支 C
|
||
方案:重构 方案:补丁 方案:绕开
|
||
│ │ │
|
||
▼ ▼ ▼
|
||
运行测试 运行测试 运行测试
|
||
│ │ │
|
||
┌────┴────┐ ┌────┴────┐ ┌────┴────┐
|
||
▼ ▼ ▼ ▼ ▼ ▼
|
||
通过 挂起 挂起 挂起 通过 挂起
|
||
(技术) (风险) (认知) (技术) (技术) (风险)
|
||
│ │ │ │ │ │
|
||
▼ ▼ ▼ ▼ ▼ ▼
|
||
继续 通知 通知 通知 继续 通知
|
||
运行 人类 Supervisor 人类 运行 人类
|
||
|
||
│
|
||
▼
|
||
分支 A 和 C 还在运行,B 已挂起
|
||
│
|
||
▼
|
||
(假设 A 和 C 后续也挂了)
|
||
│
|
||
▼
|
||
ALL_BRANCHES_SUSPENDED 事件
|
||
│
|
||
▼
|
||
强制触发评审会
|
||
```
|
||
|
||
### 3.3 认知型挂起处理流(Supervisor 介入)
|
||
|
||
```
|
||
产品 Agent 遇到认知盲区
|
||
│
|
||
▼
|
||
策略检查:认知型挂起是否被允许?
|
||
│
|
||
┌────┴────┐
|
||
▼ ▼
|
||
否 是
|
||
│ │
|
||
▼ ▼
|
||
硬撑继续 发送 COGNITIVE_SUPPORT 请求
|
||
(到测试阶段 │
|
||
再暴露) ▼
|
||
中央路由
|
||
│
|
||
▼
|
||
Supervisor Agent
|
||
│
|
||
┌────┴────┐
|
||
▼ ▼
|
||
查知识库 找不到
|
||
│ │
|
||
▼ ▼
|
||
返回信息 尝试次数 +1
|
||
│ 超上限?
|
||
│ ┌────┴────┐
|
||
│ ▼ ▼
|
||
│ 否 是
|
||
│ │ │
|
||
│ ▼ ▼
|
||
│ 继续等待 升级为真正挂起
|
||
│ (通知人类)
|
||
▼
|
||
产品 Agent 基于新信息继续
|
||
```
|
||
|
||
---
|
||
|
||
## 4. 状态机总览
|
||
|
||
### 4.1 任务级状态机(Session)
|
||
|
||
```
|
||
┌─────────────────────────────────────┐
|
||
│ │
|
||
▼ │
|
||
CREATED ──→ PLANNING ──→ EXECUTING ──→ MEETING ──→ SUSPENDED
|
||
│ │ ↑ │ │
|
||
│ │ │ │ │
|
||
│ ▼ │ ▼ │
|
||
│ CHECKPOINT ABORTED │
|
||
│ │ │ │ │
|
||
│ └───┘ └──────────────┘
|
||
│ │
|
||
└────────────────────────────────────────────┘
|
||
(人类或 Supervisor 决策后恢复)
|
||
```
|
||
|
||
- `CREATED`:需求已接收,尚未开始。
|
||
- `PLANNING`:产品 Agent 生成方案阶段(线性,无分支)。
|
||
- `EXECUTING`:编码 + 测试 + 分支探索阶段。
|
||
- `CHECKPOINT`:执行过程中的暂停点(检查点),可能由挂起触发。
|
||
- `MEETING`:评审会进行中,材料冻结,等待人类决策。
|
||
- `SUSPENDED`:任务挂起,保留完整上下文,可随时恢复或终止。
|
||
- `ABORTED`:任务被终止(仍保留存档,只是不再运行)。
|
||
|
||
### 4.2 分支级状态机(Branch)
|
||
|
||
```
|
||
FORKED ──→ ACTIVE ──→ SUSPENDED ──→ [评审会决策]
|
||
│
|
||
┌─────────┼─────────┐
|
||
▼ ▼ ▼
|
||
RESUMED ABANDONED MERGED
|
||
│ │
|
||
└───────────────────┘
|
||
│
|
||
▼
|
||
(回到 ACTIVE 或结束)
|
||
```
|
||
|
||
- `FORKED`:刚创建,尚未开始运行。
|
||
- `ACTIVE`:正在运行中(BFS 调度的一环)。
|
||
- `SUSPENDED`:挂起,等待外部决策。
|
||
- `RESUMED`:决策后恢复运行。
|
||
- `ABANDONED`:被废弃(在快照树上标记为灰色,但记录保留)。
|
||
- `MERGED`:被合并到另一分支或主干(记录合并关系)。
|
||
|
||
---
|
||
|
||
## 5. 接口契约(子系统间)
|
||
|
||
### 5.1 中央路由 ↔ Agent
|
||
|
||
```
|
||
Agent.register(agent_id, role_card_id, capabilities, permission_list)
|
||
Agent.send(message_envelope)
|
||
Agent.receive() → message_envelope
|
||
Agent.join_group(group_id)
|
||
Agent.leave_group(group_id)
|
||
```
|
||
|
||
**身份牌(Role Card)**:
|
||
Agent 注册时必须绑定一个身份牌,身份牌定义了该 Agent 的决策模型、可用工具集和工作区权限。身份牌本身由工作台系统统一管理,支持动态切换(如人类可以临时给某个 Agent 换一张更保守/更激进的身份牌)。
|
||
|
||
### 5.2 中央路由 ↔ 工作台
|
||
|
||
```
|
||
Router.request_content(snapshot_id, object_path, requester_id)
|
||
→ { allowed: bool, content_ref: string }
|
||
|
||
Router.log_audit(event_metadata)
|
||
```
|
||
|
||
### 5.3 Agent ↔ 工作台
|
||
|
||
```
|
||
Workspace.create(agent_id) → workspace_id
|
||
Workspace.snapshot(workspace_id, reason) → snapshot_id
|
||
Workspace.fork(snapshot_id, new_agent_id) → new_workspace_id
|
||
Workspace.checkout(snapshot_id) → workspace_id
|
||
Workspace.read(workspace_id, path) → content
|
||
Workspace.write(workspace_id, path, content) → { success, new_snapshot_id }
|
||
Workspace.diff(snapshot_a, snapshot_b) → diff_object
|
||
Workspace.trace(snapshot_id) → [snapshot_id, ...] // 从根到该节点
|
||
```
|
||
|
||
### 5.4 评审会系统 ↔ 其他子系统
|
||
|
||
```
|
||
Meeting.create(session_id, trigger_reason, branch_ids) → meeting_id
|
||
Meeting.freeze_materials(meeting_id) → { snapshot_refs }
|
||
Meeting.add_annotation(meeting_id, agent_id, target_module, text)
|
||
Meeting.make_decision(meeting_id, agent_id, decision_type, params)
|
||
Meeting.archive(meeting_id) → archive_id
|
||
Meeting.get_transcript(meeting_id) → full_record
|
||
```
|
||
|
||
### 5.5 可视化层 ↔ 其他子系统
|
||
|
||
```
|
||
Visual.get_snapshot_tree(session_id) → tree_data
|
||
Visual.get_module_graph(snapshot_id) → graph_data
|
||
Visual.get_diff_view(snapshot_a, snapshot_b) → diff_data
|
||
Visual.get_meeting_room(meeting_id) → meeting_state
|
||
Visual.execute_tool(tool_name, params, user_id) → result
|
||
```
|
||
|
||
---
|
||
|
||
## 6. 关键技术选型建议(非约束,供参考)
|
||
|
||
| 层面 | 当前建议 | 理由 |
|
||
|------|----------|------|
|
||
| 工作区隔离 | 文件系统目录 + 权限掩码 | MVP 阶段足够轻量,无需 Docker |
|
||
| 快照系统 | 基于 Git 对象模型,但自定义索引 | 利用 Git 的 diffs 和 Merkle Tree,但绕过工作区限制 |
|
||
| 消息队列 | 内存通道(单进程多线程) | 原型阶段足够,未来可替换为 Redis/RabbitMQ |
|
||
| 存档存储 | SQLite + 文件系统 | 结构化查询 + 大文件(代码快照)分离存储 |
|
||
| 可视化 | TUI(ratatui)或轻量 Web(Leptos)| 取决于团队前端能力,两者都支持树状图和模块图 |
|
||
| LLM 接口 | 预留 OpenAI/Claude 兼容层 | MVP 先用硬编码模拟,接口保持一致 |
|
||
|
||
---
|
||
|
||
## 7. 未解决问题(需在原型中验证)
|
||
|
||
1. **快照树的规模上限**:复杂任务可能产生数百个快照,树状渲染性能如何?
|
||
2. **盲执行的实现细节**:测试 Agent 如何在"看不到源代码"的情况下编译和运行测试?(可能需要产品 Agent 提供预编译产物或接口桩)
|
||
3. **Supervisor 知识库的范围和更新机制**:知识库是静态文件还是可动态写入?谁负责维护?
|
||
4. **多人类协作的并发控制**:如果两个人类同时加入评审会并做出矛盾决策,系统如何处理?
|
||
5. **BFS 的"一步"粒度**:以"修复-测试循环"为一步可能太慢,以"单个 LLM 调用"为一步可能太快,需在原型中调参。
|
||
|
||
---
|
||
|
||
*文档版本:2026-06-08*
|
||
*状态:等待审阅*
|