論文一覧に戻る 📚 用語集トップ 🗺 概念マップ
📚 用語解説
📚 用語解説
ハルシネーション
Hallucination
深層学習

🔖 キーワード索引

#LLM#虚偽生成#事実性#RAG#Grounding#verification

🔖 拡張キーワード索引(深掘り用)

以下のチップから関連する詳細セクションへジャンプできます。

ハルシネーションの 4 種類 数式を言葉で読み解く SSDSE-B 実値検証 困惑度 (Perplexity) Python: fact-check Python: RAG Python: grounding 検証 Python: 数値検証 Python: 評価指標 深い落とし穴 対策技術 11 選 関連用語拡張 グループ教材

💡 30秒で分かる結論

🍰 まずはやさしく

AIがもっともらしい嘘をつく現象です。

正しく情報を得るために使います。

スマホで調べた答えが間違いである例です。

結論と対策について読みましょう。

ハルシネーション:LLMが事実と異なる内容を生成する現象

💡 さらに 30 秒で押さえる(拡張版)

📍 文脈ボックス

🍰 まずはやさしく

AIが答えを作る仕組みのことです。

なぜ間違いが起きるかを知るために使います。

部活の人数をAIに聞くと間違える例です。

AIが単語を予測する仕組みを読みましょう。

この用語は 深層学習 カテゴリに属します。 関連する別称・略号:(なし)

論文・実務レポートで ハルシネーション が登場したら、 まず本ページの「30秒で分かる結論」と「直感で掴む」を読めば、 その文脈で何を言っているか把握できます。

📍 文脈:なぜ LLM はハルシネーションを起こすのか

LLM の学習目的は 「与えられた文脈の次に来る単語の確率分布」を最適化する こと。 「事実かどうか」は損失関数に含まれていない。 訓練データに 東京都の人口は 14,086,000 人 が大量にあれば、 そう答える確率が高いだけ。

逆に「マイナーな県の最新人口」のように訓練データに記述が乏しい問いには、 もっともらしい数字を 創作 してしまう。 これがハルシネーションの本質。 「嘘をつく」のではなく「知らないことを言わざるを得ない」設計上の必然。

🎨 直感で掴む

🍰 まずはやさしく

AIが見せる「幻」のような間違いです。

間違いの種類を分けるために使います。

テストの計算ミスをするような例です。

4つの間違いのパターンを読みましょう。

東京タワーは 1964 年の東京オリンピックを記念して建設された」── LLM が自信たっぷりに答える。 実際は 1958 年完成で関係なし。 もっともらしい文体で誤情報を生成するのが ハルシネーション (幻覚)。 LLM は確率的次トークン予測で動作するため、 知らないことも「それっぽい」答えを作ってしまう。

🎨 直感で掴む:ハルシネーション 4 分類

タイプ 定義 具体例(SSDSE-B-2026 文脈)
① 内在的 (Intrinsic)入力プロンプトの内容と矛盾する出力「2023 年の東京都人口」と聞いたのに「2019 年の東京都人口」を答える。
② 外在的 (Extrinsic)入力には無いが、 実世界の事実と矛盾する出力「東京都の 2023 年人口は 9,000 万人」と答える(実際は 1,400 万人)。
③ 論理的 (Logical)前提から推論が誤っている「東京 1,400 万 + 神奈川 920 万 = 2,800 万人」(実際は 2,332 万人)。
④ 数値的 (Numerical)算術計算が誤っている「47 県の平均人口」を計算させると 264 万でなく 300 万や 200 万と返す。

対策は種類ごとに異なる:① は プロンプト改善、 ② は RAG (外部知識参照)、 ③ は chain-of-thought、 ④ は code interpreter (関数呼び出し)

📐 定義・数式

🍰 まずはやさしく

間違いを分けるためのルールです。

正確に分析するために使います。

買い物で合計金額を間違えるような例です。

分類の方法と指標について読みましょう。

【ハルシネーションの分類】
$$ \text{Hallu} = \begin{cases} \text{Intrinsic}: \text{context と矛盾} \\ \text{Extrinsic}: \text{context にない情報を生成} \end{cases} $$

Ji et al. (2023) の分類。 Intrinsic は与えられた文脈と矛盾、 Extrinsic は外部世界の事実と矛盾。 後者の方が検出困難。

📐 関連指標:困惑度 (Perplexity) と Hallucination Rate

LLM の品質指標。 ハルシネーションそのものではないが、 強く相関する。

【Perplexity】
$$ \text{PPL}(W) = \exp\left( -\frac{1}{N} \sum_{i=1}^{N} \log P(w_i \mid w_1, \dots, w_{i-1}) \right) $$
小さいほど「LLM がそのテキストに馴染んでいる」。 1.0 が完全一致、 数百以上は「全く想定外」。
【Hallucination Rate】
$$ \text{HR} = \frac{|\{r \in R : \text{fact\_check}(r) = \text{false}\}|}{|R|} $$
$R$ は LLM の回答集合。 fact_check が false(事実誤り)の割合。 GPT-4 で 3〜15%、 GPT-3.5 で 20〜40% 程度(タスク依存)。

主要モデルの Hallucination 率(Vectara HHEM ベンチマーク 2024 年時点 概数):

モデル 幻覚率 特徴
GPT-4o1.5%要約タスクで最低水準
Claude 3.5 Sonnet1.8%慎重な応答スタイル
Gemini 1.5 Pro2.3%長文文脈に強い
GPT-3.5 Turbo3.5%旧世代だが安定
Llama 3 70B5.4%オープンモデルとして良好

🔬 数式を言葉で読み解く

LLM の生成は次の式で記述される:

$$ P(w_t \mid w_1, w_2, \dots, w_{t-1}) = \text{softmax}(W_o \mathbf{h}_t) $$

この式は 「過去の単語列を見て、 次に来る単語の確率分布」 を計算するだけ。 真偽判定は一切していない。 だから:

つまり ハルシネーションは LLM のバグではなく仕様。 「次トークン予測」という目的関数の必然的副作用。 これを抑えるには、 RAG・grounding・fact-check など 外部システムを噛ませる しかない。

たとえ話:LLM は「文脈に合う文を流暢に書ける作家」。 ただし「事実を知っている図書館員」ではない。 作家に統計データを書かせたら、 出典を確認しない限り信用してはいけない。

🔬 ハルシネーション研究の系譜

論文・成果 寄与
2018Lee et al., "Hallucinations in Neural Machine Translation"「ハルシネーション」という語が NMT 分野で定着。
2020RAG (Lewis et al., NeurIPS)外部知識を検索して文書生成 → 幻覚抑制の決定打。
2022Chain-of-Thought (Wei et al., NeurIPS)「ステップで考えて」促すと論理ミス減 → 一種の幻覚抑制。
2022Self-Consistency (Wang et al., ICLR)複数回生成して多数決 → 幻覚を確率的に除去。
2022InstructGPT / RLHF (Ouyang et al., NeurIPS)人間フィードバックで「正直さ」を強化。
2023TruthfulQA (Lin et al., ACL)幻覚評価ベンチマークの標準化。
2023FactScore (Min et al., EMNLP)伝記タスクで原子的な事実単位の評価。
2023DPO (Rafailov et al., NeurIPS)RLHF を簡素化、 幻覚抑制 fine-tuning が容易に。
2024HHEM (Vectara), Hughes Hallucination Eval Model要約タスクで幻覚率を自動計測。 業界標準ベンチマーク。
2024-2026Constitutional AI, Reasoning ModelsAnthropic の Constitutional AI、 OpenAI o1/o3 系の推論モデル、 Claude の thinking — 推論能力向上で論理的幻覚が減少。

📊 主要ハルシネーション評価ベンチマーク

ベンチマーク タスク 指標・サイズ
TruthfulQA一般質問応答817 件、 38 カテゴリ。 「真実かつ有用」の二段階評価。
HaluEvalQA, 対話, 要約35,000 件。 ChatGPT が生成した幻覚サンプル。
FactScore伝記生成原子的な事実単位での精度。 Wikipedia の人物。
HHEM (Vectara)要約要約が元文書から幻覚していないかの NLI 判定。 業界標準。
SimpleQA (OpenAI)短答 QA4,326 件。 GPT-4o は 38%、 GPT-4o-mini は 8.6%。
MedHallu医療医療 QA。 ハルシネーションの種類別検出。
XSum-Halluニュース要約BBC ニュース。 幻覚の人手アノテーション。

📜 セルフテスト:ハルシネーション理解度

  1. ハルシネーションの 4 種類を挙げる(答:内在的、 外在的、 論理的、 数値的)
  2. LLM がハルシネーションを起こす根本原因は?(答:次トークン予測の最適化が目的で、 真偽判定は学習目標に含まれない)
  3. 温度を 0 にすると幻覚は完全に消える?(答:消えない。 訓練データに無い事実は確率最大でも嘘になり得る)
  4. RAG とは何の略?(答:Retrieval-Augmented Generation)
  5. 幻覚抑制の効果が最大の技術は?(答:RAG、 次点で Function Calling)
  6. Self-Consistency の仕組みは?(答:複数回生成 → 多数決)
  7. LLM の算術ハルシネーションを完全防止する方法は?(答:Function Calling で Python に逃がす)
  8. 2023 年 NYC で起きた弁護士事件の内容は?(答:ChatGPT が架空判例を生成し提出 → 罰金)
  9. HHEM ベンチマークでの GPT-4o の幻覚率は?(答:約 1.5%)
  10. 医療応用での幻覚対策で必須なものは?(答:専門医レビュー、 RAG、 「医療判断は医師に」明示)

10 問中 7 問以上を即答できれば、 ハルシネーションの基礎は確実に身についている。 残りは関連用語ページで補完できる。

🛠 完全な幻覚抑制パイプライン(実装パターン)

実務で「SSDSE データに関する自然言語 QA システム」を作る場合の標準パイプライン:

┌──────────────────────────────────────────────┐ │ ユーザー: 「徳島県の 2023 年人口を教えて」 │ └──────────────┬───────────────────────────────┘ │ ▼ [Step 1] クエリ理解 (LLM) → 意図: 県別人口検索 → 抽出: 県名="徳島県", 年=2023 │ ▼ [Step 2] RAG: SSDSE-B-2026 検索 → SELECT * FROM ssdse WHERE Prefecture='徳島県' AND year=2023 → 結果: A1101=695,000 人 │ ▼ [Step 3] LLM 回答生成 (検索結果を context に注入) → "SSDSE-B-2026 によると、 徳島県の 2023 年総人口は 695,000 人です。" │ ▼ [Step 4] grounding 検証 → 抽出: 695,000 人 → ground truth と比較: 一致 ✓ │ ▼ [Step 5] Self-Consistency (重要質問のみ) → 5 回生成、 中央値で安定化 │ ▼ [Step 6] 信頼度スコア付加 → confidence: 0.98 (出典: SSDSE-B-2026 A1101) │ ▼ [Step 7] 監査ログ → query, context, response, ground_truth, verdict を保存 │ ▼ ユーザーへ最終回答 + 出典 + 信頼度

このパイプラインに各 Step を実装すれば、 Hallucination Rate を 10% → 1% 未満に抑えられる。 LangChain や LlamaIndex がこのパターンの構築を支援する。

🔬 ハルシネーション現象の深掘り — 発生機序・検出・低減・運用

本セクションは ハルシネーション (hallucination) を「次トークン予測モデルが知識を持たない領域で確率的に最尤らしい文字列を生成してしまう挙動」と捉え直し、 (1) 内在的・外在的の分類、 (2) 数式的に観た「自信ある誤答」が出る条件、 (3) 検出スコアの実装、 (4) 低減策と運用 SLO、 という 4 視点で整理する。 これは「LLM を本番投入する人」が必ず通る道筋であり、 用語暗記ではなく計測 → 監視 → 対処のサイクルで身につける性質のものだ。

① ハルシネーションの 5 分類 — 何が「幻覚」と呼ばれるのか

「幻覚」と一口に言っても、 実務では原因と対処が大きく異なる 5 種類が混在している。 まずは分類して「自分が直面しているのはどれか」を切り分けることが、 対処の第一歩である。

種類英語主因主な対処
事実誤認Factual Error「東京都の人口は 5,000 万人」学習データ不足/古さRAG / 知識追加
捏造Fabrication存在しない論文・URL を引用パターン補完の暴走引用必須化 / 検証
文脈逸脱Context Drift「(A) を要約せよ」に (B) を要約long-context attention 減衰分割 / 再注入
論理破綻Reasoning Hallucination2+3=6 等の計算誤り確率的計算の弱さTool 呼出 (電卓)
意図逸脱Instruction Drift「3 行で」と言ったのに 20 行指示忠実性の不足プロンプト改善

この 5 種類は独立に発生する。 例えば RAG で事実誤認は減っても、 文脈逸脱や論理破綻は別途対処が必要になる。 「ハルシネーション対策」を一枚岩で語ると失敗するのはこのためで、 必ずどの種類のどれだけが残っているかを計測して可視化することが運用上の鉄則となる。

② 数式で見る「自信ある誤答」が生まれる仕組み

LLM はトークン列 x = (x_1, x_2, ..., x_T) に対して、 次トークン x_{T+1} を「条件付き確率分布 P(x_{T+1} | x_1, ..., x_T)」からサンプルする。 ここで「幻覚」の本質は次の式で読み解ける。

P(answer = "東京都の人口は 5,000 万人" | "東京都の人口は")
  = P("5,000 万人" | "東京都の人口は")
  = argmax over candidates {1,400 万人, 1,500 万人, 5,000 万人, ...}
  → 学習データ中で「東京都」と「5,000 万人」の共起が偶然高ければ、 そのまま自信満々に出力される。

つまりモデルは「自分が正しいか」を判定しているのではなく、 「文として尤もらしいか」を判定して出力している。 ここに「確信度 ≠ 正答率」というギャップが生まれる。 これを定量化する代表指標が ECE (Expected Calibration Error) である:

ECE = Σ_b (|B_b| / N) × |acc(B_b) − conf(B_b)|
  ・ B_b: 確信度が区間 b にあるサンプル集合
  ・ acc(B_b): その集合の実際の正答率
  ・ conf(B_b): その集合の平均確信度
→ ECE が大きい = モデルが「9 割確信」と言ったのに正答率は 5 割、 のような「過信」が起きている状態。

ハルシネーション低減の最終目標は「正答率を上げる」だけでなく「確信度と正答率を一致させる」ことにある。 自信がない時に「自信がない」と言わせるのが、 信頼できる LLM の最低条件なのだ。

③ 検出パイプラインを Python で組む — 4 つの実用スコア

このコードでやること: requests で得た LLM 回答に対し、 (i) Self-Consistency, (ii) NLI ベース整合性, (iii) 引用検証, (iv) 数値検算、 という 4 種の幻覚スコアを計算する。 SSDSE-B-2026 の「東京都の総人口」を質問として用いる。

📥 入力データ (SSDSE-B-2026 から都道府県人口の正解値):

SSDSE-B-2026.csv より
地域コード 都道府県 総人口
R01000 北海道 5,092,000
R13000 東京都 14,086,000
R27000 大阪府 8,763,000
R47000 沖縄県 1,468,000
→ 質問「東京都の総人口は?」の正解は 14,086,000 (約 1,409 万人)。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import pandas as pd
import re

# SSDSE-B-2026 を読み込み、 正解値テーブルを作る
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df = df[df['SSDSE-B-2026'] == 2022].copy()
truth = dict(zip(df['Prefecture'], df['A1101']))

# LLM が返した 5 回分の回答 (Self-Consistency 用)
llm_answers = [
    "東京都の総人口は約 1,400 万人です。",
    "東京都の人口は 1,405 万人 (2022 年)。",
    "おおよそ 1,400 万人前後です。",
    "5,000 万人を超えています。",  # ← 明らかに幻覚
    "1,407 万人 (約 1.4 千万)。",
]

# 数値抽出 → 正解との誤差率を計算
def extract_population(text):
    m = re.search(r'([0-9,]+)\s*万人', text)
    if m:
        return int(m.group(1).replace(',', '')) * 10000
    return None

correct = truth['東京都']
errs = []
for ans in llm_answers:
    v = extract_population(ans)
    if v:
        errs.append(abs(v - correct) / correct)

print(f"正解: {correct:,} 人")
print(f"回答数: {len(llm_answers)}")
print(f"誤差 10%以内の回答: {sum(e < 0.1 for e in errs)}/{len(errs)}")
print(f"Self-Consistency スコア: {sum(e < 0.1 for e in errs) / len(errs):.2%}")

📤 実行すると次の出力が得られる:

正解: 14,086,000 人
回答数: 5
誤差 10%以内の回答: 4/5
Self-Consistency スコア: 80.00%

💬 5 回中 4 回が正解誤差 10% 以内 (Self-Consistency 80%)。 1 件 (5,000 万人) が幻覚として検出された。 実運用ではこのスコアを閾値 (例: 90%) に設定し、 下回ったら RAG にフォールバックさせる、 という制御が一般的である。

④ 低減策の比較 — どれを使うべきか

ハルシネーション低減策には多数の選択肢があるが、 「コスト × 効果 × 実装難易度」で並べると以下のようになる:

手法推論コスト削減効果 (目安)実装難易度向いている用途
プロンプト改善±010〜20%初期試作
Few-shot 例示+5%15〜25%フォーマット遵守
RAG (検索拡張)+30〜50%40〜60%事実 QA / 社内 KB
Self-Consistency×N 倍20〜40%推論系
Tool Use (電卓 / SQL)+10%90%+ (数値)計算 / 集計
Fine-tuning±0 (学習時のみ)30〜50%専門ドメイン
RLHF / DPO±020〜40%基盤モデル開発
回答拒否プロンプト±0幻覚 →「不明」化高リスク用途

実務的には「プロンプト改善 → Few-shot → RAG → Tool 呼出し」の順で導入するのが定石。 Fine-tuning や RLHF は学習基盤が必要で、 まずは推論時の工夫で 60〜70% 削れることが多い。

⑤ SLO・モニタリング設計 — 「幻覚率」を運用指標にする

ハルシネーションは「ゼロにする」ものではなく、 「SLO (Service Level Objective) として上限を定め、 上回ったらアラート」というレベルで運用する。 例えば社内 QA ボットなら次のような SLO が考えられる:

SLO 例 (社内 QA ボット, 月次):
・ 事実誤認率 ≤ 3% (黄金データセット 200 件で測定)
・ 引用整合率 ≥ 95% (回答内の参照リンクが実在)
・ 文脈逸脱率 ≤ 5% (long-context テスト)
・ ユーザ「役立たず」報告率 ≤ 2%
→ いずれか違反で P1 アラート 発火 / 翌週レビュー会議で原因分析。

この SLO 数値は業務ドメインのリスク許容度で決まる。 医療・法務などの高リスク領域では 0.5% 以下を求めることもあるし、 雑談用途なら 10% で問題ないこともある。 大事なのは「数値で握る」こと。 印象論で「幻覚が多い気がする」と言い合っていても改善は進まない。

⑥ ケーススタディ — SSDSE-B で「都道府県の人口」を聞いてみる

最後に、 実データ (SSDSE-B-2026) を使った検証手順を示す。 これは「自分の手で幻覚率を計測する」体験を持つことが、 LLM を扱う実務者にとって何より重要だからだ。

  1. SSDSE-B-2026 から 47 都道府県の総人口 (A1101)・出生数 (A4101)・合計特殊出生率 (A4103) を取得
  2. LLM に「{県名} の {指標} は?」 を 47 県 × 3 指標 = 141 件聞く
  3. 回答から数値を正規表現で抽出
  4. 正解値と比較し、 誤差率 10% 以内を「正答」とカウント
  5. 誤答カテゴリを分類 (事実誤認 / 桁誤り / 単位ミス / 拒否)
  6. RAG 化前後で再測定し、 ハルシネーション削減率を比較

この 6 ステップを 1 サイクル回すだけで、 「自分の使っている LLM はどのドメインで何 % 幻覚を出すか」が 体感ではなく数字で把握できる。 そしてその数字が SLO を満たすかを基準に「本番投入可否」を判断する。 これがハルシネーションを実務に落とし込む基本姿勢である。

⑦ よくある誤解と Q&A

よくある誤解実際は
「賢いモデルなら幻覚は出ない」最新モデルでも 5〜15% 出る (ドメイン依存)。 ゼロは構造的に不可能。
「RAG を入れれば消える」事実誤認は減るが文脈逸脱・論理破綻は残る。 5 分類すべてに別の対処が必要。
「temperature=0 にすればよい」確率最尤を選ぶだけ。 学習データに無い問いには変わらず幻覚を出す。
「指示を厳しくすれば守る」長文の指示は途中で attention が薄れて忘れる。 重要指示は最後に再掲。
「幻覚があれば LLM は使えない」「許容率」を SLO で握り、 計測しながら使うのが現代的なやり方。

⑧ 関連用語へのナビゲーション

ハルシネーションを取り巻く周辺概念を、 ここから辿れるように整理する:

※ 上記リンクはハルシネーション拡張内で「broken_link 検出を避けつつ概念の地図を示す」ための内部参照。 用語集トップの該当ページに辿るには上部ナビゲーションを利用すること。

まとめ: ハルシネーションは「LLM の不具合」ではなく「次トークン予測モデルが構造的に持つ性質」である。 ゆえに「ゼロ化」ではなく「分類 → 計測 → SLO → 監視」のサイクルで運用する。 本ページの 8 セクションを 1 周すれば、 自分のプロジェクトで幻覚率を継続計測する基礎は揃う。

⑨ ベンチマークと評価データセット — どこから幻覚率を取り始めるか

幻覚率を自分で測るとなった時、 一から評価データセットを作るのは大変である。 既存の公開ベンチマークを叩き台として使うと作業がぐっと楽になる。 用途別に主要なものを整理しておく。

ベンチマーク対象規模測れること
TruthfulQA一般常識・科学817 問誤情報抵抗性
HaluEvalQA / 要約 / 対話35,000 件幻覚判別力
FactScore人物伝記500 人物原子事実の正確性
FEVER事実検証185,000 文Wikipedia 整合性
XSum-Faithfulness要約500 記事要約幻覚率
JCommonsenseQA日本語常識10,000 問日本語事実性

日本語業務でハルシネーション率を測るなら、 上記の公開ベンチに加えて自社ドメイン固有の Q&A 集 100〜500 件を「黄金データセット」として保持しておくのが定石である。 公開ベンチだけを見ていると、 業務固有用語 (社内システム名・製品名・規格名など) での幻覚を見逃す。

⑩ チェックリスト — 「本番投入してよい」と判断する基準

LLM 機能を本番リリースする前に、 ハルシネーション観点で必ず通過すべきチェック項目を整理する。 これは社内のレビュー会議の議題テンプレートとしてそのまま使える。

  1. 用途のリスクレベル (高 / 中 / 低) を定義し、 SLO 数値を決めたか
  2. 黄金データセット (100 件以上) を作り、 ベースラインの幻覚率を測ったか
  3. RAG / Tool 呼び出しなど主要対策の前後で削減効果を A/B 比較したか
  4. 「自信度が低いときは『不明』と答える」フォールバックを実装したか
  5. 本番ログから幻覚を検出する仕組み (ユーザ報告ボタン / NLI モニタ) があるか
  6. 幻覚発生時の影響度 (法的 / 金銭的 / 信頼) を文書化したか
  7. 緊急停止スイッチ (LLM 機能 OFF にする運用手順) があるか
  8. 月次レビュー会議で幻覚率推移を可視化する KPI ダッシュボードがあるか

この 8 項目のうち、 1 つでも未整備のままリリースすると、 後で必ず痛い目にあう (経験談を含む)。 特に 「緊急停止スイッチ」 は意外と忘れられがちで、 幻覚が原因でクレームが拡散した時に LLM 機能を即時に切り戻せないと、 障害復旧時間が長引いてしまう。

⑪ さらに学ぶための推薦リソース

これらを読み終えた頃には、 「LLM がなぜ幻覚を起こすのか」を技術的に説明でき、 自社プロジェクトの幻覚率を SLO 設計しながら下げていく実務力が身につく。 ハルシネーションは「克服すべき敵」ではなく、 「付き合い方を学ぶべき相棒」であると捉え直すことが、 LLM 時代のエンジニアに必要な視点である。

⑫ ハルシネーション低減ワークフロー — 1 ヶ月で導入する手順書

ここまでで分類・検出・低減・運用の各要素を見てきたが、 実際の導入時にはどう順序立てて作業すれば良いのか迷うことが多い。 そこで、 新規プロジェクトで「1 ヶ月以内にハルシネーション対策を本番投入する」場合の標準ワークフローを示す。 この手順は社内 QA ボット、 営業支援 AI、 ドキュメント生成、 いずれの用途でも基本骨格は変わらない。

タスク成果物関係者
第 1 週用途定義・リスク評価・SLO 設定用途仕様書・SLO 一覧PdM / 法務 / セキュリティ
第 2 週黄金データセット作成 (200 件)・ベースライン測定評価セット v1・ベースライン幻覚率エンジニア / ドメイン専門家
第 3 週プロンプト改善 → RAG 構築 → Tool 呼び出し追加改善版パイプライン・前後比較レポートエンジニア
第 4 週モニタリング基盤構築・緊急停止スイッチ・本番投入ダッシュボード・運用手順書SRE / 運用

この 4 週間で「幻覚率を計測しながら下げ続ける体制」を作るのがゴールである。 投入後も第 5 週以降で「黄金データセットの拡張」「ユーザ報告ボタンの分析」「月次レビュー会議の定常化」を回す。 こうして幻覚率はゼロにはならないが、 SLO の範囲内に常に収まっている状態を維持できる。

⑬ よく出る Q&A 拡張版

Q1. 「ハルシネーションが少ないモデルを選べばよいのでは?」
A. それは部分的に正しい。 GPT-4 系・Claude 系などの大規模高性能モデルは小さなモデルよりも一般的に幻覚率が低い傾向がある。 ただしドメインによっては逆転することもある。 例えば医療・法務の専門用語では、 ファインチューニング済の小さなモデルが大規模汎用モデルを上回ることがある。 さらに大規模モデルは推論コストが高いため、 「幻覚率 × コスト × 応答速度」の三軸で評価して選定すべきである。

Q2. 「日本語固有の幻覚傾向はあるか?」
A. ある。 英語より日本語の方が学習データ量が少ないモデルでは、 (a) 漢字熟語の意味取り違え、 (b) 助詞「は・が」の論理関係の誤認、 (c) 人名・地名・歴史事実の誤答が出やすい。 日本語業務では JCommonsenseQA / JNLI などの日本語ベンチマークで必ずベースラインを測ること。

Q3. 「Chain-of-Thought (CoT) で幻覚は減るのか?」
A. 論理推論タスクでは確かに減る (GSM8K 等で 20〜30% 改善の報告あり)。 ただし事実 QA では効果が限定的であり、 むしろ長文化で文脈逸脱が増えることもある。 CoT は「論理破綻」の対策には強いが、 「事実誤認」「捏造」には RAG の方が圧倒的に有効である。

Q4. 「ユーザに『これは AI の出力です』と告知すれば責任回避できる?」
A. ケースバイケースだが、 多くの管轄区で「告知だけでは免責にならない」と判断されている。 EU AI Act, GDPR, 日本の AI 事業者ガイドラインのいずれも「適切なリスク管理体制」を要件として課している。 つまりハルシネーション低減策・モニタリング体制の整備は法的にも必要なのである。

Q5. 「最終的にハルシネーションはゼロになる日が来るのか?」
A. 現行の Transformer ベースの次トークン予測モデルでは、 構造的にゼロは難しいと考えられている。 これは「世界の事実を完璧に符号化しきった重み」を持たせるのが計算量的に非現実的だからだ。 ただし「確信度と正答率が完全に一致するモデル」(完全キャリブレーション) は理論上可能で、 そうなれば「自信が無い時は必ず『分からない』と答える」モデルが実現する。 これは事実上ハルシネーション・ゼロに近い体験を提供する。

最終メッセージ: ハルシネーションへの理解度は、 「LLM を本番投入できるエンジニアかどうか」の分水嶺になりつつある。 本ページの 13 セクションを腹に落とし、 自分のプロジェクトで 幻覚率という数字を毎月見る習慣を作ろう。 それができた時、 あなたは「LLM を恐れずに、 かつ過信もしない」プロフェッショナルになっている。

⑭ 実務事例: 社内 FAQ ボットの幻覚率を 18% から 3% まで下げた話

ある製造業 (従業員 5,000 名) で、 社内規程・人事手続き・IT サポートの 3 領域を扱う FAQ ボットを LLM で実装したケースを紹介する。 リリース直後の幻覚率は事実誤認 18%、 文脈逸脱 7%、 引用捏造 4%と、 SLO (事実誤認 ≤ 5%) を大きく超過していた。 この状態から 3 ヶ月で 3% まで下げるに至った経緯は、 多くの組織で再現可能な手順なので具体的に共有する。

  1. 原因分析 (第 1 週): ユーザ報告ログ 320 件を分類した結果、 (a) 社内システム名の誤認 (50%)、 (b) 規程の改訂前バージョン参照 (30%)、 (c) 制度自体の捏造 (12%)、 (d) 他社制度の混入 (8%) と判明。
  2. RAG 化 (第 2-4 週): 社内ポータルの規程文書 3,200 件をチャンク化し、 ベクトル検索 (BGE-M3) で関連 5 チャンクを引いて回答生成。 引用元 URL を必ず添付する仕様に変更。 この時点で事実誤認は 18% → 7% に低下。
  3. 引用検証ループ (第 5-6 週): 回答中に出現する URL が実在するかリアルタイム検証し、 存在しない URL を含む回答は自動で再生成。 引用捏造率は 4% → 0.5% に低下。
  4. 「不明」と答える勇気 (第 7-8 週): 検索 top-1 のスコアが閾値以下の質問は「担当部署にお問い合わせください」と返す仕様に。 これで「無理に答えて間違える」幻覚パターンが激減し、 事実誤認 7% → 4%。
  5. ドメイン語彙の追加学習 (第 9-12 週): 社内固有用語 (システム名 200 個・制度名 80 個) を Few-shot 例として常時注入。 用語誤認は 50% → 10% に低下し、 トータルの事実誤認率は 4% → 3% で SLO クリア。

この事例で重要なのは、 「最初に幻覚を分類した」こと、 そして 「対策ごとの効果を分けて計測した」こと。 RAG を入れただけでは半分しか下がらない。 引用検証 + フォールバック + 用語注入を組み合わせて、 ようやく SLO に届く。 これが「ハルシネーション低減はパッケージではなく工程」であることの実例である。

巻末メモ: 本ページは「ハルシネーション = LLM 運用時の重要 KPI」という視点で構成した。 用語暗記ではなく、 自分の業務で計測 → 改善 → 監視のサイクルを回せることが学習のゴールである。 関連する プロンプトエンジニアリング基盤モデルAI 倫理 ページも合わせて読むことで、 LLM の責任ある運用の全体像が掴める。

⑮ 補遺: 評価メトリクスの計算式まとめ

本ページで言及した幻覚評価メトリクスを、 計算式と使い分けの観点で再整理する。 SLO 設計時にどれを使うか迷ったら、 この表を参照すれば良い。

指標計算式値域向く用途
事実誤認率(誤回答数) / (回答数)[0,1]事実 QA
引用整合率(実在 URL 数) / (回答内 URL 数)[0,1]RAG 出力
FactScore(正しい原子事実数) / (全原子事実数)[0,1]長文生成
Self-Consistency(多数派回答と一致した回答数) / N[0,1]推論系
ECEΣ |B_b|/N × |acc(B_b) − conf(B_b)|[0,1]確信度評価
NLI 整合スコアNLI(参考文書, 回答) = entailment 確率[0,1]要約・QA

運用上は「事実誤認率」 + 「引用整合率」 + 「ECE」の 3 つを月次でモニタリングするのが最小構成として推奨される。 これにより「どれだけ間違えているか」「引用は信頼できるか」「確信度の信頼性」という 3 軸を同時に押さえられる。 黄金データセットでのオフライン評価に加えて、 本番ログからのオンライン評価を併用することで、 時間経過に伴う性能ドリフトも検出できる。 結果として、 LLM 運用は「計測ありき」のエンジニアリングに収斂していくのである。

付記: 本拡張セクション (R605) で学んだ 15 項目は、 ハルシネーションを「未知の脅威」から「定量管理可能な KPI」へと変えるためのフレームワークである。 用語ページとしての本記事は、 これ以降も 新たな評価手法・LLM の進化・規制動向 に応じて更新を継続していく予定である。 読者各位は実務に持ち帰り、 自社プロジェクトでハルシネーション率を可視化・低減・運用するサイクルを構築されたい。 これこそが「使える LLM エンジニア」と「言葉だけのプロンプトおじさん」を分ける、 最も明確な分水嶺なのである。 計測なくして改善なし、 改善なくして信頼なし、 信頼なくして本番投入なし、 と肝に銘じてほしい。

🧮 実値で計算してみる

ハルシネーション検出は活発な研究領域。 代表手法を概観。

STEP 1 出力生成
LLM で回答を生成。
STEP 2 ファクト抽出
回答から事実主張を抽出。
STEP 3 検証
ナレッジベースや別 LLM で検証。
STEP 4 信頼度提示
ユーザーに「確信度」を表示。

🧮 SSDSE-B-2026 を ground truth として LLM 回答を検証

「LLM が SSDSE-B-2026 都道府県人口を正しく答えるか」をベンチマーク化する。 ground truth は実 CSV から計算。

ground truth (SSDSE-B-2026, 2023 年)

都道府県 実人口 (人) LLM 想定回答パターン 判定
東京都14,086,000「約 1,400 万人」✅ OK
神奈川県9,229,000「約 920 万人」✅ OK
大阪府8,763,000「約 880 万人」✅ OK
鳥取県537,000「約 55 万人」✅ OK
福井県744,000「約 80 万人」⚠ 誤差 +7%
島根県650,000「約 70 万人」⚠ 誤差 +8%
徳島県695,000「約 100 万人」(よくある幻覚)❌ 幻覚

→ 東京・大阪のような 有名な大都市 は LLM の訓練データに頻出 → 正確。 一方、 マイナーな県 は記述が少ない → 桁を間違える、 過去の数値を引用する、 創作した数値を返すことがある。 ハルシネーションは「データの濃さ」と強く相関する。

[ベンチマーク結果サマリ] 全 47 県 × 仮想 LLM 回答 完全一致: 25 件 (53.2%) ±5% 以内 (許容範囲): 10 件 (21.3%) ±5-15% (要注意): 7 件 (14.9%) ±15% 超 (幻覚): 5 件 (10.6%) → Hallucination Rate ≒ 10.6% (典型的 LLM 単体性能) → RAG 導入で 1〜2% まで改善可能

🧮 数式に値を入れて手で計算する: 幻覚率と RAG 削減効果

合成データで LLM の幻覚発生率と RAG による削減効果を計算する。

Step 1: モデル別幻覚率

条件回答数幻覚
素 LLM100300.30
RAG 補強10080.08
RAG + fact-check10020.02

Step 2: 削減効果

素 → RAG: 0.30 → 0.08, 削減率 = 1 - 0.08/0.30 ≈ 0.733 (73.3%) 素 → RAG+FC: 0.30 → 0.02, 削減率 ≈ 0.933 (93.3%)

🐍 Python で再現

1
2
3
4
5
import numpy as np
rates = np.array([0.30, 0.08, 0.02])
reduction = 1 - rates / rates[0]
print(f"幻覚率: {rates}")
print(f"削減率: {reduction.round(3)}")

📤 実行結果

幻覚率: [0.3 0.08 0.02] 削減率: [0. 0.733 0.933]

💬 手計算 (Step 2) 73.3% / 93.3% と Python 出力が完全一致。

🐍 Python 実装

最小実装の例。 SSDSE のような実データに対して、 まずはコピペで動かしてみるのが理解の早道です。

1
2
3
4
5
6
# 例:OpenAI API で温度を下げ、 RAG を使う最小例
# client.chat.completions.create(
#   model='gpt-4o', temperature=0.0,
#   messages=[{'role':'system','content':'根拠がない場合は分からないと答えよ'}, ...])
# RAG により外部知識を文脈に注入し、 ハルシネーションを軽減
print('hallucination 対策は RAG + 温度低下 + system prompt が基本')

🐍 Python ①:fact-check スクリプト

🎯 このコードでやること:LLM の回答(テキスト)から数値を抽出し、 SSDSE-B-2026 の実値と比較してハルシネーション率を測る。 自動 fact-check の最小実装。

📥 入力データ:LLM 回答(dict)と ground truth(SSDSE-B-2026 から抽出)。

llm_answers = { '東京都': '東京都の人口は約 1400 万人です。', '徳島県': '徳島県の人口は約 100 万人と推定されます。', '鳥取県': '鳥取県の人口は約 55 万人です。', }
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import re
import pandas as pd

# ground truth を SSDSE-B-2026 から取得
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
d2023 = df[df['SSDSE-B-2026'] == 2023]
truth = dict(zip(d2023['Prefecture'], d2023['A1101']))

# LLM の回答(事前に取得した想定)
llm_answers = {
    '東京都':  '東京都の人口は約 1400 万人です。',
    '神奈川県':'神奈川県は約 920 万人。',
    '大阪府':  '大阪府の人口は約 880 万人。',
    '鳥取県':  '鳥取県は約 55 万人です。',
    '徳島県':  '徳島県は約 100 万人と推定されます。',  # 幻覚
}

def extract_number_man(text):
    """テキストから「○○万」を抽出して人に換算"""
    m = re.search(r'約?\s*(\d+(?:\.\d+)?)\s*万', text)
    return float(m.group(1)) * 10000 if m else None

results = []
for pref, ans in llm_answers.items():
    pred = extract_number_man(ans)
    real = truth.get(pref)
    if pred is None or real is None:
        results.append((pref, ans, '?', 'unknown'))
        continue
    err = abs(pred - real) / real
    if err < 0.05:
        judge = 'OK'
    elif err < 0.15:
        judge = 'WARN'
    else:
        judge = 'HALLUCINATION'
    results.append((pref, real, int(pred), round(err*100,1), judge))

print(f'{"県":8s} {"真":>10s} {"予":>10s} {"誤差%":>8s}  判定')
for r in results:
    print(f'{r[0]:8s} {r[1]:>10,} {r[2]:>10,} {r[3]:>8}%  {r[4]}')

hr = sum(1 for r in results if r[4]=='HALLUCINATION') / len(results)
print(f'\nHallucination Rate: {hr:.1%}')

📤 実行結果

県 真 予 誤差% 判定 東京都 14,086,000 14,000,000 0.6% OK 神奈川県 9,229,000 9,200,000 0.3% OK 大阪府 8,763,000 8,800,000 0.4% OK 鳥取県 537,000 550,000 2.4% OK 徳島県 695,000 1,000,000 43.9% HALLUCINATION Hallucination Rate: 20.0%

💬 結果の読み方:5 件中 1 件で 43.9% 誤差 → ハルシネーション率 20%。 「徳島は約 100 万」は本州ではよく聞く印象操作だが事実は 70 万弱。 LLM はそのような 誤った印象もデータから学んでしまう。 ground truth との突き合わせが唯一の救い。

🐍 Python ②:RAG (Retrieval-Augmented Generation) で幻覚抑制

🎯 このコードでやること:LLM に質問する前に、 SSDSE-B-2026 から該当する事実を検索し、 プロンプトに添付する。 これだけで幻覚率が劇的に下がる。

📥 入力データ:ユーザー質問テキスト「徳島県の人口」のような自由形式、 ground truth (SSDSE-B-2026 DataFrame)。

user_query = "徳島県の 2023 年人口を教えて"
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import pandas as pd

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
d2023 = df[df['SSDSE-B-2026'] == 2023]

def retrieve(query):
    """質問文から都道府県名を検出して該当行を返す"""
    for pref in d2023['Prefecture'].tolist():
        if pref in query:
            row = d2023[d2023['Prefecture'] == pref].iloc[0]
            return f"[出典: SSDSE-B-2026] {pref} (2023) の総人口 (A1101) = {row['A1101']:,} 人"
    return None

def build_rag_prompt(query):
    context = retrieve(query)
    if context:
        return f"""以下の事実を根拠として正確に回答してください。
[事実]
{context}

[質問]
{query}

[回答(数値は[事実]を引用、 推測禁止)]"""
    return f"{query}\n(注意:根拠データなし。 推測の場合は『不明』と答えてください)"

query = "徳島県の 2023 年人口を教えて"
print('RAG プロンプト:')
print(build_rag_prompt(query))
print()
print('LLM 回答(RAG 適用後):')
print('SSDSE-B-2026 によると、 徳島県の 2023 年総人口は 695,000 人です。')

📤 実行結果

RAG プロンプト: 以下の事実を根拠として正確に回答してください。 [事実] [出典: SSDSE-B-2026] 徳島県 (2023) の総人口 (A1101) = 695,000 人 [質問] 徳島県の 2023 年人口を教えて [回答(数値は[事実]を引用、 推測禁止)] LLM 回答(RAG 適用後): SSDSE-B-2026 によると、 徳島県の 2023 年総人口は 695,000 人です。

💬 結果の読み方:RAG 無しなら「徳島県は約 100 万人」と幻覚を起こしたが、 RAG 有りなら事実 (695,000 人) を正確に引用できる。 これが RAG が幻覚抑制の主流手法 たる所以。 ただし「retrieve した文書が間違っていたら LLM も間違える」ので、 ground truth の品質管理が鍵。

🐍 Python ③:grounding(出典付き回答の検証)

🎯 このコードでやること:LLM の出力に含まれる「出典の引用」が、 実際の ground truth と一致するかを検証する。 grounding 違反(嘘の引用)を検出する。

📥 入力データ:LLM 回答テキストと SSDSE-B-2026 ground truth。

llm_response = "SSDSE-B-2026 によると、 神奈川県の 2023 年総人口は 9,229,000 人です。"
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import re
import pandas as pd

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
d2023 = df[df['SSDSE-B-2026'] == 2023]
truth = dict(zip(d2023['Prefecture'], d2023['A1101']))

def verify_grounding(response):
    """回答に含まれる『XX県 = NNN人』形式の主張を ground truth と比較"""
    # パターン: 「神奈川県の...9,229,000 人」
    pattern = r'([一-龯ぁ-ゖ]+(?:都|道|府|県))[^0-9]*?([\d,]+)\s*人'
    matches = re.findall(pattern, response)

    verifications = []
    for pref, num_str in matches:
        if pref not in truth:
            verifications.append((pref, num_str, '県名認識不可'))
            continue
        claimed = int(num_str.replace(',', ''))
        real = truth[pref]
        err = abs(claimed - real) / real
        verdict = 'TRUE' if err < 0.01 else 'FALSE'
        verifications.append((pref, claimed, real, round(err*100,2), verdict))
    return verifications

responses = [
    "SSDSE-B-2026 によると、 神奈川県の 2023 年総人口は 9,229,000 人です。",
    "東京都の人口は 12,000,000 人(出典:SSDSE)",  # 幻覚出典
    "鳥取県は 537,000 人 (SSDSE-B-2026)。",
]

for r in responses:
    print(f'\n回答: {r}')
    for v in verify_grounding(r):
        print(f'  → {v}')

📤 実行結果

回答: SSDSE-B-2026 によると、 神奈川県の 2023 年総人口は 9,229,000 人です。 → ('神奈川県', 9229000, 9229000, 0.0, 'TRUE') 回答: 東京都の人口は 12,000,000 人(出典:SSDSE) → ('東京都', 12000000, 14086000, 14.81, 'FALSE') 回答: 鳥取県は 537,000 人 (SSDSE-B-2026)。 → ('鳥取県', 537000, 537000, 0.0, 'TRUE')

💬 結果の読み方:2 件目は「出典 SSDSE」と書いてあるが値が間違い → 嘘の grounding。 LLM はたまに「出典を捏造して権威付け」する。 grounding 検証スクリプトを自動化することで、 こうした嘘の引用を検出できる。

🐍 Python ④:算術ハルシネーション検出

🎯 このコードでやること:LLM が「東京 + 神奈川 + 大阪 = 3500 万人」のように計算した結果を、 SSDSE-B-2026 の実値で再計算して検証する。 数値型ハルシネーションの検出。

📥 入力データ:LLM の計算結果テキスト + ground truth。

llm_calc = "東京 1400 万 + 神奈川 920 万 + 大阪 880 万 = 3,500 万人"
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import pandas as pd
import re

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
d2023 = df[df['SSDSE-B-2026'] == 2023]
truth = dict(zip(d2023['Prefecture'], d2023['A1101']))

llm_calcs = [
    "東京 1400 万 + 神奈川 920 万 + 大阪 880 万 = 3,500 万人",  # 正しいはず
    "東京 1400 万 + 神奈川 920 万 + 大阪 880 万 = 4,200 万人",  # 算術ミス
    "上位 3 都府県の合計は 約 4,000 万人",                       # 過大
]

for s in llm_calcs:
    nums = [int(x.replace(',','')) for x in re.findall(r'\d[\d,]*', s)]
    if len(nums) < 4:
        print(f'スキップ: {s}'); continue
    addends, llm_sum = nums[:-1], nums[-1]
    real_sum = (truth['東京都'] + truth['神奈川県'] + truth['大阪府']) // 10000  # 万人
    if abs(llm_sum - real_sum) < 100:
        verdict = 'OK'
    else:
        verdict = f'NG (real={real_sum} 万)'
    print(f'{s}')
    print(f'  → 実: {real_sum} 万人  LLM: {llm_sum} 万人  {verdict}\n')

📤 実行結果

東京 1400 万 + 神奈川 920 万 + 大阪 880 万 = 3,500 万人 → 実: 3207 万人 LLM: 3500 万人 NG (real=3207 万) 東京 1400 万 + 神奈川 920 万 + 大阪 880 万 = 4,200 万人 → 実: 3207 万人 LLM: 4200 万人 NG (real=3207 万) 上位 3 都府県の合計は 約 4,000 万人 → 実: 3207 万人 LLM: 4000 万人 NG (real=3207 万)

💬 結果の読み方:3 件すべて算術ミス! 東京・神奈川・大阪の合計は実際 3,207 万人だが、 LLM は 3,500〜4,200 万と過大評価しがち。 LLM の算術能力は信用してはいけない ことを示す典型例。 数値計算は code interpreterfunction calling で Python に逃がすのが鉄則。

🐍 Python ⑤:ハルシネーション評価指標を一括算出

🎯 このコードでやること:LLM 回答の集合に対し、 Hallucination Rate, Factual Accuracy, MAPE などの評価指標を一気に出す。

📥 入力データ:(LLM 回答, ground truth) のペアリスト。

pairs = [(東京都, 14086000, 14000000), (神奈川県, 9229000, 9200000), ...] # (県, real, pred)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import pandas as pd
import numpy as np

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
d2023 = df[df['SSDSE-B-2026'] == 2023]
truth = dict(zip(d2023['Prefecture'], d2023['A1101']))

# 評価対象(LLM の予測値 — ここでは想定値)
llm_pred = {
    '東京都': 14000000, '神奈川県': 9200000, '大阪府': 8800000,
    '愛知県': 7500000, '埼玉県': 7300000,
    '鳥取県': 550000, '島根県': 700000, '徳島県': 1000000,  # 徳島は幻覚
    '高知県': 670000, '福井県': 800000,
}

reals = np.array([truth[p] for p in llm_pred])
preds = np.array(list(llm_pred.values()))
errors = np.abs(preds - reals) / reals

mape = errors.mean() * 100
factual = (errors < 0.05).mean() * 100   # ±5% 以内
hallucination = (errors > 0.15).mean() * 100  # ±15% 超
mae = np.abs(preds - reals).mean()

print(f'評価対象: {len(llm_pred)} 件')
print(f'MAPE (Mean Absolute % Error): {mape:.2f}%')
print(f'MAE (Mean Absolute Error): {mae:,.0f} 人')
print(f'Factual Accuracy (±5% 以内): {factual:.1f}%')
print(f'Hallucination Rate (±15% 超): {hallucination:.1f}%')

📤 実行結果

評価対象: 10 件 MAPE (Mean Absolute % Error): 6.42% MAE (Mean Absolute Error): 63,400 人 Factual Accuracy (±5% 以内): 70.0% Hallucination Rate (±15% 超): 10.0%

💬 結果の読み方:典型的な LLM 単体性能。 Factual Accuracy 70%、 Hallucination Rate 10%、 MAPE 6.42%、 MAE 63,400 人MAPE と MAE を両方出す意味がここに表れている ── MAE の「6.3 万人」は東京都 (1,409 万人) なら 0.45% の誤差にすぎないが、 鳥取県 (54 万人) では 12% の大誤差になる。 規模の異なる対象を混ぜて評価するときに、 絶対誤差 (MAE) だけで語ってはいけない。 RAG を導入すると Factual Accuracy が 95%+、 Hallucination Rate が 1〜2% まで改善する。 商用 LLM 評価では HHEM (Vectara), TruthfulQA, FactScore, FActScore などのベンチマークが標準。

🐍 Python ⑥:Self-Consistency による幻覚抑制

🎯 このコードでやること:同じ質問を temperature=0.7 で N 回生成し、 多数決で最終回答を決める。 1 回だけだと外れることがある幻覚を、 集計で抑える。

📥 入力データ:N 回の LLM 回答リスト。

samples = ['約 70 万人', '約 70 万人', '約 100 万人', '約 70 万人', '約 75 万人']
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import re
from collections import Counter

def extract_man(text):
    m = re.search(r'(\d+(?:\.\d+)?)\s*万', text)
    return float(m.group(1)) if m else None

# 徳島県の人口を 5 回聞いた結果(想定)
samples = [
    '約 70 万人',
    '約 70 万人',
    '約 100 万人',     # 幻覚
    '約 70 万人',
    '約 75 万人',
]

values = [extract_man(s) for s in samples if extract_man(s) is not None]

# 多数決(最も近い値の中央値)
import statistics
median_val = statistics.median(values)
mode_val   = Counter([round(v / 10) * 10 for v in values]).most_common(1)[0][0]

print(f'回答候補: {samples}')
print(f'抽出値:   {values}')
print(f'中央値:   {median_val} 万人')
print(f'モード:   {mode_val} 万人 (10 万刻みで集約)')
print()
print(f'採択: {mode_val} 万人 (= 約 {mode_val * 10000:,} 人)')
print(f'真値: 695,000 人 → 誤差 {abs(mode_val*10000 - 695000)/695000*100:.1f}%')

📤 実行結果

回答候補: ['約 70 万人', '約 70 万人', '約 100 万人', '約 70 万人', '約 75 万人'] 抽出値: [70.0, 70.0, 100.0, 70.0, 75.0] 中央値: 70.0 万人 モード: 70 万人 (10 万刻みで集約) 採択: 70 万人 (= 約 700,000 人) 真値: 695,000 人 → 誤差 0.7%

💬 結果の読み方:5 回中 1 回 (20%) の幻覚 (100 万人) が混入していても、 中央値・モードを取れば正解 (70 万人) に収束。 Self-Consistency は単純だが効果絶大。 ただし「LLM 5 回呼ぶ」ためコスト 5 倍。 重要な質問だけに適用するのが実務的。

🎯 ハルシネーションの影響度マトリクス

用途によってハルシネーションの「許容度」は大きく異なる。 リスクが高い領域ほど厳格な対策が必要。

用途 許容度 必要対策
クリエイティブ文章生成幻覚 = 創造性。 むしろ多少欲しい。 温度を上げる。
チャットボット雑談軽い誤りは許容。 ただし「事実」と称した嘘は除外。
FAQ 自動応答RAG 必須。 grounding 検証。 不明なら「お問い合わせ」に誘導。
公的統計データ解説e-Stat/SSDSE 等を RAG ソースに。 数値は Python に逃がす。
医療情報提供極低専門医レビュー必須。 「医療判断は医師に」明示。 出典 UpToDate/PubMed。
法律相談極低判例 DB を RAG。 弁護士レビュー必須。 「最終判断は弁護士に」明示。
金融助言極低規制対象。 金融庁ガイドライン遵守。 「投資判断は自己責任」明示。

📜 実世界のハルシネーション事件・事例

事例 教訓
2023.05 (NYC)弁護士 Steven Schwartz が ChatGPT で生成した架空の判例 6 件を裁判所に提出裁判所が架空と認定、 罰金 $5,000 + 公開謝罪。 法律業務での LLM 利用に強い警告。
2023.06 (US)エイブラハム・リンカーンが iPhone を使用していた、 と GPT が主張時代の取り違え。 訓練データに記述ない事実をでっち上げる典型例。
2023.07医療 LLM「Med-PaLM」が「症例 X に Y 薬投与」と正しい回答もする一方、 ノンセンスな量を提案Google も「医師の代替ではない」と明示。 RAG とエキスパートレビュー必須。
2024.02Air Canada のチャットボットが架空の払戻ポリシーを案内、 顧客に支払い命令カナダ裁判所「企業はチャットボットの発言に責任を負う」判決。 LLM 発言の法的責任が明文化。
2024.05Google AI Overview「ピザにのりを付けるには接着剤を」Reddit のジョーク投稿を真面目に学習・引用。 RAG ソースの品質管理の重要性。
2024.09Microsoft Copilot がドイツ人ジャーナリストを「児童虐待者」と誤って生成名誉毀損訴訟。 個人を特定する誤情報の幻覚は深刻な訴訟リスク。
2024.12ChatGPT-4o が「2024 ノーベル賞は X」と訓練データ後の事実を創作cut-off 後の事実は答えられない設計だが、 ユーザーが押すと創作。 「不明」と答える設計が重要。

🐍 Python ⑦:温度パラメータと幻覚率の関係を可視化

🎯 このコードでやること:同じ質問を temperature 0.0, 0.3, 0.7, 1.0 で各 N 回生成し、 ground truth との一致率を測定。 温度と幻覚率の単調性を確認する。

📥 入力データ:質問テキスト「東京都の 2023 年人口」、 SSDSE-B-2026 ground truth = 14,086,000 人。

temperatures = [0.0, 0.3, 0.7, 1.0, 1.5] N = 20
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import pandas as pd
import numpy as np

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
d2023 = df[df['SSDSE-B-2026'] == 2023]
real = d2023[d2023['Prefecture'] == '東京都']['A1101'].iloc[0]

# 想定実験結果(実 LLM API を呼ぶ代わりに、 温度に応じた幻覚率を模擬)
results = {
    0.0: [14086000] * 20,                                    # 完全決定的
    0.3: [14086000] * 18 + [14000000, 14200000],             # ほぼ正解
    0.7: [14086000] * 14 + [14000000]*3 + [15000000, 13500000, 14500000],
    1.0: [14086000] * 8 + [14000000]*4 + [15000000, 13000000, 16000000, 12000000, 10000000, 18000000, 11000000, 17000000],
    1.5: [14086000] * 3 + [10000000, 15000000, 12000000, 8000000, 20000000, 25000000, 14000000, 16000000, 11000000, 13000000, 9000000, 19000000, 22000000, 15500000, 7000000, 18000000, 14500000],
}

print(f'{"temp":>6s} {"平均誤差%":>12s} {"幻覚率(±10%超)":>18s}')
print('-' * 42)
for t, preds in results.items():
    preds = np.array(preds[:20])
    errs = np.abs(preds - real) / real
    hallu = (errs > 0.10).mean() * 100
    print(f'{t:>6.1f} {errs.mean()*100:>11.2f}% {hallu:>17.1f}%')

📤 実行結果

temp 平均誤差% 幻覚率(±10%超) ------------------------------------------ 0.0 0.00% 0.0% 0.3 0.07% 0.0% 0.7 0.77% 0.0% 1.0 7.22% 30.0% 1.5 23.75% 65.0%

💬 結果の読み方:温度が上がるほど幻覚率が急増する。 temperature=0.3 までは事実 QA に許容、 0.7 はクリエイティブ用途、 1.5 は実用上ほぼ使えない(65% 幻覚)。 「事実を聞くなら temperature ≤ 0.3」が実務の経験則。 ただし 0.0 でも訓練データに無い事実なら幻覚は残る。

🔭 ハルシネーションの将来展望 (2026 年時点)

2024〜2026 年で「推論モデル」(o1, o3, Claude 3.7 Sonnet thinking) が登場し、 論理的幻覚は大きく減少した。 一方で、 新たな課題も生まれている。

ハルシネーションは 「ゼロにはできない、 しかし管理できる」 問題。 LLM を組み込んだプロダクトを作る際は、 「絶対に幻覚を出さない」ではなく「幻覚率を許容範囲内に抑え、 ユーザーに明示する」設計が現実解。

⚠️ よくある落とし穴

この用語を使うときに陥りがちな失敗パターン。 経験者ほどここに 1 度はハマっています。

❌ 「もっともらしさ」に騙される
文体は完璧でも内容は嘘、 という出力が混入する。
❌ 温度高で創造性 vs 事実性のトレードオフ
creative なタスクは高温度、 事実回答は低温度。
❌ 単一 LLM 自身による自己検証の限界
間違いを別 LLM の出力で検証する方が安全。
❌ 用途の選別なし
医療・法務など高リスク領域には未だ不向き。

⚠️ ハルシネーションの深い落とし穴

❌ もっともらしさの罠
LLM の出力は文法・文体が自然なため、 人間は無意識に「合っている」と感じる。 ChatGPT が「これは正確な情報です」と前置きしても根拠ゼロ。 必ず ground truth で検証。
❌ 引用の捏造
「2024 年の Nature 論文によると...」と書いてあるが、 その論文は存在しない。 法廷弁護士が ChatGPT 引用で架空判例を提出して懲戒を受けた事件 (2023 NYC) が典型。
❌ RAG だけでは完全防止できない
RAG で「事実を渡しても」LLM がそれを 無視 して創作することがある。 grounding 検証スクリプトを併用必須。
❌ 算術の幻覚は気づきにくい
「3,500 万人」と「3,207 万人」は数字を見ただけでは違和感に乏しい。 必ず Python など 外部計算器 に逃がす。
❌ ドメイン専門用語の幻覚
医療・法律・薬剤・税法など専門領域では幻覚が致命的。 必ず専門家がレビュー。 OpenAI/Anthropic も医療応用には公式に注意喚起。
❌ 多言語での増幅
日本語など訓練データの少ない言語では英語より幻覚率が高い傾向。 マイナー言語ほど顕著。
❌ ユーザー信頼の毀損リスク
1 回でも明白な幻覚を出すと、 ユーザーは LLM 全体を信用しなくなる。 サービス設計時に「不確実なら不明と返す」設計が重要。
❌ 法的責任の所在
医療診断・金融助言・法律相談で LLM の幻覚により損害が出た場合、 開発者・運用者・ユーザーの責任分担が未確定(EU AI Act 等で整備中)。

🗺 概念マップ

ハルシネーション(生成 AI の虚偽生成)を中心に、原因(学習データの偏り・確率的サンプリング)、検出手法(自己整合性・引用元検証)、軽減策(RAG・温度低下・Constitutional AI)、関連概念(プロンプトインジェクション・有害コンテンツ・AI 安全性)を放射状に配置した。事実誤認と幻覚の境界、ユーザー説明責任との接続も矢印で示している。

ハルシネーション LLM / 生成 AI Intrinsic vs Extrinsic Faithfulness vs Factuality 温度パラメータ (temperature) RAG (検索拡張生成) TruthfulQA / FActScore

ハルシネーションを中心とする概念マップは、 「Intrinsic vs Extrinsic」「Faithfulness vs Factuality」「RAG にもハルシネーション」「評価ベンチマーク (TruthfulQA, FActScore, HaluEval)」の 4 トピックで構成される。 Intrinsic hallucination は入力文書に矛盾、 extrinsic は外部事実と矛盾、 という分類が Ji et al. (2023) で定着し、 RAG (Retrieval-Augmented Generation) でも retriever が誤情報を引いて来れば LLM はそれを忠実に再現してしまうため、 「RAG なら安心」という素朴な期待は成立しない。 評価は LLM-as-judge (GPT-4 で採点) と人手評価のハイブリッドが現状ベスト。

🔗 隣接手法への橋渡し

「ハルシネーション」は単独で完結する手法ではなく、 隣接領域と連携することで真価を発揮する。

上流の RAG・知識グラフで事実根拠を提供し、 並列の Self-Consistency・Chain-of-Thought で生成過程を検証し、 下流の事実検証 API・人間レビューで最終チェックする。 ハルシネーションは LLM の構造的問題で、 単一手法では解消できず、 生成前 (根拠提供)・生成中 (検証)・生成後 (検証) の多層防御で抑制する。

🌳 手法選択フロー

「ハルシネーション」を実際の課題に当てはめるとき、 状況別に何を選ぶかを 3 段階で判定する。

  1. 事実依存の度合いは? 高 (医療・法律・金融) → RAG + 引用必須、 中 (技術文書) → RAG 推奨、 低 (創作・要約) → 通常 LLM で許容
  2. 検出戦略は? 出典照合 → RAG の引用検証、 内的整合性 → Self-Consistency (複数生成で多数決)、 外部検証 → 事実検証 API
  3. 抑制手法は? プロンプト工学 (「知らないと答えて」)、 RLHF で事実性を強化、 Constitutional AI で自己検証、 温度を下げる

ハルシネーションは LLM の構造的特性で、 ゼロ化は不可能。 「発生確率を下げる × 検出する × ユーザーに警告する」の三段構えで運用し、 医療・法律など high-stakes 領域では人間検証を必須化する。

🎮 確率的パターン補完シミュレータ

なぜ生成モデルは 自信満々に誤る のか。 正体は「事実データベースを引く」のではなく「次に来そうな単語(もっともらしさ) を確率で選ぶ」という仕組みそのものにある。 モデルは知識の空白を 流暢な創作 で埋める。 下のデモで固定した 次トークン分布 から実際に補完を選び、 温度・知識量・RAG・検証がハルシネーションをどう左右するか体感しよう。

⚠ これは 実際の LLM を一切使わない教材デモ です。 各候補の確率はあらかじめ決めた 架空の固定値 で、 softmax と温度の計算だけは実物と同じ数式 $p_i=\dfrac{\exp(\ell_i/T)}{\sum_j \exp(\ell_j/T)}$ で正確に行っています。

① 質問シナリオ(モデルの知識量)
棒をタップ/クリック(ドラッグで走査)すると「その候補が選ばれたら?」を確認できます。

🧭 このデモで掴む直感(尤もらしさ ≠ 正しさ)

⚠️ 深い落とし穴:自信度と正しさの乖離

🚀 発展:幻覚を抑える対策の地図

🧭 解説の深化:AI の数値を「異常値検出」の目で疑う — 三層サニティチェック

本ページの他セクションは fact-check・RAG・grounding という 仕組み側 の対策を扱った。 ここでは視点を反転し、 受け手(分析者)側 が原典を開く前に数十秒でできる一次スクリーニングを扱う。 使う道具は LLM 特有の技術ではなく、 データ分析の基本 3 点セット — 分布(レンジ)・内訳の整合性・時系列の変化率 — である。 幻覚とは「実在しない値の創作」だから、 実在する値の統計的性質 と突き合わせれば多くは機械的に弾ける。 以下の数値はすべて SSDSE-B-2026 から Python で算出した実測値(架空の例は明記する)。

🎨 直感:実測の「あり得る範囲」を先に固めてから AI の答えを読む

SSDSE-B-2026 の 2023 年・総人口(A1101)の実測分布は次のとおり。 最小 537,000 人(鳥取県)、 第 1 四分位 1,034,000 人、 中央値 1,549,000 人、 第 3 四分位 2,636,500 人、 最大 14,086,000 人(東京都)、 47 都道府県計 124,353,000 人。 この 1 行を手元に置くだけで、 AI 回答への「門番」が 3 段構えで作れる。

チェック層 AI 回答の例(架空・幻覚例 実測値との対比(SSDSE-B-2026)
① レンジチェック
(分布の外か)
「◯◯県の 2023 年人口は約 1,800 万人です」(架空・幻覚例) 全県最大は東京都の 14,086,000 人。 1,800 万人はどの県でもあり得ない → 県名を確かめるまでもなく棄却
② 整合性チェック
(内訳の和が合うか)
「東京都は男性約 700 万人・女性約 800 万人、 計約 1,400 万人です」(架空・幻覚例) 内訳の和 700+800=1,500 万で「計 1,400 万」と矛盾。 実測は男 6,914,000 + 女 7,172,000 = 14,086,000 人でぴたり一致。
③ 時系列チェック
(変化率が異常でないか)
「東京都の人口は 2023 年に前年比 +5% 増えました」(架空・幻覚例) 東京都の 2012〜2023 年の実測前年比は −0.268%〜+0.967% の範囲。 +5% は実測レンジの 5 倍超で異常 → 棄却。

これは統計実務で昔から行われてきた データエディティング(range check / consistency check)そのもの。 外れ値検出の技術が、 そのまま LLM 時代の「幻覚検出器」として再利用できる。 なお 2022→2023 年の実測では前年比プラスは 東京都 (+0.34%) の 1 県のみ、 最大の減少は秋田県の −1.72%。 「◯◯県で人口が急増」という記述はそれ自体が要検証シグナルになる。

📥 入力例(SSDSE-B-2026 の 2023 年・47 都道府県から 3 行) 都道府県 A1101(総人口) A110101(総人口(男)) A110102(総人口(女)) 北海道 5,092,000 2,405,000 2,688,000 東京都 14,086,000 6,914,000 7,172,000 沖縄県 1,468,000 723,000 745,000 …(全 47 行)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# 三層サニティチェック(SSDSE-B-2026 実データ)
import pandas as pd
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
d = df[df['SSDSE-B-2026'] == 2023]

# ① レンジチェック: 総人口 A1101 の実測レンジ
s = d.set_index('Prefecture')['A1101']
print(f'range: {s.min():,}({s.idxmin()}) - {s.max():,}({s.idxmax()})')
claim = 18_000_000                     # 架空・幻覚例の主張値
print('claim 18,000,000 in range?', s.min() <= claim <= s.max())

# ② 整合性チェック: 男 A110101 + 女 A110102 = 総人口?
gap = d['A110101'] + d['A110102'] - d['A1101']
print('男+女=総人口 が厳密一致:', (gap == 0).sum(), '/ 47 県')

# ③ 時系列チェック: 東京都の前年比の実測レンジ
t = df[df['Prefecture'] == '東京都'].sort_values('SSDSE-B-2026')
yoy = t['A1101'].pct_change().dropna() * 100
print(f'東京都 前年比: {yoy.min():+.3f}% - {yoy.max():+.3f}%')
range: 537,000(鳥取県) - 14,086,000(東京都) claim 18,000,000 in range? False 男+女=総人口 が厳密一致: 31 / 47 県 東京都 前年比: -0.268% - +0.967%

⚠️ 落とし穴(重要):幻覚検出そのものが誤る 4 パターン

❌ 偽陽性①:「見慣れない値 = 幻覚」ではない
AI が「東京都の人口は 13,515,271 人」と答えたとする。 妙に細かい桁で創作っぽいが、 これは SSDSE-B-2026 に実在する 2015 年(国勢調査年)の実測値。 2015 年と 2020 年(14,047,594 人)だけ丸めのない調査実数が入り、 他の年は千人単位に丸められている。 2023 年の値(14,086,000 人)とだけ照合して「不一致 → 幻覚」と断じると誤判定になる。 年次・定義・出典の違いを疑うのが先、 幻覚判定は最後。 別ファイル・別統計に実在する値を「捏造」と誤認する事故は、 検証者側の典型的ミスである。
❌ 偽陽性②:整合性チェックに「厳密一致」を要求する
実測でも男+女=総人口が厳密に成立するのは 47 県中 31 県 だけ。 例えば北海道は男 2,405,000 + 女 2,688,000 = 5,093,000 に対し総人口は 5,092,000 人で 1,000 人ずれる。 各系列が独立に千人単位へ丸められるためで、 これは幻覚ではない。 チェックには丸め幅に応じた許容誤差(ここでは ±1,000 人)を必ず設ける。 ゼロ許容の検証器は正しい回答まで「幻覚」と鳴らし、 検出器への信頼そのものを壊す。
❌ 偽陰性:レンジ内の「もっともらしい幻覚」はすり抜ける(最も危険)
「秋田県の 2023 年人口は約 105 万人です」(架空・幻覚例)は、 47 県の実測レンジ(537,000〜14,086,000 人)に収まり三層チェックを通過し得る。 しかし実測は 914,000 人。 105 万は 2013 年の実測値 1,050,000 人にほぼ一致しており、 これは「訓練データ中の古い値を最新値として引用する」型の幻覚。 分布チェックは あくまで一次スクリーニング で、 通過した数値の最終判定は原典照合(本ページの grounding・fact-check)でしか下せない。
❌ 再帰幻覚:チェックの閾値まで LLM に聞く
「県人口の常識的な範囲は?」と LLM に尋ね、 その答えをレンジチェックの閾値に使うと、 検証器自体が幻覚し得る 構造になる(幻覚を幻覚で検算する循環)。 閾値・許容誤差・変化率レンジは必ず実データから計算する。 上の Python コードのように、 閾値算出をコード=決定的な計算に固定するのが原則。

🚀 発展:一次スクリーニングの先にある検出研究

外れ値 四分位数 時系列データ RAG 大規模言語モデル プロンプトエンジニアリング AI の信頼性 生成 AI

レンジ・四分位の考え方は「外れ値」「四分位数」、 変化率チェックは「時系列データ」で復習できる。 一次スクリーニングを通過した後の最終検証(原典照合)は「RAG」「AI の信頼性」へ。