世界を動かす技術を、日本語で。

フラクチャードJSON

概要

  • FracturedJson は、人間にとって読みやすく、かつコンパクトなJSONフォーマットを自動生成するツール群
  • 配列やオブジェクトを可能な限り 1行 で表現し、似た構造の場合は 表形式 で整列
  • 豊富な 設定項目 があるが、通常はデフォルトで十分な利便性
  • .NETライブラリJavaScript/TypeScriptパッケージVS Code拡張機能 として利用可能
  • 標準JSONでは非対応の コメント保持 もオプションでサポート

FracturedJsonの特徴

  • FracturedJson は、JSONデータを 人間が読みやすい形 で出力するユーティリティ群
  • 配列やオブジェクトを 短く単純 な場合は1行で出力
  • 似た構造 の複数行は 表形式 で整列
  • 長い配列は 複数アイテムを1行 にまとめて複数行で表現
  • 自動的に最適なフォーマット を選択し、どんなJSONでも見やすい出力を生成
  • Webブラウザ用フォーマッタページ で試用可能
  • .NETライブラリJavaScript/TypeScriptパッケージVisual Studio Code拡張 で提供
  • Python向けの選択肢も存在

サンプル出力例と設定

  • デフォルト設定での出力例を公式サイトで確認可能
  • 各種設定(例: MaxInlineComplexityMaxCompactArrayComplexity など)で出力スタイルを細かく制御
  • オプションページで設定ごとの出力例を参照可能

コメント保持機能

  • 標準JSONは コメント非対応 だが、FracturedJsonは コメントも保持 可能
  • コメントは関連要素と一緒に 適切に配置 される設計

背景と動機

  • 一般的なJSONライブラリは「 最小化 (minified)」と「 整形(インデント)」の2択のみ
    • 最小化JSON :効率的だが人間には読みにくい
    • 整形JSON :広がりすぎて情報把握やスキャンが困難
  • FracturedJsonは 人間が直感的に読みやすい フォーマットを自動で実現

フォーマット方法の種類

  • Inlined

    • 内容が単純・短い場合は 1行 で出力
    • ネストの深さは MaxInlineComplexity で制御
  • Compact Multiline Array

    • 配列を 複数アイテム/行 で複数行出力
    • ネストの深さは MaxCompactArrayComplexity で調整、-1で無効化
  • Table

    • 同種のインライン要素が並ぶ場合、 表形式 で整列
    • ネストの深さは MaxTableRowComplexity で調整、-1で無効化
    • TableCommaPlacement でカンマの位置を調整可能
  • Expanded

    • 上記いずれにも当てはまらない場合は 複数行・インデント付き で出力

利用方法・ディスカッション

  • 疑問点・要望・意見 は公式の Discussionsエリア で受付
  • 各種プラットフォームで利用可能なため、用途に応じて選択可能

Hackerたちの意見

パイプから内容を読み込むオプションってあるの?それがjqアプリの一番の使い道なんだけど。

これをjqと組み合わせたらすごいだろうな。私も最初にそう思った。

リポジトリにはC#のCLIアプリがあるよ:https://github.com/j-brooke/FracturedJson/blob/main/Fracture... 出力は標準出力か、--outfileスイッチで指定されたファイルに。入力は標準入力か、--fileスイッチを使った場合はファイルからだよ。JavaScript版と新しいPython C#ラッパーにも同等のCLIツールがあるみたい。

入力ファイル名を「-」(ハイフン一つ)に指定すれば、標準入力から読み込むことができるよ。

これは面白いけど、人間が読める設定ファイルには使ってほしくないな。TOMLやYAMLの方がいいと思う。Git diffも再整列とかで難しいことがあるし。これの有用性はデバッグモードのAPIにあると思う。コメントも送信されて、きれいに表示されるのが特にゲーム開発のJSONでは役立つね。

YAMLに「ノルウェー」って言えばいいよ。

YAMLは最悪だね。人間もLLMも間違えるし。昔はXMLを笑ってたけど、YAMLのおかげでXMLが懐かしく感じるようになったよ。YAML - ノルウェーって言えばいいじゃん。

これは興味深いね。こういうことをするコードフォーマッターが見てみたいな。今のフォーマッターはほとんど柔軟性がないから、フォーマットされたコードから構造を引き出すのが難しいこともある。

そうだね。前の仕事では、テーブルのように見えるカスタムXMLフォーマッターを書いたんだ。それが私たちのユースケースだったから。理想的にはXMLから離れるのが良かったけど、レガシーから逃げられないよね。

これをやるC++フォーマッターを作ったんだけど(残念ながら私の従業員のもの)。実際、フォーマットオブジェクトは2つだけ:タブ揃えのテーブルと、1行の行。どちらのオブジェクトも右寄せのカラム/タブ揃えの"//"コメントをサポートしてる。どちらもセグメント(行)のシーケンスにデスugarされる。結果的に、式/代入ブロックとステートメントを自由に混ぜられる。switch-caseブロックやマクロテーブルも2Dでフォーマットするのが簡単になる。コメントは右寄せで処理されるから、全てのコメントがきれいに揃うんだ。ベースレイヤーは1時間でコーディングした。自動生成されたコードを使ってるから、出力は手動で私の入力に基づいてコーディングしてる。ちょっと難しいのはテーブルやブロックを「発見」することかな。LSPと連続したステートメントの直接観察の組み合わせを使うつもり。

現在、これには2つのメンテナンスされている実装があるみたいだね。1つはC#のやつで、もう1つはTypeScript/JavaScriptのやつ。各々にテストスイートがあるよ。古い純粋なPythonバージョンもあるけど、もうメンテされてないんだ。最近、その作者がC#コードをラップしたPythonライブラリに置き換えたみたい。これって、言語に依存しない準拠スイートを作る絶好のチャンスだと思うんだ。データファイルとして定義されたテストのセットを作れば、複数の実装で共有できるしね。これにより、既存のC#とTypeScriptの実装が全く同じ動作をすることが保証されるだけでなく、他の言語での実装を構築してメンテナンスするのもずっと楽になるよね。面白いことに、今は非推奨のPythonライブラリは、実際に僕が言ってるようなデータ駆動型のテストスイートを使ってるんだ。新しいPythonライブラリはC#ライブラリのラッパーで、"有効な.NETランタイムをインストールする必要があります"って書いてあるから、他のPythonプロジェクトの依存関係としてはほとんど使えないね。これじゃ「pip install」するのが難しくなるから。

これはいいアイデアだと思うけど、テストケースを超えてプログラムの同等性を保証するわけではないと思う。

JSONがコメントを正式にサポートしてくれたらいいなと思うけど、キー付きリストやオブジェクトの中に文字列としてネストする方が、もっと理にかなってる(互換性がある)と思う。{ foo: "bar", ans: 42, comments: { ans: "ダグラス・アダムス" } }

commentsフィールドが急に重要になるエンティティが出てきたら、全ての場所で変更しなきゃいけなくなるよね。JSONCが必要なら、ちゃんとJSONCを使うのが一番だと思う。

個人的には、JSONにコメントが必要なら、それはおそらく設定用か、ユーザーが自分で編集することを想定してるものだと思う。その場合、プレーンなJSONや実際のペイロードにコメントを追加するよりも、もっといい選択肢があるはず。もし純粋に機械用の消費が目的なら、スキーマを説明してるかもしれないし、それ用のツールもあるよ。

このJSONファイル、実際に読みやすいね。おめでとう! もしかしたら、追加の添付ファイルで処理できるかも。例えば、mycomplexdata.jsonとその付随ファイルのmycomplexdata.jsonfrancがあったとする。IDEでファイルを開くと、自動的に2つがマージされる感じで。そうすれば、元のJSONファイルはきれいなままで、余計なデータで汚れないよね。

これをトークン化したら、元のJSONより約20%少ないトークンを使ってるみたい。これって、こういうスキーマが制約のあるLLMデコーディングでレイテンシやコストを最適化するかもしれないって思わせるね。LLMはJSONに非常に慣れてるし、トークンを減らすために珍しいスキーマを選ぶと意味的なパフォーマンスが悪くなるのは知ってる。でも、十分にJSONっぽいスキーマなら、モデルのパスやパターンを大きく乱すこともなく、意図しないバイアスを防げるんじゃないかな。

ミニファイドJSONなら、さらにトークンを少なく使えるね。

これいいね!人間が読みやすいほど良い!俺も逆の方向で作業してて、JSONをもっと機械が読みやすくしてるんだ。リンクはここだよ: https://github.com/kstenerud/bonjson/ これ、JSONと全く同じ機能と制限があって、機械が読み書きするのに35倍速いドロップイン置き換えとして使えるんだ。余計な型も機能もなし。JSONができることは全部できるし、JSONができないことはできないよ。

それは面白いけど、君のConcise Encodingプロジェクトの方がもっと興味あるな。[1] 3年間更新されてないGoのリファレンス実装が一つだけみたいだけど、まだプロジェクトは有効なの?作品をシェアしてくれてありがとう![1]: https://concise-encoding.org/

いいね… ログ用にJSONをstdoutに使うのが好きなんだけど、これならローカル開発の時にフル分解せずに見栄え良くフォーマットできるからいい選択肢だね。