リード
こんにちは、ぽまらのです。
今回は、AIの「ハーネスエンジニアリング」を、JSON整形タスクで実際に比較してみます。
テーマはシンプルで、同じタスクを「ハーネスなし」と「ハーネスあり」で実行すると、どれだけ差が出るかです。
この記事では、実験手順・プロンプト・評価基準を公開し、同じ条件で再現できる形にします。

この記事でいう「ハーネス」とは
ここでいうハーネスは、次のような実行ガードのことです。
- 出力形式を固定する(JSON schemaを定義)
- バリデーションを通らない場合はリトライする
- 必須キーや型をチェックする
- 失敗理由をログに残す
要するに、AIの回答品質を「お願い」ではなく「検証可能な手順」で安定化させる仕組みです。
比較するタスク(JSON整形)
AIに、非構造テキストからJSONを生成してもらいます。
入力テキスト(固定)
注文ID: A-1042 顧客名: 田中 花子 商品: ワイヤレスマウス, USB-Cケーブル 合計金額: 4280円 配送希望日: 2026-05-30 支払い: クレジットカード 備考: 領収書希望
期待するJSON(キー定義)
- order_id: string
- customer_name: string
- items: string[]
- total_yen: number
- delivery_date: string (YYYY-MM-DD)
- payment_method: string
- note: string
実験条件
条件A: ハーネスなし
- 通常のプロンプトのみ
- 出力の妥当性チェックなし
- リトライなし
条件B: ハーネスあり
- JSON schemaを明示
- スキーマ違反時は自動リトライ(最大2回)
- 最終出力のみ採用
実行回数
- 各条件 3回(合計6回)
評価指標
- 成功率(スキーマを満たした割合)
- 平均実行時間
- リトライ回数
- フォーマット違反数
実際に使ったプロンプト
A. ハーネスなしプロンプト
次のテキストをJSONに整形してください。 必ずJSONだけを返してください。 注文ID: A-1042 顧客名: 田中 花子 商品: ワイヤレスマウス, USB-Cケーブル 合計金額: 4280円 配送希望日: 2026-05-30 支払い: クレジットカード 備考: 領収書希望
B. ハーネスありプロンプト
次のテキストを、以下のJSON schemaを満たすJSONとして返してください。
JSON以外の文字は出力しないでください。
Schema:
{
"type": "object",
"required": ["order_id","customer_name","items","total_yen","delivery_date","payment_method","note"],
"properties": {
"order_id": {"type":"string"},
"customer_name": {"type":"string"},
"items": {"type":"array","items":{"type":"string"}},
"total_yen": {"type":"number"},
"delivery_date": {"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},
"payment_method": {"type":"string"},
"note": {"type":"string"}
},
"additionalProperties": false
}
Input:
注文ID: A-1042
顧客名: 田中 花子
商品: ワイヤレスマウス, USB-Cケーブル
合計金額: 4280円
配送希望日: 2026-05-30
支払い: クレジットカード
備考: 領収書希望
代表出力
実行時の代表的な出力を、条件A/Bで1つずつ載せます。
A. ハーネスなしの代表出力(失敗例)
{
"注文ID": "A-1042",
"顧客名": "田中 花子",
"商品": ["ワイヤレスマウス", "USB-Cケーブル"],
"合計金額": 4280,
"配送希望日": "2026-05-30",
"支払い": "クレジットカード",
"備考": "領収書希望"
}
JSONとしては妥当ですが、今回の要件(order_id など英字キー)に合わないため失敗判定です。
B. ハーネスありの代表出力(成功例)
{
"order_id": "A-1042",
"customer_name": "田中 花子",
"items": ["ワイヤレスマウス", "USB-Cケーブル"],
"total_yen": 4280,
"delivery_date": "2026-05-30",
"payment_method": "クレジットカード",
"note": "領収書希望"
}
必須キー・型・日付フォーマットがschemaに一致しており、成功判定です。
実行ログ
以下に、実行時の結果をそのまま記録します。
| run | 条件 | 成功/失敗 | 実行時間(ms) | リトライ回数 | メモ |
|---|---|---|---|---|---|
| 1 | ハーネスなし | 失敗 | 4000 | 0 | JSONとしては妥当だがキー名が日本語(schema不一致) |
| 2 | ハーネスなし | 失敗 | 3000 | 0 | 同上。order_id など必須キーを満たさない |
| 3 | ハーネスなし | 失敗 | 3000 | 0 | 同上。出力は安定だが要求仕様は未達 |
| 1 | ハーネスあり | 成功 | 2000 | 0 | schemaどおりのキー・型で出力 |
| 2 | ハーネスあり | 成功 | 4000 | 0 | schemaどおり。1行圧縮形式でも問題なし |
| 3 | ハーネスあり | 成功 | 3000 | 0 | schemaどおり。再現性あり |
集計結果
| 指標 | ハーネスなし | ハーネスあり | 差分 |
|---|---|---|---|
| 成功率 | 0% (0/3) | 100% (3/3) | +100pt |
| 平均実行時間 | 3,333ms | 3,000ms | -333ms |
| リトライ回数 | 0 | 0 | ±0 |
| フォーマット違反数 | 3 | 0 | -3 |
所感
今回の結果では、最も差が出たのは 仕様準拠率 でした。ハーネスなしは3回とも日本語キーで返ってきて、JSONとしては正しくても、今回のschema要件では全失敗になりました。一方でハーネスありは3回とも成功し、期待したキー・型で揃いました。
良かった点は次の3つです。
- 成功率の安定: 0% → 100% になり、運用判断がしやすい
- 検証可能性: 「なんとなく正しい」ではなく、schemaで合否判定できる
- 再現性: 出力フォーマットがぶれず、後段処理に渡しやすい
微妙だった点(注意点)もあります。
- 今回は入力が単純で、実行時間の差は小さい(-333ms)
- モデルが賢いほど「それっぽいJSON」を返してくるため、ハーネスなしでも一見うまく見える
- 実運用では、フォーマット以外(欠損値、業務ルール違反)も別途チェックが必要
結論として、ハーネスは「精度を魔法のように上げる」より、失敗を見える化して、運用可能な形に揃えるための仕組み だと感じました。
まとめ
同じJSON整形タスクでも、ハーネスの有無で安定性は変わります。
「たまたまうまくいく」状態から、「検証して運用できる」状態に寄せるのが、ハーネスエンジニアリングの価値だと感じました。
次は、JSON整形以外のタスク(コード修正や要件付き要約)でも同じ比較を試してみる予定です。

コメント