LlamaIndexを使って手を動かしてみようということで、gawkプログラマーが使える、質問回答アプリケーションを作ってみた。
LlamaIndexとは
LlamaIndexという、LLMアプリケーションのためのフレームワークがある。 Pythonで書かれたプログラムで、内部でOpenAI APIを実行するが、その前後の処理なども行ってくれるものである。
LlamaIndexがどのようなものかの説明は、次の記事がわかりやすい。
Llamaindex を用いた社内文書の ChatGPT QA ツールをチューニングする - GMOインターネットグループ グループ研究開発本部(次世代システム研究室)
記事の中程の、LlamaIndex 処理フローに丁寧に書いてある。主に以下のことをやっているようである。
- 事前に与えられた知識となる文章を適切に分割し、embeddingでベクトル化しておく
- 質問文をembeddingし、ベクトルの類似性を元に、関連の文章を取り出して、LLMに一緒に渡す。
LlamaIndexを使うと、モデルが学習済みで無い、かつ、一度に与えられる上限を超えた沢山の文章をベースに、文章生成ができる。
公式ドキュメントにチュートリアルが用意されているので、それを動かして雰囲気を掴んだ。
gawk-rubber-duck
LlamaIndexをつかってみたいということで、一つアプリケーションを作ってみた。
最近趣味でgawkのコードを書いているのだが、そのとき、gawkの公式マニュアルである、The GNU Awk User's Guideをよく参考にしている。このマニュアルは分量がそこそこある英語の文章で、これをLlama-Indexと組み合わせて、gawkに特化した文章生成ができたら面白いのでは無いかと思ったのが、発想のはじまり。
ラバーダック・デバッグという言葉があるように、プログラマーの相棒といえばアヒルだろう。今回は賢いアヒルを用意したつもりでgawk rubber duckと名付け、gawkの質問に答えるWebアプリケーションとして作成/公開した。
作り方
以下、どのように作ったかを記録しておく。
インデックスの作成
まず、事前準備として、gawkの章ごとに分割されているHTML版のマニュアルをダウンロードし、HTMLタグを取り除いてプレーンテキストにする。(プレーンテキスト版も配布されてはいるが、全セクションが1つにまとまったファイルなので、意味のある単位で最初から分割されているHTML版のものを使った)
- gawk-rubber-duck/pipeline/download.sh at main · yammerjp/gawk-rubber-duck · GitHub
- gawk-rubber-duck/pipeline/html2txt.js at main · yammerjp/gawk-rubber-duck · GitHub
次に、これをLlamaIndexに渡すと、入力が一定の粒度に分割され、それぞれがembeddingによってベクトル化された上で、JSONファイルとして出力される。
なお、多数の文章をOpenAI APIに渡すので、事前に金額感をつかむために、tiktokenというライブラリを使って、トークンの消費量を計算してから行った。
JSONに保存された文章やベクトルを元に、回答生成するのも数行でかける。
Webアプリケーションにする
Flaskを使って、HTTPリクエストを受け付けるようにする。
リクエストごとにOpenAI APIを実行するので、IPアドレスベースのレートリミットを導入した。Flask-Limiterと、記憶領域には、無料枠のあるMongoDB Atlasを、パスワード認証で使っている。
できたアプリケーションはDockerでまとめて、Cloud Runに載せた。OpenAI API Keyと、MongoDBへの接続情報は、シークレットマネージャで環境変数から差し込んでいる。
感想
実際のところ、今回のアプリケーションはひとまず作って公開してみた、という程度で、どこまで実用かはまだ未知数。
LlamaIndexを使って試してみる、というのはそれこそPythonのプログラムを10行程度書けばできてしまった。入力を分割したり、ベクトル検索したりという部分も含めて何もしなくてもいいので、とりあえず試してみる、というのがとてもやりやすい。
求めていた回答が出ているかといわれると、ちょっと微妙で、今回でいえば以下がみえている課題
- 適切な文章を探せるか
LlamaIndexは、与えた文章を、最初にベクトル検索で絞り込むので、そのときに目的のものが絞り込めなければ、良い結果が出ないようである。例えば入力を日本語で与えると、そのままembeddingしても関係のある文章を引っ張って来れないようで(ここ間違っていたら指摘してください)、英語に翻訳してからLlamaIndexに渡すようにしてみたりしている。 - 文章から知見を抽出できるか
今回入力に与えたThe GNU Awk User's Guideはおそらく昔からネット上に公開されているもので、言語モデル自体がこの情報を学習していると思われる。なので、LlamaIndexで情報を与えずとも、元々多少なりとも回答してくれるので、今回の方法が効果的かは疑問がある。 - 品質の評価ができるか
上記を含め、作ったものや仕組みがどれくらい実用に耐えうるか、方式を変えると改善しうるかというのは、評価する必要があるが、こういった具体的なユースケースにおいてどのように評価すればいいのかがわかっていない。作ってみたが、いまのところは作ってみて終わり、となっている。
というわけで、以上、今回は作ってみたという記事。実用的はどうかは疑問があるが、デプロイまでできると一区切りした感があっていい。