GPU代10ドルで自作検索エンジン——動いたのに拾ってきたのは「間違ったウェブ」だった

スポンサーリンク

GPUのレンタル代が約10ドル、使ったストレージは1GB未満。それだけの元手で、約56万件のサイトを索引した自分専用の検索エンジンを作った人がいます。英国ノッティンガムのソフトウェア開発者、Alex Morley-Finch氏です。名前は「Marlin(マーリン)」。映画『ファインディング・ニモ』で海じゅうを探しまわるお父さんカクレクマノミから取ったそうで、コードはGitHubでオープンソースとして公開されています。

ただしこの話、いちばん面白いのは「安く作れた」という部分ではありません。最初のバージョンは数時間で動いたのに、集まってきたのは本人いわく「間違ったウェブ」だった——その顛末(てんまつ)です。

大手検索で埋もれてしまうもの

Morley-Finch氏がMarlinを作った動機は、はっきりしています。個人のポートフォリオ、ジン(個人で作る小さな冊子)、ちょっと変わったアートプロジェクト、ひとりで開発しているソフト。そういう「誰かが何かを作って公開しているサイト」を探したいのに、大手の検索エンジンではそれらが企業サイトやSEO対策された記事の下に沈んでしまう。だったら、自分の関心があるものだけを索引する検索エンジンを自分で持てばいい、という発想です。

日曜の深夜2時、眠れずに検索結果へのいらだちを募らせた氏は、ターミナルを開いて計画を書き始めました。世の中のドメインはおよそ4,000万件。1件あたり1KBのメタデータを保存しても40GB程度で、個人のデータベースで十分に扱える量です。しかもMarlinが取りに行くのは各サイトのホームページ(トップページ)だけで、サイト内の全ページは巡回しません。ページの本文も保存せず、要約が終わったら捨てる設計です。だからストレージが1GBに収まります。

Marlinの構成

仕組みは4つのプロセスに分かれています。ドメインのホームページを取りに行く「フェッチャー」。取ってきたページを小型の言語モデルに読ませ、サイト名・数行の要約・カテゴリ・タグを書かせる「ワーカー」。おかしなページが索引に紛れ込まないよう見張る「スチュワード(執事)」。そして検索画面と管理ダッシュボードを提供するAPIとWeb UIです。

言語モデルには、Googleが公開している軽量モデルGemma(ジェマ)の4Bパラメータ版を使っています。手元のPCでも動くサイズですが、氏の環境では1秒に1ページの処理が精一杯。そこでクラウドのGPUを時間貸しで借り、同じモデルを高い並列度で回しました。うまく設定できたときの処理速度は毎分約600ページ、レンタル料金は1時間あたり約35セント。つまり10万サイトの索引化に約1ドルという計算です。冒頭の「約10ドル」は、このGPU代の合計にあたります。

数時間で動いた最初の版と「間違ったウェブ」

最初のバージョンは、着手から数時間で動きました。ドメインのサンプルを渡すと、次々に要約が付き、検索もできる。ここまでは順調です。ところが日曜の午後、実際に何がカタログ化されたかを確かめてみると、様子がおかしい。索引の9割以上が、企業サイトと技術文書で埋まっていたのです。氏はこれを「間違ったウェブだった」と表現しています。

原因は、種として与えたドメインのリストに偏りがあったうえ、クローラー(自動巡回プログラム)が「次にどこを見に行くか」について何の方針も持っていなかったこと。リンクをたどって広がっていくクローラーは、放っておけばウェブの構成比をそのまま持ち帰ってきます。そしてウェブの大部分は、企業サイトなのです。個人サイトを探すつもりで作った検索エンジンが、集めることには成功して、選ぶことに失敗した。検索エンジンの本当の難しさは、集めることではなく、何を集めないかを決めることでした。

遮断ではなく重み付けによる制御

ここで氏が採らなかったのが、企業サイトをブロックするという分かりやすい方法です。理由は、退屈な企業ページからでも、誰かの個人ブログへのリンクが張られているかもしれないから。入口を塞いでしまうと、その先にある目当てのサイトごと失ってしまいます。

代わりに導入したのが、巡回の順番待ちリストに優先度を付ける仕組みでした。「ポートフォリオ」「ジン」「ソフトウェア」と分類されたページから見つかったリンクは順番の先頭近くへ、「企業」「技術文書」と分類されたページから見つかったリンクは後ろへ回す。優先度は1つのテキストファイルに書かれた数値で、氏はこのファイルを「その週末のハンドル」と呼んでいます。数値を変えては1時間ほど流れてくるサイトを眺め、また変える。この地道な操縦の繰り返しで、クロールの中身が少しずつ狙いに近づいていきました。

もっとも、問題は次々に形を変えて現れます。日曜の夜にはTumblrやNeocitiesの個人ページが大量に流れ込み、放っておくと索引全体がそれらで埋まりそうになりました。ここでも全面ブロックではなく、「1つのドメインからサブドメイン100件まで」という上限で対応。このルールを一度適用しただけで、順番待ちから4万5,000件超が消えたそうです。また、規模が大きくなると目視の見張りが追いつかなくなったため、怪しいほど大量にページを出しているドメインからサンプルを抜き取り、言語モデル自身に「ブロックすべきか」を判定させるスチュワードを深夜に追加。この自動見張り役は、ホテル予約系の量産サイトを中心に177ドメインを自力でブロックし、索引を約6万5,000件から56万件まで育てる立役者になりました。

タグ12万個が示した「AI任せ」の限界

クロールの制御がついたあと、氏が「この方式を試す人に一番効いてくる」と警告しているのが、分類の後始末です。Marlinでは、カテゴリ名もタグ名も言語モデルに自由に発明させていました。あらかじめ分類の一覧を人間が決めるのではなく、モデルに命名させれば、ウェブの実態に合った分類が自然に育つはず——という目論見です。

立ち上がりを速くする意味では、この判断は正しかったと氏は振り返っています。ただし代償も大きく、最終的にカテゴリは671種類(多くは1回しか使われていない)、タグは12万1,000個以上にふくらみました。タグの半分以上は、たった1回しか登場しません。モデルが呼び出しのたびに微妙に違う綴りで書いてしまうのが主な原因です。氏は手作業でマージするツールを自作してひどい部分を整理しましたが、結論ははっきりしています。「モデルに自由にやらせる方式は、すぐに限界が来る」。趣味の規模を超えるものを作るなら、最初から固定のカテゴリ一覧に縛るか、後片付けの時間をきちんと見積もっておくべきだ、と。

ちなみに誤分類には笑える例もあって、ドメイン名に”furry”という文字列を含むだけの中身が空っぽのページ(ドメイン販売業者の仮ページ)を、モデルが「ファーコミュニティ向けのサイト」と要約したことがあったそうです。本文がほぼ無いのに、ドメイン名だけから存在しないサイト像を作り上げてしまった。この一件から氏は「見えている本文>タイトル>ドメイン名からの推測、の順で信用する。中身が空のページはそもそもモデルに聞かない」というルールを導いています。

再現するときの前提と注意点

誤解のないように書いておくと、これは「10ドルでGoogleの代わりが作れる」という話ではありません。56万件という規模は、大手検索エンジンの索引とは桁がいくつも違います。索引しているのは各サイトのトップページだけで、サイト内のページ検索はできません。JavaScriptで描画されるページは読めない設計のため、クロール全体の約15%は中身を取れずに終わっています。10ドルという金額もGPUのレンタル代だけで、本人が費やした数日分の時間は含まれていません。氏自身、現在の設計は趣味の規模向けだと認めています。

もうひとつ、Morley-Finch氏が作った56万件の索引そのものは配布されていません。Marlinは誰でも検索しに行ける公開サービスではなく、公開されているのはコード(MITライセンス)です。つまりこれは「完成品をどうぞ」ではなく「同じものを自分の関心に合わせて作れます」という話。リポジトリには手順書やクラウドGPUの設定例がそろっていて、氏は「週末で実装できるし、GPU代が試さない理由になる金額ではない」と呼びかけています。

大手検索への不満はよく聞きますが、そこから「なら自分の分は自分で作る」まで行き、しかも費用と失敗談まで開示してくれた例はそう多くありません。クローラーに個性を持たせるという発想は、検索に限らず、AIに情報収集を任せるあらゆる場面に応用が利きそうです。

出典

The Registerの記事:Give Google the boot by building your own search engine(Brandon Vigliarolo、2026年8月13日)

開発者本人による解説記事:How I built a 500k-Domain Search Engine for Makers in a Weekend for $10

ソースコード:GitHub – alexmorleyfinch/marlin(MITライセンス)

コメント

タイトルとURLをコピーしました