🔍

Cloudflare 上で Jev で作るほぼ0円運用可能な高品質なページ内検索

に公開1件

自分は Go Proposal Weekly Digest というサイトを個人で運用しています。
https://go-proposal-weekly-digest.mazrean.com
Go 言語の Proposal と呼ばれる言語機能追加の提案を毎週 Claude Code がまとめるサイトで、公開してからそろそろ 8か月程度が立つものになります。
ありがたいことにユーザーが一定数付いて毎週 200PV 程度が安定してあるのですが、懐事情関係なく継続運用できるように Cloudflare 上で基本的に金銭負担なく動作するインフラを構築しています。

これまではまだ運営期間が短く記事数も少ないため過去記事を人力で探すことが可能だったのですが、最近記事が増えてきたことで検索機能が欲しくなってきていました[1]。
このタイミングでちょうど jev が出てきて自分も触ってみたくなったため、Cloudflare Vectorize・Workers AI などと組み合わせて低コスト運用可能な検索機能を実装してみました。
今回は実現方法の解説記事となります。

概算ではありますが、検索1回あたり約 $0.0002 のコストになっており、かなり多めに 10PV あたり 1 検索される想定で見積もっても毎月 $0.016 程度で運用できる計算になります。
一度、数ドルあればおそらく数年は大丈夫と思われるコスト感です。
また、期限付きではありますが TypeSafe AI の無料クレジット $5 がある現状では、金銭負担なしで運用できています[2]。

Jev とは

Jev は TypeSafe AI が提供するモデルで、一般的な LLM と違いテキストを生成せず、型付きの値を確率や confidence とともに返します。

使い方は、コンテキストとなる state とそれに関する質問を送るだけです。
質問の形式は、選択肢から選ぶ Choice、ルーブリックで採点する Score、文が真かを 0〜1 で返す Noul の 3 種類です。

最大の魅力は速度とコストで、70〜500 ミリ秒で回答し、価格は入力 100 万トークンあたり $0.042、出力は無料です。
https://typesafe.ai/blog/introducing-system-one-models-and-jev

検索方法設計

jev は高速かつ低コストで、教師データなしの判定問題を処理できるという良さがある一方できることは限られており、今回であれば検索問題を判定問題に落とし込む必要があります。
また、現状コンテキストの制約も厳しく、全ページの本文を食わせるようなことは当然できません。
そこである程度使い方を工夫してあげる必要があります。

今回のような検索処理の中で Jev の活用分野として即座に注目され、検証された分野として RAG があり、日本でも以下の記事が話題となりました。
https://qiita.com/kikuziro/items/2be9091b328d8b844640
この記事では RAG の基本的な処理フローの「ベクトル検索 → リランク → LLM 回答」のどこに Jev を差し込むのが効果的かの検証がされており、リランク以上に答えられない質問の事前排除で効果を発揮するという結論になっています。
一方で、今回のページ内検索ではそもそも「回答不能」という概念は存在しません。
また、リランクでも Jev を活用することでコストは 1/8 まで下がっており、かなりコスパが良いことが見て取れます。
他にも、以下のような Jev をリランクに活用するツールを作り、関係ない情報の足切りとして非常に有用だったという報告もあります。
https://secon.dev/entry/2026/09/20/100000-jev-reranker/

そこで今回は、事前にベクトル検索で 20 個に候補を絞り込んだうえで、Jev でリランクするようにしました。
ベクトル検索時のベクトル化には Cloudflare Workers AI でホストされた bge-m3を使用しています。
Jev でのリランクはタイトル・要約などの内容を踏まえて「検索内容と関連しているか」を Noul の質問として投げることで関連度を判定、値が 0.2 以上で返ったものを降順ソートして返しています。

インフラ構成

既存部分を Cloudflare Workers Asset により構築していたため、素直に Cloudflare スタックで全てをそろえる形にしています。
詳細な構成図は以下です。

コンテンツが静的なため、コンテンツ更新時に GitHub Actions で記事内容を Workers AI の bge-m3 モデルでベクトル化したうえで Vectorize に格納し、ベクトル検索で候補を絞ったうえで AI Gateway を通じて Jev でリランクする構成です。

利用してみての所感

検索能力について

正直なところ、もともと実験的にやってみた部分も大きく、Google 検索でサイト内検索の方が結局精度が良いのでは?と思っていました。
ただ、実際やってみると、Jev ではドメイン知識や周辺知識を踏まえて検索の方向性をカスタムできるのが大きいのか、Google のサイト内検索より使い勝手が良い印象です。
今回の場合、検索対象が機能追加提案なため背景に Go 言語の仕様などがあり、単語としては登場していないが文脈を考えると関連性がある場合があります。

例えば、以下の「generics」で検索した結果などでは差がはっきり出ます。
Jev による検索結果: https://go-proposal-weekly-digest.mazrean.com/search/?q=generic
Google 検索結果: https://www.google.com/search?q=site:go-proposal-weekly-digest.mazrean.com+generics
今回実装した Jev の検索結果では含まれる以下のプロポーザルが、Google のサイト内検索では含まれません。
このプロポーザルは最下部の議論過程にわずかに含まれている通り、ジェネリックメソッドの機能が追加されることで可能となった機能で、ジェネリクスに関連したプロポーザルです。しかし、Google 検索ではこの背景を認識できていない結果、検索結果に出てきません。
https://go-proposal-weekly-digest.mazrean.com/2026/w26/54297

このように、ドメイン知識を踏まえた検索が可能になっている結果なのか、結果的には Google 検索よりも使い勝手の良い検索結果が得られているように思います。

レイテンシについて

同様の構成で速度面を検証した記事として以下があります。
https://zenn.dev/henteko/articles/1d159d10413312
上記記事では残念ながら Jev には現状日本のサーバーがなくネットワークレイテンシが大きい結果、Jev 本来の速度を生かしきれず結果が返るまでに数百 ms かかるという結果でした。
また、Cloudflare AI Gateway ではリクエスト間隔があくと接続が切れてレイテンシが悪化することも観測されています。

今回実装した検索 API でもこれを裏付ける挙動となっており、間隔を開けずにリクエストを行うと数百 ms 程度で応答が返り、間隔があくと1秒以上のレイテンシとなるという挙動になっています。
そこまでシビアなパフォーマンスを求められる機能ではないため、開発の楽さを優先して今回は Cloudflare AI Gateway 経由で Jev を利用していますが、レイテンシ悪化がユーザー体験において重要な場面では注意が必要そうです。

まとめ

Jev を利用して低コストで高品質なページ内検索を実現する方法を紹介しました。
興味本位で実装したものでしたが、思った以上に実用性のある形で仕上がり良かったです。
思い返すと、数年前までは低コストで検索を実装しようすると DB 内の LIKE 検索でごまかすか、メモリのコストが許容できるなら elasticsearch で全文検索になる印象でした。それが AI 全盛になったことでベクトル検索が無料枠で簡単に使えるようになったり、最近では Jev が登場したことで機械学習ベースの検索が使用できたりで、数年で大きく状況が変わったように思います。
この記事が小規模な開発での検索の品質向上に役立てば幸いです。

脚注
  1. 自分のサイトで検索するために、Google に移動するという不毛なことをすることがそこそこ出てきていました ↩︎

  2. このあとも他も類似物作って競争激化する気がしており、定期的にクレジット配られる気はしています ↩︎

Discussion