見出し画像

mi/旅botに独自RAGを拡張する(1)/「賢いAI」ではなく「気の利くAI」

現在私のAIツールは以下の用途で運用されています。

  • プライベートToDoの進捗管理/指示/示唆

  • 日常アイドルタイムを検出して気分転換示唆

  • 一部家電の音声指示

  • 旅bot会話生成、旅bot blog記事生成

  • AI絵日記会話生成

  • blog記事自己解析(試行中)

エイヤで作って拡張し続けたのでごちゃごちゃなんですが、AIとしての機能も強化したいので、かなり根っこのところからリファクタリングし続けているところです。

次のAIとしての機能強化については、RAG回りを強化するのがよいかなと検討しています。

元々RAGっぽいものは組み込まれている

管理システムmi-Serverには元々RAG的な機能を組み込んでいます。

(Noteを書く前にNotionで書いた記事ですが、Note側には書き写してなかったですね。。書いてたかと思ってました。。)
RAGを知らなかった頃にChatGPTを触っていて「過去知識を会話に入れたい」と思って書いたものです。embeddingもvector検索もなしに、形態素解析だけでRAGっぽい動作を書いたものです。

これを書いてしばらく後にRAGの話しを読んで、考えたのですが「検索の方法が形態素解析での有意単語検索か、文のembedingをvector検索するかの違いだけで、自分の目的である過去を会話を想起するという目的ならば、だいたい同じもの」と判断しました。
「言語を基にするAI」であるLLMは、有意性の高い単語(例えば固有名詞)には関連する情報が集約されており、想起するというざっくりした目的であれば単語での検索で十分です。
少なくとも自分はこれを使っていて困っていない。困っていないなら触らない、はmiの開発ポリシーです。これだって検索を拡張しているという意味ではRetrieval-Augmented Generation (検索拡張生成)と言えます。

この文は「そういえば、ガソリンというと、」で始まっていますが、これは先行する生成文を形態素解析し、名詞などの有意語からランダムで「ガソリン」を選択し、過去ログを検索し、そのログをプロンプトに混ぜて生成しています。

embeddingエンジンとvector検索エンジンの選定

今風のRAG機能を追加するにあたり、日本語文を数字のベクトルに変換するembedding LLMとベクトルから記事情報を検索するベクトル検索エンジンを選ぶ必要があります。

multilingual-e5-large

embedding LLMには、とりあえずmultilingual-e5-largeを使っています。

OpenAIのtext-embedding-adaなどクラウドAPIベースのものも考えたのですが「おそらく検索文の持たせ方など、あーでもないこうでもないと何度もembeding生成を作り直すだろうな」と考え、そうだとするとコストのかかるAPIはつらい、と考えて、わりと使っている情報が多かったmultilingual-e5を使っています。
日本語のembedding LLMはあまり情報がなく、日本語特化でオープンなembeddingローカルLLMがあると助かるのですが、ビジネスと考えるとembeddingはおいしいのでしょうかね?

milvus lite

ベクトル検索についてもそんなに詳しくありません。なので単純にChatGPTに聞きました。
「既存RDBと相性のよいベクトル検索エンジンの候補を教えてください」
5候補くらい出てきたものを見ながらなんとなくmilvusを選んでみました。

ドキュメントのページも応用例のサンプルが多くとりあえずはよいのではないかと。
高機能版は有償になりますが有償を使う気はないのでmilvus liteをdockerで動かす形です。今のところ有償版を使わなければならないような高度な応用は考えてないですし、もしそこで制限が出てきたら別のベクトル検索エンジンに切り替える話しでもよいですし。

当初はこのあたりはLlamaIndexを使うのがよいのかなとドキュメントページを読んでいたのですが、どうもこれもLangChainなどと同じように複数のツールをオールインワンで使う用途のようで、自分がやるならRAG付近の仕組みそのものもゴリゴリ手を入れたいので直接embedding LLMとvector search engineを選んだほうがよさそうと判断して上記の選択をしています。

RAGを使う目的

で、要素技術は調べながら上記のように選んだとして、そもそもどういうRAGを作るかです。

RAGは一般に次のような用途に使われていると考えています。

  • 素のLLMに含まれていない「専門分野の知識、専門ノウハウ」の文章を、文章類似検索出来るようにして、高度な専門分野の思考判断するAIにする

  • 素のLLMに含まれていない「ビジネスルール、実務ノウハウ、社是」の文章を、文章類似検索出来るようにして、実務ビジネスを実行判断するAIにする

。。。いや、そっちは考えていない。そもそもmi用のAIに直接問題を解決することを期待していません。問題を提起してくれるとか、考え漏れの可能性を示唆してくれるとか、元々プライベートToDo管理ツールであり「補助」に徹することを期待しています。

目的が補助だからこそ「整理された専門知識」からでなく、現在の課題に関連する「過去の会話を取りだす機能」=「想起」が重要です。
つまりmi用のAIは、想起RAG(Recall RAG)が目標です。

「賢いAI」ではなく「気が利くAI」にする

「専門分野の知識」=ほぼ全世界で共通、変化は日進月歩だが大枠は年単位
「ビジネスルール」=社内でほぼ共通、変化は短くても3ヶ月くらい

一般にRAGに読ませるデータは「世界共通~社内部署共通」「数ヶ月~数年不変」が想定です。それでビジネス課題をAIで自動解決するのが目的です。

でも私が求めているのはそっちの方向ではありません。miの元々のRAGもどき機能も目的は「ChatGPTに擬似的中期記憶を付加して昨日の話をする」であり、想起の検索をする仕組みです。その延長を最近の技術で強化するのが目的です。

読ませるデータ=
「数分過去~無制限過去(一応1ヶ月くらい)のAIとの会話情報、逐次更新されていく」
解決する課題=
「いつもの飲み物をください」という曖昧な問いかけに、過去会話情報から最適な返答/実行を行う。

つまり「賢いAI」を作りたいのではなく「気が利く」AIが目標です。

第一、「賢いAI」は名だたるAI企業が山ほどお金をかけて血眼でやってる超レッドオーシャンです。そんなのAI大企業に任せておきましょう。

ところで、一連の会話で以前に行った会話の文脈を理解した返答は普通のLLMでも出来ます。

USER:pascalで1から100まで加算するプログラムを書いてください。
GPT:以下はPascalで1から100までの数を加算するプログラムです。・・・
USER:javascriptだとどうなりますか。
GPT:JavaScriptで1から100までの数を加算するプログラムは以下のようになります。・・・

「javascriptで1から100まで加算するプログラムを書いてください」ではなく「javascriptだとどうなりますか」で文脈を読んだ回答をできます。
ですがこれは一連の会話セッションでまとめて入力したトークンの中で出来ているものです。
一旦会話セッションが閉じて別のトークンセットになったら文脈は入りません。環境情報としてシステムプロンプトなどに入れる方法もありますが、動的な更新はしない場合が多いです。

最近のLLMでは一度に入れるトークン数が長くなったので丸一日の会話くらい入るでしょう。しかし仮に丸一日の会話を入れた場合、会話の先頭と会話の末尾のトピックが同じということは考えにくい状況です。一連のレポートを入力した場合は一貫したトピックがあるでしょうが、いくら長く入力できたとしても一般会話を丸一日分では返答の目標が定まらず曖昧な返答にしかならないと考えています。

通常、文が短く、トピック間の時間の間隙が長い一般会話の場合、そのやり方は長文レポートを解析させるやり方とは違うやり方になると考えています。その案としての想起RAGです、

ベクター検索を既存擬似RAGへ追加

具体的な概要ブロック図を示すと次のようになります。

既存RAGと追加RAG

mi-serverは数年以上運転中で、AI機能を追加してから1年以上運転しています。そしてすでに形態素ベースでの想起RAGもどきが動いています。
ですので想起に使えるデータもすでにRDBおよびファイルとして存在している状態です。
これらのログを粗加工して読み込ませてみました。
ざっくり6000件でベクトルdbに読み込ませるのにほぼまる1日かかっています。

さて動かしてみると

キーワードになる単語を表示しなくなったくらいでたいして変わらないように見えます。

要である想起キーワードのサマライズ

当然といえば当然で、単に既存のRAGもどきのロジックにベクター検索を追加しただけです。ブロック図でも、単に既存の形態素RAG機能にベクター検索RAGが追加しただけであることがわかります。
それに一方通行な会話合成である旅botは想起RAGの例としては最適ではないという話もあります。

想起RAGの要は、過去会話の適切な要約とその要約を想起目的に最適化した検索処理部分です。そこは今試行錯誤しながら構築しているところです。

そもそも形態素解析検索部をベクター文検索に置き換えるだけなら、AI処理周りをリファクタリングまでは不要です。過去会話の持たせ方から改良途中です。
肩透かしのようではありますが、そこの付近はある程度固まって検証できたらまた記事を書こうかと思います。
でも現状でもいくつか知見は得られてきており、例えばベクター類似文検索よりも形態素有意単語検索のほうが想起検索には向いているのではないかとかいろいろ考えているところです。

「旅の思い出を想起する」が意味するもの

今回の想起RAGの構築に使う過去会話データは次のものになります。

  • ToDoにまつわる相談会話と日常気分転換会話文

  • 旅botの旅記録

  • AI絵日記の記録

日常相談会話とAI絵日記の記録は、目標である「いつものをください」の元データになりうるものです。
問題は旅botの旅記録です。

旅botの旅記録は以前を見て貰えば分かるように「Google Map APIの地域情報+素のLLMが持つ街知識/旅知識+ハルシネーション」で出来た一種の合成創作物です。
しかしこの1年間、地図に沿ってその過程を記録していったのは事実です。その記録にAIが反応するという形で体験していったのは事実です。

それを「思い出」として想起記録に持たせて、

user: 東京はどうでしたか。
AI: 大田区のランチがおいしかったですよ。ホテルもきれいだったです。

と答えたとしたら、それは単なる創作なのか、それとも(人にとって非リアルだがAIにとってリアルな)旅の思い出の想起と言えるのか。

まぁトータルリコールとかマトリックスみたいな話がそろそろ現実に来ているのかもと思う訳です。

(余談)

文脈が会話セッション間をまたがないのはビジネス的に考えると正しいものです。課題A-数学をAIに解決させた後に、課題B-国語を与えたときに、数学の話しをし出したら意味がわかりません。ユーザAの問いかけをAIに処理させた後にユーザBの問いかけを入力したとき、ユーザAの話しをしだしたらプライバシー漏洩です。

miの用途はシングルユーザなのでそのあたりは考えません。
逆に国語の課題解決時に「じゃ数学的に考えてみましょう」くらい飛躍してくれたほうが面白いです。

また、「専門分野の知識」など一般的にRAGに使うデータが「全世界共通~組織共通」と言いましたが、それはある程度当然な選択です。
全世界共通の知識であれば、一回作ればどこでも誰にとっても有用なAIとして使えます。再販もしやすいです。RAGデータを作るコストも利用者数で折半できますからトータルコストもかけやすいです。
それに機能の検証をするための再現テストもしやすいです。科学の原則として、誰でもどこでも再現可能でない事象は科学として扱われません。最重要な要件です。
一方、1ヶ月の私的な情報の想起が有用かどうかを検証できるのはその本人だけです。「いつものをください」への返答の答えは人と状況によってすべて異なるので、科学的再現検証はより難しいです。

ですが、上手く動けば便利だというのはイメージが伝わるでしょ。

この記事が参加している募集

この記事が気に入ったらサポートをしてみませんか?