lexsim を公開しました — 辞書不要の多言語テキスト類似度エンジン
形態素辞書なしで日本語にも対応する語彙的類似度エンジン lexsim を、Rust クレートとして公開しました。handoff-mcp のメモリ検索を支えています。
Handoff のメモリを検索するために
Handoff を開発する中で、セッションをまたいだメモリの検索と重複排除が必要になりました。たとえば「atomic_write を必ず使う」という教訓を以前のセッションで保存していたら、次のセッションで似た場面に出くわしたときにそれを引き出したい。逆に、同じ教訓をもう一度書こうとしていたら、重複と気づいて止めたい。
既存の NLP ライブラリは、日本語を扱うために数 MB の形態素辞書を要求するものが多く、MCP サーバーの依存としては重すぎました。lexsim は辞書をまったく使わずにこれを解くために書いたクレートです。
2 つの問いに答える
lexsim が扱うのは、シンプルな 2 つの問いです。
- 「これは同じものか?」 — Jaccard 類似度で判定します。メモリを保存する前に、すでに同じ内容がないかを確認する場面で使います
- 「これに関連するものは?」 — BM25 でランキングします。いま取り組んでいるタスクに関連する過去のメモリを引き出す場面で使います
どちらも同じトークナイザの上に載っているので、「重複判定では一致するのに検索では見つからない」といったちぐはぐな挙動が起きません。
辞書を持たないという選択
日本語のように空白で区切れない言語では、文字を 2 つずつ重ねながらスライドして比較の単位にします。たとえば「メモリ機能」なら「メモ」「モリ」「リ機」「機能」の 4 つに分かれます。辞書で正しい単語に区切る必要がないので、どんな文でもそのまま処理できます。全角・半角の揺れは正規化で吸収し、言語をまたぐ識別子や固有名詞も拾います。
辞書を持たないので、同じ言語の中でも「消す」と「削除する」のように語彙が異なる言い換えは検出できません。日本語と英語のように言語をまたぐ場合も同様で、「削除する」と "delete" が同じ意味だとは認識できない。共通の識別子や固有名詞があれば拾えますが、翻訳的な類似度判定は範囲外です。この先、必要になれば辞書クレートを別に開発するかもしれません。
公開について
Handoff のメモリエンジンとして実際に動いているコードを、独立クレートとして切り出しました。crates.io と GitHub で公開しています。
