Agentive
AIエージェント活用

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幻覚存在しないドキュメントURLHTTPステータスチェック

ファクトチェックプロンプト設計

出力の検証には、生成とは別のプロンプトで検証用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}

パイプラインの統合フロー

  1. 生成: メインモデルがタスクを実行
  2. 構文検証: コードブロックのコンパイルチェック
  3. 実在性検証: パッケージ・URL・バージョンの照合
  4. クロスチェック: 別モデルによるファクトチェック
  5. 判定: 全チェック通過で出力確定、不合格なら再生成

再生成は最大3回まで。3回失敗した場合は人間にエスカレーションする。

コスト対効果

検証パイプラインの追加コストは、メイン生成の約15-20%程度だ。しかし幻覚による手戻りや本番障害を防げることを考えれば、十分にペイする投資といえる。

まとめ

AI出力の検証は「パターン検出 + 実在性照合 + クロスチェック」の多層構造で実装する。完璧な検出は不可能だが、主要な幻覚パターンの90%以上をこのパイプラインで捕捉できる。

関連記事

A

Agentive 編集部

AIエージェントを実際に使い倒す個人開発者。サイト制作の自動化を実践しながら、その知見を発信しています。