docs(multi-agent): 添加多智能体模式设计文档7份

This commit is contained in:
JOJO 2026-07-12 02:28:47 +08:00
parent c08c4ab141
commit e8b857f3ae
7 changed files with 1984 additions and 0 deletions

View File

@ -0,0 +1,227 @@
# 多智能体模式总体架构
> 文档状态:设计草案
> 适用范围宿主机模式host mode不覆盖 docker/web 模式
> 隔离原则:与现有对话系统完全隔离,复用底层能力但上层独立
---
## 1. 设计目标
在 Astrion 中引入一个实验性的「多智能体模式」:
- 主智能体固定扮演 **Team Leader**,负责任务拆解、调度、协调、回答子智能体提问。
- 支持预置角色与自定义角色,每个角色可以有多个实例(`RoleName_1`、`RoleName_2`)。
- 子智能体之间、子智能体与主智能体之间可以双向通信。
- 所有通信遵循统一的消息格式与路由规则。
- 与现有单智能体模式完全隔离,不影响现有代码与用户体验。
---
## 2. 核心设计原则
### 2.1 完全隔离
- 数据目录隔离:`~/.astrion/astrion/host/mutiagents/`
- 页面隔离:新页面 `/multiagent/new`
- 入口隔离:登录页单独按钮「多智能体模式 beta」
- 代码隔离:所有新增代码放在 `modules/multi_agent/`、`docs/multi_agent_mode/`、`static/src/views/MultiAgentView.vue` 等独立位置
- 现有文件如需改造,优先复制一份再改,不直接修改
### 2.2 能复用则复用
- 模型调用:复用 `DeepSeekClient`
- 工具执行链路:复用 `WebTerminal.handle_tool_call` 的底层执行能力
- 文件/终端/搜索等工具:复用现有工具实现
- 对话持久化格式:复用 `ConversationManager` 的存储格式
- 沙箱/权限机制:复用现有 `evaluate_tool_permission` 与宿主机沙箱
### 2.3 子智能体即完整对话
每个子智能体是一个独立的、完整的对话上下文:
- 有自己的 `messages` 列表
- 有自己的系统提示词
- 有自己的工具列表
- 自然输出 assistant 消息
- 支持被主智能体/其他子智能体在运行中插入消息引导
- 任务结束 = 本轮自然停止输出,但上下文保留
---
## 3. 角色与实例
### 3.1 角色Role
角色由 Markdown + YAML Frontmatter 定义,存储在:
```
~/.astrion/astrion/host/mutiagents/agents/<role_id>.md
```
示例 `ui-operator.md`
```markdown
---
id: ui-operator
name: UI Operator
description: 负责前端设计、UI 还原、配色方案
model: qwen3-max
thinking_mode: fast
---
你是团队的前端设计专家。你擅长:
- 根据需求设计 UI 界面
- 制定配色方案
- 输出设计文档和前端代码
工作风格:
- 先分析需求,再给出设计方案
- 输出简洁明确的设计说明
```
### 3.2 实例Agent
- `role_id`:角色类型,如 `ui-operator`
- `agent_id`:这个角色的第几个实例,从 1 开始
- 显示名:`{Role Name}_{agent_id}`,如 `UI Operator_1`、`Full-Stack Engineer_1`
- 同一个 `role_id` 可以有多个实例UI Operator_1、UI Operator_2
- 不同 `role_id` 的实例序号独立Full-Stack Engineer_1 与 UI Operator_1 可以同时存在
- 主智能体固定显示名为 `Team Leader`,没有 agent_id
---
## 4. 总体架构图
```
┌─────────────────────────────────────────────────────────────┐
│ 用户Web 前端) │
│ /multiagent/new 页面 │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ MultiAgentTerminal │
│ (基于 MainTerminal 复制改造) │
│ - 工具列表:主工具 + 多智能体专用工具 │
│ - 子智能体管理器MultiAgentSubAgentManager │
│ - 对话存储:指向 mutiagents/conversations/ │
└─────────────────────────────────────────────────────────────┘
┌─────────────────┼─────────────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Agent 1 │ │ Agent 2 │ │ Agent 3 │
│UIOperator│ │ Full- │ │ Code │
│ 1 │ │ Stack │ │ Reviewer │
│ │ │Engineer1│ │ 1 │
└──────────┘ └──────────┘ └──────────┘
│ │ │
└─────────────────┴─────────────────┘
┌───────────────────────────────┐
│ MessageRouter │
│ 根据接收方状态决定: │
│ - inline 插入工具结果后 │
│ - 空闲时作为 user 消息触发新任务│
└───────────────────────────────┘
```
---
## 5. 主智能体职责
主智能体 = Team Leader其系统提示词中明确
- 除非任务极其简单或明确不需要,否则主动拆解任务并调用子智能体。
- 为每个子任务选择最合适的角色role_id
- 子智能体可以向你提问,你必须及时通过 `answer_sub_agent_question` 回答。
- 子智能体之间可以互相沟通,你负责监督整体进度。
- 如果子智能体的中间输出需要干预,使用 `send_message_to_sub_agent` 引导。
---
## 6. 子智能体职责
子智能体系统提示词由两部分组成:
1. **基础 prompt**:通用团队规则
2. **自定义 prompt**:角色专属设定
基础 prompt 中明确:
- 你是智能体集群团队的一员。
- 不要频繁输出内容,不重要内容会污染主智能体上下文。
- 只汇报关键步骤。
- 任务完成后给出详细结论。
- 需要主智能体决策时,使用 `ask_master`
- 需要与其他子智能体沟通时,使用 `ask_other_agent` / `answer_other_agent`
- 如果向其他子智能体提问,必须同时直接向主智能体输出汇报。
---
## 7. 与现有系统的边界
| 现有系统 | 多智能体模式处理方式 |
|---------|---------------------|
| 现有对话页面 | 不改动,新增 `/multiagent/new` |
| 现有 `MainTerminal` | 不改动,复制为 `MultiAgentTerminal` |
| 现有 `SubAgentManager` | 不改动,继承创建 `MultiAgentSubAgentManager` |
| 现有 `SubAgentTask` | 不改动,继承创建 `MultiAgentSubAgentTask` |
| 现有 `ConversationManager` | 不改动,多智能体模式用自己的存储目录 |
| 现有后台通知池机制 | 参考其设计,多智能体模式实现自己的消息路由 |
| 现有工具执行链路 | 复用 `execute_tool_for_sub_agent` |
| 现有沙箱/权限 | 复用,不额外限制子智能体工具参数 |
---
## 8. 入口与数据目录
### 8.1 入口
登录页面增加按钮:「多智能体模式 beta」。
点击后进入 `/multiagent/new` 页面,加载 `MultiAgentTerminal`
### 8.2 数据目录
```
~/.astrion/astrion/host/mutiagents/
├── agents/ # 角色定义
├── conversations/ # 多智能体会话
│ └── <conv_id>/
│ ├── metadata.json
│ ├── messages.json # Team Leader 对话
│ └── agents/
│ └── <agent_id>/
│ ├── metadata.json
│ └── messages.json # 子智能体完整对话记录
└── state.json # 全局状态
```
子智能体对话记录的保存精度、时机、格式与主智能体对话记录一致。
---
## 9. 实现顺序(非严格 phase
1. 创建独立目录与数据存储结构
2. 实现角色配置加载与预置角色
3. 实现 `MultiAgentSubAgentTask` / `MultiAgentSubAgentManager`
4. 实现 `MultiAgentTerminal` 与多智能体工具定义
5. 实现消息路由inline / idle / 通知池)
6. 实现前端 `/multiagent/new` 页面
7. 登录页加入口按钮
8. 联调测试
---
## 10. 相关文档
- `02_message_protocol.md`:统一消息格式
- `03_tool_definitions.md`:工具定义
- `04_message_routing.md`:消息路由机制
- `05_data_model.md`:数据模型
- `06_implementation_plan.md`:实现细节
- `07_existing_code_analysis.md`:现有代码分析

View File

@ -0,0 +1,249 @@
# 多智能体模式消息协议
> 所有插入对话的 user 消息必须遵循统一格式。
> 不使用 `[系统通知|xxx]` 前缀,改用自然语言前缀。
---
## 1. 消息格式模板
所有通信 user 消息都使用以下结构:
```
来自 {显示名} 的{消息类型}
id: {消息id}
<{显示名}>
<{标签}>
{内容}
</{标签}>
</{显示名}>
```
### 字段说明
| 字段 | 说明 | 示例 |
|------|------|------|
| 显示名 | `{Role Name}_{agent_id}``Team Leader` | `UI Operator_1`、`Full-Stack Engineer_1` |
| 消息类型 | 任务发布 / 任务进度输出 / 任务完成汇报 / 提问 / 消息 / 回答 | 见下表 |
| 消息id | 本次消息的全局唯一标识,用于 answer 时引用 | `ask_fse_001`、`msg_uio_003` |
| 标签 | Task / Output / Ask / Message / Answer | 与消息类型对应 |
| 内容 | 消息正文 | 任意文本 |
### 消息类型与标签对应表
| 消息类型 | 标签 | 发送方 | 接收方 |
|---------|------|--------|--------|
| 任务发布 | `<Task>` | Team Leader | 子智能体 |
| 任务进度输出 | `<Output>` | 子智能体 | Team Leader |
| 任务完成汇报 | `<Output>` | 子智能体 | Team Leader |
| 提问 | `<Ask>` | 子智能体 | Team Leader / 其他子智能体 |
| 消息 | `<Message>` | Team Leader / 子智能体 | 子智能体 |
| 回答 | `<Answer>` | 子智能体 | 子智能体(返回到 ask 工具结果) |
---
## 2. 主智能体 → 子智能体
### 2.1 任务发布
当主智能体通过 `create_sub_agent``send_message_to_sub_agent` 向子智能体发布任务时使用。
```
来自 Team Leader 的任务发布
id: task_001
<Team Leader>
<Task>
请为项目设计前端配色方案,输出 design.md 到 sub_agent_results/design/。
</Task>
</Team Leader>
```
### 2.2 后续消息 / 运行中引导
当主智能体在子智能体运行期间通过 `send_message_to_sub_agent` 插入引导消息时使用。
```
来自 Team Leader 的消息
id: msg_tl_002
<Team Leader>
<Message>
先不要创建 API先确认一下现有的 auth 模块是否可复用。
</Message>
</Team Leader>
```
### 2.3 主智能体问子智能体ask_sub_agent
当主智能体通过 `ask_sub_agent` 向子智能体提问时使用。
```
来自 Team Leader 的提问
id: ask_tl_001
<Team Leader>
<Ask>
你预计还需要多久完成?
</Ask>
</Team Leader>
```
子智能体的回答返回到 `ask_sub_agent` 工具结果中,不插入主智能体对话。
---
## 3. 子智能体 → 主智能体
### 3.1 任务进度输出
子智能体在自然输出中汇报进度时,由后端捕获并插入主智能体对话。
```
来自 UI Operator_1 的任务进度输出
id: out_uio_001
<UI Operator_1>
<Output>
我现在开始分析现有设计风格和用户需求...
</Output>
</UI Operator_1>
```
### 3.2 任务完成汇报
子智能体本轮自然结束输出时,最后一条输出作为完成汇报插入主智能体对话。
```
来自 UI Operator_1 的任务完成汇报
id: out_uio_002
<UI Operator_1>
<Output>
我完成了前端配色的设计,生成了 design.md主色调为蓝色系。
</Output>
</UI Operator_1>
```
**注意**:子智能体不调用 `report_progress``finish_task` 工具。自然的 assistant 输出即表示进度或完成。
### 3.3 子智能体向主智能体提问
子智能体通过 `ask_master` 工具向主智能体提问。
```
来自 Full-Stack Engineer_1 的提问
id: ask_fse_001
<Full-Stack Engineer_1>
<Ask>
我该怎么处理版本冲突问题?项目里当前用的是什么分支策略?
</Ask>
</Full-Stack Engineer_1>
```
主智能体通过 `answer_sub_agent_question` 工具回答,回答内容返回到 `ask_master` 工具结果中。
---
## 4. 子智能体 → 子智能体
### 4.1 A 向 B 提问
子智能体 A 通过 `ask_other_agent` 向子智能体 B 提问。
```
来自 UI Operator_1 的提问
id: ask_uio_001
<UI Operator_1>
<Ask>
API 接口已经确定了吗?我需要接口字段来设计表单。
</Ask>
</UI Operator_1>
```
这条消息插入到 B 的 user 消息中。
### 4.2 B 回答 A
子智能体 B 通过 `answer_other_agent` 回答 A。
```
来自 Full-Stack Engineer_1 的回答
id: ans_fse_001
<Full-Stack Engineer_1>
<Answer question_id="ask_uio_001">
已经确定,见 api.md。用户注册接口为 POST /api/users字段为...
</Answer>
</Full-Stack Engineer_1>
```
回答返回到 A 的 `ask_other_agent` 工具结果中。
### 4.3 A 向 B 发送普通消息
子智能体 A 通过 `ask_other_agent` 问 B但内容不是需要回答的问题而是通知。
```
来自 UI Operator_1 的消息
id: msg_uio_003
<UI Operator_1>
<Message>
前端页面已经 ready可以开始对接了。
</Message>
</UI Operator_1>
```
B 可以直接通过自然输出回复,回复会返回到 A 的 `ask_other_agent` 工具结果中。
---
## 5. ID 生成规则
| 消息类型 | ID 前缀 | 示例 |
|---------|---------|------|
| 任务发布 | `task_` | `task_001` |
| 任务进度输出 | `out_` | `out_uio_001` |
| 任务完成汇报 | `out_` | `out_uio_002` |
| 子智能体问主智能体 | `ask_` | `ask_fse_001` |
| 主智能体问子智能体 | `ask_` | `ask_tl_001` |
| 子智能体间提问 | `ask_` | `ask_uio_001` |
| 子智能体间回答 | `ans_` | `ans_fse_001` |
| 普通消息 | `msg_` | `msg_tl_002` |
ID 需要保证在多智能体会话内全局唯一。
---
## 6. 前端渲染
前端消息气泡只显示三部分:
1. 角色:如 `UI Operator_1`
2. 目的/动作:如 `任务进度输出`、`提问`、`消息`
3. 内容XML 标签内的文本
不显示 XML 标签本身。
示例渲染:
```
┌────────────────────────────────────┐
│ UI Operator_1 任务进度输出 │
│ │
│ 我现在开始分析现有设计风格... │
└────────────────────────────────────┘
```
---
## 7. 关键约束
1. 所有插入对话的 user 消息都必须包含完整的 XML 包裹,便于后端解析和前端渲染。
2. `id` 放在 XML 外面,不放在 `<>` 属性中。
3. 子智能体之间的通信不强制同步到主智能体,但子智能体必须在提示词中被要求:向其他子智能体提问时,必须同时直接向主智能体输出汇报。
4. 回答类消息(`answer_sub_agent_question`、`answer_other_agent`)不插入 user 消息,只返回到对应 ask 工具的结果中。

View File

@ -0,0 +1,470 @@
# 多智能体模式工具定义
> 主智能体工具基于现有主智能体工具,移除旧版子智能体工具,新增多智能体专用工具。
> 子智能体工具保留现有 8 个基础工具,新增多智能体通信工具。
> 所有工具定义集中在 `modules/multi_agent/tools/` 目录下,不修改现有 `core/main_terminal_parts/tools_definition/`
---
## 1. 主智能体Team Leader工具
主智能体 = Team Leader其工具列表 = 现有主智能体工具(去掉旧版子智能体工具) + 多智能体专用工具。
### 1.1 从现有工具中移除
以下旧版子智能体工具不在多智能体模式中使用:
- `create_sub_agent`(旧版)
- `close_sub_agent`
- `terminate_sub_agent`(旧版)
- `get_sub_agent_status`(旧版)
### 1.2 新增/替换的多智能体工具
#### `create_sub_agent`
创建并启动一个子智能体实例。
```json
{
"type": "function",
"function": {
"name": "create_sub_agent",
"description": "创建一个子智能体实例并启动它。一个角色可以有多个实例,如 UI Operator_1、UI Operator_2。",
"parameters": {
"type": "object",
"properties": {
"agent_id": {
"type": "integer",
"description": "这个角色的第几个实例,从 1 开始。同一 role_id 下每个编号只能用一次。"
},
"role_id": {
"type": "string",
"description": "角色 ID如 ui-operator、full-stack-engineer。"
},
"task": {
"type": "string",
"description": "任务描述,会作为给子智能体的首条任务发布消息。"
},
"run_in_background": {
"type": "boolean",
"description": "是否后台运行。多智能体模式下通常直接运行false因为需要观察输出。"
},
"timeout_seconds": {
"type": "integer",
"description": "超时时间,默认 600 秒。"
},
"thinking_mode": {
"type": "string",
"enum": ["fast", "thinking"],
"description": "思考模式,不指定则使用角色配置。"
},
"model_key": {
"type": "string",
"description": "模型 key不指定则使用角色配置。"
}
},
"required": ["agent_id", "role_id", "task"]
}
}
}
```
#### `terminate_sub_agent`
强制终止指定子智能体实例。
```json
{
"type": "function",
"function": {
"name": "terminate_sub_agent",
"description": "强制终止指定子智能体实例。终止后无法恢复,但已生成的文件保留。",
"parameters": {
"type": "object",
"properties": {
"agent_id": {
"type": "integer",
"description": "要终止的子智能体实例编号。"
}
},
"required": ["agent_id"]
}
}
}
```
#### `send_message_to_sub_agent`
向子智能体发送消息或运行中引导。不等待回答。
```json
{
"type": "function",
"function": {
"name": "send_message_to_sub_agent",
"description": "向指定子智能体发送消息。如果子智能体正在运行,消息会插入到当前输出流中作为引导;如果子智能体空闲,消息会触发新一轮运行。用于运行中纠正、补充上下文、追加指令。",
"parameters": {
"type": "object",
"properties": {
"agent_id": {
"type": "integer",
"description": "目标子智能体实例编号。"
},
"message": {
"type": "string",
"description": "要发送的消息内容。"
}
},
"required": ["agent_id", "message"]
}
}
}
```
#### `ask_sub_agent`
向子智能体提问并等待回答。
```json
{
"type": "function",
"function": {
"name": "ask_sub_agent",
"description": "向指定子智能体提问并等待其回答。适用于需要子智能体给出明确答复的场景。",
"parameters": {
"type": "object",
"properties": {
"agent_id": {
"type": "integer",
"description": "目标子智能体实例编号。"
},
"question": {
"type": "string",
"description": "问题内容。"
},
"question_id": {
"type": "string",
"description": "问题唯一 ID子智能体回答时会引用。"
}
},
"required": ["agent_id", "question", "question_id"]
}
}
}
```
#### `answer_sub_agent_question`
回答子智能体向主智能体提出的问题。
```json
{
"type": "function",
"function": {
"name": "answer_sub_agent_question",
"description": "回答子智能体提出的问题。回答会返回到子智能体 ask_master 工具的结果中。",
"parameters": {
"type": "object",
"properties": {
"agent_id": {
"type": "integer",
"description": "提问的子智能体实例编号。"
},
"question_id": {
"type": "string",
"description": "问题 ID与 ask_master 时一致。"
},
"answer": {
"type": "string",
"description": "回答内容。"
}
},
"required": ["agent_id", "question_id", "answer"]
}
}
}
```
#### `list_active_sub_agents`
查询当前多智能体会话中所有活跃/可通信的子智能体。
```json
{
"type": "function",
"function": {
"name": "list_active_sub_agents",
"description": "查询当前多智能体会话中所有活跃或可通信的子智能体列表,包括运行中和空闲的实例。",
"parameters": {
"type": "object",
"properties": {}
}
}
}
```
返回示例:
```json
{
"success": true,
"agents": [
{
"agent_id": 1,
"role_id": "ui-operator",
"display_name": "UI Operator_1",
"status": "running",
"summary": "设计前端配色方案"
},
{
"agent_id": 2,
"role_id": "full-stack-engineer",
"display_name": "Full-Stack Engineer_1",
"status": "idle",
"summary": "等待 API 接口确认"
}
]
}
```
#### `get_sub_agent_status`
查询指定子智能体的详细状态。
```json
{
"type": "function",
"function": {
"name": "get_sub_agent_status",
"description": "查询指定子智能体实例的详细状态、统计和最近输出。",
"parameters": {
"type": "object",
"properties": {
"agent_id": {
"type": "integer",
"description": "子智能体实例编号。"
}
},
"required": ["agent_id"]
}
}
}
```
#### `create_custom_agent`
创建并保存自定义角色。
```json
{
"type": "function",
"function": {
"name": "create_custom_agent",
"description": "创建一个自定义角色并保存到本地,后续可通过 role_id 调用。",
"parameters": {
"type": "object",
"properties": {
"role_id": {
"type": "string",
"description": "角色 ID唯一标识。"
},
"name": {
"type": "string",
"description": "角色显示名。"
},
"description": {
"type": "string",
"description": "角色简短描述。"
},
"model": {
"type": "string",
"description": "默认使用的模型。"
},
"thinking_mode": {
"type": "string",
"enum": ["fast", "thinking"],
"description": "默认思考模式。"
},
"prompt": {
"type": "string",
"description": "角色专属 prompt。"
}
},
"required": ["role_id", "name", "description", "prompt"]
}
}
}
```
#### `list_agents`
列出所有可用角色。
```json
{
"type": "function",
"function": {
"name": "list_agents",
"description": "列出所有可用的预置和自定义角色。",
"parameters": {
"type": "object",
"properties": {}
}
}
}
```
---
## 2. 子智能体工具
子智能体保留现有 8 个基础工具:
- `read_file`
- `write_file`
- `edit_file`
- `run_command`
- `web_search`
- `extract_webpage`
- `search_workspace`
- `read_mediafile`
新增以下多智能体通信工具:
### 2.1 `ask_master`
向主智能体Team Leader提问阻塞等待回答。
```json
{
"type": "function",
"function": {
"name": "ask_master",
"description": "向主智能体Team Leader提问。主智能体回答后会将结果返回到此工具调用中。",
"parameters": {
"type": "object",
"properties": {
"question": {
"type": "string",
"description": "问题内容。"
},
"question_id": {
"type": "string",
"description": "问题唯一 ID。"
}
},
"required": ["question", "question_id"]
}
}
}
```
### 2.2 `ask_other_agent`
向其他子智能体提问或发送消息,阻塞等待回复。
```json
{
"type": "function",
"function": {
"name": "ask_other_agent",
"description": "向其他子智能体提问或发送消息。对方回复后会将结果返回到此工具调用中。注意:向其他子智能体提问时,必须同时直接向主智能体输出汇报。",
"parameters": {
"type": "object",
"properties": {
"target_agent_id": {
"type": "integer",
"description": "目标子智能体实例编号。"
},
"content": {
"type": "string",
"description": "提问或消息内容。"
},
"message_id": {
"type": "string",
"description": "消息唯一 ID。"
}
},
"required": ["target_agent_id", "content", "message_id"]
}
}
}
```
### 2.3 `answer_other_agent`
回答其他子智能体的问题。
```json
{
"type": "function",
"function": {
"name": "answer_other_agent",
"description": "回答其他子智能体的问题。回答会返回到对方 ask_other_agent 工具的结果中。",
"parameters": {
"type": "object",
"properties": {
"source_agent_id": {
"type": "integer",
"description": "提问方的子智能体实例编号。"
},
"message_id": {
"type": "string",
"description": "对方提问时的 message_id。"
},
"answer": {
"type": "string",
"description": "回答内容。"
}
},
"required": ["source_agent_id", "message_id", "answer"]
}
}
}
```
### 2.4 `list_active_sub_agents`
查询当前活跃子智能体。
```json
{
"type": "function",
"function": {
"name": "list_active_sub_agents",
"description": "查询当前多智能体会话中所有活跃或可通信的子智能体。",
"parameters": {
"type": "object",
"properties": {}
}
}
}
```
---
## 3. 工具与消息映射
| 动作 | 工具 | 发送方 | 接收方形式 |
|------|------|--------|-----------|
| 创建子智能体 | `create_sub_agent` | Team Leader | 启动实例,首条消息以任务发布形式插入 |
| 终止子智能体 | `terminate_sub_agent` | Team Leader | 强制停止实例 |
| 向子智能体发消息/引导 | `send_message_to_sub_agent` | Team Leader | 插入子智能体 user 消息inline 或触发新任务) |
| Team Leader 问子智能体 | `ask_sub_agent` | Team Leader | 插入子智能体 user 消息,等待回复 |
| 子智能体问 Team Leader | `ask_master` | 子智能体 | 插入 Team Leader user 消息,等待回答 |
| Team Leader 回答子智能体 | `answer_sub_agent_question` | Team Leader | 返回到 `ask_master` 工具结果 |
| 子智能体 A 问 B | `ask_other_agent` | A | 插入 B 的 user 消息inline 或触发新任务) |
| 子智能体 B 回答 A | `answer_other_agent` | B | 返回到 A 的 `ask_other_agent` 工具结果 |
| 查询活跃子智能体 | `list_active_sub_agents` | 任意 | 返回列表 |
| 子智能体输出/汇报 | 自然 assistant 输出 | 子智能体 | 捕获后插入 Team Leader user 消息 |
---
## 4. 工具定义文件位置
- 主智能体工具:`modules/multi_agent/tools/master_tools.py`
- 子智能体工具:`modules/multi_agent/tools/agent_tools.py`
- 工具处理:`modules/multi_agent/tools/tool_handlers.py`
不修改现有 `core/main_terminal_parts/tools_definition.py``modules/sub_agent/toolkit.py`

View File

@ -0,0 +1,222 @@
# 多智能体模式消息路由机制
> 消息路由由**接收方**决定:根据接收方当前状态,选择 inline 插入工具结果后,或作为 user 消息触发新一轮任务。
> 参考现有后台任务通知池机制实现,保证消息不丢失、不错乱、可批量处理。
---
## 1. 核心思想
### 1.1 接收方决定插入方式
当一条消息需要发送给某个子智能体(或主智能体)时,路由层只关心接收方当前处于什么状态:
| 接收方状态 | 插入方式 | 效果 |
|-----------|---------|------|
| 正在运行中,且当前在某次工具调用中阻塞等待 | 把消息作为该工具调用的结果返回 | 子智能体在当前轮次继续执行,立即看到消息 |
| 正在运行中,但不在阻塞等待状态 | 把消息 inline 插入到当前对话上下文末尾 | 子智能体下一轮输出时自然看到 |
| 空闲状态(本轮已自然结束) | 把消息作为普通 user 消息插入 | 触发子智能体新一轮运行 |
### 1.2 参考现有后台通知池
现有后台任务通知机制:
- **运行期间inline**`server/chat_flow_tool_loop.py` 中 `execute_tool_calls` 末尾调用 `process_sub_agent_updates(..., inline=True)`,把已完成的子智能体任务一次性插入当前 `messages`,不触发新任务。
- **停止输出后polling**`server/chat_flow_task_main.py` 中 `handle_task_with_sender` 结尾启动 `run_completion_poll`,统一轮询子智能体 + 后台命令完成通知,批量插入 user 消息,只触发一个后续任务。
多智能体模式的消息路由借鉴此机制:
- 每个子智能体有自己的「待处理消息队列」。
- 子智能体每次进入可接收消息的状态时,从队列中取出所有消息,按顺序处理。
- 避免逐条消息触发多次「工作 → 停止 → 再工作」循环。
---
## 2. 消息路由状态机
### 2.1 子智能体状态
```
┌─────────────┐
│ idle │ 空闲
└──────┬──────┘
│ create_sub_agent / send_message_to_sub_agent
┌─────────────┐
│ running │ 运行中
│ (normal) │ 正常输出
└──────┬──────┘
│ 调用 ask_master / ask_other_agent
┌─────────────┐
│ waiting │ 阻塞等待回答
│ (asking) │
└──────┬──────┘
│ 收到 answer / 自然结束
┌─────────────┐
│ completed │ 本轮结束(上下文保留)
└─────────────┘
```
### 2.2 路由决策
```python
def route_message(target_agent_id, message):
agent = get_agent(target_agent_id)
if agent.state == "waiting" and agent.pending_tool_call:
# 目标正在阻塞等待回答:直接返回到工具结果
agent.resolve_pending_tool_call(message)
return "resolved"
if agent.state == "running":
# 目标正在运行inline 插入到当前对话上下文末尾
agent.inject_inline_message(message)
return "injected_inline"
if agent.state in ("idle", "completed"):
# 目标空闲:作为 user 消息插入,触发新一轮运行
agent.inject_user_message(message)
return "triggered_new_turn"
```
---
## 3. 关键场景分析
### 3.1 子智能体正在输出,主智能体要引导
场景:
- UI Operator_1 正在运行,输出了「接下来我会创建新 API...」
- Team Leader 要立即干预:「先不要创建 API先确认现有 auth 模块是否可复用。」
处理:
- UI Operator_1 状态为 `running`(正常输出,不在阻塞等待)
- `send_message_to_sub_agent` 的消息 inline 插入到 UI Operator_1 的 `messages` 末尾
- UI Operator_1 下一轮模型调用时会看到这条 user 消息
### 3.2 子智能体正在等待回答
场景:
- Full-Stack Engineer_1 调用了 `ask_master`,等待 Team Leader 回答
- Team Leader 调用 `answer_sub_agent_question`
处理:
- Full-Stack Engineer_1 状态为 `waiting`
- 回答直接返回到 `ask_master` 工具结果中
- Full-Stack Engineer_1 继续执行
### 3.3 子智能体已经完成,主智能体追加任务
场景:
- Full-Stack Engineer_1 已经自然结束输出,状态为 `completed`
- Team Leader 要追加新任务
处理:
- `send_message_to_sub_agent` 的消息作为普通 user 消息插入
- 触发 Full-Stack Engineer_1 新一轮运行
### 3.4 边界情况:子智能体正在进行最后一轮输出
场景:
- UI Operator_1 正在输出最后一段话,后面没有工具调用了
- Team Leader 此时调用 `send_message_to_sub_agent`
处理:
- 如果消息到达时 UI Operator_1 还在运行:尝试 inline 插入
- 但由于这是最后一轮后面没有工具调用了inline 的消息不会被模型看到
- 因此需要在 UI Operator_1 本轮任务结束后,把这条消息作为触发新一轮任务的 user 消息发送
实现要点:
- 路由层维护每个子智能体的「待处理消息队列」
- 子智能体任务自然结束时,检查队列
- 如果有待处理消息,立即作为 user 消息触发新一轮运行
### 3.5 子智能体 A 问 BB 正在运行
场景:
- UI Operator_1 调用 `ask_other_agent(target=2)` 问 Full-Stack Engineer_1
- Full-Stack Engineer_1 正在运行中
处理:
- 如果 Full-Stack Engineer_1 处于 `running` 状态inline 插入 user 消息
- Full-Stack Engineer_1 下一轮输出时看到问题
- 如果 Full-Stack Engineer_1 调用 `answer_other_agent`:回答返回到 UI Operator_1 的 `ask_other_agent` 工具结果
---
## 4. 待处理消息队列
每个子智能体维护一个待处理消息队列 `pending_messages`
```python
@dataclass
class PendingMessage:
id: str
source_display_name: str
source_agent_id: Optional[int]
target_agent_id: int
message_type: str # task / output / ask / message / answer
content: str
question_id: Optional[str] # 用于 answer 匹配
created_at: float
```
### 4.1 队列消费时机
1. 子智能体每次模型调用前,先检查队列,把待处理消息合并到 `messages`
2. 子智能体从 `waiting` 状态恢复时,优先消费回答类消息
3. 子智能体自然结束时,如果有剩余待处理消息,立即触发新一轮运行
### 4.2 批量消费
参考现有通知池,每次消费时尽可能一次性取出所有可消费消息:
```python
def consume_pending_messages(agent):
messages = agent.pending_messages.drain_all()
for msg in messages:
formatted = format_message(msg)
agent.messages.append({"role": "user", "content": formatted})
return len(messages)
```
---
## 5. 与现有通知池的对比
| 维度 | 现有后台通知池 | 多智能体消息路由 |
|------|--------------|----------------|
| 触发源 | 子智能体/后台命令完成 | 子智能体间/主智能体向子智能体发消息 |
| 接收方 | 主智能体对话 | 子智能体对话或主智能体对话 |
| 插入方式 | inline / 触发新任务 | inline / 返回到工具结果 / 触发新任务 |
| 批量处理 | `_collect_pending_completion_notices` 一次性取多条 | 每个子智能体维护自己的待处理队列 |
| 持久化 | 直接插入对话历史 | 先进入队列,再按状态消费并持久化 |
---
## 6. 消息路由实现位置
- 核心路由逻辑:`modules/multi_agent/message_router.py`
- 待处理队列:`MultiAgentSubAgentTask.pending_messages`
- 状态管理:`MultiAgentSubAgentTask.state`
- 工具调用等待:`MultiAgentSubAgentTask.pending_tool_calls`
---
## 7. 防丢失机制
1. 每条消息都有唯一 `id`
2. 消息进入队列时立即持久化到子智能体 metadata
3. 消费完成后从队列移除并持久化
4. 子智能体恢复时从 metadata 加载未消费消息
5. 回答类消息通过 `question_id` / `message_id` 精确匹配
---
## 8. 关键代码参考
- `server/chat_flow_task_support.py``inject_runtime_user_message`、`process_sub_agent_updates`
- `server/chat_flow_task_main.py``_collect_pending_completion_notices`、`poll_completion_notifications`、`_dispatch_completion_user_notice`
- `server/chat_flow_tool_loop.py``execute_tool_calls` 末尾的 `process_sub_agent_updates(..., inline=True)`

View File

@ -0,0 +1,304 @@
# 多智能体模式数据模型
> 所有数据存储在 `~/.astrion/astrion/host/mutiagents/` 下,与现有系统完全隔离。
> 子智能体对话记录的保存精度、时机、格式与主智能体对话记录一致。
---
## 1. 目录结构
```
~/.astrion/astrion/host/mutiagents/
├── agents/ # 角色定义
│ ├── ui-operator.md
│ ├── full-stack-engineer.md
│ ├── code-reviewer.md
│ └── researcher.md
├── conversations/ # 多智能体会话
│ └── <conv_id>/
│ ├── metadata.json # 会话级元数据
│ ├── messages.json # Team Leader 对话
│ └── agents/
│ └── <agent_id>/
│ ├── metadata.json # 子智能体元数据
│ └── messages.json # 子智能体完整对话
└── state.json # 全局状态
```
---
## 2. 角色定义Agent Role
文件路径:`agents/<role_id>.md`
格式YAML Frontmatter + Markdown 正文
```markdown
---
id: ui-operator
name: UI Operator
description: 负责前端设计、UI 还原、配色方案
model: qwen3-max
thinking_mode: fast
---
你是团队的前端设计专家...
```
### Frontmatter 字段
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `id` | string | 是 | 角色唯一标识,文件名也使用此 id |
| `name` | string | 是 | 角色显示名 |
| `description` | string | 是 | 角色简短描述 |
| `model` | string | 否 | 默认模型 key |
| `thinking_mode` | string | 否 | fast / thinking |
### 正文
正文部分为角色专属 prompt会拼接在基础 prompt 之后。
---
## 3. 全局状态state.json
```json
{
"version": "1.0",
"last_conversation_id": "conv_xxx",
"agent_id_counter": 5,
"created_at": "2026-07-11T21:00:00",
"updated_at": "2026-07-11T21:30:00"
}
```
| 字段 | 说明 |
|------|------|
| `version` | 数据格式版本 |
| `last_conversation_id` | 最近一次会话 id |
| `agent_id_counter` | 全局实例编号计数器(可选) |
---
## 4. 会话元数据metadata.json
```json
{
"id": "conv_20260711_210000_001",
"title": "多智能体任务:设计前端",
"created_at": "2026-07-11T21:00:00",
"updated_at": "2026-07-11T21:30:00",
"project_path": "/Users/jojo/project",
"model_key": "qwen3-max",
"thinking_mode": true,
"run_mode": "thinking",
"status": "active",
"agent_count": 3,
"agent_ids": [1, 2, 3]
}
```
| 字段 | 说明 |
|------|------|
| `id` | 会话 id |
| `title` | 会话标题 |
| `created_at` | 创建时间 |
| `updated_at` | 更新时间 |
| `project_path` | 关联项目路径 |
| `model_key` | Team Leader 使用的模型 |
| `thinking_mode` | 是否思考模式 |
| `run_mode` | fast / thinking / deep |
| `status` | active / archived |
| `agent_count` | 当前子智能体数量 |
| `agent_ids` | 当前子智能体 agent_id 列表 |
---
## 5. 主智能体对话messages.json
与现有 `ConversationManager` 保存格式一致。
```json
{
"id": "conv_20260711_210000_001",
"title": "多智能体任务:设计前端",
"created_at": "2026-07-11T21:00:00",
"updated_at": "2026-07-11T21:30:00",
"messages": [
{
"role": "user",
"content": "帮我设计一个前端页面",
"message_id": "msg_user_001",
"metadata": {
"message_source": "user",
"visibility": "chat",
"starts_work": true
}
},
{
"role": "assistant",
"content": "我来安排 UI Operator 处理这个任务...",
"message_id": "msg_assistant_001",
"tool_calls": [...]
},
{
"role": "user",
"content": "来自 UI Operator_1 的任务完成汇报\nid: out_uio_001\n\n<UI Operator_1>\n<Output>\n我完成了前端配色的设计...\n</Output>\n</UI Operator_1>",
"message_id": "msg_auto_001",
"metadata": {
"message_source": "sub_agent",
"visibility": "compact",
"starts_work": false,
"agent_id": 1
}
}
],
"metadata": { ... },
"token_statistics": { ... }
}
```
---
## 6. 子智能体元数据agents/<agent_id>/metadata.json
```json
{
"agent_id": 1,
"role_id": "ui-operator",
"display_name": "UI Operator_1",
"status": "running",
"created_at": "2026-07-11T21:05:00",
"updated_at": "2026-07-11T21:15:00",
"task_summary": "设计前端配色方案",
"model_key": "qwen3-max",
"thinking_mode": "fast",
"pending_messages": [
{
"id": "msg_tl_001",
"source_display_name": "Team Leader",
"source_agent_id": null,
"message_type": "message",
"content": "先不要创建 API...",
"created_at": 1752251700.0
}
],
"pending_tool_calls": [
{
"tool_call_id": "tc_ask_001",
"tool_name": "ask_master",
"question_id": "ask_uio_001",
"created_at": 1752251800.0
}
]
}
```
| 字段 | 说明 |
|------|------|
| `agent_id` | 实例编号 |
| `role_id` | 角色 id |
| `display_name` | 显示名 |
| `status` | running / waiting / idle / completed / terminated |
| `task_summary` | 当前任务摘要 |
| `pending_messages` | 待处理消息队列 |
| `pending_tool_calls` | 正在等待回答的工具调用 |
---
## 7. 子智能体对话agents/<agent_id>/messages.json
保存精度、时机、格式与主智能体对话完全一致。
```json
{
"agent_id": 1,
"role_id": "ui-operator",
"display_name": "UI Operator_1",
"created_at": "2026-07-11T21:05:00",
"updated_at": "2026-07-11T21:15:00",
"messages": [
{
"role": "system",
"content": "你是智能体集群团队的一员..."
},
{
"role": "user",
"content": "来自 Team Leader 的任务发布\nid: task_001\n\n<Team Leader>\n<Task>\n请为项目设计前端配色方案...\n</Task>\n</Team Leader>",
"message_id": "msg_user_001"
},
{
"role": "assistant",
"content": "我先分析一下现有设计风格...",
"message_id": "msg_assistant_001"
},
{
"role": "user",
"content": "来自 Team Leader 的消息\nid: msg_tl_001\n\n<Team Leader>\n<Message>\n先不要创建 API...\n</Message>\n</Team Leader>",
"message_id": "msg_user_002"
},
{
"role": "assistant",
"content": "好的,我先确认现有 auth 模块...",
"message_id": "msg_assistant_002"
}
]
}
```
---
## 8. 持久化策略
### 8.1 保存时机
- 每次模型调用前保存子智能体 metadata 和 messages
- 每次工具调用后保存
- 每次状态变更时保存
- 每次收到外部消息并处理后保存
### 8.2 原子写入
参考 `ConversationManager._atomic_write_json`,使用临时文件 + replace
```python
def _atomic_write_json(path: Path, data: dict):
tmp = path.with_suffix(path.suffix + ".tmp")
tmp.write_text(json.dumps(data, ensure_ascii=False, indent=2), encoding="utf-8")
tmp.replace(path)
```
### 8.3 索引
参考 `ConversationManager` 的索引机制,在 `conversations/index.json` 中维护会话列表:
```json
{
"conv_20260711_210000_001": {
"title": "多智能体任务:设计前端",
"created_at": "2026-07-11T21:00:00",
"updated_at": "2026-07-11T21:30:00",
"agent_count": 3
}
}
```
---
## 9. 与现有 ConversationManager 的关系
多智能体模式实现自己的 `MultiAgentConversationStore`,但:
- 数据格式与 `ConversationManager` 保持一致
- 文件结构与 `ConversationManager` 类似
- 不修改 `utils/conversation_manager/` 任何文件
- 可以复制 `ConversationManager` 的 CRUD 代码到 `MultiAgentConversationStore`
---
## 10. 实现位置
- 角色存储:`modules/multi_agent/agent_store.py`
- 会话存储:`modules/multi_agent/conversation_store.py`
- 全局状态:`modules/multi_agent/manager.py`

View File

@ -0,0 +1,235 @@
# 多智能体模式实现计划
> 实现顺序不作为严格 phase而是按依赖关系自然推进。
> 核心原则:完全隔离、复制改造、底层复用。
---
## 1. 目录与文件规划
### 1.1 后端代码
```
modules/multi_agent/
├── __init__.py
├── terminal.py # MultiAgentTerminal
├── manager.py # 多智能体会话与全局状态管理
├── agent_store.py # 角色配置加载与保存
├── conversation_store.py # 多智能体会话存储
├── message_router.py # 消息路由与待处理队列
├── sub_agent_task.py # MultiAgentSubAgentTask
├── sub_agent_manager.py # MultiAgentSubAgentManager
├── prompts.py # prompt 模板
└── tools/
├── __init__.py
├── master_tools.py # Team Leader 工具定义
├── agent_tools.py # 子智能体工具定义
└── tool_handlers.py # 工具处理函数
```
### 1.2 前端代码
```
static/src/views/MultiAgentView.vue
static/src/components/multi-agent/
├── ChatPanel.vue
├── AgentList.vue
├── MessageBubble.vue
└── CreateAgentDialog.vue
```
### 1.3 设计文档
```
docs/multi_agent_mode/
├── 01_overview.md
├── 02_message_protocol.md
├── 03_tool_definitions.md
├── 04_message_routing.md
├── 05_data_model.md
├── 06_implementation_plan.md
└── 07_existing_code_analysis.md
```
### 1.4 数据目录
```
~/.astrion/astrion/host/mutiagents/
├── agents/
├── conversations/
└── state.json
```
---
## 2. 实现步骤
### Step 1基础设施
1. 创建 `modules/multi_agent/`
2. 创建 `docs/multi_agent_mode/` 目录(已完成)
3. 创建 `~/.astrion/astrion/host/mutiagents/` 数据目录
4. 预置 4 个角色文件到 `agents/`
### Step 2角色配置
1. 实现 `agent_store.py`
- 加载角色 Frontmatter
- 保存自定义角色
- 列出所有角色
- 构建完整 prompt基础 prompt + 自定义 prompt
2. 预置角色:
- `ui-operator`
- `full-stack-engineer`
- `code-reviewer`
- `researcher`
### Step 3子智能体改造
1. 实现 `MultiAgentSubAgentTask`(继承 `SubAgentTask`
- 覆盖 `_run_loop`,使用多智能体工具列表
- 覆盖系统提示词生成
- 捕获 assistant 输出并转发到主智能体
- 维护 `pending_messages` 队列
- 维护 `pending_tool_calls` 等待列表
- 支持 inline 消息注入
- 支持自然结束(不依赖 finish_task
2. 实现 `MultiAgentSubAgentManager`(继承 `SubAgentManager`
- 创建 `MultiAgentSubAgentTask` 实例
- 管理所有子智能体状态
- 提供查询活跃子智能体接口
- 提供终止实例接口
### Step 4消息路由
1. 实现 `message_router.py`
- `route_message(target_agent_id, message)`
- 根据目标状态选择 inline / 工具结果返回 / 触发新任务
- 处理边界情况(最后一轮输出时收到消息)
- 批量消费待处理消息
2. 实现消息格式化函数
- `format_task_message(display_name, content)`
- `format_output_message(display_name, content)`
- `format_ask_message(display_name, content, message_id)`
- `format_message_message(display_name, content, message_id)`
- `format_answer_message(display_name, content, message_id)`
### Step 5主智能体 Terminal
1. 实现 `MultiAgentTerminal`(基于 `MainTerminal` 复制)
- 移除旧版子智能体工具
- 添加多智能体专用工具
- 使用 `MultiAgentSubAgentManager`
- 使用 `MultiAgentConversationStore`
- 实现 `answer_sub_agent_question` 等工具处理
2. 实现工具处理函数
- `create_sub_agent`
- `terminate_sub_agent`
- `send_message_to_sub_agent`
- `ask_sub_agent`
- `answer_sub_agent_question`
- `list_active_sub_agents`
- `get_sub_agent_status`
- `create_custom_agent`
- `list_agents`
### Step 6会话存储
1. 实现 `MultiAgentConversationStore`
- 复制 `ConversationManager` 的 CRUD 逻辑
- 数据目录指向 `~/.astrion/astrion/host/mutiagents/conversations/`
- 保存主智能体对话
- 保存每个子智能体对话
### Step 7前端页面
1. 创建 `MultiAgentView.vue`
- 类似现有 ChatView但专门用于多智能体模式
- 支持消息气泡按角色/类型渲染
- 支持显示活跃子智能体列表
- 支持创建子智能体
2. 创建组件
- `MessageBubble.vue`:渲染统一消息格式
- `AgentList.vue`:显示子智能体状态
- `CreateAgentDialog.vue`:创建自定义角色
3. 添加路由 `/multiagent/new`
### Step 8入口
1. 登录页添加「多智能体模式 beta」按钮
2. 点击后跳转到 `/multiagent/new`
3. 初始化 `MultiAgentTerminal`
### Step 9联调测试
1. 测试创建子智能体
2. 测试子智能体自然输出转发
3. 测试 `send_message_to_sub_agent` 运行中引导
4. 测试 `ask_master` / `answer_sub_agent_question`
5. 测试 `ask_other_agent` / `answer_other_agent`
6. 测试子智能体对话持久化
7. 测试角色创建与保存
---
## 3. 代码隔离清单
| 现有文件 | 处理方式 |
|---------|---------|
| `core/main_terminal.py` | 复制为 `modules/multi_agent/terminal.py` |
| `core/main_terminal_parts/tools_definition/agent_tools.py` | 复制改造为 `modules/multi_agent/tools/master_tools.py` |
| `core/main_terminal_parts/tools_execution.py` | 复制需要的部分到 `modules/multi_agent/terminal.py` |
| `modules/sub_agent/manager.py` | 继承创建 `modules/multi_agent/sub_agent_manager.py` |
| `modules/sub_agent/task.py` | 继承创建 `modules/multi_agent/sub_agent_task.py` |
| `modules/sub_agent/toolkit.py` | 复制改造为 `modules/multi_agent/tools/agent_tools.py` |
| `modules/sub_agent/prompts.py` | 复制改造为 `modules/multi_agent/prompts.py` |
| `utils/conversation_manager/*.py` | 复制改造为 `modules/multi_agent/conversation_store.py` |
| `server/chat_flow.py` | 参考实现,为 `/multiagent` 创建新的 API 入口 |
| `server/chat_flow_task_support.py` | 参考 `inject_runtime_user_message` 实现多智能体消息注入 |
| `static/src/views/ChatView.vue` | 复制改造为 `static/src/views/MultiAgentView.vue` |
---
## 4. 复用点清单
| 能力 | 复用方式 |
|------|---------|
| 模型调用 | `DeepSeekClient` |
| 工具执行底层 | `WebTerminal.handle_tool_call` 的执行链路 |
| 文件/终端/搜索等工具 | 现有工具函数 |
| 沙箱/权限 | `evaluate_tool_permission` |
| 对话存储格式 | `ConversationManager` 的 JSON 结构 |
| 原子写入 | `_atomic_write_json` 模式 |
| 前端组件 | 复制 ChatView 改造 |
---
## 5. 风险与应对
| 风险 | 应对 |
|------|------|
| 子智能体消息丢失 | 待处理队列持久化 + 唯一 id + 消费确认 |
| 子智能体状态错乱 | 状态机清晰 + reconcile 机制 |
| 主智能体上下文爆炸 | 子智能体只汇报关键步骤,详细内容放文件 |
| 多实例并发冲突 | 每个实例独立上下文,独立存储 |
| 与现有代码耦合 | 严格隔离,复制改造 |
---
## 6. 验收标准
1. 登录页有「多智能体模式 beta」按钮
2. 点击后进入 `/multiagent/new`
3. 可以创建至少 2 个不同角色的子智能体
4. 子智能体输出自动显示在主对话中
5. Team Leader 可以运行中引导子智能体
6. 子智能体可以向 Team Leader 提问并收到回答
7. 子智能体可以向其他子智能体提问并收到回答
8. 子智能体对话完整保存,刷新后可恢复
9. 现有单智能体模式不受影响

View File

@ -0,0 +1,277 @@
# 多智能体模式:现有代码分析
> 本文档梳理实现多智能体模式需要理解的现有代码,为复制改造提供依据。
---
## 1. 子智能体实现
### 1.1 核心文件
```
modules/sub_agent/
├── __init__.py
├── manager.py # SubAgentManager
├── task.py # SubAgentTask
├── toolkit.py # 工具定义
├── prompts.py # 提示词
├── state.py # 状态管理
├── stats.py # 统计
├── creation.py # 创建参数
└── tools.py # 本地工具实现
```
### 1.2 SubAgentManagermanager.py
- 在主进程内以独立事件循环运行子智能体协程
- `create_sub_agent()` 创建并启动任务
- `wait_for_completion()` 阻塞等待完成
- `terminate_sub_agent()` 强制终止
- `poll_updates()` 检查已完成任务
- `execute_tool_for_sub_agent()` 代理工具执行,复用主进程链路
- `tasks` 字典保存所有任务状态
多智能体模式可继承点:
- 创建 `MultiAgentSubAgentManager`,重写 `create_sub_agent` 以创建 `MultiAgentSubAgentTask`
- 扩展任务记录字段:`role_id`、`display_name`、`pending_messages`、`pending_tool_calls`
- 扩展查询接口:`list_active_sub_agents()`、`get_sub_agent_status()`
### 1.3 SubAgentTasktask.py
- `_run_loop()`LLM 主循环,最多 50 轮
- `_call_model()`:流式调用模型
- `_execute_tool()`:通过 manager 执行工具
- `_finalize_task()`:任务结束时保存 output.json、stats.json、conversation.json
- `FINISH_TOOL`:必须调用 finish_task 才结束
多智能体模式改造点:
- 移除 `FINISH_TOOL` 依赖,自然结束输出即任务完成
- 在 `_run_loop` 中每轮模型调用前消费 `pending_messages`
- 捕获 assistant 输出并转发到主智能体对话
- 新增 `ask_master`、`ask_other_agent`、`answer_other_agent` 工具处理
- 维护 `pending_tool_calls`,支持阻塞等待回答
### 1.4 工具定义toolkit.py
现有 8 个工具:
- `read_file`
- `write_file`
- `edit_file`
- `run_command`
- `web_search`
- `extract_webpage`
- `search_workspace`
- `read_mediafile`
多智能体模式可复用这些工具定义,新增通信工具。
### 1.5 提示词prompts.py
- `build_user_message()`:给子智能体的任务消息
- `build_system_prompt()`:子智能体系统提示词
多智能体模式需要:
- 新的 `build_system_prompt()`,包含团队规则
- 新的 `build_user_message()`,使用统一消息格式
- 角色 prompt 拼接函数
---
## 2. 后台任务通知池机制
### 2.1 核心文件
- `server/chat_flow_task_support.py`
- `server/chat_flow_task_main.py`
- `server/chat_flow_tool_loop.py`
### 2.2 inject_runtime_user_message
位置:`server/chat_flow_task_support.py`
功能:运行期/空闲期统一向对话插入一条 user 消息。
关键参数:
- `web_terminal`:终端实例
- `messages`当前运行中的消息列表inline 时用)
- `text`:消息文本
- `source`:消息来源,如 `sub_agent`
- `inline`True 表示运行期插入,不触发新任务
- `persist`:是否持久化到对话历史
多智能体模式参考点:
- 子智能体输出转发到主智能体时,使用类似机制
- 但消息格式改为统一 XML 格式,不使用 `[系统通知|sub_agent]` 前缀
### 2.3 process_sub_agent_updates
位置:`server/chat_flow_task_support.py`
功能:轮询子智能体完成状态,把结果插入当前对话上下文。
两种模式:
- `inline=True`:运行期间,插入 `messages` 不触发新任务
- `inline=False`:空闲期间,触发后续任务
多智能体模式参考点:
- 子智能体自然输出捕获后,可以 inline 插入主智能体 `messages`
- 子智能体空闲时收到的消息,作为 user 消息触发新任务
### 2.4 _collect_pending_completion_notices
位置:`server/chat_flow_task_main.py`
功能:从子智能体和后台命令两路统一取出所有待通知项,按时间排序,一次性处理。
关键设计:
- 取出时即就地标记 `notified`,防止重复消费
- 返回多条通知时,前 N-1 条作为前置通知,最后一条触发新任务
多智能体模式参考点:
- 每个子智能体维护自己的待处理消息队列
- 消费时批量取出,避免多次触发新任务
- 使用唯一 id 标记已消费
### 2.5 poll_completion_notifications
位置:`server/chat_flow_task_main.py`
功能:统一轮询器,单工作区只 spawn 一个,避免并发冲突。
多智能体模式参考点:
- 多智能体模式也需要一个类似的通知/消息处理循环
- 但消息源更多Team Leader → Agent、Agent → Agent、Agent → Team Leader
---
## 3. 主智能体工具调用链路
### 3.1 工具定义
位置:`core/main_terminal_parts/tools_definition/agent_tools.py`
现有主智能体子智能体工具:
- `create_sub_agent`
- `close_sub_agent`
- `terminate_sub_agent`
- `get_sub_agent_status`
多智能体模式需要移除这些,新增自己的工具定义。
### 3.2 工具执行
位置:`core/main_terminal_parts/tools_execution.py` 中 `handle_tool_call`
- 参数预检查
- 权限检查
- 根据 tool_name 分发到具体处理函数
- 返回 JSON 字符串
多智能体模式参考点:
- `MultiAgentTerminal.handle_tool_call` 中增加多智能体工具的分支
- 子智能体工具处理函数放在 `modules/multi_agent/tools/tool_handlers.py`
### 3.3 WebTerminal 广播
位置:`core/web_terminal.py`
- `handle_tool_call()` 覆盖父类,广播 `tool_execution_start` / `tool_status` / `tool_execution_complete`
- `broadcast()` 发送 WebSocket 事件
多智能体模式参考点:
- `MultiAgentTerminal` 可继承 `WebTerminal``MainTerminal`
- 保留广播能力
---
## 4. 对话上下文管理
### 4.1 ContextManager
位置:`utils/context_manager/`
- `ConversationMixin.start_new_conversation()`:创建新对话
- `ConversationMixin.load_conversation_by_id()`:加载对话
- `ConversationMixin.save_current_conversation()`:保存当前对话
多智能体模式参考点:
- 创建 `MultiAgentContextManager` 或直接用 `MultiAgentConversationStore`
- 保存格式与现有 `messages.json` 一致
### 4.2 ConversationManager
位置:`utils/conversation_manager/`
- `crud_mixin.py``create_conversation`、`save_conversation`、`load_conversation`
- `path_mixin.py`:文件路径管理
- `index_mixin.py`:索引管理
多智能体模式参考点:
- 复制 `ConversationManager` 的实现到 `MultiAgentConversationStore`
- 修改数据目录为 `~/.astrion/astrion/host/mutiagents/conversations/`
---
## 5. Skill 归档机制
### 5.1 核心文件
`modules/skills_manager.py`
### 5.2 关键函数
- `validate_skill_directory()`:验证 skill 目录
- `archive_skill_directory()`:移动 skill 到归档目录
- `_parse_frontmatter()`:解析 YAML Frontmatter
- `_scan_skills_catalog()`:扫描 skill 目录
多智能体模式参考点:
- 角色配置使用类似的 Frontmatter 格式
- 角色归档目录:`~/.astrion/astrion/host/mutiagents/agents/`
- 可以复制 `_parse_frontmatter`、`_scan_skills_catalog` 的实现到 `agent_store.py`
---
## 6. 前端消息渲染
### 6.1 现有机制
- `server/chat_flow_task_support.py``inject_runtime_user_message` 发送 `user_message` 事件
- 前端 `messaging.ts` 处理 `user_message` 事件
- 根据 `message_source`、`visibility`、`starts_work` 等 metadata 渲染
### 6.2 多智能体模式改造点
- 多智能体消息也发送 `user_message` 事件
- 前端根据消息内容中的 XML 解析出角色、类型、内容
- 渲染为特殊气泡,不显示 XML 标签
---
## 7. 关键接口总结
| 能力 | 现有实现位置 | 多智能体模式实现位置 |
|------|------------|-------------------|
| 子智能体创建/管理 | `modules/sub_agent/manager.py` | `modules/multi_agent/sub_agent_manager.py` |
| 子智能体运行循环 | `modules/sub_agent/task.py` | `modules/multi_agent/sub_agent_task.py` |
| 子智能体工具 | `modules/sub_agent/toolkit.py` | `modules/multi_agent/tools/agent_tools.py` |
| 子智能体提示词 | `modules/sub_agent/prompts.py` | `modules/multi_agent/prompts.py` |
| 主智能体工具定义 | `core/main_terminal_parts/tools_definition/agent_tools.py` | `modules/multi_agent/tools/master_tools.py` |
| 主智能体工具执行 | `core/main_terminal_parts/tools_execution.py` | `modules/multi_agent/terminal.py` |
| 运行时消息注入 | `server/chat_flow_task_support.py` | `modules/multi_agent/message_router.py` |
| 通知池轮询 | `server/chat_flow_task_main.py` | `modules/multi_agent/message_router.py` |
| 对话存储 | `utils/conversation_manager/` | `modules/multi_agent/conversation_store.py` |
| 角色归档 | `modules/skills_manager.py` | `modules/multi_agent/agent_store.py` |
| 前端页面 | `static/src/views/ChatView.vue` | `static/src/views/MultiAgentView.vue` |
---
## 8. 实现注意事项
1. **不要修改现有文件**:所有改造在 `modules/multi_agent/` 中完成,通过继承或复制实现。
2. **状态同步**:子智能体状态变更时需要同步更新 `metadata.json`
3. **消息不丢失**:待处理消息队列需要持久化。
4. **上下文隔离**:每个子智能体独立 messages不要互相污染。
5. **模型工具列表**:每轮模型调用前需要重新构造工具列表,确保多智能体通信工具可用。
6. **自然结束检测**:子智能体某轮没有工具调用且 assistant 输出为空时,认为本轮结束。
7. **阻塞问答超时**`ask_master` / `ask_other_agent` 需要设置合理超时,避免永久阻塞。