モデル / データセット
mangiucugna/json_repair avatar
mangiucugna/json_repair

json_repair 評価:壊れた JSON を Python で修復するライブラリの設計と限界

Repair malformed JSON from LLMs, APIs, logs, and user input in Python.

スター 5,097フォーク 216PythonMIT

ひと目でわかる

これは何?
LLM や API が返す不正な JSON を修復する Python ライブラリ json_repair について、README とリポジトリ情報から読み取れる仕組み、使い方、そして向かないケースを整理する。
誰に向いている?
LLM や外部 API の出力を Python 側で受け取るパイプラインを持ち、厳密な json.loads() が失敗したときのフォールバックを自前で書いているチームには候補になる。逆に、入力が常にスキーマ準拠であることを前提にした検証や、壊れた値を推測で補うことを許容できない処理には向かない。
商用利用できる?
できます。MIT は寛容なライセンスで、著作権表示とライセンス表示を残せば、使用・改変・販売が可能です。
今もメンテナンスされている?
されています。最後のコミットは 5 日前です。
何の言語で書かれている?
主に Python です(GitHub の言語統計による)。

回答はプロジェクトの GitHub データ(最終同期:2026年9月15日)と当サイトの分析に基づくもので、法的助言ではありません。

オープンソース詳細解説

json_repair が埋めるのは構文の穴であって意味の穴ではない

このライブラリが解く問題ははっきりしている。LLM が返す JSON には、閉じ括弧の欠落、末尾の余分なカンマ、キーの引用符漏れ、値の途中までの切れ、JSON の前後に混ざる説明文といった軽微な崩れが頻繁に混じる。README はこの理由を「LLM というものはそういうものだ」という調子で説明しており、著者は信頼できる軽量な Python パッケージが見つからなかったので自分で書いたと述べている。対象読者は、LLM の構造化出力や外部 API のレスポンスを Python で受け取る開発者だ。重要なのは、これが意味の修復ではない点である。壊れた構文を補って Python のオブジェクトに変換するだけで、値そのものが正しいかどうかは関知しない。フィールドの意味的な妥当性やスキーマ適合性を保証するものではないと理解して使う必要がある。

repair_json と loads の二つの入口、そして既定の二段構え

API は小さい。repair_json() は文字列を返し、loads() はデコード済みオブジェクトを返す。README によれば loads() は json.loads() の完全な置き換えとして使えるとされている。内部の流れは README の performance considerations の節に書かれている。既定では、まず標準ライブラリの JSON ローダーを試し、厳密なパースが失敗したときだけ修復パーサーにフォールバックする。つまり正常な入力に対しては通常の json.loads() とほぼ同じ経路を通る。この設計の帰結として、README は try で json.loads() を呼び、例外が出たら json_repair.loads() に切り替えるという定番の書き方を「無駄」だと明示している。二段構えはすでにライブラリ側で行われているからだ。この指摘は、既存コードを置き換えるときに最初に読むべき箇所になる。

skip_json_loads が意味するトレードオフ

既定の検証を飛ばしたい場合、repair_json() に skip_json_loads=True を渡せる。README はこれを明示的なトレードオフとして説明している。既定は標準ライブラリで検証してから必要時に修復、skip_json_loads=True は検証の速い経路を飛ばして修復パーサーに直行する。ただし README は、これは既に不正だと分かっている入力に限ると注意している。正しい JSON を渡すと、修復パーサーは標準ライブラリとは異なる解釈をする可能性があるためだ。ログの後処理のように入力の大半が壊れていると分かっている場面では有効だが、入力の性質が混在する場面で無条件に有効化するのは危険側の選択になる。README の記述からは、このフラグを付けたときに正しい JSON がどう扱われるかの詳細までは読み取れない。採用するなら手元で確認したほうがよい。

修復できるものの範囲は README の列挙に留まる

README が挙げる修復対象は、引用符の欠落、カンマの位置ずれ、エスケープされていない文字、不完全なキーと値の組、true/false/null の書式、コメントや不正な位置の文字の除去、閉じられていない配列やオブジェクトへの要素や既定値(null、空文字列)の補完、そして値が欠けているフィールドの自動補完である。Python 風のタプル、つまり丸括弧で囲んだカンマ区切りの並びは JSON 配列に変換され、単一の値ならスカラーとして扱われる。配列やオブジェクト、タプルの内部では true/false/null と None が大文字小文字を問わず認識される。ここで注意したいのは、これらは README の記述であって、修復の網羅性を保証する仕様ではないという点だ。どの入力がどう修復されるかを事前に列挙しきれるものではなく、対象外の崩れ方をする入力は残る。

非 Latin 文字を扱うなら ensure_ascii=False が必須

日本語を含む入出力で使う場合、この点は実務上の落とし穴になる。README の例では、repair_json("{'test_chinese_ascii':'統一码'}") は {\"test_chinese_ascii\": \"\\u7edf\\u4e00\\u7801\"} を返す。ensure_ascii=False を渡すと {\"test_chinese_ascii\": \"統一码\"} が返る。つまり既定では非 Latin 文字はエスケープされた状態で出力される。JSON としてはどちらも妥当だが、人間が読むログや、後段にそのまま渡す処理では差が出る。また repair_json は json.dumps が受け取る引数をそのまま渡すと README に書かれており、indent なども同様に機能する。日本語圏のプロジェクトで採用するなら、この引数の有無を最初に決めておくことになる。

ファイル入力と例外の扱いは呼び出し側の責任

文字列以外の入口も用意されている。README によれば、json.load() の置き換えとして json_repair.load(file_descriptor) が使え、ファイルから読む別の方法として json_repair.from_file(json_file) がある。ここで README が明示している制約が重要だ。ライブラリは IO 関連の例外を捕捉しない。ファイルが開けない、読み取りに失敗するといった問題は呼び出し側で処理する必要がある。README のサンプルでも OSError や IOError を個別に捕まえる形になっている。つまりこのライブラリが引き受けるのはあくまで JSON の構文修復であり、入出力の失敗やリソース管理は利用者のコードに残る。この境界は、ラッパーを書くときに意識しておかないと例外の取りこぼしにつながる。

スキーマ検証やストリーミングの代替と比べたときの立ち位置

同じ問題領域には、壊れた出力を修復するのではなく、そもそも壊れた出力が出にくい形で生成を制約するアプローチがある。たとえば JSON Schema に沿った構造化出力をモデル側の機能として強制する方法や、Pydantic のモデルで検証して失敗を例外として扱う方法だ。違いは方向にある。json_repair は生成後のテキストを受け取ってから直す。スキーマ制約やバリデーションは、受け取る前か受け取った直後に弾く。前者は壊れた入力でも値を取り出せるが、その値が意図と一致する保証はない。後者は通らない入力を明確に失敗として扱えるが、修復はしない。リポジトリの topics には json-schema、pydantic、streaming といった語が並んでおり、README もスキーマ誘導の修復ステップとして使えると述べているが、README の本文からはスキーマ検証そのものの挙動は読み取れない。検証を主目的にするなら別の道具を選ぶべきだ。

メンテナンス頻度とライセンスから見た採用判断

リポジトリ情報によれば、ライセンスは MIT、既定ブランチは main、最終 push は 2026-09-03、直近のリリースは v0.63.4(2026-08-25)、v0.63.3(2026-08-19)、v0.63.2(2026-08-14)である。0.63 台で細かいリリースが続いており、活発に更新されていることが分かる。ただしこれは品質の証拠ではなく、更新に追従する側のコストでもある。0.x の間はマイナー番号の上がり方によっては挙動が変わりうるので、バージョンを固定して検証してから上げる運用が現実的だ。README にはスポンサー募集の記述があり、サイドプロジェクトとして維持されていると書かれている。MIT ライセンスなので商用利用を含めて使いやすいが、ライセンス条項の解釈は案件ごとに異なるため、ここでは法的助言はしない。依存を追加する前に、自組織のポリシーに照らして確認してほしい。

編集部の結論

LLM や外部 API の出力を Python 側で受け取るパイプラインを持ち、厳密な json.loads() が失敗したときのフォールバックを自前で書いているチームには候補になる。逆に、入力が常にスキーマ準拠であることを前提にした検証や、壊れた値を推測で補うことを許容できない処理には向かない。導入前に確認すべきは、自分の入力パターンで repair_json が何を返すかを手元で試すこと、非 Latin 文字を含むなら ensure_ascii=False を渡すこと、そして不正と分かっている入力に対して skip_json_loads=True を使うかどうかを決めることだ。

公式情報源

  1. License: MIT
  2. mangiucugna/json_repair on GitHub
  3. Project website
  4. README
  5. Releases
コミュニティノート

コミュニティノート