add agent page development doc
Some checks failed
Lint / build (20) (push) Has been cancelled
Playwright Tests / test (push) Has been cancelled

This commit is contained in:
Your Name 2026-03-10 10:12:51 +08:00
parent a458baaca9
commit 7ff6af2065

View File

@ -0,0 +1,774 @@
# 智能体页面开发文档(基于当前 `ai-chatbot-main`)
> 目标:在现有“无限画布 + 画布对话 + 多模型生成”体系上,新增一个独立的“智能体”工作台页面。
> 页面形态:左侧半屏展示生成结果画布,右侧半屏展示智能体工具栏;支持公共/私有智能体、分类筛选、用户自建智能体、自建分类、预设词和参考图注入。
---
## 1. 需求目标
本期不是重做一套生成系统,而是在现有项目基础上新增“智能体工作台”:
1. 新增一个页面,名称为“智能体”
2. 页面左半区复用现有无限画布能力,用于展示生成的图片/视频结果
3. 页面右半区为智能体面板,分为:
- 公共智能体区
- 私有智能体区
4. 公共智能体区支持按分类筛选查看
5. 用户创建智能体时可:
- 选择已有分类
- 创建新分类
6. 用户可以创建新的智能体,智能体需支持:
- 类型:`生图模型` / `视频模型`
- 自定义名称
- 智能体分类
- 预设提示词
- 参考图
- 公开 / 私有
7. 用户点击某个智能体后,可将其以“标签/卡片”的形式挂载到页面底部对话框
8. 后端在发送时自动注入该智能体的预设提示词和参考图
9. 用户只需:
- 上传自己的图片
- 可选补充提示词
- 点击发送
10. 后端完成生图或生视频后,结果直接落到左侧画布区显示
---
## 2. 当前系统可复用能力
本项目已经具备实现该页面的大部分基础设施,不建议另起一套链路。
### 2.1 前端可复用能力
- 画布主页面:`app/canvas/[id]/page.tsx`
- 已具备画布容器、自动保存、浮动工具栏
- 画布工作区:`components/canvas/CanvasWorkspace.tsx`
- 已具备图片、视频、文本、3D 节点渲染
- 画布对话面板:`components/canvas/CanvasChatPanel.tsx`
- 已具备上传图片、模型选择、消息发送、结果流式回注画布
- 画布状态:`store/canvas/index.ts`
- 已具备节点管理、选中状态、附件暂存、自动保存等能力
- 画布类型:`types/canvas/index.ts`
- 已支持 `image`、`video`、`text`、`model3d`
### 2.2 后端可复用能力
- 画布项目持久化:
- `GET/POST /api/canvas`
- `GET/PUT/DELETE /api/canvas/[id]`
- 图片上传:
- `POST /app/(chat)/api/files/upload/route.ts`
- 模型列表获取:
- `GET /app/(chat)/api/models/route.ts`
- 统一聊天/Agent 生成主链路:
- `POST /app/(chat)/api/chat/route.ts`
- 画布图片生成直连能力:
- `POST /app/api/canvas/generate/image/route.ts`
### 2.3 数据层基础
- 画布项目表:`CanvasProject`
- 模型表:`AiModel`
- 统一媒体资产表:`MediaAsset`
- 用户表:`User`
- 系统设置表:`SystemSettings`
### 2.4 当前已有但不足以直接承载智能体的能力
当前已有“画布快捷标签”机制:
- 配置定义:`lib/canvas-skill-tags.ts`
- 接口:`app/api/canvas-skill-tags/route.ts`
- 使用位置:`components/canvas/CanvasChatPanel.tsx`
但它不适合直接扩展为正式智能体,因为:
1. 只能做全局配置,不能用户自建
2. 没有公共/私有隔离
3. 没有分类体系
4. 没有参考图绑定
5. 主要依赖前端拼 `hiddenPrompt`
6. 无法形成正式智能体资产
因此本功能建议升级为独立的数据模型,而不是继续放在 `SystemSettings` 或 `canvasSkillTags` 中。
---
## 3. 产品形态建议
### 3.1 页面路由
建议新增独立工作台路由,而不是塞进现有 `CanvasChatPanel`:
- 入口页:`/agents`
- 工作页:`/agents/[id]`
推荐行为:
1. 访问 `/agents` 时自动打开最近一次智能体工作台
2. 若没有工作台,则创建一个新的工作台
3. 工作台底层仍复用 `CanvasProject`
### 3.2 页面布局
桌面端建议采用左右 1:1 分栏:
- 左侧 50%:结果画布区
- 复用 `CanvasWorkspace`
- 只展示当前智能体工作台结果
- 底部固定一个对话输入区
- 右侧 50%:智能体工具区
- 顶部:搜索 / 类型筛选 / 新建按钮
- 公共区顶部:分类筛选栏(全部 + 分类 Tab/下拉)
- 中部:公共智能体区
- 下部:私有智能体区
- 点击卡片后变为当前激活智能体
### 3.3 交互约束
MVP 建议限制:
1. 单轮仅允许激活 1 个智能体
2. 智能体类型二选一:
- `image`:生图智能体
- `video`:生视频智能体
3. 创建为公开后,立即出现在公共区
4. 参考图统一绑定媒体资产
5. 公共区默认只支持单分类筛选
---
## 4. 核心用户流程
### 4.1 创建智能体
1. 用户点击“新建智能体”
2. 弹出表单,填写:
- 智能体名称
- 智能体类型(生图 / 视频)
- 可见性(公开 / 私有)
- 智能体分类(选择已有分类 / 新建分类)
- 预设提示词
- 默认模型
- 参考图(可多张)
3. 前端先调用上传接口上传参考图
4. 后端保存智能体记录
5. 若勾选“公开”,则直接出现在公共区,并归入对应分类
6. 若勾选“私有”,则出现在私有区;分类字段保留,便于后续扩展
### 4.2 使用智能体
1. 用户点击某个智能体卡片
2. 底部对话框出现智能体标签
3. 标签展示:
- 名称
- 类型
- 分类
- 默认模型
- 参考图数量
4. 用户上传图片
5. 用户可补充一句额外提示词
6. 点击发送
### 4.3 后端执行
1. 请求携带 `agentPresetId`
2. 后端查询智能体定义
3. 后端校验当前用户是否有权限使用
4. 后端合并:
- 智能体预设提示词
- 智能体参考图
- 用户上传图片
- 用户补充提示词
- 当前工作台上下文
5. 根据智能体类型进入:
- 图片生成链路
- 视频生成链路
6. 结果通过现有流式消息返回
7. 左侧画布自动新增图片或视频节点
### 4.4 结果展示
继续复用现有 `data-canvasMedia` 流:
- 图片结果 -> 新增 `image` 节点
- 视频结果 -> 新增 `video` 节点
---
## 5. 技术方案
### 5.1 总体原则
1. 不新造一套生成后端,继续复用 `/api/chat`
2. 不复制一套画布,继续复用 `CanvasWorkspace`
3. 不继续使用系统设置存智能体,改为正式数据表
4. 智能体 prompt 必须由服务端注入
5. 结果继续走现有流式落画布逻辑
### 5.2 页面结构建议
建议新增文件:
- `app/agents/page.tsx`
- `app/agents/[id]/page.tsx`
- `app/agents/[id]/layout.tsx`
- `components/agents/AgentWorkbench.tsx`
- `components/agents/AgentPresetPanel.tsx`
- `components/agents/AgentPresetCard.tsx`
- `components/agents/AgentCategoryTabs.tsx`
- `components/agents/AgentPresetDialog.tsx`
- `components/agents/AgentComposer.tsx`
- `services/agents/index.ts`
- `types/agent.ts`
- `store/agent-workbench.ts`
建议修改文件:
- `components/top-navbar.tsx`
- 新增“智能体”入口
- `app/(chat)/api/chat/schema.ts`
- 扩展请求体,允许传入 `agentPresetId`
- `app/(chat)/api/chat/route.ts`
- 服务端读取并注入智能体定义
- `lib/db/schema.ts`
- 新增智能体相关表
- `lib/db/queries.ts`
- 增加智能体 CRUD 与分类查询
### 5.3 组件复用策略
#### A. 左侧结果区
直接复用:
- `CanvasWorkspace`
- `store/canvas`
- `canvasService`
#### B. 发送能力
建议从 `CanvasChatPanel.tsx` 中抽离一个可复用运行时层,例如:
- `hooks/useCanvasChatRuntime.ts`
- 负责:
- `sendMessage`
- 模型选择
- 图片/视频参数
- 流式结果消费
- 结果写入画布
然后:
- 旧页面继续使用 `CanvasChatPanel`
- 新页面使用更轻量的 `AgentComposer`
这样可以避免把 `CanvasChatPanel` 再复制一份。
---
## 6. 数据库设计
### 6.1 新增表:`AgentPreset`
建议新增正式智能体表,而不是继续放在 `SystemSettings`。
| 字段 | 类型 | 说明 |
|---|---|---|
| `id` | uuid | 主键 |
| `ownerUserId` | uuid | 创建者 |
| `name` | varchar(128) | 智能体名称 |
| `type` | varchar(16) | `image` / `video` |
| `visibility` | varchar(16) | `public` / `private` |
| `categoryId` | uuid nullable | 智能体分类 |
| `promptTemplate` | text | 预设提示词 |
| `description` | text | 可选描述 |
| `defaultModelId` | uuid nullable | 默认模型,关联 `AiModel.id` |
| `coverAssetId` | uuid nullable | 封面图,可选 |
| `status` | varchar(16) | `active` / `disabled` |
| `sortOrder` | integer | 排序 |
| `createdAt` | timestamp | 创建时间 |
| `updatedAt` | timestamp | 更新时间 |
说明:
- `visibility=public`:所有已登录用户可见
- `visibility=private`:仅创建者可见
- `promptTemplate` 为服务端最终合成提示词的主模板
- `categoryId` 首期主要用于公共区分类筛选,也可保留给私有区未来扩展
### 6.2 新增表:`AgentPresetCategory`
用于给公共智能体区提供分类筛选,也支持用户创建新分类。
| 字段 | 类型 | 说明 |
|---|---|---|
| `id` | uuid | 主键 |
| `name` | varchar(64) | 分类名称 |
| `slug` | varchar(64) | 分类标识 |
| `scope` | varchar(16) | `public` / `private` / `global` |
| `createdBy` | uuid nullable | 创建人 |
| `sortOrder` | integer | 排序 |
| `isEnabled` | boolean | 是否启用 |
| `createdAt` | timestamp | 创建时间 |
| `updatedAt` | timestamp | 更新时间 |
说明:
- MVP 建议允许用户在创建智能体时输入新分类名,若不存在则自动创建
- 若智能体为公开,分类建议归入 `public` 或 `global`
- 公共区默认展示 `public/global` 分类
- 若后续要治理分类,可以再补后台合并/禁用能力
### 6.3 新增表:`AgentPresetReferenceAsset`
用于绑定参考图,避免把 URL 直接写死在智能体表。
| 字段 | 类型 | 说明 |
|---|---|---|
| `id` | uuid | 主键 |
| `presetId` | uuid | 关联 `AgentPreset.id` |
| `assetId` | uuid | 关联 `MediaAsset.id` |
| `sortOrder` | integer | 参考图顺序 |
| `createdAt` | timestamp | 创建时间 |
说明:
- 参考图建议全部走 `MediaAsset`
- 后续若要做公共智能体复制、统计、缓存,会更稳定
### 6.4 扩展表:`CanvasProject`
为了让 `/agents` 能像 `/canvas` 一样恢复最近工作区,建议给 `CanvasProject` 增加:
| 字段 | 类型 | 说明 |
|---|---|---|
| `workspaceType` | varchar(16) | `canvas` / `agent` |
默认值:
- 旧画布默认 `canvas`
- 智能体工作台创建时写 `agent`
### 6.5 迁移建议
当前 `lib/db/migrations` 已存在到 `0052`,本期建议新增:
- `0053_add_agent_presets.sql`
---
## 7. 接口设计
### 7.1 智能体接口
#### `GET /api/agents`
用途:获取当前用户可见的智能体列表
建议支持查询参数:
- `scope=all | public | private`
- `type=image | video`
- `categoryId=xxx`
- `keyword=xxx`
返回建议:
```json
{
"success": true,
"data": {
"categories": [],
"public": [],
"private": []
}
}
```
#### `POST /api/agents`
用途:创建智能体
请求体建议:
```json
{
"name": "商品主图增强",
"type": "image",
"visibility": "private",
"categoryId": "uuid",
"newCategoryName": "电商主图",
"promptTemplate": "你是资深电商视觉设计师,请在保持主体一致的前提下优化主图视觉冲击力。",
"defaultModelId": "uuid",
"referenceAssetIds": ["uuid1", "uuid2"]
}
```
说明:
- `categoryId` 和 `newCategoryName` 二选一
- 若传了 `newCategoryName`,后端先创建或复用同名分类,再回填 `categoryId`
#### `GET /api/agents/[id]`
用途:获取单个智能体详情
#### `PUT /api/agents/[id]`
用途:编辑智能体
#### `DELETE /api/agents/[id]`
用途:删除智能体
#### `GET /api/agent-categories`
用途:获取智能体分类列表
建议支持:
- `scope=public | private | all`
#### `POST /api/agent-categories`
用途:创建分类
请求体建议:
```json
{
"name": "电商主图",
"scope": "public"
}
```
说明:
- 也可以不单独暴露该接口,而是在 `POST /api/agents` 时隐式创建分类
- 若希望分类治理更规范,建议保留独立接口
### 7.2 对现有聊天接口的扩展
#### 扩展 `POST /api/chat`
建议在 `app/(chat)/api/chat/schema.ts` 新增字段:
```ts
agentPresetId?: string;
```
必要时可增加:
```ts
agentPresetType?: "image" | "video";
```
#### 前端发送时的请求体建议
```json
{
"id": "workspace-id",
"message": {
"id": "message-id",
"role": "user",
"parts": [
{ "type": "file", "mediaType": "image/png", "name": "demo.png", "url": "..." },
{ "type": "text", "text": "帮我再强化一点高级感" }
]
},
"selectedChatModel": "model-id",
"selectedVisibilityType": "private",
"agentPresetId": "preset-id"
}
```
#### 服务端合成策略
服务端不要完全信任前端拼出来的 prompt,而应以数据库智能体定义为准:
最终执行输入建议:
1. 智能体预设提示词:来自 `AgentPreset.promptTemplate`
2. 智能体参考图:来自 `AgentPresetReferenceAsset`
3. 用户上传图:来自本轮 `message.parts`
4. 用户补充提示词:来自本轮 `text part`
5. 当前工作台上下文:可复用现有 `contextPayload`
合成优先级建议:
```text
系统路由/安全限制
-> 智能体 promptTemplate
-> 用户补充提示词
-> 画布上下文 autoContext/contextPayload
```
#### 类型路由规则
- `image` 智能体:
- 仅允许走图片生成/图片编辑能力
- `video` 智能体:
- 仅允许走视频生成能力
若用户选了不兼容模型:
- 前端优先过滤
- 后端再次校验,不兼容则报错
---
## 8. 前端行为设计
### 8.1 智能体面板
右侧建议结构:
1. 顶部工具栏
- 搜索框
- 类型筛选(全部/生图/视频)
- 分类筛选(全部 + 分类 Tab/下拉)
- “新建智能体”按钮
2. 公共智能体区
- 所有 `visibility=public`
- 支持按分类切换
3. 私有智能体区
- 当前用户创建且 `visibility=private`
卡片字段建议展示:
- 名称
- 类型标签(生图 / 视频)
- 分类名称
- 可见性标签(公共 / 私有)
- 默认模型名称
- 参考图数量
- 创建人(公共区建议展示)
### 8.2 对话输入区
底部输入区建议包含:
1. 当前激活智能体标签
2. 图片上传入口
3. 补充提示词输入框
4. 模型选择器
5. 发送按钮
标签行为:
- 点击智能体卡片 -> 激活并显示标签
- 再点击同一个标签 -> 可取消激活
- 切换到另一个智能体 -> 替换当前标签
MVP 不建议一次选择多个智能体。
### 8.3 新建智能体弹窗建议
表单字段建议:
1. 智能体名称
2. 智能体类型
3. 可见性
4. 分类选择
- 下拉展示已有分类
- 支持“新建分类”
- 选择“新建分类”后出现输入框
5. 默认模型
6. 预设提示词
7. 参考图上传
交互建议:
- 当用户选择 `visibility=public` 时,分类必填
- 当用户选择 `visibility=private` 时,分类可选
- 若输入的新分类名已存在,后端直接复用
### 8.4 模型选择策略
根据智能体类型过滤模型:
- 生图智能体:只显示支持图片生成的模型
- 视频智能体:只显示视频模型
默认行为:
1. 若智能体配置了默认模型,则优先用该模型
2. 若未配置,则走系统默认模型
3. 用户可手动改模型,但必须满足类型限制
### 8.5 结果落画布
继续复用 `CanvasChatPanel` 现有逻辑中的结果落图机制:
- 消费 `data-canvasMedia`
- 图片新增 `image` 节点
- 视频新增 `video` 节点
建议给节点 `metadata` 增加:
- `agentPresetId`
- `agentPresetName`
- `agentCategoryId`
- `agentCategoryName`
- `workspaceType: "agent"`
---
## 9. 后端实现细节建议
### 9.1 服务端必须接管智能体 prompt 注入
正式方案应改为:
1. 前端只传 `agentPresetId`
2. 服务端查询智能体
3. 服务端注入:
- `promptTemplate`
- `reference assets`
- `default model`
4. 服务端统一构造最终调用参数
价值:
- 防止前端绕过规则
- 便于权限校验
- 便于日志审计
- 便于后续版本化
### 9.2 参考图处理
智能体参考图建议走两层:
1. 智能体固定参考图
2. 用户本轮上传图
最终传给模型时:
- 先拼固定参考图
- 再拼用户上传图
- 去重后按模型能力截断
### 9.3 公开/私有权限
私有智能体:
- 仅创建者自己可查、可用、可编辑、可删除
公共智能体:
- 所有登录用户可查、可用
- 仅创建者可编辑、删除
公共分类:
- 默认所有登录用户可见
- 若分类由普通用户创建,建议允许复用,但保留后续后台禁用/合并能力
### 9.4 公共智能体是否立即发布
按当前需求,本期可直接采用:
- 创建时选“公开” -> 立即出现在公共区对应分类下
---
## 10. 与现有 `canvasSkillTags` 的兼容方案
建议分两步处理:
### Phase A:先并行存在
- 旧画布页面继续使用 `canvasSkillTags`
- 新“智能体页面”使用 `AgentPreset`
### Phase B:后续统一
待智能体稳定后,可考虑:
1. 将公共智能体映射到画布页面
2. 用 `AgentPreset` 替换 `canvasSkillTags`
3. 后台不再维护两套预设
---
## 11. 推荐开发顺序
### 第一阶段:数据层
1. 新增 `AgentPreset`
2. 新增 `AgentPresetCategory`
3. 新增 `AgentPresetReferenceAsset`
4. 扩展 `CanvasProject.workspaceType`
5. 增加 `lib/db/queries.ts` 查询函数
6. 增加 `/api/agents` 与 `/api/agent-categories`
### 第二阶段:页面骨架
1. 新增 `/agents`
2. 新增 `/agents/[id]`
3. 左侧接入 `CanvasWorkspace`
4. 右侧接入智能体列表
5. 接入公共区分类筛选
6. 增加“新建智能体”弹窗
### 第三阶段:发送链路
1. 抽离 `CanvasChatPanel` 发送运行时
2. 新增 `AgentComposer`
3. 发送时带 `agentPresetId`
4. 后端 `/api/chat` 注入智能体定义
5. 结果复用 `data-canvasMedia` 落到画布
### 第四阶段:体验增强
1. 智能体搜索/筛选
2. 公共区分类管理
3. 智能体编辑/删除
4. 参考图拖拽排序
5. 最近使用智能体
6. 公共智能体卡片展示创建者/热度
---
## 12. MVP 验收标准
满足以下条件即可视为第一版完成:
1. 可以从页面入口进入“智能体”工作台
2. 左侧能看到画布结果区域
3. 右侧能看到公共区、私有区
4. 公共区可以按分类筛选智能体
5. 新建智能体时可以选择已有分类
6. 新建智能体时可以创建新分类
7. 可以新建一个生图智能体
8. 可以新建一个视频智能体
9. 可以上传参考图并成功保存
10. 可以选择公开或私有
11. 点击智能体卡片后,底部输入区出现智能体标签
12. 上传用户图片并发送后,后端会自动注入智能体预设
13. 生图结果会自动落到左侧画布
14. 生视频结果会自动落到左侧画布
15. 其他用户不能使用当前用户的私有智能体
---
## 13. 本期不建议做的内容
1. 多智能体串联
2. 智能体版本管理
3. 智能体分享页/详情页
4. 公共智能体审核流
5. 公共智能体评分/收藏/排行榜
6. 智能体对外分享链接
7. 复杂工作流编排型智能体
---
## 14. 一句话结论
这次“智能体页面”最合适的实现方式是:
**复用现有无限画布和 `/api/chat` 生成主链路,在其上新增正式的 `AgentPreset + AgentPresetCategory` 数据模型与工作台页面,而不是重新做一套生成系统。**