From 3cb4405b1471ed4e92bc94053bbeb4b6a4cc0622 Mon Sep 17 00:00:00 2001 From: kris Date: Sun, 29 Mar 2026 15:03:02 +0800 Subject: [PATCH] docs: add attachment storage and ai processing spec --- ...hments-storage-and-ai-processing-design.md | 685 ++++++++++++++++++ 1 file changed, 685 insertions(+) create mode 100644 docs/superpowers/specs/2026-03-29-chat-attachments-storage-and-ai-processing-design.md diff --git a/docs/superpowers/specs/2026-03-29-chat-attachments-storage-and-ai-processing-design.md b/docs/superpowers/specs/2026-03-29-chat-attachments-storage-and-ai-processing-design.md new file mode 100644 index 0000000..44f6664 --- /dev/null +++ b/docs/superpowers/specs/2026-03-29-chat-attachments-storage-and-ai-processing-design.md @@ -0,0 +1,685 @@ +# Boss 聊天附件、双存储与 AI 处理设计 + +日期:`2026-03-29` + +## 1. 背景 + +当前 `Boss` 原生 Android 客户端已经完成: + +- 微信式 `会话 / 设备 / 我的` 一级交互 +- 线程 = 聊天窗口 +- 会话信息、独立群聊、微信式消息转发 + +但聊天主链仍缺少真实的附件协作能力: + +- 聊天框还不能直接发送本机图片、视频、文件 +- 接收端还不能收到可预览/可下载的附件消息 +- 存储目前只有服务器本地文件路线,没有可切换的对象存储 +- AI 还不能基于聊天里的附件自动或手动分析内容 + +这次工作要把这四条链路一起打通: + +1. 原生聊天框发送本机图片、视频、文件 +2. 默认服务器文件存储 + 可选阿里 OSS 私有桶 +3. Web 端做最简化的用户级存储配置 +4. 主 Agent 统一处理附件分析,并把结果回写到聊天中 + +## 2. 目标 + +本次设计完成后,系统应满足: + +1. 原生 Android 聊天框左侧提供单个 `+` 附件入口。 +2. 点击 `+` 后通过底部抽屉选择 `图片 / 视频 / 文件`。 +3. 图片、视频在发送前需要预览确认;文件直接发送。 +4. 默认使用服务器文件存储。 +5. 用户可在 Web 端 `我的 > 附件与存储` 中切换到 `OSS`。 +6. `OSS` 当前只支持 `阿里 OSS`,并使用私有桶 + 签名 URL。 +7. 存储配置按当前登录用户保存,不做全局唯一配置。 +8. 接收端收到的附件消息不感知底层存储差异,都能统一预览/下载。 +9. 图片 / PDF / 文本默认自动交给主 Agent 处理。 +10. 视频 / Office / 大文件默认手动触发分析。 +11. “大文件”阈值固定为 `20 MB`。 +12. AI 处理结果以“简短回复 + 可继续查看的分析卡片”形式回到当前聊天。 + +## 3. 非目标 + +本次明确不做: + +1. 非阿里云的 OSS / S3 / COS 接入。 +2. 语音附件、录音、外部分享面板。 +3. 跨应用分享、系统分享菜单接入。 +4. 附件版本管理、回收站、批量迁移工具。 +5. 视频高级转码、视频在线播放 CDN 优化。 +6. Office / 视频的深度结构化解析引擎。 +7. 多租户复杂权限模型。 + +## 4. 已确认的产品决策 + +### 4.1 原生聊天入口 + +- 聊天输入框左侧保留单个 `+` +- 点击后打开底部抽屉 +- 抽屉内固定展示: + - `图片` + - `视频` + - `文件` + +### 4.2 发送前确认 + +- 图片:选中后先进入发送确认态 +- 视频:选中后先进入发送确认态 +- 文件:直接进入发送,不额外确认 + +### 4.3 Web 配置入口 + +- 配置入口固定放在 `我的 > 附件与存储` +- 不放在会话页,不藏在多层设置后面 + +### 4.4 OSS 最小配置项 + +阿里 OSS 最小配置字段固定为: + +- `AccessKey ID` +- `AccessKey Secret` +- `Bucket` +- `Endpoint` +- `Region` +- `目录前缀`(可选,默认 `boss/`) + +### 4.5 AI 处理策略 + +- 图片 / PDF / 文本:默认自动处理 +- 视频 / Office / 大文件:默认手动触发 +- 大文件阈值:`20 MB` +- 所有附件分析统一走主 Agent + +### 4.6 AI 结果展示 + +分析结果返回当前聊天时,固定使用混合展示: + +1. 一条简短的主 Agent 回复 +2. 一张分析结果卡片 + +## 5. 总体架构 + +### 5.1 发送链 + +发送链拆成两步: + +1. 原生 APP 选择附件并上传 +2. 服务端创建附件消息 + +用户视角上,它们仍是一条连续动作。 + +上传成功后,服务端会在目标会话写入统一的“附件消息”,而不是单独写“上传请求消息”。 + +### 5.2 存储链 + +存储层统一抽象成 `AttachmentStorageProvider`,底层实现两种: + +- `server_file` +- `aliyun_oss` + +所有附件都通过同一套元数据模型进入消息系统,聊天页和 AI 处理链不直接感知底层存储类型。 + +### 5.3 AI 处理链 + +AI 处理与上传解耦: + +- 上传完成后先落附件消息 +- 再由服务端根据文件类型和大小决定是否自动排队给主 Agent +- 不自动处理的附件,显示为“可分析”,由用户手动触发 + +### 5.4 接收链 + +接收端收到的消息固定是统一附件消息: + +- 可看到文件类型、名称、大小、状态 +- 图片支持预览 +- 视频支持预览/下载 +- PDF / 文本 / Office / 其他文件支持下载 +- 可看到 AI 分析状态与结果 + +## 6. 存储设计 + +### 6.1 用户级配置模型 + +每个登录用户拥有独立的存储偏好: + +```ts +type AttachmentStorageMode = "server_file" | "oss"; +type OssProvider = "aliyun_oss"; + +interface UserAttachmentStorageConfig { + account: string; + mode: AttachmentStorageMode; + ossProvider?: OssProvider; + aliyunOss?: { + enabled: boolean; + accessKeyId: string; + accessKeySecretEncrypted: string; + bucket: string; + endpoint: string; + region: string; + prefix?: string; + }; + updatedAt: string; + validatedAt?: string; +} +``` + +其中: + +- `mode=server_file` 时,不要求任何 OSS 字段 +- `mode=oss` 时,必须要求 `ossProvider=aliyun_oss` +- `prefix` 默认值为 `boss/` + +### 6.2 密钥存储策略 + +由于当前系统仍使用文件持久化,阿里 OSS 的 `AccessKey Secret` 不能明文直接写入 `boss-state.json`。 + +本次设计采用: + +- `boss-state.json` 中只保存加密后的 `accessKeySecretEncrypted` +- 服务器本地使用单独密钥对该字段做对称加密 +- 该本地密钥不进入仓库,不通过客户端下发 + +推荐实现方式: + +- 优先读取环境变量,如 `BOSS_STORAGE_SECRET_KEY` +- 如果不存在,则在服务器本地生成仅运行时可见的密钥文件并持久化到数据目录 + +### 6.3 默认服务器文件存储 + +默认存储后端为服务器本地文件。 + +建议目录结构: + +```text +data/uploads////- +``` + +优势: + +- 符合当前“极轻云 + 本地设备端”路线 +- 不引入额外云资源即可先跑通 +- 与现有 `boss-state.json` 路线一致 + +### 6.4 阿里 OSS 存储 + +阿里 OSS 固定采用: + +- 私有桶 +- 临时签名 URL + +服务端负责: + +- 上传对象 +- 生成对象 key +- 在下载或预览时生成短期签名 URL + +对象 key 建议结构: + +```text +////- +``` + +其中: + +- `prefix` 默认为 `boss/` +- 用户可在配置中改为其他目录前缀 + +### 6.5 统一下载入口 + +前台不直接拼 OSS URL,也不直接暴露本地文件路径。 + +统一下载/预览入口建议为: + +```text +GET /api/v1/attachments/[attachmentId]/download +``` + +该接口统一负责: + +- 鉴权当前用户是否可访问对应会话 +- 如果是 `server_file`: + - 流式返回文件 +- 如果是 `aliyun_oss`: + - 生成短期签名 URL + - 302 跳转,或由服务端转发流式响应 + +这样可以保证: + +- 客户端体验统一 +- 存储切换不影响聊天 UI +- 不暴露底层凭证 + +## 7. 附件消息模型 + +### 7.1 新消息类型 + +现有消息类型只有文本和若干 intent 占位,不足以表达真实附件。 + +本次应扩展消息模型: + +```ts +type MessageKind = + | "text" + | "voice_intent" + | "image_intent" + | "video_intent" + | "forward_notice" + | "forward_single" + | "forward_bundle" + | "attachment"; +``` + +### 7.2 附件元数据 + +```ts +type AttachmentKind = + | "image" + | "video" + | "pdf" + | "text" + | "office" + | "binary"; + +type AttachmentStorageBackend = "server_file" | "aliyun_oss"; + +type AttachmentAnalysisState = + | "not_applicable" + | "queued_auto" + | "ready_manual" + | "processing" + | "completed" + | "failed"; + +interface MessageAttachment { + attachmentId: string; + fileName: string; + mimeType: string; + fileSizeBytes: number; + attachmentKind: AttachmentKind; + storageBackend: AttachmentStorageBackend; + storagePath: string; + previewAvailable: boolean; + uploadedAt: string; + uploadedBy: string; + analysisState: AttachmentAnalysisState; + analysisSummary?: string; + analysisCardId?: string; +} +``` + +每条附件消息可以先只支持单附件,避免第一轮就把消息结构做成多附件复合体。后续若要支持一条消息多个附件,再扩展成数组。 + +### 7.3 附件消息结构 + +```ts +interface Message { + id: string; + sender: MessageSender; + senderLabel: string; + body: string; + sentAt: string; + kind?: MessageKind; + attachment?: MessageAttachment; + forwardSource?: ForwardSource; + forwardBundle?: ForwardBundlePayload; +} +``` + +附件消息的 `body` 用作聊天摘要和兼容展示,例如: + +- 图片:`已发送图片:车间异常截图.png` +- 视频:`已发送视频:工位巡检录像.mp4` +- 文件:`已发送文件:北区回归报告.pdf` + +## 8. AI 分析模型 + +### 8.1 分析任务 + +附件分析统一走主 Agent,不让单个普通线程自行处理。 + +建议新增任务模型: + +```ts +type MasterAgentTaskType = + | "chat_reply" + | "attachment_analysis"; + +interface AttachmentAnalysisTaskPayload { + projectId: string; + messageId: string; + attachmentId: string; + fileName: string; + mimeType: string; + attachmentKind: AttachmentKind; + fileSizeBytes: number; + downloadUrl: string; + triggerMode: "auto" | "manual"; +} +``` + +### 8.2 自动 / 手动分析规则 + +自动进入主 Agent 的条件: + +- `attachmentKind=image` +- `attachmentKind=pdf` +- `attachmentKind=text` +- 文件大小 `<= 20 MB` + +手动触发的条件: + +- `attachmentKind=video` +- `attachmentKind=office` +- 文件大小 `> 20 MB` + +### 8.3 AI 处理执行者 + +统一执行者为主 Agent: + +- 优先走 `Master Codex Node` +- 只有在容灾路径明确支持时,才考虑 `openai_api` + +在能力未覆盖的情况下,应返回明确状态,不要假装已完成分析。 + +### 8.4 分析结果回写 + +分析结果固定回写到当前聊天会话中,形式为: + +1. 一条简短主 Agent 回复 +2. 一张分析结果卡片 + +简短回复示例: + +```text +主 Agent:已分析《北区回归报告.pdf》。核心问题是登录态恢复链和 OTA 覆盖安装文档不一致。 +``` + +分析卡片中至少应包含: + +- 分析对象文件名 +- 分析模式(自动 / 手动) +- 核心结论摘要 +- 关键提取点列表 +- 分析完成时间 + +## 9. API 设计 + +### 9.1 Web 配置接口 + +新增用户级附件存储配置接口: + +```text +GET /api/v1/storage/config +PATCH /api/v1/storage/config +POST /api/v1/storage/config/validate +``` + +语义: + +- `GET`:获取当前用户的附件与存储配置 +- `PATCH`:更新当前用户配置 +- `validate`:校验阿里 OSS 是否配置可用 + +`validate` 至少检查: + +- AK/SK 是否能通过认证 +- Bucket 是否存在 +- Endpoint / Region 是否匹配 +- 是否具备读写权限 + +### 9.2 附件上传接口 + +新增统一附件上传接口: + +```text +POST /api/v1/projects/[projectId]/attachments +``` + +建议使用 `multipart/form-data`,字段至少包括: + +- `file` +- `sourceType`: `image | video | file` + +该接口负责: + +1. 鉴权 +2. 解析文件类型 +3. 读取当前用户存储配置 +4. 上传到对应后端 +5. 生成附件消息 +6. 决定是否自动创建主 Agent 分析任务 + +返回值应直接带回新创建的消息和分析状态。 + +### 9.3 手动分析接口 + +新增: + +```text +POST /api/v1/projects/[projectId]/attachments/[attachmentId]/analyze +``` + +用途: + +- 对 `ready_manual` 的附件手动触发 AI 分析 + +### 9.4 统一下载接口 + +新增: + +```text +GET /api/v1/attachments/[attachmentId]/download +``` + +用途: + +- 图片预览 +- 视频预览或下载 +- 文件下载 + +### 9.5 SSE 刷新 + +现有 `/api/v1/events` 继续承担刷新出口,需要增加这些事件: + +- `attachment.uploaded` +- `attachment.analysis.queued` +- `attachment.analysis.updated` +- `attachment.analysis.completed` +- `attachment.analysis.failed` + +## 10. 原生 Android 设计 + +### 10.1 聊天输入区 + +聊天输入区固定为: + +- 左侧 `+` +- 中间输入框 +- 右侧发送按钮 + +点击 `+` 后弹出底部抽屉,包含: + +- 图片 +- 视频 +- 文件 + +### 10.2 系统文件选择 + +原生 Android 需要新增: + +- 图片选择器 +- 视频选择器 +- 文件选择器 + +建议基于 `ActivityResultContracts.OpenDocument` / `GetContent` 实现。 + +### 10.3 发送前确认 + +- 图片:展示预览 + `取消 / 发送` +- 视频:展示预览或文件摘要 + `取消 / 发送` +- 文件:直接进入上传 + +### 10.4 聊天中的附件渲染 + +图片消息: + +- 缩略图 +- 文件名 +- 大小 +- 分析状态 + +视频消息: + +- 缩略图或占位封面 +- 文件名 +- 大小 +- 分析状态 + +文件消息: + +- 文件图标 +- 文件名 +- 类型 +- 大小 +- 下载/查看动作 +- 分析状态 + +### 10.5 分析状态呈现 + +附件卡片需能表示: + +- `queued_auto`:自动分析排队中 +- `ready_manual`:可分析 +- `processing`:分析中 +- `completed`:分析完成 +- `failed`:分析失败,可重试 + +## 11. Web 配置页设计 + +### 11.1 入口 + +入口固定为: + +```text +我的 > 附件与存储 +``` + +### 11.2 页面结构 + +第一页只做两层: + +1. 存储方式选择 + - 服务器文件存储(默认) + - OSS +2. 如果选 `OSS` + - 供应商选择:当前只显示 `阿里 OSS` + - 展开最小配置表单 + +### 11.3 表单交互 + +表单交互应尽可能简化: + +- `AccessKey ID` +- `AccessKey Secret` +- `Bucket` +- `Endpoint` +- `Region` +- `目录前缀(可选)` + +按钮建议只有两个: + +- `测试并保存` +- `切回服务器文件存储` + +不做额外的高级设置入口作为第一屏主内容。 + +## 12. 与主 Agent 的关系 + +主 Agent 不再只处理文本请求,也需要能理解附件分析任务。 + +这次要求主 Agent: + +1. 收到附件任务时,知道当前附件来自哪个会话、哪条消息 +2. 能通过统一下载 URL 获取附件 +3. 对图片 / PDF / 文本自动分析 +4. 对手动模式附件在用户触发后再分析 +5. 把结果回写为: + - 一条简短消息 + - 一张分析卡片 + +如果主 Agent 当前无法处理某类附件,应明确返回失败原因,而不是静默成功。 + +## 13. 错误处理 + +至少覆盖以下错误: + +1. 用户未配置 OSS,但切换到了 OSS +2. OSS 配置无效 +3. Bucket 无权限 +4. 上传中断 +5. 本地文件 URI 无法读取 +6. 附件消息已创建但自动分析排队失败 +7. 分析任务执行失败 +8. 下载 URL 失效 +9. 原文件已被删除或不可用 + +错误处理原则: + +- 上传失败:不创建成功消息,前台保留失败提示 +- 上传成功、分析失败:保留附件消息,但把分析状态标为 `failed` +- 下载失败:允许用户重试,不直接删除消息 + +## 14. 测试与验收 + +### 14.1 Web / 服务端 + +至少验证: + +1. 默认服务器文件存储上传成功 +2. 阿里 OSS 上传成功 +3. 用户级配置切换生效 +4. 未配置 OSS 时不能误走 OSS +5. 图片 / PDF / 文本能自动排队分析 +6. 视频 / Office / 大文件默认进入手动分析 +7. 下载接口能正确返回本地文件或 OSS 签名 URL + +### 14.2 原生 Android + +至少验证: + +1. `+` 按钮打开底部抽屉 +2. 图片发送前确认 +3. 视频发送前确认 +4. 文件直接发送 +5. 图片消息渲染 +6. 视频消息渲染 +7. 文件消息渲染 +8. 分析状态切换 +9. 下载 / 预览动作 + +### 14.3 验收标准 + +本次工作完成时,应满足: + +1. 用户能从原生聊天框发送图片、视频、文件 +2. 接收端能看到附件消息并统一预览/下载 +3. 默认服务器文件存储可直接使用 +4. 用户可在 Web 端开启 OSS,并完成阿里 OSS 最小配置 +5. 图片 / PDF / 文本会自动交给主 Agent 分析 +6. 视频 / Office / 大文件可手动触发分析 +7. 主 Agent 的分析结果会回到当前聊天中 +8. UI 和交互仍保持当前微信式方向,不回退成控制台面板 + +## 15. 推荐实现顺序 + +1. 先补数据模型与用户级存储配置 +2. 再补服务器文件存储上传 / 下载链 +3. 再补阿里 OSS 适配器与校验 +4. 再补原生 Android 选择文件、上传和附件卡片 +5. 再把主 Agent 附件分析任务接通 +6. 最后补 Web 配置页、联调、部署与发包