カテゴリー: Productivity

  • 壊れたJSONファイルを素早く直す方法:開発者向けフィールドマニュアル

    壊れたJSONファイルを素早く直す方法:開発者向けフィールドマニュアル

    API呼び出しが JSONDecodeError: Expecting property name enclosed in double quotes で失敗した。時間は刻々と過ぎていく。データはLLM由来で、その2000トークンの応答のどこかにある、たった一つの末尾カンマがパイプライン全体を壊してしまった。

    2026年5月現在、壊れたJSONファイルを直す最速の方法は、json_repair(Python)や jsonrepair(npm)のような自動化ライブラリを使うことです。これらのツールは、LLMが生成した構文エラーを瞬時に修正するために作られています。手動修正の場合、よくいる犯人は末尾カンマシングルクォートクォートなしのキー——RFC 8259 規格に対する最も一般的な3つの違反です。

    最速の修正法:LLM出力向け json_repair

    Python の json.loads() のような標準パーサーは、設計上厳格です。一文字でも位置を間違えると JSONDecodeError が発生し、すべてが止まります。これは2026年では日常的な問題です。LLMはJSONを会話テキストで包んだり、応答を途中で切り詰めたり、仕様を壊すコメントを撒き散らしたりするからです。

    json_repair ライブラリが定番の解決策です。GitHub によると、このプロジェクトは2026年時点で4700以上のスターを獲得しています。文字列の意図を「推測」する仕組みで動作します——足りない括弧を閉じ、引用符を補い、JSONブロックの周囲の余分なテキストを取り除きます。

    json_repair のシンプルな3ステップ:入力(壊れている)-> 意図を推測 -> 出力(有効)

    Python:ビフォーアフター

    インストール:pip install json-repair

    壊れた入力:

    import json_repair
    
    bad_json = '{"user": "Alice", "status": tru'
    decoded_object = json_repair.loads(bad_json)
    

    裏で何が起きたか:json_repairtru がおそらく true であると判断し、足りない閉じ括弧を補い、有効なPython辞書を返しました。手作業は一切不要です。

    サルベージモード:データがひどく壊れているとき

    より難しいケース向けに、json_repair(v0.59.5+)には サルベージモード があります。プロジェクトドキュメント にある通り、このモードは切り詰められたAI応答や破損したログ専用に作られています。配列をオブジェクトに強制変換したり、救えないほど壊れた項目を削除したりして、出力がスキーマに合うようにします。

    import json_repair
    
    # Salvage mode for severely truncated data
    result = json_repair.loads(
        '{"items": [{"id": 1, "name": "Widget"}, {"id": 2, "na',
        salvage_mode=True
    )
    # Result: {'items': [{'id': 1, 'name': 'Widget'}, {'id': 2}]}
    # Dropped the incomplete 'na' but saved everything else
    

    npm の代替

    Node.js プロジェクトでは、jsonrepair CLI が同じ役割を果たします:

    # Fix a file in place
    npx jsonrepair broken.json > fixed.json
    
    # Fix a string in a script
    const { jsonrepair } = require('jsonrepair');
    const fixed = jsonrepair('{"name": "test",}');
    

    手動デバッグ:仕様を壊した犯人を見つける

    自動化でも追いつかないときは、ファイルが RFC 8259 のどこに違反しているかを正確に見つける必要があります。JSONは YAML や JavaScript ほど寛容ではありません。JSONParser 診断チーム が説明する通り、「パーサーは理解できない最初の文字で失敗しますが、それは多くの場合、数行前の問題の下流の症状です」。

    3人の JSON キラー

    キラー1:末尾カンマ

    DEV Community によると、末尾カンマはパース失敗の原因第1位です。JavaScript では問題ありませんが、JSON の配列やオブジェクトの最後の項目の後では違法です。

    // BROKEN - trailing comma after "active"
    {
      "name": "Alice",
      "status": "active",
    }
    
    // FIXED - no comma before closing brace
    {
      "name": "Alice",
      "status": "active"
    }
    

    キラー2:シングルクォート

    JSON はキーと文字列値の両方にダブルクォート(")を要求します。多くの Python や JavaScript 開発者が誤ってシングルクォート(')を使います。TidyCode が指摘する通り、これは必須の修正です。

    // BROKEN - single quotes
    {'name': 'Alice'}
    
    // FIXED - double quotes
    {"name": "Alice"}
    

    キラー3:クォートなしのキー

    JavaScript では { name: "Alice" } と書けます。しかし JSON では、すべてのキーにダブルクォートが必要です。

    // BROKEN - unquoted key
    {name: "Alice"}
    
    // FIXED - quoted key
    {"name": "Alice"}
    

    無効なJSONと有効なJSONの構文を横並びで比較

    「Unexpected Token」エラー

    バリデーターが「Unexpected Token」を指摘したとき、それはパーサーが NaNInfinityundefined ——JSON が対応しない JavaScript の定数——に遭遇したことを意味します。JSON が許すのは nulltruefalse、数値だけです。

    // BROKEN - NaN is not valid JSON
    {"score": NaN, "result": Infinity}
    
    // FIXED - replace with null or valid values
    {"score": null, "result": null}
    

    厳格パース vs. 修復パース:どちらを使うべきか

    正しいアプローチはデータの出所によります。人間が編集した設定ファイルは、著者に間違いを直させるため厳格なパースに値します。LLM や API ログからの機械生成データには、修復ベースのパースが必要です。

    機能 厳格(json.loads 修復(json_repair
    末尾カンマ JSONDecodeError を発生 自動的に削除
    シングルクォート 失敗 ダブルクォートに変換
    切り詰められたデータ 失敗 開いた括弧/引用符を閉じる
    コメント 失敗 自動的に削除
    最適な用途 人間が編集した設定ファイル LLM出力、APIログ

    Pydantic でスキーマ主導の修復を行う

    Pydantic v2JSON Schema を使って修復プロセスを導くことができます。json_repair にスキーマを与えると、ツールは構文を直すだけでなく、型も修正し(文字列の "1" を数値の 1 に)、必須フィールドの欠落をデフォルト値で埋めます。

    from pydantic import BaseModel
    import json_repair
    
    class User(BaseModel):
        id: int
        name: str
        active: bool = True
    
    # Broken JSON with wrong types
    raw = '{"id": "42", "name": "Alice"}'
    repaired = json_repair.loads(raw)
    
    # Validate against schema
    user = User(**repaired)
    # user.id is now int(42), user.active defaults to True
    

    Stefano Baccianella が2025年のプロジェクト引用で述べた通り、このアプローチは、言語モデルが生成しがちな「ほぼ正しいが技術的には無効な」JSON向けに最適化されています。

    クラッシュさせずに数GBのファイルを扱う

    10KB のスニペットを修復するのは簡単です。2GB のファイルを直すには、メモリを食い尽くさない戦略が必要です。ファイル全体をメモリに読み込むと、メモリ不足(OOM)エラーを引き起こします。

    戦略1:ijson でストリーミング

    巨大なデータセットには ijson を使い、データを少しずつ処理します。Scrapfly が述べる通り、ijson はデータをインクリメンタルに処理します。パースの前に行単位で問題を修正するクリーンアップスクリプトと組み合わせて使います。

    import ijson
    
    # Stream through a large JSON file
    with open('huge_broken.json', 'r') as f:
        for item in ijson.items(f, 'records.item'):
            # Process each item individually
            process(item)
    

    戦略2:最大効率の CLI パイプ

    大きなファイルで最もメモリ効率の良い方法は、jsonrepair CLI を使い、出力を直接新しいファイルへパイプすることです:

    # Streams repair, never loads full file into memory
    jsonrepair large_broken.json > fixed.json
    

    これはファイルを Python やブラウザに読み込むよりずっとメモリ効率が良いです。

    まとめ

    json_repair のようなAI対応ライブラリのおかげで、壊れたJSONの修正はもはや手作業ではありません。RFC 8259 の基本——末尾カンマなし、シングルクォートなし、クォートなしのキーなし——を理解する必要はありますが、2026年の大規模データには自動化だけが現実的なアプローチです。

    ワークフローはシンプルです:まず修復ライブラリを試します。それが失敗したら、バリデーターで正確な構文エラーの場所を特定します。これにより、入力データが完璧でなくてもアプリケーションを動かし続けられます。

    FAQ

    JSON は公式にコメントやシングルクォートをサポートしていますか?

    いいえ。RFC 8259 規格はコメントを厳格に禁じています。シングルクォートも無効で、キーと文字列にはダブルクォートしか使えません。ただし json_repair のようなツールは、コメントを取り除き引用符を変換して、ファイルが標準ライブラリでパースできるようにできます。

    クラッシュさせずに非常に大きな壊れたJSONファイルを扱うには?

    ijson のようなストリーミングパーサーを使ってデータをチャンク単位で処理します。壊れた文字列全体を一つの変数に読み込むのは避けてください。最速の結果を出すには、CLI 修復ツールを使って出力をメモリに保持せず直接ディスク上の新しいファイルへパイプします。

    壊れたJSONと無効なJSONの違いは何ですか?

    壊れた(malformed)JSON は構文規則に違反し——括弧の欠落、クォートなしのキー、末尾カンマ——パース不可能です。無効な(invalid)JSON はすべての構文規則に従いますが、特定の JSON Schema に合致しません(例:フィールドが文字列だがスキーマは整数を期待)。壊れたJSONの修正は構造的修復、無効なJSONの修正はデータ整合性の問題です。

    json_repair を Pydantic のバリデーションと一緒に使えますか?

    はい。まず json_repair.loads() で構文エラーを直し、その後、修復された辞書を Pydantic モデルに渡して型バリデーションとスキーマ強制を行います。この2段階のアプローチで、構造的および意味的な問題の両方に対処できます。

    JavaScript 風のコメント付き JSON はどうすればいいですか?

    標準 JSON はコメントをサポートしませんが、json_repair///* */ コメントを自動的に取り除けます。設定ファイルにコメントが必要なら、JSONC(コメント付きJSON)形式と、Python 向け json5 のような互換パーサーの使用を検討してください。

  • フォーマッターでAIプロンプトを書く方法:開発者のための構造化エンジニアリング

    フォーマッターでAIプロンプトを書く方法:開発者のための構造化エンジニアリング

    AIの出力が、お願いした内容とまるで違う——あの落胆する瞬間を味わったことはありませんか?JSONは壊れている、トーンは違う、指示の半分は無視されている。問題はモデルではなく、プロンプトのフォーマット方法にあります。

    フォーマッターでAIプロンプトを書く方法を習得するには、RTCCOフレームワーク(Role 役割、Task タスク、Context 文脈、Constraints 制約、Output 出力)を、XMLやJSONのような構造化区切り文字とともに実装します。これによりプロンプトを再利用可能なソフトウェア資産として扱えるようになり、2026年5月時点で、モデルのハルシネーションを最大60%削減し、手作業の処理時間を75%短縮できます。

    段落型プロンプトが失敗し続ける理由

    2026年までに、プロフェッショナルなAI業務は「チャット」からプロンプト・アズ・コード(Prompt-as-Code、PaC)へと移行しました。段落型プロンプト——あの長く構造化されていないテキストの塊——の問題は、モデルがあなたの本来の指示を、混ぜ込まれた背景データや出力要件と切り離せずに苦労することです。

    PromptOT のデータによると、構造化エンジニアリングへの移行はエラーを60%減らし、手作業の処理を75%高速化します。Alex Ostrovskyy はハードコードされたプロンプトを「ソースコードにおけるマジックナンバーの現代版」と表現しています——何かを壊さずには更新不可能な、脆弱なシステムです。

    ビフォーアフター:フォーマットの違い

    ビフォー(非構造化):

    You are a helpful coding assistant. Please write a Python function that validates
    email addresses. Make sure it handles edge cases like plus signs and subdomains.
    The output should be in JSON format with a valid boolean and the cleaned email.
    Also make sure you add proper error handling and don't forget logging.
    

    アフター(RTCCO + XML区切り文字):

    <system_instructions>
      <role>Senior Python engineer specializing in input validation</role>
      <primary_objective>Write a production-grade email validator</primary_objective>
    </system_instructions>
    
    <context>
      Must handle: plus addressing ([email protected]), subdomains,
      internationalized domains. Target: Python 3.11+.
    </context>
    
    <task_requirements>
      <rules>
        - Use only stdlib (no regex shortcuts)
        - Return structured JSON
        - Include type hints
      </rules>
      <steps>
        1. Parse the input string
        2. Validate format per RFC 5322
        3. Return JSON with "valid" boolean and "cleaned_email"
      </steps>
    </task_requirements>
    
    <output_format>
      {"valid": bool, "cleaned_email": str, "error": str | null}
    </output_format>
    

    目標は同じでも、結果は劇的に変わります。フォーマット版はモデルに曖昧さの入り込む余地を与えません。

    RTCCOフレームワーク:プロンプトの骨格

    業界は標準的なプロンプトアーキテクチャとして RTCCO に収束しています。すべてのプロンプトは5つの部分に分解できます。

    要素 役割
    R Role(役割) AIは誰か? 「シニアバックエンドエンジニア」
    T Task(タスク) 具体的な行動は? 「レートリミッターミドルウェアを書く」
    C Context(文脈) 背景データは? RAG取得結果、コードベースのスニペット
    C Constraints(制約) ルールは? 「外部依存なし」
    O Output(出力) どんな形に? 「型ヒント付きの有効なPython 3.11」

    RTCCOフレームワークの5つの構成要素

    今すぐコピーできるXMLスケルトンテンプレート

    本番対応のテンプレートです。コピーして、改造して、出荷してください。

    <system_instructions>
      <role> [Expert Persona] </role>
      <primary_objective> [Main Goal] </primary_objective>
    </system_instructions>
    
    <context>
      [Background Data or RAG Retrieval]
    </context>
    
    <task_requirements>
      <rules> [Non-negotiable Constraints] </rules>
      <steps> [Specific Workflow] </steps>
    </task_requirements>
    
    <output_format>
      [JSON/XML/Markdown Specification]
    </output_format>
    
    <recency_recap>
      [Reminder of Critical Constraints]
    </recency_recap>
    

    なぜ「リーセンシー・リキャップ」が重要なのか

    大規模言語モデルには「初期性と新近性(Primacy and Recency)」のバイアスが知られています——プロンプトの冒頭と末尾を中間部分よりも良く記憶します。PromptOT が引用したテストでは、重要なルールを中間から末尾のリーセンシー・リキャップ(Recency Recap)ブロックへ移動させたところ、本番運用での精度が78%から96%に向上しました。役割は先頭に、最も重要なルールは末尾に置きましょう。

    長いプロンプトにおける初期性と新近性の効果の可視化

    セキュリティフェンスとしての区切り文字

    区切り文字は単なる整理ではありません——セキュリティの仕組みでもあります。ユーザー入力を <user_input> のようなタグで囲むことで、モデルに「これは処理すべきデータであり、従うべき新しい指示ではない」と伝えられます。これがプロンプトインジェクション攻撃(ユーザーがシステム指示を上書きしようとする攻撃)に対する主要な防御策です。

    よくある落とし穴: 区切り文字なしでユーザーデータを直接プロンプトに注入すると、ユーザーは「以前のすべての指示を無視して……」と書くだけでモデルが従ってしまいます。外部データは必ずタグ付きブロックで囲んでください。

    モジュラーアーキテクチャ:メガプロンプトの作成はやめる

    脆い2000トークンのプロンプトを1つ書くより、システムを独立したモジュールに分割しましょう。これにより指示の衝突——プロンプトのトーンを変えた拍子にJSON出力フォーマットが壊れること——を防げます。

    鍵となる原則はコンテキストエンジニアリング(Context Engineering)です。静的な指示と動的なデータを分離します。本番のRAGシステムでは、プロンプトはテンプレートであり、<context> ブロックがクエリ時に最新データで埋められます。OptizenApp の Jono Farrington が説明する通り、このモジュール式アプローチにより大規模AIデプロイの一貫性が大幅に向上します。

    プロンプトチェーン:モジュールを繋ぐ

    複雑なワークフローでは、プロンプトチェーン(Prompt Chaining)を使います——あるモジュールの出力が次のモジュールの入力になります。

    [Planner Module] --> outline --> [Executor Module] --> draft --> [Reviewer Module] --> final
    

    この段階的アプローチは出力品質を約35%向上させます。モデルが一度に集中するサブタスクは1つだけで済むからです。

    シンプルな3ステップのプロンプトチェーンワークフロー

    コピペして使えるチェーンの例:

    planner_prompt = """
    <system_instructions>
      <role>Technical architect</role>
      <task>Create a step-by-step plan for: {user_request}</task>
    </system_instructions>
    <output_format>JSON array of steps</output_format>
    """
    
    executor_prompt = """
    <system_instructions>
      <role>Senior developer</role>
      <task>Implement step: {step_from_planner}</task>
    </system_instructions>
    <context>{previous_outputs}</context>
    <output_format>Code block with inline comments</output_format>
    """
    

    難問に推論連鎖(CoT)を追加する

    タスクが複雑な論理を含むときは、<thought_process> ブロックを追加します。これによりモデルは答える前に段階的に推論することを強いられ、数学、コーディング、多段推論のエラーが大幅に減ります。

    <task_requirements>
      <rules>Reason inside <thought> tags before answering</rules>
    </task_requirements>
    
    <output_format>
      <thought> [Your step-by-step reasoning here] </thought>
      <answer> [Final JSON output here] </answer>
    </output_format>
    

    Zencoder によると、思考の木(Tree-of-Thoughts、ToT)といった技法はこれをさらに進め、複数の解法パスを同時に評価して最善を選ぶようモデルに求めます。これは正解が1つではないアーキテクチャ上の決定に特に有用です。

    トークンコストの警告

    構造化推論はより多くのトークンを消費します。典型的な <thought_process> ブロックはリクエストごとに200〜500トークンを追加します。スケールが大きくなるとAPIコストの上昇につながります。引き換えは精度です——リクエスト単価は高くなりますが、再試行や手動修正は減ります。

    本番対応:バージョニング、テスト、CI/CD

    最後のステップはプロンプトをソフトウェアとして扱うことです。セマンティックバージョニング(v1.0.0など)を使えば、チームは変更を追跡でき、新しいプロンプトバージョンが品質を落としたときに即座にロールバックできます。

    PromptOT の報告によれば、50以上のプロンプトを管理する企業は、管理を一元化しエンジニアが手作業で微調整する時間を減らすことで、年間最大40万ドルを節約できます。

    プロンプトCI/CDパイプラインの構築

    # .github/workflows/prompt-tests.yml
    name: Prompt Quality Gate
    on: [push]
    jobs:
      test-prompts:
        runs-on: ubuntu-latest
        steps:
          - name: Run Golden Dataset Tests
            run: |
              # Test against 50-200 curated cases
              python scripts/eval_prompts.py \
                --dataset golden_dataset.json \
                --judge-model gpt-4 \
                --min-score 0.85
    
          - name: Regression Check
            run: |
              # Compare new version vs. production
              python scripts/compare_versions.py \
                --staging v2.1.0 \
                --production v2.0.3 \
                --threshold 0.05
    

    プロンプトは、「LLM-as-a-judge」が採点するこれらの品質ゲートを通過して初めて Staging から Production へ昇格します。

    まとめ

    フォーマッターを使った構造化プロンプトエンジニアリングは、もはや任意ではありません——信頼できるAIツールを構築するすべての人にとっての基準です。RTCCOフレームワーク、XML区切り文字、モジュラーアーキテクチャが、予測不能なLLM出力を一貫した本番品質の結果へ変えるためのスタックです。

    最もよく使うプロンプトから始め、上記のXMLテンプレートを使ってRTCCOフレームワークへリファクタリングしましょう。バージョン管理に組み込み、基本的な評価を設定すれば、スケールするプロンプト基盤が手に入ります。

    FAQ

    既存の段落型プロンプトをRTCCOブロック形式に変換するには?

    まず中核のタスク(Task)を特定し、文脈(Context)と切り離します。指示は <rules> タグで囲み、<examples> タグに3〜5個の例を示します。LLMに手伝わせることも可能です——「この非構造化テキストをXML区切り文字を使ってRTCCOフレームワークに再解析して」と指示すれば、面倒な作業を引き受けてくれます。

    XML、JSON、Markdownのどれを使うべきですか?

    ClaudeやGPT-5のようなモデルで指示と長文コンテンツを切り離すには、XMLが現在のゴールドスタンダードです。厳格な階層構造を持つからです。API連携用のプログラム的な入出力が必要な場合はJSONが適しています。Markdownはシンプルで人間が読みやすいプロンプトに向きますが、複雑で多層的な本番プロンプトに必要な厳格な境界定義は持ちません。

    プロンプトの自動化されたCI/CDテストはどう実装しますか?

    「ゴールデンデータセット」(50〜200個の厳選テストケース)と「LLM-as-a-judge」を備えたテストスイートを構築し、ルーブリックに沿って出力を採点します。これらのテストをGitHub ActionsやJenkinsのパイプラインに統合し、プロンプトの変更がデプロイ前に精度とトーンについて検証されるようにします。

    構造化プロンプトへの移行で最もよくある失敗は?

    <context> ブロックへの詰め込みすぎです。開発者はコードベースや文書全体を文脈に投げ込みがちで、モデルの注意を散らします。文脈はタスクに直接関連する内容だけに絞りましょう。大きな文書を参照する必要がある場合は、RAG取得で関連する部分だけを引き出してください。