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上,並提供了線上演示頁面。