AIの精度を上げたいなら、まず計算とデータ変換に検証を足す
万能なプロンプトは見つかっていません。簡単な質問はそのまま答えさせる。まずは計算を計算器に任せ、JSON変換にスキーマ検査と元データの保存チェックを足す。資料との証拠照合やサンドボックスでのテストは、その後に用途を絞って導入する。この順番をおすすめします。
結局、何から始めればいい?
| 用途・優先順 | チャットで使う人 | APIでアプリを作る人 |
|---|---|---|
| 簡単な質問 | 短く、そのまま質問する。 | 通常の1回回答。検証を通していなければ「検証済み」と表示しない。 |
| まず:計算 | 計算ツールがある環境で「この式を計算器で計算して」。なければ電卓で照合する。 | 計算器をtoolsに接続。入力の式とツール引数の一致、実行結果を確認する。 |
| まず:JSON変換 | 元データ・出力例・変換規則を一緒に渡す。結果の型と文字列の欠落を確認する。 | 出力後にJSON解析+スキーマ検査+元データとの照合。形式が合うだけでは合格にしない。 |
| 次に:資料から抽出 | 対象資料を渡し、回答に対応する引用箇所を確認する。 | レコードID・値・引用を元資料と照合。資料自体の真偽は別に確認する。 |
| 次に:コード | テストと実行結果を求め、実行した記録を確認する。 | 時間・権限を制限したサンドボックスでテストする。任意コードのテスト効果は今回未測定。 |
チャットに「検証して」と書くだけで、計算器や検査プログラムが増えるわけではありません。今回コードで測ったのも、レビュー済みの固定4関数の実行だけです。任意の生成コードをテストして品質が上がるかは、別途測定が必要です。
APIアプリでは、どこに何を入れる?
| 置き場所 | 入れるもの |
|---|---|
system | 直接回答とツール利用の方針、未確認を断定しない指示。 |
user | 今回の質問・元データ・出力形式・明示的な変換規則。 |
tools | 計算器などの呼び出し定義。実際の処理はアプリ側で実装する。 |
出力後の検証post-validation | 型・内容・元データ保存の検査、最大1回の修復、採用か停止かの判断。モデルの自己申告に任せない。 |
短いsystemプロンプトの説明用例 — UNBENCHMARKED(この文単体の効果は未測定)
簡単な質問には直接、簡潔に答えてください。 計算は計算ツールを使い、データ変換は指定の形式と元データを守ってください。 資料に基づく回答は根拠を示し、確認できないことは未確認と伝えてください。 検証エラーを受け取ったら、その指摘に基づいて修正してください。
これは実装方針を伝える例で、実験で使った長いsystemプロンプトとは異なります。下の成績を、この短文の効果として読むことはできません。
検査に落ちたら、1回直して、それでも駄目なら止める
以下はこれから組むアプリ向けの疑似コードです。検証対象の計算・データ変換に適用します。入力と変換規則は固定し、モデルに合格条件を書き換えさせません。
candidate = generate(input, system, tools)
check = validate(candidate, source=input, rules=fixed_rules)
if not check.ok:
candidate = repair_once(candidate, input, check.errors)
check = validate(candidate, source=input, rules=fixed_rules)
if not check.ok:
return {status: "not_verified", answer: null} # 自動採用を停止
return {status: "correctness_verified", answer: candidate}
実験がこの停止動作まで実装していたわけではありません。実験では修復後も拒否されたJSONの候補を、not_verifiedのまま返しました。上の「答えを採用せず止める」は改善提案で、実験済みの成果ではありません。また、合格が意味するのは定義した検査の範囲内だけです。
クラウドAPIでも、モデルの外側にこの検証処理を置く構成は可能です。ただし今回測ったのはローカルの1モデルだけ。クラウドでの精度・速度・料金への効果は未測定です。使うモデルと実際の業務データで、正答率・未検証率・時間・トークンを比べてから広げてください。
おすすめの根拠:同じモデルで、新しい20入力を比較
Qwen2.5 14Bを両方式で使い、実装を固定した後に作った同じ5種類のテンプレートの新しい入力20件を比べました。未知の種類の仕事を試した結果ではありません。検証側にはツールと追加の生成機会があり、プロンプトだけを変えた比較でもありません。
通常方式 → 検証方式。固定採点器の厳格正答は12/20→18/20。
コールドロードを含む。入力トークンは約2.9倍。料金が2.9倍という意味ではありません。
6勝0敗14引き分け。改善は計算4問・固定コード1問・JSON1問で、証拠抽出と直接回答には差がありませんでした。JSON修復は3回中2回成功、1回失敗。検証で誤りを見つけても、直せるとは限りません。
採点側にも不備があります。HD4の色名は両方式ともRedで意味は正しいのに、指示にない小文字限定で不合格になりました。元の測定・採点結果は変更せず、厳格12→18と意味13→19を併記しています。
実験方法と、検証器が保証する範囲を読む
何を比べたのか
有名なひっかけ問題ではなく、機械可読の入力がある小さな業務処理。実装を固定してから、入力と正解を後で作りました。
実装を先に固定し、入力と正解を後から作成。推論前に照合済み。
計算・固定コード・証拠照合・JSON検査。
ローカルOllamaのみ。モデルはQwen2.5 14B。
問題は同じ5種類のテンプレートに、新しい入力値を入れた各4問です。新しい種類の仕事ではありません。
| 種類 | 内容 |
|---|---|
| 整数計算 | 複数桁の乗算・整数除算・剰余(4問) |
| 固定コードの出力 | 状態更新・在庫集計・重複除去・連続値圧縮(4問) |
| 提供証拠の抽出 | 条件に合うレコード・値・引用(4問) |
| JSON正規化 | 整数・真偽値・null・引用符・改行・バックスラッシュ(4問) |
| 単語の直接回答(対照) | 小文字化・復唱・反対語・色名(4問) |
通常方式は問題をそのまま渡して1回生成。検証方式は同じuserメッセージにツールメニューを加え、モデルはツール要求か構造化した回答案を返します。拒否された場合だけ、事実に基づくエラーを渡して最大1回修復します。検証側には長いsystemプロンプトと決定的なツール、追加の生成機会があるため、同じ予算でのモデル比較ではなく、実際に組んだ2つの処理方式の比較です。
検算係は、何を保証するのか
「検証済み」の中身は、4つで全然違いました。
| 検算係 | 保証すること | 保証しないこと |
|---|---|---|
| 計算 | 入力と完全一致する式を安全なASTで整数評価 | モデル自身の計算力 |
| 固定コード | レビュー済み4関数を供給データで実行 | 任意コード生成の品質 |
| 証拠照合 | 入力レコードと一致・一意・引用が同一 | 資料自体が現実に正しいこと |
| JSON検査 | 形式に加え、入力と明示された変換規則との一致 | 規則が未定義な文章や任意の意味の正しさ |
evalではありません。整数リテラルと + - * // % だけを許可するAST評価器です。変数・関数呼び出し・属性アクセス・巨大な累乗は拒否します。コードも、モデルが生成した任意コードは実行せず、事前にレビューした4つの純粋関数だけを動かします。
今回の検証方式の最終状態は、15問が correctness_verified、5問が not_verified。内訳は、検証経路を通らない単語の直接回答4問と、修復後も直らなかったJSONの1問です。「採点で正答」と「実行時に検証済み」は別々に記録しています。
全指標・修復の実例・採点上の不備を読む
結果 — 意味の正答は13/20から19/20へ
厳格正答 = 意味が正しい AND 指定形式を守る AND 通信成功。失敗や未実行を分母から除かず、各方式20問で採点しています。
| 指標 | 通常 | 検証方式 |
|---|---|---|
| 意味の正答 | 13/20 | 19/20 |
| 厳格正答(意味+形式+通信) | 12/20 | 18/20 |
| 形式適合 | 14/20 | 19/20 |
| モデル呼び出し | 20 | 23 |
| 修復 | 0 | 3 |
| 通信失敗 | 0 | 0 |
以下はカテゴリー別の厳格正答です。
| 種類 | 通常 | 検証方式 |
|---|---|---|
| 整数計算 | 0/4 | 4/4 |
| 固定コードの出力 | 3/4 | 4/4 |
| 提供証拠の抽出 | 4/4 | 4/4 |
| JSON正規化 | 2/4 | 3/4 |
| 単語の直接回答(対照) | 3/4 | 3/4 |
| 合計 | 12/20 | 18/20 |
対応ありの比較で6勝0敗14引き分け。勝ちはHA1〜HA4、HC1、HJ2の6問です。引き分け14の内訳は、両方正解12問と、両方とも厳格不正解2問。全カテゴリーに効果が出たわけではありません。
exact McNemarの両側p値は0.03125ですが、単一モデル・単一seed・手作り20問の記述的な結果であり、広い母集団に対する優位性の証明にはしません。40条件は一度だけ実行し、全43本のモデル呼び出しはHTTP 200・stop・通信失敗0でした。両方式のuserメッセージは20/20で同一です。
検出と修復は、別の能力だった
JSON正規化の3問で、修復は2回成功し、1回失敗しました。
HJ2:改行の後の文字が欠けた。検証側の初回提案は deckA\ndekB で、入力の deckA\ndeckB と一致しませんでした。入力保存チェックが拒否し、1回の修復で正しくなりました。通常方式も別の誤記 deckA\ndepkB を返しており、この問題は検証方式の1勝です。
HJ4:保存すべき文字列をnullにした。検証側は初回にnoteをnullへ置き換えました。拒否後、タブを含む 保管\t済 を正しく保存できました。通常方式は最初から正答していたので、これは修復成功ですが方式間では引き分けです。
None をnullと取り違えた。指示は厳密に小文字の none だけをnullにするものでした。検証器は初回も修復後も拒否しましたが、モデルは同じ誤りを繰り返しました。最終状態は not_verified。実装は2回目の拒否でも候補回答を返すため、正しい回答への回復や回答保留まで保証する設計ではありません。見つけられることと、直せることは違います。
採点規則の厳しさも開示します
HD4は「意味は正しいのに、形式で落ちた」1問です。
HD4はRGB #FF0000 の英語名を答える問題で、両方式とも Red と回答しました。意味は正しい。しかし固定した採点器は単語の形式を小文字 [a-z]+ に限定しているため、形式不合格になりました。この色名の指示文には小文字限定が明記されていません。したがって、実際の指示違反と単純に呼ぶより、採点器が課した追加制約として開示するのが正確です。
結果を見て規則を緩めたり再採点したりはしていません。固定した主要指標は12対18のまま示し、意味の正答13対19も併記します。JSONの厳格採点もバイト一致ではなく、解析後の型・内容・スキーマを確認しています。
時間・トークン・実行環境と限界を読む
時間とトークンの代償
ローカルOllamaで1件ずつ実行した、各方式20問の合計です。
| 指標 | 通常 | 検証方式 |
|---|---|---|
| 20問の合計時間 | 16.77秒 | 21.53秒 |
| 1問の中央値 | 0.86秒 | 1.07秒 |
| 入力トークン | 2,587 | 7,564 |
| 出力トークン | 431 | 530 |
| 修復回数 | 0 | 3 |
検証方式の合計時間は約28%長く、入力トークンは約2.9倍。ツールメニューを渡すコストは残ります。両方式を交互に逐次実行した全体は38.31秒でした。
環境はApple M5 Max・128 GiB、Ollama 0.21.0、Python 3.14.5。設定はtemperature=0、seed=20260912、num_predict=1024、num_ctx=4096、timeout=90秒。モデル名は qwen2.5:14b-instruct-q4_K_M で、インストールされたローカルタグの識別名であり、上流公式重みとの同一性は未確認です。実行後の /api/ps には対象モデル1件がロード済みと記録されていますが、GPUをOS全体で独占したことまでは測定していません。
この実験から言えること
ここから言えるのは、同じテンプレートの小さな構造化タスクでの改善まで。モデル能力全般の向上、未知の仕事への一般化、検証済みなら常に正しいという保証は示していません。この20入力は、実装を固定した後に作った入力の置き換えであり、無作為標本でも、未知のカテゴリーでの一般化テストでもありません。goldの「独立」は、検証器とは別の導出手順・コードで求めたという意味で、別の人間による盲検評価ではありません。
記録の公開状況
生データは保存済み、公開ダウンロード準備中。以前載せていた404のダウンロードリンクは削除しました。公開アーカイブが利用できる状態ではありません。
| 保存記録の要約 | 内容 |
|---|---|
| 今回の新しい20入力 | 2026-09-12に一度だけ実行。20入力×2方式=40条件、モデル呼び出し43本、通信失敗0。 |
| 結果・再現条件 | 回答・判定・時間、生トレース、固定時の設定とハッシュを保存。意味13/20→19/20、厳格12/20→18/20。 |
| 初期の開発用20問 | 14/20→20/20は調整後の開発用成績。今回の新しい入力での成績とは別で、一般化の根拠にしない。 |
開発用データとの違い・記録上の注意を読む
初期の14/20→20/20は、同じ開発用問題を使って実装を調整した後の結果です。それを受けて実装を固定し、入力値を変えた今回の20問を作りました。開発用と今回の結果を混ぜて「20問すべて正答」とは言えません。
開発用記録はコミット9fb7a4eの成果物に対応しますが、そのコミットだけでは固定用スクリプトや各runの結果・メタデータ・生ログが揃わず、完全再現には不足があります。公開ダウンロードの案内ではありません。
実行器・検証器は gold.json を読み込まず、別プロセスの採点器が正解と照合します。これはコード上の分離であり、OS権限で正解ファイルへのアクセスを禁止しているわけではありません。固定したsystemプロンプトには旧「JSONはsyntax/schemaのみ」の説明が残り、元のunit testにも旧状態名の期待が残っています。「旧テストがすべて合格」とは主張しません。
まず1つの処理に、検証を足す
計算器かJSONの入力保存チェックから始める。teai.ioは複数モデルへのAPI窓口として使えます。ツール実行と検証・停止の処理はアプリ側で組み、効果を測ってから対象を広げましょう。
APIの使い方を見る →