AI News HubLIVE
站内改写2 分钟阅读

Show HN:在服务端或客户端增量解析LLM Markdown流

一个支持流式增量解析的Markdown解析器,遵循CommonMark规范,可处理LLM生成的Markdown流,逐步输出已完成的AST节点。

来源Hacker News AI作者: nayajunimesh

大型语言模型(LLM)在流式输出时,往往逐步生成Markdown格式的文本。传统的Markdown解析器需要完整的输入才能构建抽象语法树(AST),这显然不适合流式场景。为了解决这一问题,开发者nimeshnayaju发布了一款名为markdown-parser的TypeScript库,支持流式增量解析,能够随着输入的增加,逐步输出已确定的AST节点。

该解析器完全遵循CommonMark规范,并支持GitHub Flavored Markdown(GFM)表格。它可以在服务端或客户端使用,核心原理是通过维护内部状态,在多次调用parse()方法时仅返回新完成的块。当流结束时,可以关闭所有仍处于开放状态的块,得到完整的AST。

安装非常简单,只需执行npm install markdown-parser即可。基本用法是创建一个MarkdownParser实例,然后调用parse()方法。在流式模式下,可以连续将文本传递给解析器,每次调用仅返回新确定的块。例如:

import { MarkdownParser } from "markdown-parser";

const parser = new MarkdownParser();
let nodes = parser.parse("# Hello World\nThis", { stream: true });
// 仅返回标题节点,段落尚未完成
nodes = parser.parse(" is a paragraph\n\nThis is another paragraph.", { stream: true });
// 返回段落节点

除了基本的解析功能外,该库还提供了一个实验性的experimental_openNode属性,用于预览当前正在解析的开放块。这对于在流式渲染时提前展示部分内容非常有用,尽管该节点尚未最终确定,可能会随着更多输入而变化。

在内部实现上,markdown-parser借鉴了commonmark.js、markdown-it和marked.js等解析器的思路,结构上类似commonmark.js。主要区别在于流式模式下如何决定解析哪些行。开发者在初始实现时采用了更简单、更易读的版本,但在支持块级容器(如引用块和列表)后,代码变得复杂,最终采用了更为健壮且可扩展的方案。

需要注意的是,CommonMark规范允许链接引用定义出现在使用它们的链接之后。因此,在流式解析时,必须考虑链接引用可能无法立即解析,因为其定义可能出现在后续的输入块中。这是实现流式Markdown解析的一个关键难点。

markdown-parser支持CommonMark规范中的所有块级节点和行内节点,包括标题、段落、代码块、分隔线、HTML块、引用块、列表、链接引用定义以及GFM表格。行内节点则涵盖文本、代码片段、换行、HTML行内元素、自动链接、链接、图片、强调和粗体等。

作为一个流式Markdown解析器,markdown-parser为LLM输出的实时渲染提供了一种高效且符合规范的解决方案。无论是用于聊天机器人、代码生成还是其他流式文本应用,它都能帮助开发者更优雅地处理增量Markdown内容。该项目完全开源,采用MIT许可证,代码托管在GitHub上,并提供了在线演示页面。