top of page

【前編】Langfuse v3.158.0の"fulltext search"を読み解く — その実態は部分一致検索だった

  • 執筆者の写真: 健介 橘
    健介 橘
  • 10 時間前
  • 読了時間: 5分

はじめに

Langfuse v3.158.0(2026年3月13日リリース)で、PlaygroundおよびPrompt Managementのチャットメッセージ編集画面にテキスト検索機能が追加されました。ChangelogやPRタイトルでは "fulltext search"(全文検索)と表現されています。

日本語環境でLangfuseを使っている身としては、「全文検索」と聞くと気になるのが日本語の対応状況です。そこで今回、ソースコードを読んで実装の中身を調べてみました。


この前編では、まず新機能の概要とLangfuseの検索アーキテクチャの全体像を整理し、今回Langfuseに実装された検索機能が、技術的にはどういう仕組みなのかを明らかにします。後編では、ソースコードをさらに深く読み、日本語で使った場合の具体的な挙動や制約について掘り下げます。


今回の新機能:Playground / Promptsのメッセージウィンドウ内検索

今回追加されたのは、Cmd+F(Mac)/ Ctrl+F(Windows)でPlaygroundやプロンプト編集画面内に検索バーが表示され、複数のメッセージウィンドウにまたがってテキストを検索できる機能です(PR #12578 by @nimarb)。マッチ箇所はハイライトされ、前後のマッチへの移動も可能です。プロンプトの編集・比較作業中に、特定のフレーズや変数名を素早く見つけたい場面で役立ちます。


実際のプロンプト編集画面における検索の様子
実際のプロンプト編集画面における検索の様子

Langfuseにはすでに2つの検索機能が存在していました。2025年5月に導入されたTraces / Observationsのinput/output検索(サーバーサイドでClickHouseに問い合わせる方式)と、2025年7月に導入されたPrompt Management一覧でのプロンプト名・本文検索(PostgreSQLに問い合わせる方式)です。今回のPR #12578は、これらに続く3つ目の検索機能として、クライアントサイド(ブラウザ内)で完結する形で追加されました。


"fulltext search"の中身を見てみよう

PRタイトルやChangelogではこの機能を "fulltext search" と表現していますが、この用語は文脈によって指す範囲がかなり広いです。ElasticsearchやPostgreSQLのtsvector/tsqueryのようにトークナイズと転置インデックスを伴う狭義の全文検索を指すこともあれば、単にテキスト本文を対象にした検索という広い意味で使われることもあります。


実際にソースコードを読んでみると、Langfuseの実装はJavaScriptのindexOf()やSQLのILIKE '%...%'による部分一致検索(substring search) でした。転置インデックスやトークナイザは使われていません。

この違いは、日本語での検索挙動を考える上で重要な意味を持ちます。英語のような言語では、本来はトークンベースの全文検索のほうがステミング(語形変化の吸収)や同義語展開などの豊かな検索体験を実現しやすいです。一方、日本語のように分かち書きしない言語ではトークナイズ自体が難しいという問題があります。Langfuseの実装は言語を理解する全文検索ではなく部分一致検索であるため、英語でも高度な検索機能は提供されないものの、日本語でも無難に動くという状況になっています。


以降、技術的な区別を明確にするため、Langfuseの検索機能は実装に即して「部分一致検索」と表記します。


Langfuseの検索アーキテクチャは3層構造

前述のとおり、Langfuseの検索機能は3つのレイヤーに分かれています。それぞれの仕組みをもう少し詳しく見てみましょう。


レイヤー1:クライアントサイド検索(今回のPR #12578

Playground / Prompt Managementのメッセージ編集画面で動作します。完全にブラウザ内で完結し、サーバーへのリクエストは発生しません。


レイヤー2:ClickHouseによるTraces / Observations検索

2025年5月のLaunch Week 3で導入された、traces/observationsのinput/outputに対する検索です。v3で導入されたClickHouseバックエンドに対してILIKEクエリが発行されます。


レイヤー3:PostgreSQLによるPrompt一覧検索

2025年7月に追加されたPrompt Management一覧のプロンプト本文検索です。こちらはPrisma経由でPostgreSQLにILIKEが発行されます。


この3つは見た目上は同じ「検索バー」ですが、裏側の仕組みはそれぞれ異なります。一方ですべてのレイヤーが「部分一致検索」というアプローチで共通しています。トークナイザやn-gramインデックスといった狭義の全文検索の仕組みは使われていません。


コラム:全文検索と部分一致検索、そして日本語

「全文検索(Full-Text Search)」は技術的に厳密な意味では、文書をトークン(単語や部分文字列)に分割し、転置インデックスを構築した上で高速にキーワードを引く検索手法を指します。ElasticsearchやPostgreSQLのtsvector/tsqueryなどが代表的な実装です。対して、SQLのLIKE '%keyword%'やJavaScriptのindexOf()は、テキストを先頭から順に走査する部分一致検索です。字面として完全一致しているものしか検索できず、語形変化や同義語の吸収は行われません。


この区別が特に重要になるのが日本語です。狭義の全文検索で必須となるトークナイズは、英語のようにスペースで単語が区切られる言語では単純ですが、日本語は分かち書きをしないため、形態素解析(MeCab等)やn-gramといった特別な処理が必要になります。これらにはそれぞれ辞書依存性や偽陽性(「京都」で「東京都」がヒットする、いわゆる「京都東京都問題」)といった課題があります。


部分一致検索はトークナイズを経由しないため、「日本語がうまくトークンに分割できず検索自体が機能しない」という問題は発生しません。ただし万能ではなく、偽陽性の問題はn-gramと同様に存在しますし、活用形の吸収や表記揺れの統合といった形態素レベルの正規化も行われません。


前編のまとめ:現行の検索をどう理解して使うか

現時点のLangfuseの検索は、「語を理解する検索」ではなく「文字列を探す検索」です。入力した文字列がそのまま含まれているかどうかを探す仕組みなので、日本語でも基本的な用途では問題なく使えます。

ただし、ソースコードを詳しく読むと、いくつかの気になる挙動も見えてきました。後編では、PR #12578のコードリーディングを行い、TextモードとChatモードの検索挙動の違い、3つのマッチングシステムの不整合、サーバーサイド検索の日本語対応について掘り下げます。

後編はこちら:「ソースコードから読み解くLangfuse検索の挙動と制約」リンク

コメント


bottom of page