Files
sanguo_moziplus_v2/docs/design/v3.0-router-refactor.md
T
2026-05-21 10:57:41 +08:00

175 lines
5.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# v3.0 Router 重构方案:去掉独立 LLM,改用 Gateway spawn Agent
**日期**: 2026-05-21
**状态**: 方案待确认
**影响文件**: `router.py`, `dispatcher.py`, `main.py`, `config/default.yaml`
---
## 问题
当前 Router`LLMDriver`)用独立的 `OpenAI()` 客户端直接调 zhipu API 做路由决策。
这违反设计文档 `architecture-v2.6.md` 的核心原则:
> **系统只有两种 LLM 调用方式,都通过 Gateway**
> 1. **L3 run agent** — `openclaw agent --agent <id>`spawn 完整 Agent
> 2. **L2 spawn sub** — `openclaw agent --agent <id> --session-id <uuid>`,轻量一次性
独立 `OpenAI()` 不属于任何一层,是设计之外的野路子。
### 具体问题
1. **凭据管理**:需要单独维护 api_base/api_key,和 Gateway 配置重复
2. **不走 Gateway**:无法利用 Gateway 的模型路由、fallback、计费
3. **设计不一致**:设计文档三层模型(L1/L2/L3),Router 不在其中
4. **可靠性差**:凭据为空时静默 fallback,不报错
---
## 方案:Router 改为"能力匹配 + spawn 庞统兜底"
### 核心思路
Router 有两种路由方式:
- **确定性路由**(能力匹配、retry、handoff)→ 保留,纯 L1 逻辑,不调 LLM
- **模糊路由**(首次分配、不确定场景)→ **不再调独立 LLM,改为 spawn 庞统让庞统决定**
### 路由决策流程(改后)
```
任务进入 Router.route()
├─ 快速路径1: 本地 action → daemon
├─ 快速路径2: retry → 原执行者
├─ Mode B: Agent handoff (next_capability) → 能力匹配
├─ 快速路径3: 生命周期流转 → 能力匹配
├─ 快速路径4: 有 assignee → 直接分
└─ 模糊场景(以上都不匹配)
→ 返回 RouteDecision(agent_id="pangtong-fujunshi", mode="delegate")
庞统被 spawn 后,读取黑板任务信息,自己决定分配给谁
庞统通过 API 回写 assignee → ticker 下一轮 spawn 实际执行者
```
### 改动清单
#### 1. 删除 `LLMDriver` 类(router.py
整个 `LLMDriver` 类删除,约 120 行。Router 的 `route()` 方法末尾:
```python
# 当前(Mode A: 独立 LLM 调用)
if self.llm_driver:
decision = self.llm_driver.route(...)
...
# 改后(委托庞统)
return RouteDecision(
agent_id=self.FALLBACK_AGENT, # "pangtong-fujunshi"
reason="Uncertain routing, delegate to coordinator",
mode="delegate",
confidence=0.0,
)
```
#### 2. `AgentRouter.__init__` 去掉 `llm_driver` 参数
```python
def __init__(self, agent_profiles, counter=None): # 删 llm_driver
```
#### 3. Dispatcher 增加 `delegate` 模式处理
`mode="delegate"` 时,spawn 庞统并传入"请分配此任务"的 prompt
```python
# dispatcher.py decide() 中
if decision.mode == "delegate":
return {
"level": DispatchLevel.FULL_AGENT,
"agent_id": "pangtong-fujunshi",
"reason": decision.reason,
"mode": "delegate", # 标记,用于构建不同 prompt
}
```
`_build_spawn_message` 中为 `delegate` 模式生成专门的 prompt
```python
if mode == "delegate":
return f"""你是任务协调员。请分析以下任务,决定最合适的执行者。
## 任务信息
- ID: {task.id}
- 标题: {task.title}
- 描述: {task.description}
- 类型: {task.task_type}
## 操作
1. 分析任务需求
2. 选择最合适的 Agent(从你已知的团队中)
3. 通过 API 回写分配结果:
curl -X POST {api}/tasks/{task.id}/status -d '{{"status":"claimed","assignee":"<agent_id>"}}'
4. 如果你自己能做,直接认领执行
"""
```
#### 4. main.py 去掉 LLMDriver 初始化
```python
# 删掉 routing_config / llm_driver 的整个初始化块(~10行)
# Router 构造不再传 llm_driver
router = AgentRouter(
agent_profiles=agent_profiles,
counter=counter,
)
```
#### 5. config/default.yaml 去掉 routing 节
```yaml
# 删掉整个 routing: 节(model/api_base/api_key/timeout/...
# 确定性路由的能力匹配不依赖配置
# 模糊路由由庞统决策,不需要配置
```
---
### 改动前后对比
| 场景 | 改前 | 改后 |
|------|------|------|
| retry | 原执行者(确定性)| 不变 |
| Agent handoff | 能力匹配(确定性)| 不变 |
| 生命周期 review | 能力匹配(确定性)| 不变 |
| 有 assignee | 直接分(确定性)| 不变 |
| **首次分配/模糊** | **独立 LLM 调用** | **spawn 庞统决策** |
### 影响
- **删代码**~130 行(LLMDriver + routing config
- **改代码**~30 行(Router.route 末尾 + Dispatcher._build_spawn_message
- **config**:删 routing 节
- **行为变化**:模糊场景从"1-2秒 LLM 返回"变成"spawn 庞统 → 庞统思考 → 回写",多 30-60 秒但更准确
- **优点**:不再需要维护独立 LLM 凭据,所有 AI 调用统一走 Gateway
### 风险
1. **庞统成为单点**:所有模糊路由都走庞统,如果庞统繁忙会被跳过(counter 限制)
- 缓解:庞统 max_concurrent=3,且 delegate 模式是轻量决策不是重活
2. **速度变慢**:独立 LLM 1-2s vs spawn 庞统 30-60s
- 评估:首次分配本来就不用急,准确比快重要
3. **确定性路由覆盖不到的场景**:如果能力匹配足够好,大部分场景不需要庞统
- 评估:对。实际运行中大部分任务要么有 assignee 要么有 task_type 可匹配
---
## 实施步骤
1. 删 LLMDriver + router.py 清理
2. main.py 去掉 llm_driver 初始化
3. Dispatcher 增加 delegate 模式 prompt
4. config/default.yaml 删 routing 节
5. 发司马懿评审
6. 评审通过后部署