☰
如何在Web终端实时渲染LLM流式Markdown:wterm markdown包教程
2026/9/26 15:10:17 网站建设 项目流程

如何在Web终端实时渲染LLM流式Markdown:wterm markdown包教程

【免费下载链接】wtermA terminal emulator for the web项目地址: https://gitcode.com/gh_mirrors/wterm1/wterm

wterm 是一个面向 Web 的终端模拟器,其中的@wterm/markdown包能实时将 LLM 流式输出的 Markdown 逐块转换成终端 ANSI 文本。本教程带你快速掌握 Web 终端实时渲染 LLM 流式 Markdown 的完整方法:从一行命令安装,到把 AI 回复流接入浏览器终端,新手也能照着做出来。

为什么 Web 终端要实时渲染 LLM 流式 Markdown?

在大模型应用中,回复是一次次以小块文本(chunk)的形式返回的。传统做法是:

  1. 等全部文本接收完毕;
  2. 用 Markdown 库渲染成 HTML。

这在网页聊天框里没问题,但如果你用的是Web 终端(比如 AI 编程助手嵌在终端里),等全文接收完再渲染会有明显的"空白等待期",而且 Markdown 库产出的是 HTML,终端根本不认。

@wterm/markdown解决的就是这个问题:它是一个流式 Markdown 转 ANSI 渲染器,文本一到就立刻转成带样式的终端输出,用户在终端里看到回答"打字机式"逐行浮现,体验与本地 TUI 一致。

💡 一句话理解:push()喂进流式文本,终端立刻拿到可显示的 ANSI 内容;flush()在流结束时兜底收尾。

一键安装:如何快速上手 wterm markdown 包

安装只需一条命令:

npm install @wterm/markdown

核心用法极简,只需三步:

import { MarkdownRenderer } from "@wterm/markdown"; const md = new MarkdownRenderer({ width: 80 }); // 流式过程中,每收到一段文本就调用一次 const ansi = md.push("# 标题\n\n这是 **加粗** 内容。\n"); terminal.write(ansi); // 流结束后收尾 terminal.write(md.flush());

完整 API 说明见官方文档 markdown.mdx 与包内 README。

核心 API 讲解:push 与 flush 如何工作?

MarkdownRenderer类的实现非常紧凑,源码仅约 200 行,值得了解其工作机制:

方法作用
push(delta: string): string喂入一段 Markdown 文本,返回已完整行的 ANSI 输出
flush(): string流结束时刷出缓冲区剩余内容,并关闭未结束的代码块
构造参数width终端列宽(默认 80),用于生成分隔线长度

关键点:内部按行缓冲。push()会把不完整的一行留在内部缓冲区,只有遇到换行符、确认一行完整时才渲染输出。这个设计正是为流式场景准备的——LLM 的 chunk 边界是随机的,可能正好把一行切成两半,而渲染器会自动拼接,不会出现半行闪烁或格式错乱。

实现细节可以阅读源码 index.ts,其中push方法(第 32-44 行)展示了缓冲逻辑,flush方法(第 46-56 行)负责收尾。

支持哪些 Markdown 语法?渲染效果一览

@wterm/markdown覆盖了 LLM 回复中最常用的语法,渲染效果如下:

语法终端渲染效果
#~######标题H1/H2 粗体亮白色,H3+ 粗体,并自动留白行
**粗体**/__粗体__加粗
*斜体*/_斜体_斜体
`行内代码`青色高亮
文字绿色下划线 + 灰色淡显的 URL
围栏代码块```缩进展示,上下带暗淡分隔线
- item无序列表缩进圆点列表
1. item有序列表带序号列表
> 引用带暗淡竖线的引用块
---分隔线暗淡横线

每种渲染都有对应的单元测试保障,例如 H1 渲染为粗体亮白色的断言见 markdown.test.ts。

实战:3 步把 LLM 流接入 Web 终端

wterm 官方提供了一个完整可运行的示例项目markdown-streaming,使用@wterm/react+ AI SDK 演示了全流程,项目说明见 examples/markdown-streaming/README.md。

第 1 步:服务端流式返回

API 路由使用 AI SDK 的streamText发起流式请求,通过toTextStreamResponse()把文本流原样推给前端:

const result = streamText({ model: "openai/gpt-4o-mini", messages }); return result.toTextStreamResponse();

参考实现:route.ts

第 2 步:前端逐块读取并渲染

这是整个方案的核心循环——用ReadableStream的 reader 逐块读取,每块立即push进渲染器并写入终端:

const reader = response.body.getReader(); const decoder = new TextDecoder(); while (true) { const { done, value } = await reader.read(); if (done) break; const rendered = md.push(decoder.decode(value, { stream: true })); if (rendered) write(rendered); } write(md.flush());

完整页面实现(含用户输入、会话历史、错误处理)见 page.tsx。

第 3 步:体验与细节

  • 回答边生成边渲染,标题、粗体、代码块等样式随内容实时出现;
  • 生成过程中按Ctrl+C可中断流(示例中用AbortController实现,见 page.tsx);
  • 每次新回答建议创建新的MarkdownRenderer实例,避免上一轮的缓冲状态残留。

新手避坑:4 个最佳实践

  1. 流结束务必调用flush()—— 否则最后一行文本和未闭合的代码块不会被渲染,这是最常见的遗漏。
  2. 忽略返回的空字符串——push()在收到不完整的行时返回空串,if (rendered)判空后再写入终端即可。
  3. 按需设置width—— 该参数只影响分隔线长度,一般跟随终端实际列宽设置。
  4. 不要对整段文本重复 push—— 渲染器是状态式的,每个 chunk 只能喂一次,重复喂会导致内容翻倍。

小结:wterm markdown 包适合谁?

@wterm/markdown用极小的体积(核心实现不足 300 行)解决了「Web 终端里 LLM 流式输出」这一真实痛点:

  • 做AI 终端助手 / 编程 Agent 产品:终端 UI + 流式 Markdown 是理想形态;
  • 做浏览器内演示 / 文档站点:几行代码即可让 AI 回复在真终端里打字机式呈现。

结合 wterm 的 React / Vue / Svelte 框架绑定(源码位于 packages/@wterm/react/ 等目录),你可以快速把实时渲染 LLM 流式 Markdown 的能力嵌入任何前端项目。

【免费下载链接】wtermA terminal emulator for the web项目地址: https://gitcode.com/gh_mirrors/wterm1/wterm

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询