From 7ff6af2065907eb92f0a55cc6faf18125b440651 Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 10 Mar 2026 10:12:51 +0800 Subject: [PATCH] add agent page development doc --- docs/智能体页面开发文档.md | 774 +++++++++++++++++++++++++++++++++++++ 1 file changed, 774 insertions(+) create mode 100644 docs/智能体页面开发文档.md diff --git a/docs/智能体页面开发文档.md b/docs/智能体页面开发文档.md new file mode 100644 index 000000000..aff909e03 --- /dev/null +++ b/docs/智能体页面开发文档.md @@ -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` 数据模型与工作台页面,而不是重新做一套生成系统。** +