auto-sync: 2026-05-30 15:28:18
This commit is contained in:
@@ -0,0 +1,290 @@
|
||||
# #04 黑板协作模型设计
|
||||
|
||||
> 版本: v1.0
|
||||
> 日期: 2026-05-30
|
||||
> 作者: 庞统(副军师)
|
||||
> 状态: 评审中
|
||||
> 前置: #02 Main Session + Delegation, #03 Prompt 进化
|
||||
|
||||
---
|
||||
|
||||
## 一、问题陈述
|
||||
|
||||
当前黑板有 7 种信息类型(Task/Comment/Output/Event/Review/Decision/Observation),全部通过 `task_id` 平铺关联。E2E 测试暴露了三个设计缺陷:
|
||||
|
||||
### 问题 1:assignee 和 @mention 功能重叠
|
||||
|
||||
| 机制 | 触发方式 | 路由行为 |
|
||||
|------|---------|---------|
|
||||
| assignee 字段 | 创建任务时传 `assignee: "zhangfei-dev"` | 确定性路由 |
|
||||
| @mention | Comment 中 `mentions: ["zhaoyun-data"]` | mention_queue → spawn |
|
||||
|
||||
**问题**:两者都能触发"找人做事",语义不同但边界模糊。
|
||||
- Agent 不知道什么时候用 assignee,什么时候用 @
|
||||
- assignee 是单人的,但任务可能需要多人协作
|
||||
- @mention 需要额外传 `mentions` 数组,容易遗漏
|
||||
|
||||
### 问题 2:一个任务只能有一个 assignee
|
||||
|
||||
当前 `assignee` 是单个字符串。但现实中:
|
||||
- 一个数据准备任务可能需要赵云(获取)+ 关羽(风控审核)
|
||||
- 一个部署任务可能需要姜维(部署)+ 关羽(安全检查)
|
||||
- 庞统创建子任务时需要同时指定多人
|
||||
|
||||
### 问题 3:信息组织是平铺的,缺乏结构化视图
|
||||
|
||||
当前 `expand=all` 只展开当前 task 的子表,不递归子任务。用户想看"数据准备子任务的所有 comments 和成果物",需要:
|
||||
1. 先查父任务,找到子任务 ID
|
||||
2. 再逐个查每个子任务的 `expand=all`
|
||||
|
||||
信息之间的关联(比如 Output #3 是 Comment #2 的结果)无法表达。
|
||||
|
||||
---
|
||||
|
||||
## 二、优秀实践调研
|
||||
|
||||
### 2.1 项目管理工具的共识
|
||||
|
||||
**Jira / Linear / Asana 共同模式**:
|
||||
|
||||
| 洞察 | 来源 | 启示 |
|
||||
|------|------|------|
|
||||
| 单表存所有任务 + 类型字段区分 | Jira `issuetype` | 不需要为不同任务类型建不同表 |
|
||||
| `parent_id` + `topmost_id` 实现层级 | Jira | 父子关系用指针,不是嵌套 |
|
||||
| Project 是逻辑隔离边界 | Jira/Linear | 一个 Project 一个黑板 DB |
|
||||
| 一个 Task 可属于多个 Project | Asana | 多对多关系(cross-project) |
|
||||
|
||||
### 2.2 AI Agent 编排系统的共识
|
||||
|
||||
**LangGraph / CrewAI / AutoGen 共同模式**:
|
||||
|
||||
| 洞察 | 来源 | 启示 |
|
||||
|------|------|------|
|
||||
| 子任务隔离 + 结果摘要回传 | LangGraph Subgraph | 子任务有独立状态,完成后折叠 |
|
||||
| 共享 Memory + Crew 边界 | CrewAI | 同一 Crew 共享记忆 |
|
||||
| 对话历史即上下文 | AutoGen | 不需要额外机制,消息本身就是上下文 |
|
||||
| 扁平 Handoff + Context Variables | OpenAI Swarm | 最简模型,适合简单场景 |
|
||||
|
||||
### 2.3 学术和实践前沿
|
||||
|
||||
| 洞察 | 来源 | 启示 |
|
||||
|------|------|------|
|
||||
| **共享产出物 > 共享消息** | O'Reilly 2026 | 围绕 artifact 协作,不是围绕消息 |
|
||||
| **Phase gates + shared artifacts + final supervisor** | O'Reilly 2026 | 2026 存活系统的共同特征 |
|
||||
| **共享工作区 + 结构化产出 > 消息传递** | Claude Code 实践 | 文件系统 + JSON 接口 |
|
||||
| **对话历史传递 surprisingly effective** | OpenAI Handoff | 转交时携带完整上下文 |
|
||||
| **bMAS 迭代收敛到共识** | arXiv:2507.01701 | Agent 轮流行动直到黑板达成共识 |
|
||||
| **propose→validate→commit 原子写入** | Network-AI | 消除 split-brain |
|
||||
| **Auftragstaktik 任务式指挥** | ClawTeam #10 | Intent→End State→Constraints,不指定步骤 |
|
||||
|
||||
### 2.4 核心设计原则(从调研提炼)
|
||||
|
||||
1. **黑板是唯一真相源** — 所有 Agent 通过黑板共享信息
|
||||
2. **产出物 > 消息** — 围绕共享产出物协作,不是围绕消息传递
|
||||
3. **结构对称** — 不把任何 Agent 当"主",Canonical IR 原则
|
||||
4. **单一职责** — 每种信息类型只表达一件事
|
||||
5. **可追溯** — 不可变事件日志,写入即审计
|
||||
6. **任务式指挥** — Intent→End State→Constraints,Agent 自主决定怎么做
|
||||
|
||||
---
|
||||
|
||||
## 三、设计方案
|
||||
|
||||
### 3.1 统一路由:取消 assignee,用 @mention 统一
|
||||
|
||||
**核心决策**:取消 `assignee` 字段的路由功能,统一用黑板 Comment + @mention 触发路由。
|
||||
|
||||
| 之前 | 之后 |
|
||||
|------|------|
|
||||
| 创建任务传 `assignee` → 确定性路由 | 创建任务时在 description 中 `@张飞` → daemon 自动路由 |
|
||||
| Agent 不知道用 assignee 还是 @mention | 只有一种方式:@ |
|
||||
| assignee 是单人的 | @ 可以 @ 多人 |
|
||||
|
||||
**实现**:
|
||||
- `assignee` 字段保留但降级为**纯显示用途**(由 daemon 自动从 mention 中推断)
|
||||
- 创建任务时,daemon 扫描 description 和第一条 comment 中的 `@Agent` 模式
|
||||
- 匹配到的 Agent 作为确定性路由目标
|
||||
- 无 @ 匹配 → 广播认领
|
||||
|
||||
**API 变化**:
|
||||
```python
|
||||
# 之前
|
||||
POST /tasks {
|
||||
"title": "写 hello.py",
|
||||
"assignee": "zhangfei-dev" # 谁来做
|
||||
}
|
||||
|
||||
# 之后
|
||||
POST /tasks {
|
||||
"title": "写 hello.py",
|
||||
"description": "@zhangfei-dev 写一个 hello.py" # @ 谁
|
||||
}
|
||||
# daemon 自动提取 assignee=zhangfei-dev
|
||||
```
|
||||
|
||||
### 3.2 @mention 语义增强
|
||||
|
||||
**当前问题**:Comment 需要**同时**写 `body` 中的 `@zhaoyun-data` **和** `mentions` 数组。Agent 容易遗漏。
|
||||
|
||||
**改进方案**:daemon 自动从 `body` 中提取 `@Agent` 模式,自动填充 `mentions`。
|
||||
|
||||
```python
|
||||
# Agent 只需要写 body
|
||||
POST /comments {
|
||||
"author": "pangtong-fujunshi",
|
||||
"body": "@zhaoyun-data 你来获取沪深300行情数据,@guanyu-dev 数据到了你做风控检查"
|
||||
}
|
||||
|
||||
# daemon 自动提取 → mentions: ["zhaoyun-data", "guanyu-dev"]
|
||||
# 写入 mention_queue → 两人都收到 mention spawn
|
||||
```
|
||||
|
||||
**提取规则**:
|
||||
- 正则 `@([a-z]+-[a-z]+)` 匹配已知 Agent ID
|
||||
- 匹配到的 Agent 写入 `mentions` 字段(如果前端也传了 `mentions`,取并集)
|
||||
- 不认识的 @ 目标忽略(可能是 @文档 @链接)
|
||||
|
||||
### 3.3 多人协作模式
|
||||
|
||||
@ 多人 ≠ 多人同时执行同一任务。而是**串行/并行子任务**:
|
||||
|
||||
| @ 模式 | 含义 | Daemon 行为 |
|
||||
|--------|------|------------|
|
||||
| `@zhangfei-dev` | 指定张飞做这个任务 | 确定性路由给张飞 |
|
||||
| `@zhaoyun-data @guanyu-dev` | 需要两人协作 | 创建两个子任务,分别路由 |
|
||||
| `@所有人` | 不知道谁合适 | 广播认领 |
|
||||
| 无 @ | 不需要特定人 | 广播认领 |
|
||||
|
||||
**@多人 → 自动拆子任务**(Phase 2,暂不实现):
|
||||
|
||||
```
|
||||
庞统创建任务:@zhaoyun-data 获取数据,@zhangfei-dev 写策略代码
|
||||
|
||||
Daemon 自动拆解:
|
||||
├── 子任务 1: 获取数据 → assignee: zhaoyun-data
|
||||
└── 子任务 2: 写策略代码 → assignee: zhangfei-dev, depends_on: [子任务 1]
|
||||
```
|
||||
|
||||
Phase 1 只做:@多人 → 每个人收到 mention spawn,各自决定如何协作。
|
||||
|
||||
### 3.4 信息关联模型重构
|
||||
|
||||
**当前**:7 种信息平铺挂在 `task_id` 上,互相之间无关联。
|
||||
|
||||
**改进**:引入 `parent_id` 串联信息流。
|
||||
|
||||
#### Output 关联 Comment
|
||||
|
||||
```python
|
||||
# 当前
|
||||
POST /outputs {agent, content_type, summary}
|
||||
# 产出物和讨论没有关联
|
||||
|
||||
# 改进:output 关联到触发它的 comment
|
||||
POST /outputs {
|
||||
agent: "zhaoyun-data",
|
||||
content_type: "data",
|
||||
summary: "沪深300日频行情",
|
||||
triggered_by_comment: 42 # ← 新字段,关联到 @赵云 的那条 comment
|
||||
}
|
||||
```
|
||||
|
||||
#### Review 关联 Output
|
||||
|
||||
当前 `Review.output_id` 已有关联,保持不变。
|
||||
|
||||
#### 信息流视图
|
||||
|
||||
```
|
||||
Comment #1: "@zhaoyun-data 获取沪深300行情"
|
||||
└── mention_queue → spawn 赵云
|
||||
└── Comment #2: "数据已获取,见附件"
|
||||
└── Output #1: content_path=/data/market.csv, triggered_by_comment=#1
|
||||
└── Review #1: verdict=approved, output_id=#1
|
||||
```
|
||||
|
||||
### 3.5 层级查询 API
|
||||
|
||||
**当前痛点**:想看"数据准备子任务的所有信息"需要多次查询。
|
||||
|
||||
**改进**:新增聚合查询 API。
|
||||
|
||||
```
|
||||
GET /api/projects/{pid}/tasks/{task_id}/timeline
|
||||
|
||||
返回:
|
||||
{
|
||||
"task": {...},
|
||||
"children": [
|
||||
{
|
||||
"task": {...},
|
||||
"comments": [...],
|
||||
"outputs": [...],
|
||||
"reviews": [...]
|
||||
}
|
||||
],
|
||||
"timeline": [
|
||||
{"ts": "...", "type": "comment", "author": "pangtong", "body": "@zhaoyun-data ..."},
|
||||
{"ts": "...", "type": "mention", "agent": "zhaoyun-data", "status": "notified"},
|
||||
{"ts": "...", "type": "status", "from": "pending", "to": "claimed"},
|
||||
{"ts": "...", "type": "comment", "author": "zhaoyun-data", "body": "数据已获取"},
|
||||
{"ts": "...", "type": "output", "agent": "zhaoyun-data", "summary": "沪深300行情"},
|
||||
{"ts": "...", "type": "review", "verdict": "approved"}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
`timeline` 把一个任务(含子任务)的所有事件按时间线排列,一目了然。
|
||||
|
||||
---
|
||||
|
||||
## 四、实施计划
|
||||
|
||||
### Phase 1(与 #02/#03 一起验证)
|
||||
|
||||
| 改动 | 影响 |
|
||||
|------|------|
|
||||
| daemon 自动从 body 提取 @mention | Agent 不再需要手动传 `mentions` 数组 |
|
||||
| claim prompt 补充完整 API(RC-2) | Agent 知道怎么写产出物 |
|
||||
| assignee 保留但降级为显示字段 | 向后兼容 |
|
||||
|
||||
### Phase 2(#04 独立实施)
|
||||
|
||||
| 改动 | 影响 |
|
||||
|------|------|
|
||||
| 创建任务时从 description 提取 @ → 自动 assignee | 统一路由入口 |
|
||||
| Output 新增 triggered_by_comment 字段 | 信息关联 |
|
||||
| /timeline 聚合查询 API | 结构化视图 |
|
||||
| @多人自动拆子任务 | 复杂协作 |
|
||||
|
||||
### Phase 3(未来)
|
||||
|
||||
| 改动 | 影响 |
|
||||
|------|------|
|
||||
| @所有人 广播语法 | 统一广播入口 |
|
||||
| Context Folding(子任务完成后折叠) | 上下文管理 |
|
||||
| Fidelity 三档信息路由 | 按 Agent 角色分档展示 |
|
||||
|
||||
---
|
||||
|
||||
## 五、设计决策待确认
|
||||
|
||||
1. **assignee 是否完全取消?** — 还是保留为"谁负责"的语义,但路由统一走 @mention?
|
||||
2. **@多人 Phase 1 是否实现自动拆子任务?** — 还是 Phase 1 只做多人 mention,手动拆?
|
||||
3. **timeline API 是否 Phase 1 就做?** — 还是先用 `expand=all` + 前端聚合?
|
||||
4. **mentions 自动提取的 @模式** — `@zhangfei-dev` 还是 `@张飞` 还是两者都支持?
|
||||
|
||||
---
|
||||
|
||||
## 附录:调研来源
|
||||
|
||||
- Jira 数据库设计(单表 + issuetype + parent_id)
|
||||
- Linear/Asana 层级模型(Workspace 隔离 + 逻辑分组)
|
||||
- LangGraph Subgraph 模式(子任务隔离 + State 映射回传)
|
||||
- CrewAI 共享 Memory(Crew 边界)
|
||||
- bMAS 黑板架构(Control Unit 动态路由 + 迭代收敛)
|
||||
- O'Reilly 2026(共享产出物 > 共享消息 + Phase gates)
|
||||
- OpenAI Handoff(对话历史传递 surprisingly effective)
|
||||
- Network-AI(propose→validate→commit 原子写入)
|
||||
- ClawTeam #10(Auftragstaktik 任务式指挥)
|
||||
- Opal-Bridge(Canonical IR + Fidelity 三档)
|
||||
Reference in New Issue
Block a user