AIで作った報告書をそのまま社内に出すとき、一番怖いのは「文章が変」なことではなく、むしろ文章がきれいすぎることだと思っています。
営業資料でも企画メモでも、数字が入ると急にそれっぽく見えるんですよね。「市場規模は3年で2倍」「導入企業は73%」みたいな文が、さらっと混ざる。読み手も忙しいので、体裁が整っていると流してしまう。
2026-06-29に、Gizmodo Japanで「大手コンサル作のAI報告書がハルシネーションだらけだった」という記事を読みました。大きい会社の失敗として見るより、僕はかなり身近な話だと感じました。AIで下書きを作る現場では、同じことが小さい資料で普通に起きます。
なので、提出前に「出典が必要そうな行だけ」を抜き出す小さいチェックを書きました。
真偽判定はしません。そこまで自動化すると、別の事故になります。ここでは、数字・調査・発表・市場規模みたいな言葉があるのにURLや出典表記がない行を拾うだけです。ここ地味に効きます。
AI報告書で先に見る行
僕が提出前に見たいのは、だいたいこの3つです。
まず数字が入った行。割合、金額、件数、年月、倍率。数字は説得力が強いぶん、間違えると資料全体の信用を落とします。
次に「調査」「報告」「発表」「によると」のような、誰かの情報に乗っている行。ここに出典がないと、読み手は検証できません。
最後に市場規模やシェアの話。営業資料では便利ですが、AIがもっとも自然に盛りやすいところです。
下のスクリプトはMarkdownの報告書を読み、根拠を付けたほうがよさそうな行をCSVで出します。
from __future__ import annotations
import argparse
import csv
import re
import sys
from pathlib import Path
NUMBER_CLAIM = re.compile(r"\d+(?:\.\d+)?\s*(%|%|円|万円|億円|人|社|件|倍|年|月|日)")
SOURCE_WORD = re.compile(r"(調査|報告|発表|によると|市場規模|シェア|ランキング|平均)")
HAS_SOURCE = re.compile(r"(https?://|\[[^\]]+\]\(https?://|Source:|出典[::])")
def iter_target_lines(text: str):
in_code = False
for line_no, line in enumerate(text.splitlines(), 1):
stripped = line.strip()
if stripped.startswith("```"):
in_code = not in_code
continue
if in_code or not stripped or stripped.startswith("#"):
continue
yield line_no, stripped
def reason_for(line: str) -> str | None:
if HAS_SOURCE.search(line):
return None
reasons: list[str] = []
if NUMBER_CLAIM.search(line):
reasons.append("number_claim")
if SOURCE_WORD.search(line):
reasons.append("source_word")
return "+".join(reasons) if reasons else None
def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument("markdown", type=Path)
args = parser.parse_args()
text = args.markdown.read_text(encoding="utf-8")
warnings: list[tuple[int, str, str]] = []
checked = 0
for line_no, line in iter_target_lines(text):
checked += 1
reason = reason_for(line)
if reason:
warnings.append((line_no, reason, line))
writer = csv.writer(sys.stdout)
writer.writerow(["line", "reason", "text"])
writer.writerows(warnings)
print(f"checked={checked} warnings={len(warnings)}")
return 2 if warnings else 0
if __name__ == "__main__":
raise SystemExit(main())
動作確認
たとえば、こんなMarkdownを用意します。
# AI導入メモ
2026年のAI導入企業は73%まで増えた。
市場規模は3年で2倍になる。
OpenAIの発表では新機能が追加された。https://example.com/news
```text
テストデータは100件
```
営業部の確認フローを月末までに決める。
実行します。
$ python3 evidence_lint.py report.md
line,reason,text
3,number_claim,2026年のAI導入企業は73%まで増えた。
4,number_claim+source_word,市場規模は3年で2倍になる。
checked=4 warnings=2
コードブロック内の 100件 は無視しています。URLが同じ行にある OpenAIの発表では... も今回は通しています。
終了コードは、警告があれば 2、なければ 0 にしました。提出前チェックに入れるなら、このまま落とせます。
python3 evidence_lint.py draft_report.md > evidence_warnings.csv
evidence_warnings.csv が空でなければ、そこだけ人間が見る。全部を読み直すより現実的です。
このチェックで防げること、防げないこと
このスクリプトは、出典の正しさを見ていません。URLが本当に根拠になっているか、引用した数字が最新か、元記事の文脈を外していないか。そこは人が確認します。
ただ、確認すべき場所を狭めることはできます。
AIで下書きを作ると、文章量が増えます。全部を同じ濃さでレビューしようとすると、だいたい疲れて流します。先に「数字と出典っぽい行」だけ抜くと、レビューの順番が決まります。ここが現場では大きいです。
もうひとつ、書き手側の抑止にもなります。警告が出ると、「この数字、どこから取ったんだっけ」と一度止まる。AIに出させた文を、自分の資料として引き受けるタイミングを作れます。
現場で使うなら少しだけ足す
そのまま使うなら、まず SOURCE_WORD を自社資料に合わせます。営業なら「導入実績」「継続率」「満足度」。採用なら「離職率」「平均年収」。経理なら「削減額」「予算」。部署によって危ない言葉は違います。
次に、出典の書き方を決めます。僕なら、最低限このどちらかにします。
市場規模は3年で2倍になる。出典: https://example.com/report
または、
[調査レポート](https://example.com/report)によると、市場規模は3年で2倍になる。
形式をそろえると、機械で拾いやすくなります。人によって「参考」「ソース」「参照」などが混ざると、チェック側がだんだん甘くなります。
最後に、全部をブロックしないこと。社内メモの段階なら警告で十分です。役員会資料、顧客提出資料、プレス向け資料だけ落とす。チェックを厳しくしすぎると使われなくなるので、止める場所を絞ったほうが続きます。
で、現場でどう使うか
AIの報告書で必要なのは、AIを疑い続ける根性ではなく、疑う場所を先に決める仕組みです。数字、調査、発表、市場規模。このあたりを提出前に機械で抜き出すだけで、レビューはかなり楽になります。
きれいな文章ほど、根拠の穴が見えにくい。だから、見た目を整える工程とは別に、根拠を点検する工程を置く。AIで資料作成を速くするなら、この小さいひと手間までセットにしたほうが安全です。
Source: https://www.gizmodo.jp/article/a-report-full-of-hallucinations/