# 对话自动跟随设计 日期:2026-06-22 状态:设计已确认,待实现 当前分支:`codex/fix-chat-auto-scroll` ## 目的 这份设计用于解决 llm-wiki-agent 对话区在发送消息后不会自动向下推进的问题。 当前现象是:用户发送消息后,AI 回复已经开始生成,但对话内容不会自动滚到最新位置。用户需要手动用滚轮向下滚,才能看到新回复或回复后续内容。这会打断对话连续性,尤其在长回复和工具调用之后更明显。 目标体验是一句话: **用户在看最新回复时,对话自动跟随;用户主动上翻看历史时,界面尊重用户,不强行拉回底部。** ## 背景依据 llm-wiki-agent 的产品定位是“以对话为中心的本地知识库工作台”。对话主区是核心入口,自动跟随最新回复属于基础对话体验。 本设计不是新增复杂功能,也不是改变对话模型、消息协议或会话存储。它只收口一件事:对话区应该在正确的时候展示最新内容。 已确认的现状: - 对话消息区本身是可滚动区域。 - 发送消息会立即新增用户消息和空的 AI 回复气泡。 - AI 回复是流式生成的,内容会持续变长。 - 当前没有专门的“是否跟随底部”的状态管理。 ## 设计结论 采用“智能跟随 + 向下箭头按钮”的方案。 1. 用户发送消息后,对话区立即滚到最新消息位置。 2. AI 回复生成过程中,如果用户仍在底部附近,对话区持续跟随最新内容。 3. 如果用户主动上翻历史,对话区暂停自动跟随。 4. 暂停跟随后,显示向下箭头按钮,提醒用户有最新内容可回到。 5. 用户点击向下箭头按钮,或自己手动滚回底部附近后,恢复自动跟随。 这里的“底部附近”指用户距离消息区底部很近,已经是在看最新内容。实现时可使用一个固定容差,例如 80-120 px;具体数值以不误判用户上翻为优先。 不采用以下方案: - 不做“永远强制滚到底部”,因为会打断用户阅读历史消息。 - 不做“只在发送时滚一次”,因为 AI 回复流式变长时仍可能看不到后续内容。 ## 用户体验规则 ### 1. 发送消息 用户点击发送或使用快捷键发送后: - 输入框清空。 - 新的用户消息和 AI 回复占位出现在对话尾部。 - 对话区自动滚到尾部。 - 自动跟随状态开启。 这样用户能立即看到“消息已发出,AI 正在回复”。 ### 2. 回复生成中 AI 回复逐步生成时: - 如果用户没有上翻,最新回复始终保持在可见范围内。 - 回复内容变长、工具状态出现、工具状态完成、Markdown 表格展开等情况,都应继续跟随。 - 跟随不需要动画夸张,重点是稳定地看到最新内容。 ### 3. 用户主动上翻 如果用户把对话区往上滚,离开底部一段距离: - 自动跟随暂停。 - 后续 AI 回复继续生成,但不强行滚动页面。 - 显示向下箭头按钮。 这里的产品原则是:一旦用户主动查看历史,系统不能替用户夺回滚动位置。 ### 4. 恢复跟随 有两种方式恢复: - 用户点击向下箭头按钮。 - 用户自己滚回底部附近。 恢复后: - 对话区滚到最新内容。 - 向下箭头按钮消失。 - 如果 AI 仍在生成,继续自动跟随。 ### 5. 切换会话或知识库 切换会话或知识库后,新的对话面板应按当前会话历史展示: - 如果进入的是已有长对话,默认展示底部最新消息。 - 如果是空会话,展示空状态。 - 切换动作不继承上一个会话的“暂停跟随”状态。 ## 界面边界 回到底部入口采用类似 Codex 的向下箭头图标按钮,不使用文字按钮。 按钮规则: - 使用单个向下箭头表达“回到底部”。 - 按钮为轻量圆形或近圆形,视觉上像悬浮的小控制点。 - 放在对话区底部中间附近,悬浮在输入区上方,不遮挡消息正文。 - 样式跟随当前主题,使用柔和背景、细边框和轻微阴影;暗色和浅色模式都要自然。 - 鼠标悬停时只做轻微强调,不做夸张动画。 - 只在用户离开底部且有必要回到底部时出现。 - 按钮本身不显示文字,但可访问名称应是“回到底部”。 - 本次不增加未读数量;如果以后需要未读计数,另开设计,不混入本次实现。 本次不做: - 未读消息数量。 - 跳转到某一条消息。 - 对话搜索定位。 - 历史消息虚拟列表。 - 全局页面滚动重构。 ## 组件与数据流 实现应集中在对话面板内部完成,不改变后端接口。 需要维护的前端状态: - 当前是否处于自动跟随状态。 - 当前是否离底部足够近。 - 是否需要显示向下箭头按钮。 主要数据流: 1. 用户发送消息,消息列表新增内容,开启自动跟随。 2. AI 流式回复更新消息内容。 3. 消息内容变化后,如果自动跟随开启,则滚到尾部。 4. 用户滚动消息区时,判断是否离开底部。 5. 离开底部则暂停自动跟随并显示向下箭头按钮。 6. 用户点击向下箭头按钮或滚回底部,则恢复自动跟随。 ## 异常与边界 需要覆盖以下情况: - 对话为空时不显示向下箭头按钮。 - 只有图标按钮时,键盘和读屏仍能识别它是“回到底部”。 - 回复出错时,如果用户在底部附近,错误提示也应可见。 - 用户停止生成时,滚动状态不应乱跳。 - 工具调用状态展开或收起时,如果用户在底部附近,应继续跟随。 - 大段 Markdown、表格、代码块渲染后高度变化时,仍能保持跟随。 - 用户正在上翻时,即使回复继续增长,也不能强行滚回底部。 ## 验收标准 实现完成后至少验证以下场景: 1. 发出一条普通消息后,不需要滚轮就能看到 AI 回复开始。 2. 长回复生成过程中,页面持续停在最新内容附近。 3. 回复生成时用户上翻历史,页面不再被自动拉到底部。 4. 用户上翻后看到符合当前主题的向下箭头按钮,而不是文字按钮。 5. 用户点击向下箭头按钮后,立即回到最新回复,并恢复自动跟随。 6. 用户自己滚回底部后,向下箭头按钮消失,后续回复继续自动跟随。 7. 切换到已有长会话时,默认看到最新消息。 8. 回复出错或停止生成时,界面没有异常跳动。 ## 验证方式 推荐验证分三层: 1. 增加前端组件测试,覆盖发送、流式更新、用户上翻、向下箭头按钮显示与恢复。 2. 运行现有前端测试和类型检查,确认没有破坏输入框、导出按钮、消息气泡和工具状态。 3. 启动本地应用,在浏览器里真实发送一条长回复请求,手动验证自动跟随和上翻暂停。 ## 后续实现范围 后续实现应只修改对话面板和必要样式。 不改: - 后端流式协议。 - 会话存储格式。 - 知识库选择逻辑。 - 图谱、右抽屉、搜索、导出等无关模块。 如果实现过程中发现对话区滚动容器和页面布局有冲突,应先优先修正对话区内部滚动边界,不扩大为整体布局重构。