VWork バイブコーディングフレームワーク

NamazuからFessへ——日本発の全文検索OSS「Fess」をdockerで立てて45本のPDFを索引し、ローカルLLMで「聞けば答える」を10問で実測(検索10/10・回答9/10)

数万件の技術資料PDFを Namazu で全文検索し、AIチャットが答える仕組みを当社は実用化しています(開発実績の記事)。Namazu は枯れていて安定していますが、これから新しく立てる会社には「後継は何か」と聞かれます。答えは Fess です。日本発(CodeLibs)、Apache-2.0、OpenSearch を土台にした全文検索サーバーで、管理画面・ドキュメントとも日本語があります。

この記事では、Fess を docker で立て、当社の技術記事45本をPDFにして索引し、ローカルLLM(gemma4)を回答役にして「聞けば答える」を10問で実測しました。結論を先に書きます。

構成

立て方(docker)

OpenSearch のために、ホスト側で先に1つ設定が要ります。

sudo sysctl -w vm.max_map_count=262144

compose は公式の compose.yamlcompose-opensearch3.yaml をそのまま使えます。当社は2本を1本にまとめ、fess01 のポートを 127.0.0.1:18371:8080 に、./docs:/opt/fess/docs:ro を足しました。docker compose up -d で、両コンテナが healthy になるまで約2分でした。

管理画面は /login/(初期は admin / admin)。管理APIを使うには、管理画面の「システム → アクセストークン」で {role}admin-api の権限を持つトークンを作ります。

踏んだ罠3つ

1. 管理APIの「作成」は POST。公式の解説記事(13系)では PUT /api/admin/fileconfig/setting で作成していますが、15.8 では PUT が更新で、作成は POST です。PUT で作ろうとすると「ID is required. Version No is required.」が返ります。ジョブの即時実行は PUT /api/admin/scheduler/{id}/start でした。

2. ファイルクロールの「含めるパス」にディレクトリも入れる.*\.pdf$ だけにすると、出発点のディレクトリ自体が除外されて中を辿れず、クロールは「完了」するのに索引が0件になります。file:/opt/fess/docs/.* のように配下全部を含めて解決しました。

3. 権限を入れないと検索に出ない。管理APIで作ったクロール設定は「権限」が空になり、索引された文書に役割が付かず、匿名の検索では1件も出ません(管理画面の一覧には30件見えるのに)。設定の権限に {role}guest を入れて再クロールすると出るようになりました。管理画面から作れば既定で入る項目なので、APIで作るときだけ踏む罠です。

もう1つ、検索APIの場所も変わっていました。15.8 では /json//api/v1/documents は無く、/api/v2/search?q= です。

実測1: 索引と検索

項目 実測
索引対象 PDF 45本(16MB・日本語の技術記事)
クロール〜索引完了 約40秒(2スレッド)
検索の応答(/api/v2/search 7〜31ms
「Vikunja」「Zammad Weblate」「商圏 到達圏」など9語の検索 9語すべてで正しい記事が1位

Namazu と同じく、専門用語や製品名のような固有の語はキーワード検索で確実に当たります。

実測2: AIに10問聞く

記事に答えが書いてある質問を10問用意し、「正解のPDFが上位5件に入ったか」「答えに正解の数値・語が含まれたか」を分けて数えました。

構成 正解PDFが上位5件 答えが正解
Fess のスニペット(検索結果の要約文)だけを LLM に渡す 8/10 4/10
ヒットしたPDFの本文から検索語の周辺を切り出して渡す 7/10 5/10
切り出しを「一致語の多い区間」順に並べ、LLMの検索語で0件なら固有名詞1語で再検索 10/10 9/10

1回目の 4/10 は、検索は当たっているのに LLM が「資料に記載がありません」と答えるケースが大半でした。Fess が返すスニペットは200文字程度の要約で、数値や条件が入っている段落まで届かないためです。Namazu の案件で当社が最初にやったのと同じ「検索でファイルを特定し、本文の該当箇所だけを渡す」を Fess でも入れると 9/10 になりました。最後に残った1問は、答えが記事の別の段落にあってプルリクエスト番号が切り出しに入らなかったもので、LLM は正直に「記載がありません」と答えています。

回答までの時間は1問あたり3〜5秒(検索語の生成と回答の2回、gemma4 12B)でした。

Namazu と Fess、どちらを選ぶか

まとめ

当社は、この構成の回答役に買い切りの Kurage Light ChatBot(税込55,000円) を使い、Namazu でも Fess でも接続します。全文検索のオープンソースを実測つきで比較した一覧は 全文検索システムのオープンソース一覧・比較、Fess と Namazu それぞれの解説は Fess の紹介ページNamazu の紹介ページ にあります。

参考