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?

LLMのハルシネーション対策として、Web検索併用のファクトチェック機能を実装した話

0
Posted at

※本記事にはアフィリエイトリンクを含みます。

[目次]

はじめに
課題設定
アーキテクチャ概要
プラン制御
パフォーマンスコスト設計
今後の課題
まとめ

はじめに

個人開発でAI記事作成ツール「Natsume」を作っています。URLやテキストを入力すると、記事生成・SEO分析・X投稿生成までを自動化するツールです。

AI記事生成ツールを作る上で避けて通れないのが、LLMのハルシネーション(もっともらしい誤情報を生成する現象)対策です。今回は、Natsumeに実装したファクトチェック機能のアーキテクチャと、設計判断の背景を書きます。

課題設定

記事生成を自動化すればするほど、人間によるレビュー工程が減ります。生成速度と正確性はトレードオフになりがちですが、このバランスを崩さずに「事実確認だけは自動でついてくる」状態を作りたい、というのが要件でした。

コスト面の制約もあります。全ユーザーの全生成に対して高精度な検証をかけると、API費用が跳ね上がります。そこで、精度とコストが異なる2段階のファクトチェックを用意し、プランに応じて出し分ける設計にしました。

アーキテクチャ概要

標準ファクトチェック(全プラン共通)

Anthropic Claude(claude-haiku-4-5)を直接API呼び出しする方式です。軽量・低コストなモデルを使い、無料プランでも標準搭載できるコスト構造にしています。

判定ロジックはシンプルです。

  • 記事本文(最大12,000文字にトリム)をプロンプトに埋め込む
  • 「事実と異なる可能性」「誤引用」「根拠不明な断定」「誇張表現」の4観点で検出させる
  • 判定はok / caution / problemの3段階のenumをJSONスキーマで固定出力させる

ここで地味に効いているのが、現在日付をプロンプト先頭に明示している点です。LLMは学習データの時点を基準に「これは未来の出来事だから架空だろう」と誤判定することがあるため、現在日付をコンテキストとして与えることでこのミスを防いでいます。

LLMの出力は完全に安定しているわけではないので、レスポンスは正規表現でJSON部分を抽出し、サニタイズ(文字列内の改行等をエスケープ)してからパースする、という防御的な処理を挟んでいます。

プレミアムファクトチェック(スタンダード/プロプラン)

Perplexity API(sonarモデル)を使用しています。return_citations: trueを指定することで、判定の根拠となった引用元URLを取得できます。

面白いのは、プロンプト・JSON出力フォーマット自体は標準版と共通化している点です。判定ロジックを二重管理せず、「同じ質問をどのAIに投げるか」だけを変える設計にすることで、保守性を保っています。Perplexityから返ってきたcitations配列は、各判定結果にsourcesとして付与されます。

フォールバック設計の変更

実装当初は、Perplexity呼び出しが失敗した場合に標準版のHaikuへ自動フォールバックする設計でした。しかし後の改修でこれを廃止し、失敗時は503エラーを返す方式に変更しています。

これは意図的な設計判断です。プレミアムファクトチェックは「Web検索による裏取り」を売りにした課金機能なので、検索なしの結果を静かに返してしまうと、ユーザーが気づかないまま品質の低い判定を受け取ることになります。それよりは、失敗をはっきりエラーとして返す方が誠実だという判断です。あわせて、Perplexity呼び出し失敗時はSlack通知で運営側にアラートが飛ぶようにしています。

スクリーンショット 2026-07-01 163251.png

プラン制御

プレミアムファクトチェックへのアクセスは、ユーザーのプラン情報を見て制御しています。standard/proプランのみpremiumFC: trueが立ち、それ以外は403を返す形です。課金プランと機能フラグを疎結合にしておくことで、将来のプラン体系変更にも対応しやすくしています。

パフォーマンス・コスト設計

  • レート制限:ユーザーIDごとに60秒間10回まで(Upstash Redisのsliding window)
  • 入力上限:50,000文字まで受付、実際にプロンプトへ渡すのは先頭12,000文字にトリム
  • コスト構造:標準版は低コストのHaiku、プレミアム版のみ課金APIのPerplexityという2段構成にすることで、コストとプランを連動させている

今後の課題

現状、ファクトチェックAPI自体には言語別(locale)の分岐がなく、プロンプトの指示文は日本語で固定しています。NatsumeのUIは15言語に対応していますが、多言語コンテンツに対するファクトチェックの精度は今のところ未検証です。ここは今後、言語ごとのプロンプト設計や精度検証をしていく必要があると考えています。

また、プレミアムファクトチェックはWeb検索を伴う分レイテンシが伸びますが、具体的な計測・可視化はまだできていません。ここも改善の余地があるところです。

まとめ

  • 低コストモデル(Haiku)と高精度モデル(Perplexity Sonar)を使い分ける2段階構成にすることで、コストと精度のバランスを取った
  • プロンプト・出力フォーマットを共通化し、判定ロジックの二重管理を避けた
  • 課金機能の障害時はサイレントフォールバックせず、明示的にエラーを返す設計にした

個人開発でもこの規模の設計判断は積み重なっていくので、同じようにAI活用サービスを作っている方の参考になれば幸いです。


Natsumeは以下から試せます。
https://natsume.ai.briven.app/lp

スクリーンショット 2026-07-01 163431.png


紹介ツール:Runable
個人的に、動画・スライド・リサーチなどをまとめて扱えるオールインワン系AIツール「Runable」も愛用しています。Natsumeとは領域が違うツールですが、コンテンツ制作の周辺作業を効率化したい人には併用がおすすめです。
Runableはこちら

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?