0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ハルシネーションを検出・抑制するためのプロンプトと検証フロー

0
Last updated at Posted at 2026-11-03

生成AIを技術調査やドキュメント作成に使うとき、最も扱いに困るのがハルシネーションです。もっともらしい説明の中に、存在しないAPIや誤ったバージョン情報が混ざると、レビューに気づかれないまま実装へ進んでしまいます。

私が実際に試して効果を感じたのは、プロンプトだけで「正しい回答」を引き出そうとする方法ではありません。回答を構造化し、根拠と不確実性を出力させ、最後に機械的・人手で検証する流れを作ることです。

この記事では、ハルシネーションを完全になくすのではなく、「見つけやすくする」「断定を減らす」「検証可能な形で回答させる」ための実践的なプロンプトと検証フローを紹介します。

ハルシネーションを前提にプロンプトを設計する

最初に重要なのは、「間違えないで」と書くだけでは不十分だと理解することです。モデルは情報が不足していても、質問に回答しようとします。そのため、分からない場合の振る舞いを明示します。

私が調査用途で使っている基本形は次のようなものです。

あなたは技術調査アシスタントです。

以下のルールに従って回答してください。

- 確認できない情報は推測せず、「確認できない」と書く
- 事実、推測、提案を分けて記載する
- API名、関数名、バージョン番号、日付は特に慎重に扱う
- 根拠が入力文にない場合は、根拠がないことを明示する
- 質問の前提が誤っている可能性があれば指摘する
- 回答の最後に、追加で確認すべき項目を列挙する

「正確に答えてください」よりも、「確認できない場合の処理」を指定する方が、回答の危険な断定を減らせます。

ただし、このプロンプトだけで正しさを保証できるわけではありません。モデルが「確認した」と出力しても、実際に外部情報を確認したとは限らないためです。根拠の有無と、根拠の正しさは別々に検証します。

回答を検証しやすい形式に固定する

自由記述の回答は、どこが事実でどこが推測なのか判別しにくくなります。そこで、私は回答形式をJSONに近い構造へ固定します。

次のJSON形式だけで回答してください。
Markdownやコードフェンスは不要です。

{
  "answer": "質問への簡潔な回答",
  "facts": [
    {
      "claim": "検証可能な主張",
      "evidence": "入力文または参照資料にある根拠",
      "confidence": "high|medium|low"
    }
  ],
  "assumptions": [
    "回答で置いた仮定"
  ],
  "unknowns": [
    "確認できなかった点"
  ],
  "verification_steps": [
    "利用者が実行できる確認手順"
  ]
}

この形式にすると、たとえば以下の問題を見つけやすくなります。

  • evidence が空なのに confidence が high
  • 具体的な主張があるのに verification_steps がない
  • facts ではなく assumptions に入れるべき内容が混ざっている
  • 参照資料に書かれていないバージョン番号を断定している

実際の運用では、厳密なJSONを毎回返させるのが難しいモデルもあります。その場合は、まず「見出しを固定する」だけでも効果があります。形式を完全に守れないこと自体も、検出対象として扱います。

検出用プロンプトで回答を再点検する

回答を一度生成したら、別のプロンプトで批判的に点検します。ここでは、元の回答をそのまま信頼せず、主張単位に分解させます。

以下の回答を監査してください。

監査対象:
<ここに生成された回答>

次の表形式で出力してください。

| 主張 | 種類 | 根拠の有無 | リスク | 確認方法 |
|---|---|---|---|---|

種類は「事実」「推測」「提案」のいずれかにしてください。
根拠がない具体名、URL、日付、数値、API仕様には高いリスクを付けてください。
確認方法は、公式ドキュメント確認、実行テスト、ソースコード確認など具体的に書いてください。

この監査用プロンプトで大切なのは、単に「間違いを探して」と頼まないことです。ハルシネーションを見落とした場合、監査側のモデルも同じ誤りを共有する可能性があります。そのため、主張、根拠、確認方法の3点を別々に出させます。

また、回答生成と監査で役割を分けるのも有効でした。生成側には「解決策を提案する」役割、監査側には「疑う」役割を与えます。1回のプロンプトで両方を実行するより、問題箇所が見えやすくなります。

コマンドとコードで事実を確認する

文章のレビューだけでは、APIやコマンドの誤りを見逃します。実行できる主張は、できるだけ実行して確認します。

たとえば、PythonパッケージのAPIについて回答を得た場合は、次のように最小コードを作ります。

python -m venv .venv
.venv\Scripts\activate
python -m pip install -U pip
python -m pip show requests
python -c "import requests; print(requests.__version__)"

関数や引数の存在を確認するだけなら、次の方法も使えます。

import inspect
import requests

print(hasattr(requests, "get"))
print(inspect.signature(requests.get))

CLIの説明であれば、ヘルプと終了コードを確認します。

my-command --help
my-command --version
$LASTEXITCODE

確認できない主張は、記事や仕様書にそのまま採用しません。私の場合は、レビュー用に次のようなチェックリストを作っています。

[ ] 公式ドキュメントに該当する仕様がある
[ ] 使用中のバージョンで実行できた
[ ] サンプルコードがエラーなく動いた
[ ] URLが存在し、内容が主張を裏付けている
[ ] 推測や前提が明示されている
[ ] 未確認事項が残っていない

特にバージョン情報は注意が必要です。モデルが古い知識をもとに回答していることもあるため、「いつ時点の情報か」を必ず確認します。

小さな自動チェックを組み込む

毎回すべてを人手で確認するのは難しいため、回答の形式的な問題は自動検出します。以下は、回答JSONの最低限のチェック例です。

import json
import sys

def validate(result: dict) -> list[str]:
    errors = []

    required = [
        "answer",
        "facts",
        "assumptions",
        "unknowns",
        "verification_steps",
    ]

    for key in required:
        if key not in result:
            errors.append(f"必須キーがありません: {key}")

    for index, fact in enumerate(result.get("facts", [])):
        for key in ("claim", "evidence", "confidence"):
            if not fact.get(key):
                errors.append(f"facts[{index}] の {key} が空です")

        if fact.get("confidence") == "high" and not fact.get("evidence"):
            errors.append(f"根拠なしでhigh判定です: facts[{index}]")

    if not result.get("unknowns"):
        errors.append("unknownsが空です。未確認事項を再確認してください")

    return errors

data = json.load(sys.stdin)
errors = validate(data)

if errors:
    for error in errors:
        print(f"ERROR: {error}")
    sys.exit(1)

print("OK")

このチェックは、内容の真偽を判定するものではありません。根拠のない「自信のある回答」や、未確認事項を出力しない回答を弾くためのゲートです。

実運用では、次のような流れにしています。

  1. 質問と参照資料を準備する
  2. 構造化プロンプトで回答を生成する
  3. JSONの形式チェックを行う
  4. 監査プロンプトで主張を分解する
  5. 重要な主張を公式資料や実行テストで確認する
  6. 未確認の主張を削除するか、条件付きの表現に変更する
  7. 最終レビューを行う

ハルシネーションを検出・抑制するための検証フローを図にすると次の通りです。

まとめ

ハルシネーション対策で重要なのは、プロンプトに「間違えないで」と書くことではありません。回答を事実・推測・提案に分け、根拠と不確実性を明示させ、検証可能な形式で出力させることです。

さらに、生成と監査を分離し、APIやコマンドは実際に実行します。形式的な不備はコードで検出し、重要な主張だけを人手で重点確認すると、作業量とリスクのバランスを取りやすくなります。

生成AIの回答を「完成品」として扱うのではなく、「検証待ちの下書き」として扱う。この前提をプロンプトと開発フローの両方に組み込むことが、現時点で最も再現しやすい対策だと感じています。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?