Show HN:在服務端或客户端增量解析LLM Markdown流
一個支持流式增量解析的Markdown解析器,遵循CommonMark規範,可處理LLM生成的Markdown流,逐步輸出已完成的AST節點。
大型語言模型(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上,並提供了在線演示頁面。