大家都很熟悉 JSON 和 CSV,但你有沒有遇過處理幾 GB 的大型 JSON 檔案時導致記憶體直接爆炸?或是用 CSV 紀錄多層次巢狀資料時覺得轉義符號超級痛苦?
在現代 AI 訓練與海量資料處理領域,有一個資料格式正在默默成為主流標準,那就是 JSONL(JSON Lines)。
JSONL 的核心價值:解決傳統 JSON 無法串流讀取與 CSV 無法支援巢狀結構的兩大痛點!
什麼是 JSONL?一分鐘搞懂「一行一個 JSON」的核心定義
JSONL 的全名是 JSON Lines (有時也被稱為 NDJSON,即 Newline Delimited JSON)。它的核心概念非常直白:每一行都是一個獨立且完整的 JSON 物件。
在傳統的 JSON 檔案中,最外層通常會有一個巨大的中括號 [] 將所有資料包起來,且各物件之間必須用逗號 , 隔開。而 JSONL 徹底摒棄了最外層的中括號與逗號,改用換行符號 \n 來分隔每筆資料。

三大常見資料格式對照
為了讓大家更直觀理解,我們將 JSONL、JSON 與 CSV 放在一起比較:
| 資料格式 | 排版結構 | 巢狀資料支援 | 串流讀寫(Streaming) | 適合情境 |
|---|---|---|---|---|
| JSON | 整份檔案為單一階層樹狀結構,需一次載入 | 原生支援 | 困難(需載入整份檔案) | Web API 傳輸、設定檔 |
| CSV | 2D 平面表格,以逗號分隔欄位 | 困難(需轉義或編碼) | 原生支援 | Excel 報表、平面數據 |
| JSONL | 一行一個獨立 JSON,以換行分隔 | 原生支援 | 極佳(逐行讀取與追加) | AI 訓練集、海量 Log 紀錄 |
為什麼 AI 模型訓練與大數據 ETL 都偏愛 JSONL?
近年隨著 OpenAI、Anthropic 等大語言模型(LLM)的崛起,JSONL 躍升為微調(Fine-tuning)與資料集準備的首選格式。這背後主要有兩大關鍵優勢:
1. 記憶體佔用極低(支援 Streaming 串流處理)
當你的訓練資料庫高達 50 GB 時,如果是傳統 JSON 檔案,程式必須把整份 50 GB 的檔案完整讀入記憶體解析語法樹,這會瞬間觸發記憶體溢出(OOM)。
而 JSONL 支援 逐行讀取(Line-by-line Streaming)。程式只需要一次讀取一行(可能只有幾 KB),處理完畢後釋放記憶體再讀下一行。
flowchart TD
subgraph TraditionalJSON["傳統 JSON 讀取方式"]
A1["讀取 50 GB JSON 檔案"] --> A2["解析全檔案語法樹"]
A2 --> A3["記憶體一次性載入 50 GB"]
A3 -->|高風險| A4["記憶體溢出崩溃 (OOM)"]
end
subgraph JSONLStreaming["JSONL 串流讀取方式"]
B1["開啟 50 GB JSONL 檔案"] --> B2["讀取第 1 行 (5 KB)"]
B2 --> B3["解析並處理單筆資料"]
B3 --> B4["釋放記憶體並讀取下一行"]
B4 --> B5["穩定高效完成海量數據處理"]
end
對於海量資料而言,JSONL 讓記憶體消耗從 O(N) 降為 O(1)!
2. 支援無鎖追加(Append-Only Logging)
在分散式系統或日誌收集情境中,如果要在檔案末尾新增資料:
- 傳統
JSON:必須讀取全檔、移除結尾的]、補上逗號,、寫入新資料再補回]。 - JSONL:直接在檔案尾端直接 append 一個字串與換行符號
\n即可完成寫入。
3. 大數據平行處理(Parallel Processing)
因為 JSONL 的每一行都是獨立的 JSON,大型檔案可以從任意換行符號切割成若干小區塊,發送給多個 CPU Core 或計算節點進行平行運算,彼此完全互不干擾。
開發者必知的 5 大 JSONL 嚴格格式鐵律
雖然 JSONL 極具彈性,但為了確保解析器能順利讀取,官方規格(jsonlines.org)訂立了 5 大格式限制:
規範詳細說明
| 規範編號 | 鐵律項目 | 說明與正確示範 |
|---|---|---|
| 規範 1 | 每一行必須是合法 JSON | 每一行獨立拿出來都必須能被标准的 JSON.parse() 解析。 |
| 規範 2 | 絕不能有未轉義的換行 | 字串內若含有換行,必須轉義寫成 \n,禁用多行排版。 |
| 規範 3 | 禁用最外層符號 | 絕不可有最外層中括號 [] ,行與行之間 不可加逗號 , 。 |
| 規範 4 | UTF-8 無 BOM 編碼 | 必須嚴格使用 UTF-8 編碼,且 不應包含 BOM 頭。 |
| 規範 5 | 檔案預設不含空行 | 每一行皆為有效資料,唯有檔案最後一行允許空換行。 |
實戰解析:如何寫出防禦性高的 JSONL 讀取程式碼?
在實際開發中,由於 JSONL 具有 無固定 Schema(Schema-less) 的特性,不同行的 Key 可能完全不同。寫程式解析時,建議遵守以下防禦性原則:
防禦性程式碼範例(Python)
import json
def process_jsonl_file(file_path):
with open(file_path, "r", encoding="utf-8") as f:
for line_num, line in enumerate(f, 1):
# 1. 自動跳過空白行(防止空白行導致解析失敗)
line = line.strip()
if not line:
continue
try:
data = json.loads(line)
# 2. 防禦性取值:使用 .get() 避免 KeyError
user_id = data.get("id")
user_name = data.get("name", "Unknown")
# 3. 欄位型態識別(多型資料處理)
doc_type = data.get("type", "default")
print(f"Line {line_num}: [{doc_type}] {user_id} - {user_name}")
except json.JSONDecodeError as e:
print(f"Error parsing line {line_num}: {e}")
# 執行讀取
process_jsonl_file("dataset.jsonl")
關鍵防禦技巧:使用
strip()清除首尾空白,並以.get()代替直取鍵值,可避免 90% 以上的運行時崩潰!
JSONL、JSON 與 CSV 的情境選擇指南
看完 JSONL 的強大功能後,是不是該把所有資料都換成 JSONL 呢?答案是:看使用情境!
| 情境需求 | 推薦使用格式 | 原因說明 |
|---|---|---|
| Web 前後端 API 傳輸 | JSON | 瀏覽器原生支援度高,單次傳輸資料量適中。 |
| 匯出數據給非技術人員/行銷 | CSV | 可直接用 Excel 開啟檢視。 |
| AI 模型微調 (Fine-tuning) | JSONL | OpenAI / Anthropic API 官方指定訓練格式。 |
| 系統海量 Log 紀錄 | JSONL | 寫入成本低、支援無限 append 與超低記憶體監控。 |
| 大數據 ETL 管線 | JSONL | 方便分散式切割與平行處理。 |
只要掌握各格式的特性,在正確的情境選擇正確工具,就能讓你的資料處理效能大幅提升!