Topics

Cloudflare AI Search で多言語サイトのサイト内検索を実装

  • column

Astro SSG + ヘッドレスCMSという構成の自社サイトに実装してみました。
導入手順そのものは割とシンプルだったのですが、弊サイトは多言語構成のため、いくつかハマりどころがありました。

Cloudflare AI Search とは

旧称AutoRAGで、2025年9月に改称されました。検索して出てくる記事は旧名・旧APIのものが多いので注意。

やってくれるのはこの一連です。

クロール → Markdown 変換 → チャンク分割 → 埋め込み → ベクトル + キーワードのインデックス構築

API は2系統。検索結果一覧を返すsearchと、RAGで回答を生成するchat/completions。今回は前者のみ使います。

設定のポイント

インスタンスを以下のように作成します。

  • データソースはWebCrawlを選択
  • クロール対象に公開URL
  • 解析タイプをサイトマップ
  • コンテンツセレクタにmain要素を指定
  • 解析モード:静的サイト
  • 特定のサイトマップでsitemap.xmlを指定
  • 埋め込みモデルを@cf/baai/bge-m3に(日本語サイトのため)

あとは基本デフォルトで問題ないです。

認証と環境変数

アカウントからAPIトークンを作成します。
注意点は「AI Search: 読み取り」だけではなく、「編集」と「実行」も必要です。
作成したトークンは、環境変数AI_SEARCH_TOKENで読み込みます。

構成:APIルート1本 + コンポーネント1つ

検索はAstroのAPIルート(Pages Functionsとして動く)からREST APIを叩きます。APIトークンをブラウザに出せないので、サーバー側でプロキシする形は必須です。なおPages FunctionsにはAI Searchのbindingがないため、SDKではなく素のfetchを使っています。

// Astro の API ルート(Pages Functions として動く)
const res = await fetch(
  `https://api.cloudflare.com/client/v4/accounts/${id}/ai-search/instances/${name}/search`,
  {
    method: 'POST',
    headers: { Authorization: `Bearer ${token}` },
    body: JSON.stringify({
      query,
      ai_search_options: {
        retrieval: {
          retrieval_type: 'hybrid',
          max_num_results: 50
        },
      },
    }),
  }
);

実装したのは APIルートと検索UIコンポーネントの2ファイルだけ。SSGへの後付けとしてはかなり軽く済みました。

多言語サイトでは検索対象を表示言語に絞る

普通のサイト内検索であれば、これでいいのですが、多言語の場合は全言語が書かれたsitemap.xmlを読んでいるため、検索結果が混ざってしまいます。

解決策は、カスタムメタデータ locale を定義して検索時に filters で絞ること。これにより、見ている言語のみが検索結果として出力されるようになりました。
※ htmlのlang属性や、og:locale からは判定できないので要注意です。

<meta name="locale" content="ja_JP">

SEO用サイトマップと検索用サイトマップを分ける

AI Search(Website データソース)はサイトマップ経由でクロールします。

ところが弊サイトの公開用サイトマップは、SEO上の判断で一部の言語を意図的に除外していました。結果、その言語では検索結果が常に 0件という問題が発生。

@astrojs/sitemap でサイトマップを生成しているので、全言語を含むサイトマップを検索用に別途出力する方法をとりました。

検索結果はどう並んでいるのか

「AI 検索」という語から想像する姿とは結構違います。

AI Searchが日本語で300〜450文字くらいのチャンクに分割します。
関連するチャンクが最大50個ピックアップされ、それが含まれるページが結果で出てきます。
関連度が高いと判断されたチャンクを含むページが上位にきます。1ページから複数のチャンクが選ばれることもあるため、検索件数は50件よりも少なくなります。

ページ単位への集約はフロント側でやっています。そしてこの一連の処理では、生成AIは1回も動いていないです。

まとめ

導入するにはドメインのゾーンがCloudflareにあり、Pages / Workersで運用している事が前提となりますが、実装はお手軽で簡易的にサイト内検索を実装したい場合にはかなり使えるのではと思いました。

逆に、インフラに触れず検索だけ後付けしたい場合や、全件出したい場合、検索ログ分析・サジェスト・同義語辞書といった運用者向けの管理機能が必要な場合は、従来型ASPの方が強いです。

とはいえ、ASPを入れるには重い、けれど検索は欲しい。そういう規模のサイトにはかなり刺さる選択肢だと思います。

この記事を書いた人

DTPからWebの世界へ飛び込み、気づけばマークアップもフロントエンドもディレクションもアクセシビリティもこなす"技の仙人"。リベロジック創業期からマルチに活躍し、今や社内の生き字引的存在。最近は「アクセシビリティ対応、もっとAIに頼れないかな?」と、プロンプトを駆使した効率化の探究にハマり中。技術も思考も、まだまだ進化中

フタさん

IAAP認定ウェブアクセシビリティスペシャリスト(WAS) / マークアップエンジニア / フロントエンドエンジニア / ウェブディレクター

このスタッフの記事を見る

安心のチーム体制とスピードのある対応力が自慢

リベロジックでは、ベテランスタッフが積極的にプロジェクトを推進するため、お客様から高く評価されています。
プロジェクトマネージャー、ディレクターをきちんとアサインし、プロジェクト全体をスムーズに進行することを心掛けています。 不必要なフルコミットでのコスト増加を防ぎ、適材適所にリソースを配分するスタイルで、業務内容の把握から見積作成/提出の速さにも定評があります。

当社はSES的な常駐業務等は積極的に行っておりませんので予めご了承ください。

Slack、Teams、Redmine、Backlog、Asana、Jira、Notion、Google Workspace、Zoom、Webexなど、ほぼすべての主要なプロジェクト管理ツールやチャットツールをご利用いただけます。

Webのお悩みご相談ください。

ケーススタディ