GPU_GUARD_MONOREPO/docs/superpowers/specs/2026-04-12-netaclaw-agent-skill-migration-design.md

235 lines
9.2 KiB
Markdown
Raw Normal View History

2026-05-20 21:39:12 +08:00
# NetaClaw Agent/Skill 管理迁移设计文档
> **日期**: 2026-04-12
> **状态**: 已批准
> **范围**: 将 Agent 管理、Skill 管理、Agent 对话页面从旧接口迁移到 NetaClaw 运行时
---
## 1. 背景与目标
现有前端 3 个页面Agent 管理、Skill 管理、Agent 对话)调用的是旧的 `/admin/agent/*``/open/agent/*` 接口体系,后端对应旧的 LangChain Agent 模块。
NetaClaw 模块已从 OpenClaw小龙虾迁移了 Agent 运行时ReAct 循环、工具系统、LLM 提供商),但缺少管理层接口。
**目标:**
- 后端在 NetaClaw 模块补全 Agent CRUD、Skill 管理、会话管理接口
- 前端统一切到 NetaClaw 接口
- 对话通信从 SSE 改为 WebSocket
- 删除旧 agent 模块代码和数据库表
## 2. 核心决策
| 决策项 | 结论 | 理由 |
|--------|------|------|
| 旧模块处理 | 直接删除 | 旧数据是保险审核场景,电商场景用不上 |
| Agent 存储 | 数据库 + 后台管理 | 保持管理页面 CRUD 体验 |
| 通信方式 | WebSocket 流式 | 与 NetaClaw 现有 WS Gateway 一致 |
| Skill 管理 | SKILL.md + 数据库状态 | 文件定义内容,数据库控制启用/禁用 |
| 数据库表 | 全部新建 netaclaw_ 前缀 | 旧 agent_* 表和数据全部删除 |
## 3. 数据库设计
### 3.1 新建表
#### `netaclaw_agent` — Agent 配置
| 字段 | 类型 | 约束 | 说明 |
|------|------|------|------|
| id | int | PK, AUTO_INCREMENT | 主键 |
| createTime | varchar(255) | NOT NULL | 创建时间 |
| updateTime | varchar(255) | NOT NULL | 更新时间 |
| tenantId | int | nullable, INDEX | 租户ID |
| name | varchar(100) | UNIQUE, NOT NULL | 唯一标识,如 `agent_xxxxx` |
| label | varchar(200) | NOT NULL | 显示名称 |
| description | text | nullable | 描述 |
| icon | varchar(100) | nullable | 图标 |
| systemPrompt | text | nullable | 系统提示词 |
| skills | json | nullable | 关联 Skill 名称列表 `string[]` |
| modelConfig | json | nullable | `{apiUrl, apiKey, modelId, contextWindow}` |
| config | json | nullable | `{welcomeMessage, middleware: {maxToolRounds, ...}}` |
| status | int | NOT NULL, DEFAULT 0, INDEX | 0=草稿, 1=已发布 |
#### `netaclaw_skill` — Skill 状态管理
| 字段 | 类型 | 约束 | 说明 |
|------|------|------|------|
| id | int | PK, AUTO_INCREMENT | 主键 |
| createTime | varchar(255) | NOT NULL | 创建时间 |
| updateTime | varchar(255) | NOT NULL | 更新时间 |
| tenantId | int | nullable, INDEX | 租户ID |
| name | varchar(100) | UNIQUE, NOT NULL | 对应 SKILL.md 的 name |
| label | varchar(200) | NOT NULL | 显示名称 |
| description | text | nullable | 描述 |
| icon | varchar(100) | nullable | 图标 |
| category | varchar(50) | nullable | 分类 |
| skillType | varchar(20) | nullable | compute/llm/multimodal |
| tags | json | nullable | 标签 |
| config | json | nullable | 配置 |
| status | int | NOT NULL, DEFAULT 1, INDEX | 0=禁用, 1=启用 |
| version | varchar(20) | nullable | 版本号 |
### 3.2 复用表(已存在,无数据)
- **`netaclaw_session`** — 增加 `agentId` int 字段关联 Agent
- **`netaclaw_message`** — 不改
### 3.3 删除表
- `agent_info`, `agent_skill`, `agent_session`, `agent_message`
- `agent_checkpoints`, `agent_checkpoint_writes`, `agent_configs`, `skill_configs`
## 4. 后端接口设计
### 4.1 Agent 管理 Controller
文件:`netaclaw/controller/agent.ts`
| 方法 | 路径 | 参数 | 返回 |
|------|------|------|------|
| POST | `/admin/netaclaw/agent/page` | `{page, size, keyWord?}` | 分页列表 |
| POST | `/admin/netaclaw/agent/add` | Agent 完整对象 | `{id}` |
| POST | `/admin/netaclaw/agent/update` | Agent 完整对象 | 成功/失败 |
| POST | `/admin/netaclaw/agent/delete` | `{ids: number[]}` | 成功/失败 |
| GET | `/admin/netaclaw/agent/info` | `?id=number` | Agent 详情 |
| POST | `/open/netaclaw/agent/list` | 无 | 已发布 Agent 列表 |
### 4.2 Skill 管理 Controller
文件:`netaclaw/controller/skill.ts`
| 方法 | 路径 | 参数 | 返回 |
|------|------|------|------|
| GET | `/admin/netaclaw/skill/metas` | 无 | Skill 元数据列表SKILL.md + DB 合并) |
| POST | `/admin/netaclaw/skill/setStatus` | `{name, status}` | 成功/失败 |
**合并逻辑:** SkillLoader 扫描 SKILL.md 文件获取内容,与数据库 `netaclaw_skill` 表的 status 字段合并。如果 SKILL.md 存在但数据库无记录,自动创建记录(默认启用)。
### 4.3 会话管理 Controller
文件:`netaclaw/controller/session.ts`
| 方法 | 路径 | 参数 | 返回 |
|------|------|------|------|
| POST | `/open/netaclaw/session/list` | `{userId?}` | 会话列表 |
| POST | `/open/netaclaw/session/messages` | `{sessionId}` | 消息历史 |
| POST | `/open/netaclaw/session/delete` | `{sessionId}` | 成功/失败 |
| POST | `/open/netaclaw/session/deleteAll` | `{userId?}` | 成功/失败 |
### 4.4 WebSocket Gateway 增强
文件:`netaclaw/gateway/server.ts`
**客户端 → 服务端:**
```typescript
// chat 事件增加 agentId
{ type: 'chat', sessionId?: string, content: string, agentId?: number }
```
**服务端 → 客户端(新增事件):**
```typescript
{ type: 'skill_start', sessionId, name, label }
{ type: 'skill_end', sessionId, name, status, result?, tokens? }
{ type: 'progress', sessionId, name, step?, detail?, percent? }
{ type: 'token_update', sessionId, input, output, total, apiCalls }
```
**agentId 处理流程:**
1. 收到 chat 事件时,如果有 agentId`netaclaw_agent` 表读取配置
2. 用 Agent 的 modelConfig 初始化 LLM 提供商
3. 用 Agent 的 systemPrompt + skills 构建系统提示
4. 调用 `runAgent()` 执行
## 5. 前端迁移设计
### 5.1 Store 改造 (`store/chat.ts`)
**API 路径替换:**
| 旧路径 | 新路径 |
|--------|--------|
| `POST /open/agent/info/list` | `POST /open/netaclaw/agent/list` |
| `POST /open/agent/chat/chat` (SSE) | WebSocket `/netaclaw` (chat 事件) |
| `POST /open/agent/chat/messages` | `POST /open/netaclaw/session/messages` |
| `POST /open/agent/chat/sessions` | `POST /open/netaclaw/session/list` |
| `POST /open/agent/chat/deleteSession` | `POST /open/netaclaw/session/delete` |
| `POST /open/agent/chat/deleteAllSessions` | `POST /open/netaclaw/session/deleteAll` |
| `POST /open/agent/chat/contextTokens` | 移除WS token_update 事件替代) |
| `POST /open/agent/chat/status` | 移除WS 连接状态替代) |
| `POST /open/agent/chat/reconnect` | 移除WS 自动重连替代) |
**通信方式改造:**
- 移除 SSEfetch stream + EventSource逻辑
- 新增 WebSocket 连接管理:
- 连接:页面加载时建立 WS 连接到 `ws://localhost:8003/netaclaw`
- 心跳:定时发送 ping收到 pong 确认
- 断线重连:连接断开后自动重连,指数退避
- 发送消息:通过 WS 发送 `{type: 'chat', sessionId, content, agentId}`
- WS 事件映射到 store 状态:
- `token` → 追加 assistant 消息内容
- `thinking` → 追加思考内容
- `tool_call` → 记录工具调用
- `tool_result` → 记录工具结果
- `skill_start` → 添加 skillProgress 条目
- `progress` → 更新 skillProgress
- `skill_end` → 完成 skillProgress
- `token_update` → 更新 token 统计
- `done` → 标记完成,更新 sessionId
- `error` → 显示错误
### 5.2 页面改造
**`agent-list.vue`**
- `/admin/agent/info/page``/admin/netaclaw/agent/page`
- `/admin/agent/info/update``/admin/netaclaw/agent/update`
- `/admin/agent/info/delete``/admin/netaclaw/agent/delete`
**`skills.vue`**
- `/admin/agent/skill/metas``/admin/netaclaw/skill/metas`
- `/admin/agent/skill/setStatus``/admin/netaclaw/skill/setStatus`
**`chat.vue`**
- 移除 SSE 相关代码
- 使用 store 中的 WS 连接发送/接收消息
- `/admin/agent/info/info``/admin/netaclaw/agent/info`
- `/admin/base/comm/upload` → 保持不变(通用上传接口)
**`agent-edit.vue`**
- `/admin/agent/info/add``/admin/netaclaw/agent/add`
- `/admin/agent/info/update``/admin/netaclaw/agent/update`
- `/admin/agent/info/info``/admin/netaclaw/agent/info`
- `/admin/agent/skill/metas``/admin/netaclaw/skill/metas`
## 6. 删除清单
### 6.1 后端删除
- 旧 agent 模块目录(如果存在 `src/modules/agent/`
- 旧 agent 相关 Entity 文件
- 旧 LangChain 相关依赖(已在之前的设计文档中列出)
### 6.2 数据库删除
```sql
DROP TABLE IF EXISTS agent_info;
DROP TABLE IF EXISTS agent_skill;
DROP TABLE IF EXISTS agent_session;
DROP TABLE IF EXISTS agent_message;
DROP TABLE IF EXISTS agent_checkpoints;
DROP TABLE IF EXISTS agent_checkpoint_writes;
DROP TABLE IF EXISTS agent_configs;
DROP TABLE IF EXISTS skill_configs;
```
### 6.3 前端
不删除目录只改内部实现API 路径和通信方式)。
## 7. 联调要点
1. **后端先行**:先完成 Entity + Controller + Service确保接口可用
2. **WS 联调**:用 WebSocket 客户端工具测试 chat 事件的完整流程
3. **前端适配**:逐页面替换 API 路径,先改管理页面(简单),再改对话页面(复杂)
4. **数据验证**:确保 Agent 创建/编辑/删除、Skill 启用/禁用、会话 CRUD 全部正常
5. **流式验证**:确保 WS 的 token/thinking/tool_call/skill_start/done 等事件正确推送和渲染