lexsim
辞書不要・多言語対応の語彙的類似度エンジン。「同じものか?」と「関連するものは?」の 2 つの問いに、ひとつのトークナイザで答える Rust クレート。handoff-mcp のメモリ検索と重複排除を支えている。

AI コーディングエージェントとの作業で、前のセッションのメモリから関連する情報を引きたい場面と、いま書こうとしている内容がすでに保存済みでないかを確かめたい場面があります。lexsim はこの 2 つを、ひとつのトークナイザの上で解くために書きました。
「これは同じものか?」には Jaccard 類似度で答え、「これに関連するものは?」には BM25 ランキングで答えます。テキストが変わったかどうかを追跡するコンテンツハッシュもあります。
いちばんの特徴は、形態素辞書をまったく使わないことです。日本語や中国語のように空白で区切れない言語には、文字を 2 つずつ重ねながらスライドしてトークンを切り出します。辞書が要らないので依存は軽く、どの言語でもそのまま動きます。ただし辞書を持たないぶん、日本語と英語のように語彙がまったく異なる言語間で「意味が同じか」を判断することはできません。
もともと Handoff のメモリエンジンとして開発し、独立クレートとして切り出しました。実際の運用の中で磨かれたコードです。
主な特徴
解決した課題
・セッション間のメモリ検索で、日本語も英語も同じように扱いたいが、形態素辞書は重すぎる
・重複チェックと関連度検索で、「語」の定義がばらばらだと結果がちぐはぐになる
・MCP サーバーに組み込むので、依存が少なく速いことが前提になる
採用したアプローチ
・文字を 2 つずつ重ねてスライドする方式で辞書なしトークナイズ。正規化で表記揺れや言語混在にも対応
・Jaccard(重複判定)と BM25(関連度ランキング)を同じトークン列の上に構築
・依存は unicode-segmentation と unicode-normalization の 2 つだけ
達成した成果
・handoff-mcp のメモリ検索・重複排除エンジンとして稼働中
・日本語と英語が混在するメモリでも、辞書なしでそのまま検索できる
・crates.io と GitHub で公開し、単体でも利用可能
