用 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 :)

相关推荐
liangshanbo12151 小时前
面试题:前端工程化中 Tree Shaking的原理是什么?
前端·treeshaking
熊猫钓鱼>_>1 小时前
从闲置平板到家里的“控制大脑“:鸿蒙智慧中控面板完整实战
运维·人工智能·华为·自动化·电脑·ai编程·harmonyos
心理之旅2 小时前
WorkbuddyAI办公----- 不懂代码,也能给自己做一个自动化工具:9 轮对话实录
ai编程
补码缩写2 小时前
视频跳转触发了seeked,画面就到位了吗
前端
库拉镜像AI牛牛2 小时前
漫剧工作室量产方案:依托知漫剧 AI 短剧降本增效
大数据·服务器·前端·人工智能·语音识别
心理之旅2 小时前
从 40 分钟到 38 秒:SAP Business One 物料库存自动取数实战
ai编程
不可能片场2 小时前
内容运营自动化 用相似度拦住撞车选题
前端·electron
HelloWorld0012 小时前
告别轮询与断流!基于 Spring Boot 3 + SSE + Redis 打造生产级 Agent 流式思考与工具调用中枢
ai编程
静默回滚2 小时前
视频进度条跳回去,先别改事件监听
前端
Lank_M2 小时前
MP4和WebM导出后为何起播与拖动不同
前端