JSONL (JSON Lines)
Коротко: Формат файлу, у якому кожен рядок сам по собі є повним допустимим об’єктом JSON — на відміну від звичайного файлу JSON, який загалом має бути одним об’єктом або масивом.
Докладніше: Зручний для журналів і потоків, бо можна читати й писати порядково, не розбираючи весь файл, а нові записи просто дописуються в кінець.
Наш контекст: Claude Code зберігає стенограми сеансів у форматі JSONL (один рядок на подію: повідомлення користувача, відповідь асистента, виклик інструмента, …) у ~/.claude/projects/<проєкт>/<ідентифікатор-сеансу>.jsonl. Хук Stop, який згодом було прибрано, звертався до цих файлів.
Подробиці
Дописування замість перезапису
Перевага JSONL над одним великим файлом JSON особливо помітна в дуже довгих або зростаючих потоках даних: запис журналу може просто дописувати кожен новий рядок у кінець файлу (fs.appendFile), не читаючи, не розбираючи, не змінюючи й не перезаписуючи весь наявний файл — зі звичайним файлом JSON (який загалом має бути допустимим масивом/об’єктом) це було б потрібно, наприклад, щоб додати новий елемент у кінець масиву. Для файлу журналу в кілька гігабайтів ця різниця не просто незручна, а практично значуща: повний перезапис для кожного нового запису ставав би дедалі повільнішим у міру зростання файлу, тоді як дописування лишається постійно швидким незалежно від розміру наявного файлу.
Порядкова обробка без завантаження всього
Порядкова обробка (замість завантаження всього в пам’ять одразу) також простіша:
const readline = require("readline");
const stream = readline.createInterface({ input: fs.createReadStream("session.jsonl") });
for await (const line of stream) {
const event = JSON.parse(line);
// ... обробка порядково, не тримаючи весь файл у пам’яті
}Це особливо важливо для файлів, що можуть стати більшими за доступну пам’ять — JSON.parse() усього багатогігабайтного файлу або зайняв би дуже багато часу, або одразу завершився б помилкою браку пам’яті, тоді як порядкова обробка потребує постійно невеликого обсягу пам’яті незалежно від загального розміру файлу.
Відмовостійкість
Недолік класичних файлів JSON у цьому контексті: у JSONL один пошкоджений рядок (наприклад, через перервий запис, скажімо, через збій процесу посеред запису) можна пропустити ізольовано, не роблячи нечитним весь файл — у класичному файлі JSON один зіпсований символ десь посередині призведе до збою розбору всього файлу, навіть якщо 99 % вмісту насправді цілі. Ця властивість робить JSONL особливо надійним для випадків, коли запис може бути перерваний (наприклад, збій системи або раптове завершення процесу).
Поширені галузі застосування
Окрім стенограм сеансів JSONL часто використовується для навчальних даних у машинному навчанні (кожен рядок — один навчальний приклад), для агрегації журналів (кожен рядок — одна подія журналу, часто з однорідними полями на кшталт позначки часу та рівня журналу) та для обміну даними між системами, де записи мають оброблятися окремо й незалежно один від одного — наприклад, під час потокової передачі експорту бази даних, де кожен рядок являє один запис.
Див. також: Claude Code Hooks, JSON