# 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 等事件正确推送和渲染