技術の話をしたい気分なので、手元にあるメモから何かを出す。 今回は、llama-indexの話をしてみる。現時点の私の理解を元に書いているため、間違っている場合は、指摘いただけると助かる。
llama-indexとは
簡単にいうと、RAGを簡単に実装するためのライブラリ。
RAG = Retrieval-Augmented Generation
RAGとは
LLMに何からの質問や問い合わせを投入して回答を作成させたいことがある。しかし、LLMをトレーニングするのはコストがかかりすぎる。なので、トレーニング済みのLLMに知識を注入するアプローチがある。それがRAG。
例えば、次のようなプロンプトを作る
これからユーザーからの質問を渡します。後続の前提知識に従って回答を生成してください。 ## 質問 {question} ## 前提知識 {context}
questionにユーザーからの入力を突っ込んで、contextに関連する前提知識を突っ込む。
そうして回答を生成すると、固有の知識に基づく結果を生成できる。
例えば、こんなプロンプトがあり、それを投入するケース。
これからユーザーからの質問を渡します。後続の前提知識に従って回答を生成してください。 ## 質問 matobaの2024年の目標はなんですか? ## 前提知識 ... ここに今年の目標のブログの本文を全て投入する
これを実行すると以下のような回答が得られる。
Matobaさんの2024年の目標は、ブログの更新数を増やすことです。具体的には年間で120記事(月10記事)を目標にし、ストレッチ目標として年間180記事(月15記事)を目指しています。この目標は、活動の多様化に伴い経験や考えを共有するため、そして情報の消化不良を防ぐために設定されています。
実装の課題
このRAGの実装に関して、課題になるのは前提となる知識をどうやって持ってくるか、になる。 適切な知識を投入することができれば、適切な回答を得られるし、そうでなければ適切な回答が得られない。
また、知識を何らかの基準でソートした後に、一番上にあるかどうかが重要になってしまう。それをどう考えるか。複数の知識を入れたい時にどうするか。
他に、その知識をどうやって収集して管理するか問題もある。Web上にある情報をクロールしたいこともあれば、何らかのドキュメントDBから持ってきたいこともあるし、ローカルからインポートしたいこともある。
あと、OpenAIの進化で気にする必要性が低くなったが、以前はコンテキスト長が長いとプロンプトに収まらなかった。なので、適切なチャンクに分割して引き出せる状態にしつつ管理する必要もあった。
この辺の課題をよしなにやっていくのがllama-index。
知識収集のプラグイン化
知識をどこかからクローリングしてくるわけだが、サービスごとのクローラーを作るのは面倒だし使いまわせそう。 そんなこんなで、llama-indexには、クローラーをプラグインとしてimportできるようになっている。
それは今では llama-hubという名称のライブラリで配布されている。
例えば、はてなブログから知識を収集するプラグインはここにある。
https://llamahub.ai/l/hatena_blog
余談だが、半年ほど前に、このブログをデータソースにしたRAGアプリケーションを作った時に上記を見つけた。そして、ついでに自分が必要な情報が足りなかったので、PRを送ったところマージされた。なのでcontributorになった。
ベクトル検索
ユーザーからの自然言語の問い合わせを回答を生成することを考えた際、収集した知識から適切な知識を引き出したい。そんな時にベクトル検索の話が出てくる。
OpenAIはemmbeding APIというAPIを提供している。これは、自然言語の文字列をベクトル化するAPIである。 そして、そのベクトル化した情報をベクトルDBに格納する。 そして、問い合わせもベクトル化して、ベクトル間の距離で検索するのがベクトル検索である(と私は理解している)
ベクトルDBには、そもそもの文字列と、その文字列をベクトル化した情報を格納しておき、ベクトル情報に対して検索をかける。そして、元々の文字列を引き出してプロンプトに埋め込み、結果を生成する、という流れになる。
llama-indexを利用すると、プラグインで収集したデータを簡単にベクトルデータベースに格納できる。
ベクトルデータベース
ベクトルデータベースといっても様々なものがある。
llama-indexはさまざまなベクトルデータベースをサポートしている。というか、llama-indexは内部でLangChainを利用しており、LangChainが様々なベクトルデータベースをサポートしている。
Vector Stores - LlamaIndex 🦙 0.9.24
どう実装するか
しばらく前に実装して動かしてないので、ここは省略する。
半年ほど前は頻繁にllama-indexを動かしていたが、その当時は頻繁なリファクタリングが入っていた。Web上にあるコードもいつのものかわからないが、LLM関係のライブラリはすぐにリファクタリングが入り、動かなくなるのを見かける。
なので、最新のコードやドキュメントを読むのが良いし、使う時には当然バージョンを固定して慎重にバージョンをあげるのが良い。
そもそも論で言うと、LangChainにしてもllama-indexにしても使いたい機能に対してライブラリの抽象度が高かったり、付属している機能が多すぎたりするので、参考にして実装するほうがいいかもしれない。
終わり
とりあえず、ここでは簡単にllama-indexを紹介した。