Streamlit 聊天界面滚动抖动问题的终极解决方案

霞舞

霞舞

2026-08-03

417人浏览

原创

Streamlit 聊天界面滚动抖动问题的终极解决方案

本文提供一种符合 Streamlit 官方最佳实践的流式聊天实现方式,通过 st.chat_message + st.write_stream 替代手动 st.empty() 刷新,彻底解决 Linux/Windows 下滚动跳动、页面重置、光标错位等常见渲染异常问题。

本文提供一种符合 streamlit 官方最佳实践的流式聊天实现方式,通过 `st.chat_message` + `st.write_stream` 替代手动 `st.empty()` 刷新,彻底解决 linux/windows 下滚动跳动、页面重置、光标错位等常见渲染异常问题。

在 Streamlit 中构建 LLM 流式聊天应用时,频繁调用 st.empty().write() 或手动触发 st.rerun() 是导致滚动抖动(scroll jitter)的根本原因——尤其在 Linux 系统上更为明显。这是因为每次 st.rerun() 都会重建整个页面 DOM 树,强制浏览器重计算布局与滚动锚点;而 st.empty() 的反复覆盖又破坏了 内部的滚动容器稳定性,造成视觉“跳回顶部”。

✅ 正确做法是:完全遵循 Streamlit 官方推荐的 st.chat_message + st.write_stream 模式,让框架自动管理消息容器生命周期与滚动行为。

以下为重构后的核心实现(已验证跨平台兼容):

CentOS Stream 9
CentOS Stream 9

CentOS Stream 9是基于RHEL 9技术路线的持续交付版本,适合需要贴近RHEL 9生态的软件开发、系统集成和测试环境。它相比传统CentOS Linux更靠近上游开发过程,用户可以更早看到RHEL 9后续小版本中的软件包变化。CentOS Stream 9仍是当前可用的官方版本线之一,适合对稳定性和新功能之间有平衡需求的团队使用。

下载
import streamlit as st

def general_chat(user_input):
    # 构建上下文与指令(保持逻辑不变)
    key_data = ["politics", "religion", "violence"]
    blocked_topics = "\n".join([f"Do not answer any questions about: {k}" for k in key_data])
    history_context = "\n".join(
        f"{msg['role']}: {msg['content']}" for msg in st.session_state.chat_history
    )
    prompt_input = (
        f"{history_context}\n"
        f"Instructions:\n{blocked_topics}\n"
        f"User: {user_input}\n"
        f"Assistant:"
    )

    # ✅ 关键改进:使用 st.chat_message 包裹 + write_stream 流式输出
    with st.chat_message("assistant"):
        # 假设你使用 ollama、langchain 或自定义流式生成器
        def response_generator():
            for chunk in llm.stream(prompt_input):  # 替换为你的实际流式调用
                yield chunk
        response = st.write_stream(response_generator())

    # ✅ 同步更新历史记录(注意字段名统一为 'content')
    st.session_state.chat_history.append({"role": "assistant", "content": response})

def chat_page():
    st.title("ThinkBot")
    st.write("Welcome to ThinkBot! I am an AI Chatbot.")

    # 初始化会话历史(务必使用 'content' 字段,与 st.chat_message 兼容)
    if "chat_history" not in st.session_state:
        st.session_state.chat_history = [
            {"role": "assistant", "content": "How can I help you?"}
        ]

    # ✅ 渲染历史消息:每条消息独立包裹在 st.chat_message 中
    for msg in st.session_state.chat_history:
        with st.chat_message(msg["role"]):
            st.markdown(msg["content"])

    # ✅ 处理新输入:无需 st.rerun(),直接追加并调用响应函数
    if user_input := st.chat_input(placeholder="Your message"):
        # 立即显示用户消息
        st.session_state.chat_history.append({"role": "user", "content": user_input})
        with st.chat_message("user"):
            st.markdown(user_input)

        # 直接调用流式响应(不触发 rerun)
        general_chat(user_input)

? 关键注意事项

  • 禁止手动 st.rerun():st.chat_input 触发后,所有后续操作(显示用户消息、调用 general_chat)均在单次脚本运行中完成,避免 DOM 重建;
  • 统一字段命名:st.session_state.chat_history 中每条消息必须含 "role" 和 "content"(非 "message"),否则 st.chat_message 渲染可能异常;
  • 禁用自定义 CSS 干预滚动:如 .stAppScrollToBottomContainer { overflow-anchor: none !important; } 可能干扰 Streamlit 内部滚动锚定机制,应移除;
  • 流式生成器必须可迭代:确保 llm.stream(...) 返回的是生成器或可迭代对象,st.write_stream() 依赖其逐块消费;
  • Linux 特别提示:部分 Linux 桌面环境(如 GNOME + Wayland)对滚动事件更敏感,本方案通过框架原生滚动容器(
    )规避底层差异。

    ? 总结:Streamlit 的 st.chat_message 不仅是 UI 组件,更是滚动状态管理器。放弃手动控制 DOM,信任框架对聊天场景的深度优化,是解决所有滚动抖动问题的最简、最稳路径。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
li是什么元素
li是什么元素

li是HTML标记语言中的一个元素,用于创建列表。li代表列表项,它是ul或ol的子元素,li标签的作用是定义列表中的每个项目。本专题为大家li元素相关的各种文章、以及下载和课程。

2023.08.03

596

5

Selenium WebDriver元素定位与页面操作教程
Selenium WebDriver元素定位与页面操作教程

本专题整理Selenium WebDriver元素定位、XPath、CSS Selector、等待机制、窗口切换、Frame处理、Alert弹窗、Cookie操作和文件上传等核心用法。

2026.08.05

0

26

Selenium Grid分布式测试与并行执行教程
Selenium Grid分布式测试与并行执行教程

本专题整理Selenium Grid架构、远程WebDriver、并行测试、Docker部署、Kubernetes动态Grid、浏览器矩阵和测试环境扩展方法,适合进阶自动化测试团队使用。

2026.08.05

0

18

Selenium常见报错排查与自动化测试稳定性
Selenium常见报错排查与自动化测试稳定性

本专题整理Selenium常见报错、驱动版本问题、元素找不到、点击失败、等待超时、浏览器闪退、脚本不稳定和测试用例维护方法。

2026.08.05

0

17

墨刀AI提示词教学
墨刀AI提示词教学

本合集由PHP中文网精心整理,为您提供全面的墨刀AI提示词教学。内容涵盖高质量原型撰写公式与实操窍门,助您轻松掌握AI设计工具。无论是零基础入门还是进阶技巧,都能让您快速上手,大幅提升产品设计与协作效率。

2026.08.04

11

21

墨刀AI完整入门
墨刀AI完整入门

PHP中文网为您倾力打造墨刀AI保姆级入门指南完整版!本合集从零基础讲起,涵盖AI生成原型、提示词优化、图片转原型及多轮对话等核心功能。无论您是新手还是进阶用户,都能轻松掌握产品设计全流程。快来PHP中文网,一键解锁高效设计技巧,让想法即刻成型!

2026.08.04

8

20

墨刀AI进阶技巧
墨刀AI进阶技巧

本合集由PHP中文网精心整理,为您提供墨刀AI核心进阶策略指南。内容涵盖高效提示词写作、原型智能生成与微调、结构化导图制作及行业分析报告输出等实战技巧。助您轻松掌握AI设计工具,大幅提升产品设计与团队协作效率。

2026.08.04

10

14

火山引擎实名认证失败怎么办
火山引擎实名认证失败怎么办

火山引擎实名认证失败可能与证件信息填写错误、姓名或企业信息不一致、证件照片不清晰、营业执照状态异常、手机号验证失败或审核资料不完整有关。本专题整理个人认证、企业认证、资料上传、审核退回、重新提交和认证不通过的常见处理方法。

2026.08.04

5

10

火山引擎域名备案流程详解
火山引擎域名备案流程详解

火山引擎域名备案适合需要在火山引擎云服务器、对象存储、CDN或网站服务上绑定域名的用户参考。本专题整理备案入口、账号实名认证、备案类型选择、主体信息填写、网站信息提交、资料上传、初审核验、管局审核和备案失败排查,帮助用户完成网站上线前的备案流程。

2026.08.04

1

10

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
CentOS 官方文档
CentOS 官方文档

共0课时 | 0人学习

极客学院Java8新特性视频教程
极客学院Java8新特性视频教程

共17课时 | 4.1万人学习

极客学院Python视频教程
极客学院Python视频教程

共67课时 | 25万人学习