Streamdown 是一个由 Vercel 开发的 React 组件,它可以作为知名库 react-markdown
的直接替代品。这个工具的核心设计目标是解决在处理 AI 模型生成的流式文本时遇到的 Markdown 渲染问题。在AI聊天等应用中,文本是逐字或逐块生成的,这常常导致 Markdown 语法在传输过程中不完整(例如,一个加粗标记 **
出现了,但结尾的标记还没生成)。Streamdown 能够优雅地处理这些不完整或未闭合的 Markdown 语法块,并将其即时渲染成正确的样式。这极大地改善了用户体验,用户可以实时看到格式化好的文本,而不是等待整个响应生成完毕。它集成了对 GitHub 风格 Markdown (GFM)、数学公式、代码高亮和图表的支持,同时注重性能和安全。
功能列表
- 专为流式传输优化: 核心优势在于能平滑处理并渲染持续传入的、不完整的 Markdown 文本流。
- 兼容
react-markdown
: 可作为react-markdown
的直接替代品,并接受几乎所有相同的属性(Props)。 - 未闭合语法解析: 能够正确解析并为未闭合的粗体、斜体、代码、链接和标题等语法设置样式。
- 支持 GFM: 内置支持 GitHub 风格 Markdown,包括表格、任务列表和删除线。
- 数学公式渲染: 通过 KaTeX 支持 LaTeX 数学方程式的渲染。
- Mermaid 图表: 能将代码块中的 Mermaid 语法渲染为图表,并提供一个渲染切换按钮。
- 代码语法高亮: 使用 Shiki 库为代码块提供美观的语法高亮。
- 安全第一: 基于
harden-react-markdown
构建,确保渲染内容的安全性。 - 性能优化: 使用 Memoized 渲染技术,有效提升更新效率,减少不必要的重复渲染。
使用帮助
Streamdown 是一个NPM包,主要用于 React 项目。它的安装和使用流程非常简单,旨在让开发者可以快速集成。
1. 安装
首先,你需要在你的项目中安装 streamdown
。可以使用 npm
、yarn
或 pnpm
等包管理器进行安装。
使用 npm
安装:
npm i streamdown
使用 pnpm
安装:
pnpm add streamdown
2. 配置样式
为了让渲染出来的 HTML 元素拥有正确的样式(例如代码块的背景色、引用块的边框等),Streamdown 需要你引入它的 CSS 文件。你需要将以下代码添加到你项目的全局 CSS 文件中,通常是 globals.css
或类似文件。
@import "../node_modules/streamdown/dist/index.css";
请确保 @import
中的路径根据你的项目结构正确指向 node_modules
文件夹。
3. 基本使用
在你的 React 组件中,导入 Streamdown
组件,然后将需要渲染的 Markdown 字符串作为其子元素传入即可。
这是一个最基础的例子:
import { Streamdown } from 'streamdown';
export default function MyPage() {
const markdownContent = "# 你好,世界!\n\n这是一个 **流式传输** 的 *Markdown* 文本。";
return (
<article>
<Streamdown>{markdownContent}</Streamdown>
</article>
);
}
在上面这个例子中,markdownContent
字符串会被 Streamdown 解析并渲染为对应的 HTML 标签。
4. 结合 Vercel AI SDK 使用
Streamdown 最大的价值体现在处理实时生成的文本流。以下示例展示了如何将其与 Vercel AI SDK 的 useChat
钩子结合使用,来实时渲染 AI 的聊天回复。
'use client';
import { useChat } from '@ai-sdk/react';
import { useState } from 'react';
import { Streamdown } from 'streamdown';
export default function ChatComponent() {
// useChat 钩子管理聊天状态和消息
const { messages, sendMessage, status } = useChat();
const [input, setInput] = useState('');
// 处理表单提交
const handleSubmit = (e) => {
e.preventDefault();
if (input.trim()) {
sendMessage({ role: 'user', content: input });
setInput('');
}
};
return (
<div>
{/* 遍历并显示所有消息 */}
<div>
{messages.map(message => (
<div key={message.id}>
<strong>{message.role === 'user' ? 'You: ' : 'AI: '}</strong>
{/* AI 的回复内容会通过 Streamdown 实时渲染 */}
<Streamdown>{message.content}</Streamdown>
</div>
))}
</div>
{/* 用户输入表单 */}
<form onSubmit={handleSubmit}>
<input
value={input}
onChange={e => setInput(e.target.value)}
disabled={status !== 'idle'}
placeholder="说点什么..."
/>
<button type="submit" disabled={status !== 'idle'}>
发送
</button>
</form>
</div>
);
}
在这个例子中,useChat
返回的 messages
数组会随着 AI 生成回复而实时更新。Streamdown
组件包裹着 message.content
,因此每当新内容片段(token)到达时,它都会立即被渲染成格式化的 HTML,用户会看到文本和格式同步出现。
5. 组件属性 (Props)
Streamdown 支持 react-markdown
的所有属性,并增加了一些针对流式传输的特有选项:
children
(string): 需要渲染的 Markdown 字符串。parseIncompleteMarkdown
(boolean, 默认值:true
): 是否解析并渲染未闭合的 Markdown 语法。这是 Streamdown 的核心功能,建议保持开启。components
(object): 用于覆盖默认的 HTML 元素渲染器。例如,你可以提供一个自定义的<a>
标签组件来处理链接。remarkPlugins
(array):remark
插件数组,用于扩展 Markdown 语法。默认集成了remarkGfm
(用于支持表格、任务列表等) 和remarkMath
。rehypePlugins
(array):rehype
插件数组,用于处理 HTML。默认集成了rehypeKatex
(用于渲染数学公式)。shikiTheme
(string, 默认值:github-light
): 用于代码块语法高亮的 Shiki 主题名称。
应用场景
- AI 聊天机器人
当与大型语言模型(如 GPT)进行交互时,模型的回答是逐字或逐词生成的。使用 Streamdown 可以将这些零碎的文本流实时渲染为带有格式的完整段落,例如代码块、列表和引用等,显著提升用户交互的即时性和体验感。 - 实时协作 Markdown 编辑器
在允许多个用户同时编辑同一个 Markdown 文档的应用中,Streamdown 可以用来为每个用户生成实时的预览视图。即使用户输入的 Markdown 语法还不完整,预览区域也能尽可能正确地展示其样式。 - 在线文档和笔记应用的实时预览
对于任何包含 Markdown 输入框的应用,例如博客发布系统、知识库或个人笔记软件,Streamdown 都可以提供一个所见即所得的实时预览窗口,用户在输入文本的同时就能看到最终的渲染效果。
QA
- 问:Streamdown 与
react-markdown
的核心区别是什么?
答:最核心的区别在于对“流”的处理能力。react-markdown
设计用于一次性渲染一个完整的 Markdown 文档。而 Streamdown 专门为处理不完整、持续输入的文本流进行了优化,能够解析并提前渲染未闭合的语法(如**文本
),这是react-markdown
无法做到的。 - 问:为什么流式渲染对 AI 应用很重要?
答:在 AI 应用中,等待模型生成完整的长篇回答可能会花费数秒甚至更长时间。流式渲染可以让用户在第一个词生成时就开始阅读,并随着文本的产生看到实时格式化,这创造了一种更自然、更即时的对话体验,避免了用户在等待过程中的不确定感。 - 问:它支持哪些 Markdown 扩展功能?
答:它原生支持 GitHub 风格 Markdown (GFM),包括表格、任务列表和删除线。此外,它还通过插件集成了对 LaTeX 数学公式(使用 KaTeX)和 Mermaid 图表的支持。 - 问:使用 Streamdown 有什么系统要求或注意事项?
答:项目需要使用 Node.js 18 或更高版本,以及 React 19.1.1 或更高版本。此外,为了确保样式正确显示,请务必在你的全局 CSS 文件中引入 Streamdown 的样式表。