AIエージェントの出力検証 — 幻覚を防ぐファクトチェック
約5分で読めます
AIエージェントの出力検証 — 幻覚を防ぐファクトチェック
AIエージェントの出力を無検証で本番に流すのは危険だ。存在しないAPIの呼び出し、架空のライブラリ名、間違った設定値など、AIの幻覚(ハルシネーション)は多様な形で現れる。本記事では、幻覚を検出し、出力品質を保証するパイプラインを構築する方法を解説する。
幻覚の代表的パターン
AIが生成する幻覚には再現性の高いパターンがある。
| パターン | 例 | 検出方法 |
|---|---|---|
| 存在しないパッケージ | pip install super-fast-ai | パッケージレジストリAPI照合 |
| 架空のAPI引数 | requests.get(url, turbo=True) | ドキュメント照合 |
| バージョン不整合 | 「Python 3.14で追加された機能」 | リリースノート照合 |
| 統計の捏造 | 「調査によると87.3%が…」 | ソース要求・検索エンジン照合 |
| URL幻覚 | 存在しないドキュメントURL | HTTPステータスチェック |
ファクトチェックプロンプト設計
出力の検証には、生成とは別のプロンプトで検証用AIを走らせる。
FACT_CHECK_PROMPT = """
以下のAI生成テキストを検証してください。
## 検証対象
{generated_text}
## 検証ルール
1. コード中のパッケージ名がPyPI/npmに存在するか確認
2. API呼び出しの引数が公式ドキュメントと一致するか確認
3. 数値・統計にソースが明記されているか確認
4. URLが実在する可能性があるか確認(パターン分析)
5. バージョン番号が実在するか確認
## 出力形式
各項目について以下のJSON形式で回答:
{{"item": "検証対象", "status": "OK/SUSPICIOUS/FALSE", "reason": "理由"}}
"""
検証パイプラインの実装
import subprocess
import requests
import re
class OutputValidator:
def __init__(self):
self.checks = [
self.check_packages,
self.check_urls,
self.check_code_syntax,
self.check_with_second_model
]
def validate(self, output: str) -> dict:
results = {}
for check in self.checks:
name = check.__name__
results[name] = check(output)
results["passed"] = all(r["ok"] for r in results.values())
return results
def check_packages(self, output: str) -> dict:
"""コード中のimport文からパッケージの実在を確認"""
packages = re.findall(r'(?:import|from)\s+(\w+)', output)
missing = []
for pkg in set(packages):
resp = requests.get(f"https://pypi.org/pypi/{pkg}/json")
if resp.status_code == 404:
missing.append(pkg)
return {"ok": len(missing) == 0, "missing": missing}
def check_urls(self, output: str) -> dict:
"""テキスト中のURLが200を返すか確認"""
urls = re.findall(r'https?://[^\s\)]+', output)
broken = []
for url in urls[:10]:
try:
resp = requests.head(url, timeout=5)
if resp.status_code >= 400:
broken.append(url)
except requests.RequestException:
broken.append(url)
return {"ok": len(broken) == 0, "broken": broken}
def check_code_syntax(self, output: str) -> dict:
"""生成されたPythonコードの構文チェック"""
code_blocks = re.findall(r'```python\n(.*?)```', output, re.DOTALL)
errors = []
for code in code_blocks:
try:
compile(code, "<ai-output>", "exec")
except SyntaxError as e:
errors.append(str(e))
return {"ok": len(errors) == 0, "errors": errors}
def check_with_second_model(self, output: str) -> dict:
"""別モデルによるクロスチェック"""
result = call_haiku(FACT_CHECK_PROMPT.format(generated_text=output))
suspicious = [r for r in result if r["status"] != "OK"]
return {"ok": len(suspicious) == 0, "issues": suspicious}
パイプラインの統合フロー
- 生成: メインモデルがタスクを実行
- 構文検証: コードブロックのコンパイルチェック
- 実在性検証: パッケージ・URL・バージョンの照合
- クロスチェック: 別モデルによるファクトチェック
- 判定: 全チェック通過で出力確定、不合格なら再生成
再生成は最大3回まで。3回失敗した場合は人間にエスカレーションする。
コスト対効果
検証パイプラインの追加コストは、メイン生成の約15-20%程度だ。しかし幻覚による手戻りや本番障害を防げることを考えれば、十分にペイする投資といえる。
まとめ
AI出力の検証は「パターン検出 + 実在性照合 + クロスチェック」の多層構造で実装する。完璧な検出は不可能だが、主要な幻覚パターンの90%以上をこのパイプラインで捕捉できる。
関連記事
A
Agentive 編集部
AIエージェントを実際に使い倒す個人開発者。サイト制作の自動化を実践しながら、その知見を発信しています。