実測・検証の内側

AIが間違えた答えを、検算係はもう知っていた

入力は note: "None"。指示は「小文字の none だけをnullに変える」。 検算係は正しい期待値を計算し、モデルの null を誤りとして拒否しました。それなのに、最終的に返ってきたのは同じ null でした。 正解はすでにコードの中にあったのに、捨てられていた——この1問を糸口に、どこでAIに任せ、どこで任せないかを追います。

公開 2026-09-13
対象 構造化20問・履歴2方式の再採点
実測 ローカル・追加推論なし
外部API料金 $0

何が起きていたのか

「検出できる」と「直せる」と「正しい値を返す」は、別の話でした。

検算係が正解を計算したのに、モデルの再生成結果が最終回答になる流れ 入力 note: None に対し、検算係 expected_record は正しい None を計算する。モデルは null を返す。検算係は拒否するが、その期待値を回答に使わず、モデルに修復を求める。モデルは再び null を返し、それが最終回答として返る。 入力 note: "None" 検算係が期待値を計算 note: "None" ✓ モデルに再生成を依頼 モデルが返した候補 note: null ✗ 拒否 期待値は使わない 修復を1回だけ要求 モデルが再び返した候補 note: null ✗ 最終回答: null(not_verified のまま返却) ここで捨てられた値 note: "None" 検算係は正しく計算済み 回答生成には未使用
検算係は正解 "None" を内部で構成していた。しかしその値は回答に使われず、モデルの再生成結果が最終回答として残った。

この1問(以下HJ3)では、検算係が入力から期待レコードを導出する関数を実行し、正しい "None" を計算しています。モデルの候補 null はその期待値と一致しないため拒否されます。ところが処理は、拒否したあとにモデルへ修復を求め、2回目も同じ null が返ると、それを最終回答として保持します。

ここで言えるのは「処理の配置」の問題です。検算係が正解を持っていたのに、回答生成の経路に渡していなかった。モデルが賢くなれば直る話ではなく、確定できる値をどこで使うかの設計の話です。ただしこれは「検証や修復が誤りを引き起こした」という因果の主張ではありません。初回から誤っており、通常方式も同じ誤変換でした。

数字で見る:主要16問と、全体20問は別物

同じ20問を、通常方式・検証方式・決定論的処理だけで解いた方式の3つで再採点しました。

9 → 15 → 16
主要16問の厳格正答

通常 → 検証方式 → 決定論的処理のみ。計算・コード・証拠照合・JSON正規化の4分類。

12 → 18 → 18
全20問の厳格正答

同点。全20問の意味正答は13 → 19 → 18で、決定論的処理は検証方式より1問少ない。

主要16問では、決定論的処理だけで16/16でした。一方、全体20問では検証方式と厳格正答で同点、意味正答では1問負けています。理由は単語の直接回答4問(対照群)で、決定論的処理は反対語と色名の2問を「対応する規則がない」として未対応にしたためです。この2問を分母から外した「対応18問」の成績だけを並べると、全体の優越と誤読されます。

指標通常検証方式決定論的処理のみ
主要4分類16問の厳格正答9/1615/1616/16
全20問の厳格正答12/2018/2018/20
全20問の意味正答13/2019/2018/20
全20問の形式合格14/2019/2018/20
対応18問の厳格正答11/1817/1818/18
単語4問(対照)の厳格正答3/43/42/4
モデル呼び出し20230
修復030

未対応の2問は、全体成績では非正解として数えています。対応した18問だけの条件付き成績(18/18)は、この処理が選んだ範囲の中での話であり、全20問での優越を意味しません。また、決定論的処理が検証方式に対して正答を上積みしたのはHJ3の1問だけで、逆に通常方式が正答していた反対語1問を未対応にしています。

「AIは不要」という結論ではありません。今回確かめたのは、既知のカテゴリーと、完全に定義された変換規則と、構造化された入力がある仕事では、最終出力の生成を決定論的処理に置き換えられる場合がある、という一事例です。自由文から入力契約を作る工程や、曖昧な要求の解釈、反対語や色名のような語彙知識が必要な仕事は、この実験の範囲外です。

なぜ「検算係だけ」で終わったのか

カテゴリーごとに、入力から答えを確定できるかどうかが違いました。

分類確定できる根拠対応/正解
整数計算入力の式を、許可した演算子だけの構文木で評価する4/4・4/4
固定コードの出力レビュー済みの4つの純粋関数を、供給データで実行する4/4・4/4
提供証拠の抽出全条件に一致する唯一の行を選び、値・ID・引用をそのまま写す4/4・4/4
JSON正規化明示された変換規則を入力に適用する(今回の主役)4/4・4/4
単語の直接回答(対照)小文字化と復唱は入力だけで決まる。反対語と色名は規則が与えられていない2/4・2/2

ポイントは、「入力と明示された規則だけで答えが一意に決まる」仕事に限ったことです。反対語(cold→hot)や色名(#FF0000→red)は、入力だけでは答えが決まりません。この2問を、その場で答え表を作って埋めることはしませんでした。それは検証ではなく、答えの後付けになるからです。

これは新しい発見ではなく、配置の見直しだった

HJ3の正解 "None" は、以前の実験の推論前チェックでも既に生成され、受理されていました。新しく見つけた計算法ではなく、すでにオフラインで成功していた処理を、最終回答の経路に採用できるという配置上の問題です。だから「より賢いモデルを見つけた」という話にはなりません。

この点は正直に書いておきます。決定論的処理は、元の検証器の関数をそのまま再利用しています。独立した実装同士が一致したわけではありません。また、今回の処理は公開されたタスクと命令文を見て書かれており、同じテンプレートの新しい入力ではあっても、この処理にとっての未知入力ではありません。「作者が事前に正解を見ていなかったこと」は、記録上そうなっているだけで、独立には証明できません。

では、どう組めばいいのか

以下は実測で確かめた成果ではなく、この記録から導いた設計案です。まだ端から端までは試していません。

1. AIで意図を整理する
   自由文や曖昧な要求から、「どのカテゴリーの、どの変換か」を取り出す。
   ここはAIの得意分野。ただし結果は構造化された入力契約として出力させる。

2. 確定処理に渡す
   入力契約が既知のカテゴリーに一致するなら、決定論的な処理で答えを確定する。
   計算・固定コード・証拠照合・正規化のように、入力だけで答えが決まる仕事が対象。

3. 確定値は書き換えない
   確定処理が出した値を、モデルに再生成させない。検算係が持っている期待値を
   捨てて作り直させるのは、まさに今回の1問が示した遠回り。

4. 必要だけ説明する
   モデルには、確定値をどう扱うかの説明や、契約に当てはまらない部分の
   要約だけを任せる。値そのものは生成させない。

この4段のうち、今回の実験で実測できたのは2と3の一部です。1の「AIで意図を整理する」工程と、契約に当てはまらない場合の扱いは、まだ試していません。提案として提示しますが、検証済みの成果としては扱いません。

コードで見る:「期待値と照合して再生成」と「入力から確定」

正解データ(gold)には一切触れず、入力と明示された規則だけで完結する最小例です。

# --- 悪い例: 期待値と照合したあと、モデルに作り直させる ---
def validate_then_regenerate(record, ask_model):
    want = normalize(record)          # 正しい期待値がここにある
    candidate = ask_model(record)     # それでもモデルに生成させる
    if candidate != want:
        candidate = ask_model(record) # 1回だけ修復
    if candidate != want:
        return {"status": "not_verified", "answer": candidate}  # 誤答を返す
    return {"status": "correctness_verified", "answer": candidate}


# --- 良い例: 変換が完全に指定されているなら、入力から確定させる ---
def normalize(record):
    """入力と明示された規則だけで期待レコードを導出する(goldは見ない)。"""
    return {
        "label": record["label"],
        "count": int(record["count"]),
        "enabled": record["enabled"] == "yes",
        # 小文字の "none" だけを null にする。大文字の "None" は文字列のまま。
        "note": None if record["note"] == "none" else record["note"],
    }


def answer_from_input(record):
    return {"status": "correctness_verified", "answer": normalize(record)}


if __name__ == "__main__":
    # 入力だけを渡す。正解表は参照しない。
    case = {"label": "D:\\archive\\weekly", "count": "407",
            "enabled": "no", "note": "None"}
    print(normalize(case)["note"])   # => None ではなく "None" が正しい

2つの関数の違いは、正しく計算した期待値を、回答に使うか捨てるかだけです。変換が完全に指定されている仕事では、モデルの生成を経由せずに入力から答えを確定できます。逆に、規則が与えられていない語彙や色名のような仕事には、この関数は使えません。

時間と費用について、言えること・言えないこと

決定論的処理は、20問を1,000回繰り返した中央値で約57マイクロ秒でした。一方、過去の検証方式の記録は20問で約21.5秒です。しかし、これは測定の境界も条件も違うので、速度倍率としては主張しません。片方はファイル入出力もモデルの起動も含まないCPU上の計算で、もう片方はモデルのHTTP往復・推論・修復・検証を含みます。同じ土俵の比較ではありません。

費用も同じです。両方の実験とも外部API料金は$0で、削減額を測ったわけではありません。電力や機材費も未測定です。「何倍速い」「何円得」という見出しには使いません。

この記録の出どころと、独立性の限界を読む

何を再検証したのか

元の実験は、同じ5種類のテンプレートに新しい入力値を入れた20問を、通常方式と検証方式の2つで解いたものです。今回はその保存済みの回答と生トレースを、決定論的処理だけの方式で解き直し、既存の採点器で再採点しました。新しいモデル推論は行っていません。

項目内容
問題数20問(主要4分類16問+単語の対照4問)
比較した方式通常回答 / 検証方式 / 決定論的処理のみ
採点意味が正しい AND 指定形式を守る(履歴モデルは通信成功も必要)
モデル呼び出し決定論的処理: 0回 / 検証方式: 23回 / 通常: 20回
外部API料金$0(ローカル実行)
新規推論なし(保存済み結果の再採点と再実行のみ)

独立性について、正直に書くこと

採点側の制約も開示する

単語の対照4問のうち色名1問は、モデルの回答 Red が意味としては正しいのに、採点器が課した小文字限定の形式条件で不合格になりました。これは指示文には明記されていない追加の制約です。元の測定・採点結果は変更せず、厳格正答と意味正答を併記しています。

元データの出典を読む(外部ファイルに依存しない要約)

この記事の数値は、すべて保存済みの記録から再集計したものです。以下は要約であり、リンク切れする外部アセットには依存しません。

記録内容
採点結果20問の意味・形式・厳格判定、3方式の正答数、呼び出し数、時間集計
保存回答決定論的処理による20問の回答と、未対応2問の理由
時間計測20問バッチ1,000回の中央値と、各問1,000回の生サンプル
固定記録処理・出力・公開入力・再利用実装のSHA-256と固定時刻
検証ログHJ3を含むJSON正規化4問の、初回・修復後の候補と拒否理由
監査記録独立再集計の結果、拒否チェックの再現、goldの別導出

決定論的処理の固定時刻は2026-09-12 23:15:37 UTC、採点プロセスが正解を開いた時刻は23:17:03 UTCです。固定した8ファイルのハッシュは一致し、保存回答20件は再現されました。これは追試と改変検出のための記録であり、第三者署名付きの証明ではありません。

この記録から言えること

検算係が正解を計算していたなら、その値を回答に使う経路を先に疑う。「検証でAIが賢くなった」と見えた実験から、実行エンジンとモデルによる選択を分けてみると、構造化された仕事の大部分は実行エンジンだけで完了しました。そして、検算係がすでに計算した正解を捨てて再生成していた1問まで直りました。

ただし、これは「LLMは要らない」という一般論ではありません。見つかったのは、この処理経路のどこにLLMが要らなかったかです。自由文から契約を作る工程、曖昧な要求の解釈、語彙知識が必要な仕事は、この実験の外側にあります。AIを使い続ける前提で、任せる場所を選び直すのが、この記録の実用的な意味です。

関連する記録として、AIの精度を上げたいなら、まず計算とデータ変換に検証を足すと、その前提になった過去記事の訂正(ローカルLLM比較の採点ミス)も合わせて確認してください。

確定できる仕事は、確定処理に渡す

まずは自分の処理のどこで「正しい値がすでに計算されているのに、作り直させているか」を探すところから。検証の始め方は実測ガイドにまとめています。

検証の始め方と実測を読む →