地平線まで行ってくる。

記録あるいは忘備録。時には検討事項。

メモ:RAGのハイブリッド検索を構築してみる

RAGのハイブリット検索を試してみます。ハイブリットということで複数の検索方法で検索した結果をRAGで利用するというものです。Langchainでは、multiple retrieversとして、EmsambleRetrieverを使った実装が紹介されています。

 

python.langchain.com

 

ベクトル検索とキーワード検索を組み合わせたものが、多いようです。密なベクトルと疎なベクトルの組み合わせです。RAGでは、ベクトル検索が主力のようですが、キーワード検索もいろいろな利点があります。例えば「RAGって何?」という問いかけの場合は、単純に「RAG」というキーワード検索の方がヒットするかもしれません。実際に、検索していてもキーワード検索の方が望む結果になったり、ベクトル検索の方が望む結果になったりします。どちらを利用するかといった戦略は、結果をみながら使い分けているのがヒトによる検索手法ではないでしょうか。

 

RAGにおけるハイブリット検索は当初から検討・実装されていました。今更やるのか案件です。サンプル見ながら実装するにしても、日本語の実装の場合は形態素解析を伴います。実際に利用するには、ベクトルデータの永続化くらいは考慮しないと実用に耐えません。それだけでは寂しいので、ハイブリット検索とキーワード検索のウェイト調整に加えて、それを動的に用いる実装を簡単に行いました。

 

手軽に日本語のテキストのデータを永続化(保存)したHybrid retrieverが欲しかったので、お勉強がてら実装をGamini君やCopilotのアシストで実装してみました。小規模のRAGなら利用には耐えられるのではと思います。

 

他の方が高度に実装されているだろうと思いますが、やってみることに(自己満足的)意義があります(笑)

 

盛り込む機能:

- 検索戦略の追加・重み調整: ハイブリット検索の戦略関数や重みを決定できるようにした。
- HybridRetrieverとして単体でも利用可能にして、既存のベクトル/BM25リトリーバーと組み合わせて使います。
- キーワード検索には、SudachiPyによる形態素解析とBM25を組み合わせます。

- streamlitを使った簡単なUIでお試しができる。

 

おいてきぼりの機能:

- キーワード検索のデータの状態保存はpickleを使っています。大規模なデータの取り扱いになると、語彙数が増えるとメモリ不足になるかも。

 

ちゃんと実装するなら:

 - elasticsearchを使って、キーワード検索とベクトル検索を実装する。

 

できたもの:

github.com