235 lines
9.2 KiB
Markdown
235 lines
9.2 KiB
Markdown
|
|
# 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 自动重连替代) |
|
|||
|
|
|
|||
|
|
**通信方式改造:**
|
|||
|
|
- 移除 SSE(fetch 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 等事件正确推送和渲染
|