聊天页面的数据和状态怎么设计?
先理解原理和示例,再练习完整口述与追问。
回答要点
区分 conversationId、messageId、requestId;分开管理会话和消息。消息至少区分等待、生成中、完成、失败、已停止,工具执行还应有独立状态。
考虑重复发送、切换会话后旧流返回、分页历史、重试、刷新恢复和乐观更新。不要用一个全局 loading 表示所有消息状态。
原理拆解
聊天状态需要区分会话、消息与一次生成任务。消息具有稳定 ID、角色、内容块、引用、工具结果和状态;生成任务维护版本、取消、错误与完成。展示状态与持久化状态可能不同,部分文本并不代表最终可恢复记录,保存策略应清楚。
示例与推演
会话里追加用户消息,再创建空 assistant 消息与 generation;delta 只写对应 assistant;工具事件作为结构化块处理。流中途失败保留部分内容并提供重试,重试生成新版本而不把文本接到旧回答后面。切换会话后旧事件仍按会话与任务 ID 归属,不能写当前列表最后一项。
易错点
不要用数组下标或“最后一条消息”作为唯一身份。多人或多设备使用时,持久化顺序、权限与冲突必须由服务端协议保证。
参考回答可直接练习口述
我会分开管理会话、消息和请求:conversationId 标识会话,messageId 标识消息,requestId 标识一次生成。消息状态至少有 queued、streaming、done、error、stopped,工具调用可另有 running/success/error。每次增量只更新其所属消息,并核对请求身份。切换会话、重试、刷新恢复和历史分页都有明确规则,避免一个全局 loading 控制所有对话,也避免旧流写入新页面。