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?

AI検索リサーチの数値を公式ページと照合したら3箇所ずれていた

0
Last updated at Posted at 2026-09-04

はじめに

AIの検索リサーチで料金の数字を集めて、記事にまとめる。
自分もそのやり方で比較記事を1本公開したあと、公開済みのその記事を、WebSearch(Web上の情報を検索して集めてくる機能)で各社の公式価格ページと照合しました。
そうしたら、料金の数値が3つずれていました。
しかも一番痛かったのが、記事の結論を支えていた数字です。

本文では、あるサービスを「国内最安」と書いていました。
公式の料金を並べ直したら、そのサービスは並びのいちばん高い側にいました。
この記事は、そのときに何がずれたのか、どう直し、そのあとにどんな工程を足したのかの記録です。

こんな人に向けて書いています

  • AIの検索リサーチで数字を拾って、記事やドキュメントに書いている人
  • 料金・プランみたいな「あとから変わる数字」を扱うコンテンツを作っている人
  • AIに書かせる工程は組んだけれど、確認の工程はまだ人の気合いに任せている人

この記事でわかること

  • AI由来の数値がどういう形で混ざるのか(「捏造」ではない、という話)
  • 数値のズレがどういう条件で起こるのか、他にどこで起こりえて、何が厄介なのか
  • 公開前に通す照合工程の手順と、照合記録を構造化する形

前提

特定の言語・フレームワークの話ではありません。
対象は公開済みの比較記事1本で、数値の照合はWebSearchで各社の公式価格ページを開いて行いました。

そして、この記事にはサービス名と実際の金額を書きません。伏せた数字は読者の側で裏が取れず、載せると「確かめられない数字」を増やすことになるからです。ここで扱うのは、数値そのものではなく、ズレの型と、そこから作った工程のほうです。

背景:AI検索リサーチ由来の数値には、何が混ざるのか

AI検索リサーチ由来の数値には、もっともらしい古い/誤ったデータが混入します。

なので、確認する対象を絞る必要があります。
この記事は「価格のような外部の数値」を、その絞り先として扱った記録です。

見つかった食い違いは3つ

公開済みの記事を照合したところ、料金まわりで3つの食い違いが出ました。型で並べるとこうなります。

  • 更新料:記事の記載より、公式ページの金額のほうが高かった
  • ドメイン料金:記事の記載より、公式ページの金額のほうが安かった
  • 率で示す調整費:記事の公開直後に改定されていた

加えて、外部のレビューサイトから引いていたスコアも載せていたのですが、こちらで検証できる形になっていなかったので全部削除しました。
数字は、確かめられないなら載せないほうがいい、という判断です。

3つ目の調整費のズレは、性質が少し違います。
書いた時点では合っていた可能性があるからです。
公開したあとに、参照先のほうが動いていました。

いつ起こるか

一般化するとこうです。
外部の公式ページが更新されうる数値を、AIの検索リサーチ経由で取り込み、公開までに公式ページと突き合わせないときに起こります。

他に起こりえる場面

同じ原理で起こるのは、たとえばこういう数値です。

  • 更新料やドメイン料金のような、公式ページ側が改定する料金。今回ずれた2件がこれでした
  • 調整費のような「率」。公開後に改定されると、書いた時点では正しかったのに間違いになります
  • 外部のレビューサイトから引いたスコア。こちらで検証できる形になっていないと、正しいかどうかを確かめる手段がありません

困りポイント

何が厄介かを並べると、こうなります。

  • ゼロから作られた嘘ではない。もっともらしい古い/誤ったデータとして混ざるため、公式ページとの照合が必要
  • 情報源が動く。書いた時点で正しくても、公開後に改定されることがある(調整費がまさにこれでした)
  • 1つのミスが結論を裏返す。「最安」は並び順ひとつで真逆になる
  • 直しが1箇所で終わらない。次に書くとおり、記事の骨格まで連鎖します

数値は本文の一部ではなく、記事の骨格

更新料の数字を直すと、そのサービスの順位が変わります。
順位が変わると、10年使ったときのランキングが変わります。
実際、記事で上位に置いていたサービスは、並べ直すと最も高い側へ移りました。

そして、リード文の結論も修正しました。
さらに記事の後半には「こういう人にはこれがおすすめ」という状況別のセクションがあって、そこも前提が変わるので直しになります。

つまり、直した箇所はこうなりました。

  • 料金表の数値そのもの
  • 10年ランキングの順位
  • リード文の結論
  • 状況別おすすめ

数値の修正が3件でも、記事の主張が乗っている場所は全部書き換えです。
「国内最安」と断言していたサービスが、実は最も高い側だったと知った時は、血の気が引きました。

ここで学んだのは、価格系の記事では数値は本文の一部ではなく、記事の骨格だということです。
骨格を後から差し替えると、上に載っているものが全部ずれます。
だから公開前に固めるしかない。

公開前に足した工程(手順)

作ったのは機能ではなく、記事の工程です。
「気をつける」だと次も同じことをやるので、入力と確認条件のある手順に落としました。順番に通します。

1. 数値の抽出

  • 入力:公開前の原稿
  • 確認条件:外部由来の数値が1つ残らず一覧になっている(金額・率・順位・スコア・件数)。自分で数えた数と、外部から持ってきた数を混ぜない

2. 公式ページの確認

  • 入力:手順1の一覧
  • 確認条件:各数値に、その数値の発行元=公式ページのURLが1つ対応している。まとめサイトや解説記事しか出てこない数値は、ここで「検証できない」に分類する

3. 確認日の記録

  • 入力:数値とURL
  • 確認条件:項目/公式URL/確認日/旧値→新値の4要素が埋まっている。ズレがなかったものも「差分なし」で残す。記録が無いと、あとで「見たつもり」と区別がつかない

4. 波及先の検索

  • 入力:手順3でズレが出た数値
  • 確認条件:その数値が出てくる箇所を全部拾って直してある。検索は2通りかける。①数字そのもの(表記ゆれ込み)②数字が根拠になっている言い回し(「最安」「1位」「おすすめ」など、本文・順位・リード文の結論・CTA)。②を飛ばすと、表だけ正しくて結論が古いままの記事ができます

5. 検証できない数値の削除

  • 入力:手順2で「検証できない」に分類したもの
  • 確認条件:原稿に残っていない。残したいなら手順2に戻って一次情報を探す

6. 公開判定

  • 入力:手順3の記録
  • 確認条件:原稿の外部数値の件数と、記録の件数が一致している。かつ確認日が公開日から離れすぎていない。合わなければ公開しない

照合記録を構造化する

手順6を目視でやると、件数の突き合わせが一番先に飛びます。記録を構造化しておくと、そこだけ機械に判定させられます。

記録はこの形です(4要素+検証可否)。

[
  {
    "item": "更新料",
    "source_url": "https://example.com/pricing",
    "checked_on": "2026-08-26",
    "before": "記事に書いていた値",
    "after": "公式ページの値"
  }
]

判定はこれだけで足ります。

import json
from datetime import date

REQUIRED = ("item", "source_url", "checked_on", "before", "after")

def validate(path: str, numbers_in_draft: int, published_on: date) -> list[str]:
    """照合記録を読み、公開してよい状態かを判定する。返り値が空なら公開OK。"""
    records = json.load(open(path, encoding="utf-8"))
    errors: list[str] = []

    # 4要素の欠けを見る。空文字も「未記入」として弾く(None だけ見ると素通りするため)
    for i, r in enumerate(records):
        for key in REQUIRED:
            if not r.get(key):
                errors.append(f"{i}件目: {key} が未記入")

    # URLが書かれているかだけを見る
    # ⚠️ これは「二次情報を弾く」検査ではない。https:// で始まれば通るので、
    #    まとめサイトや個人ブログも素通りする。一次情報かどうかを機械で判定したいなら、
    #    案件ごとに公式ドメインの一覧を持って照合する必要がある(ここでは持っていない)
    for r in records:
        if not str(r.get("source_url", "")).startswith("https://"):
            errors.append(f"{r.get('item')}: source_url が https:// で始まっていない")

    # 手順6の本体。原稿に出てくる外部数値の件数と、記録の件数を突き合わせる
    if len(records) != numbers_in_draft:
        errors.append(f"件数不一致: 記録{len(records)}件 / 原稿{numbers_in_draft}")

    # 確認日が古い記録は「確認済み」に数えない
    # ⚠️ 日付が読めないときに例外で落とさない。判定器が落ちると「エラー0件」と区別がつかなくなる
    for r in records:
        try:
            checked_on = date.fromisoformat(str(r.get("checked_on", "")))
        except ValueError:
            errors.append(f"{r.get('item')}: 確認日が読めない({r.get('checked_on')!r}")
            continue
        if (published_on - checked_on).days > 7:
            errors.append(f"{r['item']}: 確認日が古い({r['checked_on']}")

    return errors

numbers_in_draft を人が数える以上、完全な自動化ではありません。それでも「記録し忘れた1件」は、この時点で止まります。

出典・確認先

この記事には、公式ページで裏取りが必要な外部数値を載せていません。金額・率・サービス名を伏せ、ズレの型と工程だけを書いているためです。

数値を載せる記事では、この位置に手順3の4要素をそのまま並べます。

## 出典・確認先

- 項目:〈数値の名前〉
  - 公式URL:〈発行元の公式ページのURL〉
  - 確認日:〈YYYY-MM-DD〉
  - 旧値→新値:〈記事に書いていた値〉→〈公式ページの値〉

参照先はあとから改定されるので、数字だけでは足りません。どこを見て、いつ確認したのかまでを1組で残します。

最後に握っておくのは「本当にこの数字?」

AI検索リサーチ由来の数値を扱う運用では、警戒する先は「嘘をつかれること」より「古いまま混ざること」でした。
そして混ざった数字は、単体では小さく見えても、結論のほうを裏返してきます。

便利さのために自動化するほど、最後の「本当にこの数字?」を人間が握っておく価値が上がる。
今回はそれを、公開したあとに教わった形になりました。


個人でAIツールや業務自動化を作っているMiyokiといいます。
今回のような記事づくりの工程も含めて、自分の作業を楽にするための小さな仕組みを作っては、その開発ログをZennとQiitaに書いています。
こういう「確認の工程ごと仕組みにする」相談も受けています。

作ったものやポートフォリオはこちらです。

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?