LLMにJSON形式で出力するよう指示しても、クォートが欠けていたり、末尾にカンマが残っていたり、括弧が閉じられていなかったりすることがあります。構造化出力のAPIを使っていても、ストリーミング中の途中状態や、モデルによる散文の混入で壊れたJSONが返ってくることは珍しくありません。そのたびに例外処理で逃げるだけでは、下流の処理が止まりますし、修復ロジックを自前で書くのはなかなか骨が折れます。
この記事では、壊れたJSONを自動修復するPythonライブラリ json_repair の機能と、その内部設計の工夫をあわせて見ていきます。
どんなライブラリか
json_repair は、LLM・API・ログ・ユーザー入力から返ってきた不正なJSONを修復してPythonオブジェクトに変換するライブラリです。欠けたクォートやカンマ、閉じられていない括弧、コメント、余分な散文、途中で切れた値など、LLMが犯しがちなミスをほぼ網羅しています。
使い方はシンプルで、json.loads() の代替として json_repair.loads() を呼ぶだけです。修復後の文字列が欲しければ repair_json()、Pythonオブジェクトが欲しければ return_objects=True を渡すか loads() を使います。CLIとしても動作し、ファイルのインライン書き換えも可能です。PyPI経由でインストールでき(pip install json-repair)、スター数は5,000を超えています。想定ユーザーはLLMの出力をパイプラインに取り込んでいるエンジニアが中心ですが、ログ整形やユーザー入力の正規化にも使えます。
設計でここが上手い

「まず標準ライブラリで試す」フォールバック構造
デフォルトの動作は、最初に json.loads() を試し、それが成功したらそのまま返すというものです。修復パーサーは失敗したときだけ起動します。この設計には2つの意味があります。ひとつは、有効なJSONに対してライブラリが余計な変換を加えるリスクをゼロにできること。もうひとつは、標準ライブラリが最速のパスを担うため、正常系ではオーバーヘッドがほぼ発生しないことです。
READMEでは「アンチパターン」として、try: json.loads()→except: json_repair.loads() という二重呼び出しをわざわざ注意書きしています。ライブラリ内部で同等のことをすでにやっているため、ユーザーが同じチェックを外側で重ねても無駄になるという説明です。ドキュメントが正しい使い方を誘導する設計になっていて、誤用を積極的に防いでいるのは好感が持てます。
skip_json_loads=True による意図的なトレードオフの明示
入力が確実に不正なJSONだと分かっている場合は、skip_json_loads=True で標準ライブラリのバリデーションをスキップできます。ただしREADMEは「有効なJSONをこのモードで通すと構造が変わる可能性がある」と明言していて、速度改善のための等価なモードとして扱えないことを強調しています。オプションの意味とリスクを使用者が判断できるよう情報が揃っていて、使い方の誤解が生まれにくい構造です。
スキーマガイド修復とPydantic統合
ベータ機能ではありますが、JSON Schemaを渡すと修復の方向をスキーマに沿って制御できます。"1" を 1 に型変換する、不足している必須フィールドをデフォルト値で埋める、スキーマに存在しないプロパティを削除する、といった操作がオプション指定ひとつで動きます。Pydantic v2のモデルをそのまま渡せる口も用意されていて、型定義をすでに持っているプロジェクトではスキーマをJSONで書き直す必要がありません。LLMの出力をそのままDBに保存したいケースや、型チェックを通したいケースで、修復と変換を一度にまとめられるのは実用的です。
ストリーミング対応
stream_stable=True を渡すと、途中状態のJSONを安定したパーシング状態で処理できます。ストリーミング生成中のLLM出力をリアルタイムに扱うユースケースを正面から受け止めているのは、このライブラリが「LLMの出力を前提にした設計」をしていることの証左です。
こういう人に向くかも
LLMの出力をJSON形式で受け取ってパイプラインに流しているエンジニアにとって、最も素直に使えるライブラリです。特に、プロンプトで構造化出力を指示しているのにモデルが散文を混ぜてくるケース、ストリーミングで途中状態を扱いたいケース、Pydanticの型定義と修復を組み合わせたいケースでは、代替手段を探すより先にこのライブラリを試す価値があります。
逆に、LLMの出力をまったく扱わないプロジェクトで、壊れたJSONの修復に使う場合は、ライブラリの想定ユーザー像と少しずれます。ログや設定ファイルの整形にも使えますが、修復ロジックの挙動がLLM出力の誤りパターンを想定して作られている点は頭に置いておくといいかもしれません。
設計の良し悪しをどこで見るか
機能の単一性
「壊れたJSONを直す」という一点に機能が絞られています。画像生成やAPIクライアントのような他の関心事が入り込んでいません。この絞りが効いているから json.loads() の drop-in 代替という立ち位置が成立していて、呼び出し側がライブラリの責務を理解しやすくなっています。
ドキュメントの深度
READMEはアンチパターン、パフォーマンス上の注意、ストリーミング、スキーマガイド、Pydantic統合、orjsonとの組み合わせパターンまで、実用的なシナリオを広く網羅しています。さらに examples/ ディレクトリにFastAPIへの組み込み例やLLM出力の修復例がコピペできる形で置かれています。ドキュメントを読んで使い始めるまでの摩擦が小さいのは、サイドプロジェクトとしては水準が高いといえます。
想定外の使われ方への備え
strict=True モードは、修復ではなくバリデーションとして使いたい場面のために用意されています。「修復する」という主機能と「厳密にチェックする」という逆方向の需要を、同じAPIで扱えるようにしている点は、使い手の幅を広げる設計です。ただしスキーマガイドと strict=True は排他なので、両方を同時に使おうとするとエラーになります。組み合わせのルールをREADMEが明示しているのは親切ですが、初めて読んだときは少し立ち止まるかもしれません。
メンテナンスの継続性
MITライセンスで公開されており、スポンサープログラムも設けています。スポンサー一覧がREADMEに記載されていることで、外部企業が実際に利用・支援しているという事実が確認できます。ただしメンテナーは一人で、サイドプロジェクトと明記されているため、長期のサポートを前提にプロダクションへ組み込む場合は、フォークや代替手段のリスクヘッジを検討する価値はあります。
トークン経済性
ライブラリの性格上、LLMのコンテキストウィンドウへの影響はなく、この軸はあまり関係がありません。ただし「LLMが出力したJSONが壊れていたとき修復する」という役割を担うことで、修復失敗による再プロンプトや再生成のコストを減らせる可能性があります。その意味では間接的に、LLMを使う全体のコストに貢献するツールです。
自分が書くなら、どこを変えるか
スキーマガイド修復がベータ扱いになっている点は、今後の完成度が気になるところです。現状では schema_repair_mode="salvage" の動作、とくに「配列を先頭要素のオブジェクトにアンラップする」ような挙動は、意図しない損失につながる可能性があります。この機能を使うときは、まずテストデータで期待通りに動くかを確認してから本番に持ち込む方が安全です。
もし自分で似たライブラリを書くとしたら、スキーマ検証後の変換サマリーをオプションで返せるようにしたいかなと思います。「どのフィールドがどう変換されたか」が分かると、修復ロジックの挙動をデバッグするときに助かります。今の設計では修復結果のオブジェクトは返ってきますが、修復の過程は見えにくくなっています。ログ出力や詳細フラグのような形で、変換の痕跡を確認できる口があると、信頼して任せやすくなるのではないでしょうか。
導入を検討するときのチェック観点
- 修復対象がLLM出力か、それとも設定ファイルやログかを確認する。前者なら即戦力になりやすい
json.loads()の代替として使う場合は、アンチパターンのtry/except二重呼び出しを避けているか確認する- スキーマガイドを使う場合は、現時点でベータ機能である点を踏まえ、テストセットで期待通りに変換されるかを先に確認する
skip_json_loads=Trueは「入力が確実に不正なJSON」と分かっている場合に限る。有効なJSONに対して使うと構造が変わるリスクがある- 非ラテン文字(日本語・中国語・韓国語など)を扱うときは
ensure_ascii=Falseを忘れずに渡す - ストリーミング出力を扱うなら
stream_stable=Trueの動作をサンドボックス環境で確認してから組み込む - プロダクションで依存する場合は、メンテナーが一人であることを踏まえてフォークや代替策のリスクヘッジを検討する
修復という判断の出発点
LLMの出力を扱うパイプラインでは、「壊れたJSONが来たらどうするか」という問いは必ず出てきます。再生成を試みる、エラーとして返す、修復する、の三択がある中で、json_repair は修復の選択肢を最も低コストで取れるようにしてくれるライブラリです。ライブラリ自体の設計は機能を絞り込んでいて読みやすく、ドキュメントが使い方の誤りを先回りして防いでいる構造は、自分でAPIを設計するときの参考にもなります。まずライブデモで手元の壊れたJSONを試してみると、対応範囲の感触をつかみやすいと思います。

