なぜ FactLens を作ったのか
フェイクニュース時代に必要な「検証の民主化」
きっかけ: 「これ本当?」に答えられない AI
SNS を開けば毎日のように流れてくる情報。「〇〇が△△を発表」「研究で□□が判明」——でも、それは本当だろうか?
ChatGPT に「これは本当ですか?」と聞けばもっともらしい答えが返ってくる。でも、その答え自体が間違っているかもしれない。LLM(大規模言語モデル)はハルシネーション——事実と異なる内容を自信たっぷりに生成する——という根本的な問題を抱えている。
「LLM は知識の倉庫ではなく、パターンの生成器である。事実を『知っている』のではなく、事実らしい文章を『生成できる』にすぎない」
Huang et al. (2023) の大規模サーベイ論文 "A Survey on Hallucination in Large Language Models" では、LLM のハルシネーションが広範囲に存在し、特に事実の検証タスクでは深刻な問題になることが体系的に報告されている。
さらに、LLM には知識のカットオフがある。2024年の選挙結果も、先月の企業発表も、学習データに含まれていなければ「わかりません」としか答えられない。
FactLens は、この2つの問題を正面から解決するために作った。
アプローチ: 3つの学術的手法の融合
FactLens の核心は「LLM に直接聞く」のではなく、分解 → 検索 → 検証 → 集約の多段階パイプラインにある。
この4段階それぞれに、査読付き論文に基づく設計根拠がある。順に見ていこう。
手法1: リアルタイム ウェブ検索 (RAG)
Lewis et al. (2020) が NeurIPS で発表した RAG (Retrieval-Augmented Generation) は、「LLM に外部知識を与えてから回答させる」パラダイムだ。FactLens はこれを検証タスクに適用している。
具体的には、入力テキストの先頭150文字をクエリとして Jina AI Search でウェブ検索を実行。最新のニュース記事、論文、公式発表を3000文字まで取得し、LLM の判定材料として与える。
なぜ Jina AI Search か? API キー不要・無料・クリーンなテキスト出力。Google や Bing は Cloud IP からのアクセスを CAPTCHA でブロックするが、Jina はボット利用を前提とした設計で安定動作する。
これにより、LLM が学習していない最新情報——たとえば先週の政策発表や最新の研究結果——にも対応できるようになった。
📄 Lewis, P., et al. "Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks." NeurIPS 2020. arxiv.org/abs/2005.11401
手法2: 原子的事実分解 (FActScore)
「エッフェル塔は1889年に建設され、高さは500メートルある」——この文は半分正しくて半分間違っている。文全体に「本当/嘘」のラベルを付けても、有用な情報にならない。
Meta AI の Min et al. (2023) が EMNLP(Best Paper 受賞)で発表した FActScore は、この問題を「原子的事実への分解」で解決した。長文を個別に検証可能な最小単位のクレームに分解し、それぞれを独立に評価する。
FactLens はこの手法を採用し、入力テキストを自動的に原子的事実に分解する。これにより:
- どの部分が正確でどの部分が不正確かを特定できる
- 「80%は正しいが重要な1点が間違っている」というニュアンスのある判定が可能になる
- ユーザーが自分で検証を追跡できる
研究では、この分解アプローチが人間の判断と高い相関を示すことが実証されている。
📄 Min, S., et al. "FActScore: Fine-grained Atomic Evaluation of Factual Precision in Long Form Text Generation." EMNLP 2023 (Best Paper). arxiv.org/abs/2305.14251
手法3: エビデンス強制 (Chain-of-Thought)
「科学的に否定されています」——こういう曖昧な根拠では検証のしようがない。FactLens では、各クレームの判定に具体的な出典の引用を強制している。
Wei et al. (2022) の Chain-of-Thought (CoT) プロンプティングは、LLM に中間推論ステップを明示させることで、複雑な推論タスクの精度を大幅に向上させた。FactLens はこの知見を応用し、以下のルールをプロンプトに埋め込んでいる:
- 判定理由には機関名(WHO、NASA、NHK など)を含めること
- 論文名・年号を可能な限り引用すること
- 「専門家の見解では〜」のような曖昧な表現は禁止
たとえば「脳は10%しか使われない」というクレームに対しては、「神経科学の教科書(Kandel et al., Principles of Neural Science)は、脳全体が常に活動していることを示している」のように、具体的な出典を引用した判定を返す。
📄 Wei, J., et al. "Chain-of-Thought Prompting Elicits Reasoning in Large Language Models." NeurIPS 2022. arxiv.org/abs/2201.11903
手法4: 3ラベル判定体系 (FEVER)
世の中のクレームは「本当か嘘か」の二択で割り切れないものが多い。政治的主張、将来の予測、非公開情報に基づくクレームなど、現時点では検証しようがないものが存在する。
Thorne et al. (2018) の FEVER (Fact Extraction and VERification) は、18万件以上のクレームを含む大規模ベンチマークで、3ラベル体系を提唱した:
- supported(支持): 科学的コンセンサスや文書化された記録で裏付けられる
- refuted(否定): 確立された知識に基づき明確に誤り
- unverifiable(検証不能): 現時点で検証する手段がない
FactLens はこの体系を採用しつつ、重要なルールを追加した:広く知られた誤り(科学的神話)は「検証不能」ではなく「否定」と判定すること。「金魚の記憶は3秒」「適度な飲酒は健康に良い」といったクレームは、科学的に明確に否定されているからだ。
📄 Thorne, J., et al. "FEVER: a Large-scale Dataset for Fact Extraction and VERification." NAACL 2018. arxiv.org/abs/1803.05355
スコアリング: なぜ「検証不能」を50点にするのか
FactLens のスコアは以下の加重平均で算出する:
supported= 100点(2ポイント)unverifiable= 50点(1ポイント)refuted= 0点(0ポイント)
なぜ unverifiable を50点にするのか? これは意図的な設計だ。
もし unverifiable を無視して supported だけでスコアを計算すると、「1つ支持 + 5つ検証不能」のテキストが100点になってしまう。政治的主張のように検証困難なクレームが多い文章が、根拠なく高スコアを得ることを防ぐための設計だ。
ClaimBuster (Hassan et al., VLDB 2017) の「チェック価値スコアリング」の考え方を参考にしている。
なぜオープンソースにしたのか
ファクトチェックツールこそ、透明であるべきだ。
ブラックボックスなファクトチェッカーは、それ自体がバイアスの源になりうる。Quelle & Bovet (2024) は "The Perils and Promises of Fact-Checking with Large Language Models" で、LLM ベースの判定が政治的・文化的バイアスの影響を受ける可能性を指摘している。
だからこそ、FactLens は:
- プロンプト全文を公開(checker.rs で確認可能)
- スコアリングロジックを公開(同ファイル内の
compute_result関数) - どのモデルが判定したかを表示(各レポートに「🤖 Kimi-K2」等を明記)
- MIT ライセンスで誰でもフォーク可能
「AI が正しいと言っているから正しい」ではなく、「AI はこの根拠でこう判断した。あなたはどう思うか?」——これが FactLens の設計思想だ。
技術的な選択とその理由
なぜ Rust なのか
FactLens は Rust + Axum で書かれている。Python + Flask で書いた方が早く作れたが、Rust を選んだ理由は:
- メモリ効率: Fly.io の 512MB VM でも余裕で動作
- コールドスタート: auto_stop 設定でアイドル時にマシンを停止、リクエスト時に数百ミリ秒で起動
- 型安全: Web テンプレートの変数漏れをコンパイル時に検出
なぜ Kimi-K2 がデフォルトなのか
Moonshot AI の Kimi-K2 は MoE(Mixture of Experts)アーキテクチャで、1兆パラメータのうち32Bのみがアクティブになる。Groq の高速推論インフラで動作するため:
- レスポンス速度が速い(Claude の半分程度の待ち時間)
- 無料枠がある(個人開発でも気軽に使える)
- ファクトチェックタスクでの精度が Claude に迫る水準
なぜ SQLite なのか
PostgreSQL や MySQL ではなく SQLite を選んだ理由:
- 設定ゼロ: ファイル1つで完結
- WAL モード: 読み取りと書き込みを並行実行可能
- Fly.io ボリュームで永続化が簡単
- このスケールでは十分な性能
限界と今後
FactLens は万能ではない。正直に限界を述べておく:
- 検索結果の質に依存: ウェブ検索結果自体に誤情報が含まれていれば、判定も誤る可能性がある
- LLM のバイアス: モデルの学習データに偏りがあれば、判定にもバイアスが入る
- 言語の壁: 日本語のウェブ情報は英語に比べて少なく、検索精度が下がる場合がある
- 専門分野: 医学・法律など高度に専門的な分野では、一般ウェブ検索では十分な証拠が得られないことがある
だからこそ、FactLens は結果を「最終判定」ではなく「初期スクリーニング」として位置づけている。人間の本格的なファクトチェックは数時間〜数日かかるが、FactLens はその最初の一歩を数秒で提供する。
まとめ: 検証の民主化
誰もが簡単にファクトチェックできる世界。それが FactLens の目指すところだ。
フェイクニュースの拡散速度は、真実の訂正速度をはるかに上回る(Vosoughi et al., "The spread of true and false news online," Science, 2018)。だからこそ、個人が数秒で事実を検証できるツールが必要なのだ。
FactLens はオープンソースだ。コードをフォークし、改善し、自分のプロジェクトに組み込むことができる。ファクトチェックの技術をより良くするために、一緒に取り組んでくれる人を歓迎する。