主题
React + AI 应用开发
AI 对话历史、草稿和分支会话如何持久化?
对话产品既要即时反馈,也要在刷新、换设备和分支重试后保持可理解的历史。
面试官想考什么
- 消息是按整段还是按 token 保存? 考察持久化粒度。
- 用户刷新时草稿和生成状态如何恢复? 考察恢复体验。
- 重新生成和编辑历史如何建模? 考察分支语义。
- 本地缓存能否作为最终数据? 考察权威来源和隐私。
一句话回答
text
服务端以 conversation、message、attempt 和 revision 保存权威历史,前端用本地草稿和缓存改善体验;生成中可临时保存 checkpoint,完成后提交不可变版本,重新生成和编辑通过分支或新 attempt 表达而不是覆盖原始事实。面试回答详解
1. 推荐模型
text
conversation
-> message(id, parentId, role, revision)
-> attempt(id, model, status, usage)
-> event/checkpointparentId 可以表达树状分支。简单产品也可以只保存线性消息,但要明确重新生成是否覆盖、是否允许回看旧答案。
2. 保存时机
- 用户消息提交前可保存草稿。
- assistant streaming 期间按 checkpoint 保存,避免每 token 写库。
- completed/failed/cancelled 时写最终状态和 usage。
- 关键操作使用事务或 outbox,避免消息和任务状态分离。
3. 前端缓存
内存缓存负责当前体验,IndexedDB 可保存未发送草稿或有限离线队列。敏感对话要有过期、登出清理、设备共享提示和加密策略。缓存失效后以服务端 revision 为准,不要把旧本地内容覆盖新历史。
4. 分支与同步
重新生成应生成新的 attempt 或 sibling message,保留原答案。用户编辑历史消息后,应从该 parent 创建新分支,旧分支只读。多设备同步使用 cursor/revision,冲突时提示或按服务端合并。
5. 成本和隐私
不要保存每个 token 的完整事件作为长期历史;可按时间窗口 checkpoint,最终只保存聚合文本和必要 metadata。prompt、引用和工具结果可能含敏感信息,日志和分析系统应最小化、脱敏和设置保留期限。
可直接背诵的 30 秒回答
text
我会把 conversation、message、generation attempt 和 revision 分开建模。前端本地只保存草稿和短期缓存,服务端保存权威历史;流式过程中按 checkpoint 保存,结束时提交最终版本。重新生成或编辑通过新 attempt 或分支保留历史,刷新和多设备同步按 revision 合并,敏感内容有清理和保留策略。扩展知识
线性列表与消息树
- 线性列表:开发简单,适合没有编辑和重新生成的 Chat。
- 消息树:能表达重试、编辑和多候选,但需要当前 branch 指针、导航和存储成本。
面试官追问链
追问一:为什么不直接覆盖旧 assistant 消息?
- 考察点:可追溯性。
- 回答方向:会丢失模型版本、错误和用户比较依据;若产品明确只保留最新,也至少应保留审计或 attempt metadata。
追问二:checkpoint 保存多久一次?
- 考察点:成本取舍。
- 回答方向:按消息长度、时间窗口和故障恢复目标决定,通常不需要 token 粒度;需要压测数据库写入与恢复体验。
追问三:本地草稿和服务端消息冲突怎么办?
- 考察点:同步策略。
- 回答方向:带 clientId、updatedAt、revision;未发送草稿独立保存,已提交内容以服务端 revision 为准并提示冲突。