用 Streamdown 优雅地打字输出 AI 流式返回的文本

如果眼睛足够敏锐,你会发现有些 AI tool 通过 SSE 返回流式文本时,会先打印出 * ** - 或其它 Markdown 格式化字符,之后又迅速消失。用户阅读过程中,格式化的不同导致不同程度的 layout shift,文本不停换位置或忽大忽小,造成视觉疲劳。

问题

在网页中,我们通常用 react-markdown 来解析 Markdown 代码,一次性整体解析是没问题的,但 SSE 零零散散地把字串返到页面 Markdown 未成功解析时,用户就会看到奇奇怪怪的字符先。

解决办法

  • 写正则,修正各种 Markdown 语法不正确的场景;
  • 直接用 package Streamdown

代码

js 复制代码
// Nextjs

'use client';

import { useChat } from '@ai-sdk/react';
import { useState } from 'react';
import { Streamdown } from 'streamdown'; // 引入 streamdown

export default function Page() {
  const { messages, sendMessage, status } = useChat();
  const [input, setInput] = useState('');

  return (
    <>
      {messages.map(message => (
        <div key={message.id}>
          {message.parts.filter(part => part.type === 'text').map((part, index) => (
          
            { /* 用 Streamdown 包住 Markdown 文本 */ }
            <Streamdown key={index}>{part.text}</Streamdown>
          ))}
        </div>
      ))}

      <form
        onSubmit={e => {
          e.preventDefault();
          if (input.trim()) {
            sendMessage({ text: input });
            setInput('');
          }
        }}
      >
        <input
          value={input}
          onChange={e => setInput(e.target.value)}
          disabled={status !== 'ready'}
          placeholder="说点什么..."
        />
        <button type="submit" disabled={status !== 'ready'}>
          提交
        </button>
      </form>
    </>
  );
}

解决的痛点

内置的排版样式

Streamdown 为常见的 Markdown 提供了内置的 Tailwind 类,自动格式化标题、列表、代码块等。

GitHub 风格的 Markdown

Streamdown 默认支持 GitHub 风格的 Markdown (GFM),可以正常解析任务列表、表格等。

美观、交互式的代码区块

Streamdown 使用 Shiki 来高亮显示代码块,自带复制按钮,悬停显示复制按钮!

数学表达式

Streamdown 通过 remark-math 和 KaTeX 支持 LaTeX 数学表达式,在 Markdown 中完美展现各种数学符号。韦神满意地笑了!

提前解析未闭合的 Markdown 标签

Streamdown 提前解析未闭合的 Markdown 标签(# 标题、内联代码**粗体**_斜体_[链接]()等),极大提升了用户体验,大大减少了文本来回抖动的现象。

内置安全机制

Streamdown 检测 Markdown 中不安全的元素,自动屏蔽可能已 被 prompt 注入攻击 的图像和链接。

演示仓库

以上都为静态图片,未能动态演示出打字过程中的变化,checkout Demo of Streamdown 到本地试下。Have fun :)

相关推荐
华仔啊8 小时前
前端必看!12个JS神级简写技巧,代码效率直接飙升80%,告别加班!
前端·javascript
excel8 小时前
dep.ts 逐行解读
前端·javascript·vue.js
爱上妖精的尾巴8 小时前
5-20 WPS JS宏 every与some数组的[与或]迭代(数组的逻辑判断)
开发语言·前端·javascript·wps·js宏·jsa
excel8 小时前
Vue3 响应式核心源码全解析:Dep、Link 与 track/trigger 完整执行机制详解
前端
前端大卫8 小时前
一个关于时区的线上问题
前端·javascript·vue.js
whltaoin8 小时前
中秋赏月互动页面:用前端技术演绎传统节日之美
前端·javascript·html·css3·中秋主题前端
IT派同学9 小时前
TableWiz诞生记:一个被表格合并逼疯的程序员如何自救
前端·vue.js
云起SAAS11 小时前
SCL-90症状自评量表抖音快手微信小程序看广告流量主开源
微信小程序·小程序·ai编程·看广告变现轻·scl-90症状自评量表·scl-90
西洼工作室11 小时前
CSS高效开发三大方向
前端·css
昔人'11 小时前
css`font-variant-numeric: tabular-nums` 用来控制数字的样式。
前端·css