ABEJA社・CTO室 室長の村主氏

村主壮悟氏:「ノーコードとChatBotで遊んでいたら、ReActを実装しそうだった話」をしたいと思います。

ABEJAの村主と申します。ABEJAで6年ぐらい働いています。CTO室室長をしたり、Insight for Retailのマネージャーとしてでリテールの領域の話をしたり、プラットフォームの「ABEJA Platform」というMLOpsの基盤の責任者とか。セキュリティマネジメントをやっています。AWSの本を書いていたのですが、全資格が失効になりました。無免許運転をしています。

AIの進化とともに成長してきたABEJA社の取り組み

ABEJAは、2012年ぐらいからディープラーニングを中心にAIのベンチャーをやっています。2022年の夏に独自でLLMを作りました。AIベンチャーです。

ABEJAでの取り組みをサクッとだけお話しします。どういうことをしているのかをお話ししたいと思います。2018年11月に、Googleが「BERT」を発表したことをきっかけに、2022年にけっこうなお金をかけて大規模言語モデルを自分たちで作りました。

お金とGPUを回さないといけないところをがんばって、作っていましたね。今も、ローカルで動くLLMで商用可能であったりして非商用みたいな話があると思うんですけど。そういったものを模索しながら、オンプレで使えるようなものを探したりしています。

(スライドを示して)取り組みの1つですね。他の会社もやられていると思いますが「ChatGPT」を全社で導入しています。あとは「GitHub Copilot X」や「Microsoft 365 Copilot」にも注目をしています。

これも先ほどの「Retail」で、小売り向けにカメラを仕掛けてリアルGoogle Analyticsみたいなことをしているのですが、その画面の中でChatGPTをそのまま導入してみて、お客さまがどういう使い方をするのかを見ようかなと思っていて、チャットのUIとして導入しています。

そのうちLangChainを使ってやりたいなと思っています。LangChainも、1週間ぐらいでわりとコロコロ仕様が変わっていくので、どのタイミングで突っ込むかについては見合わせているところですが、足が痺れてきたのでそろそろ実装しようかなと思います。

Retailのほうも、サクッといきます。コンビニの中で店舗ごとに目標を設定して、それに対してどういう施策を打って、実際にどうだったかを振り返る機能があるのですが、その施策の登録が大変なんですよね。どういう施策をしますか? どういうアクションをしますか? そういったところでChatGPTを導入しようと思っています。

これはまだ開発予定ですが、施策をサジェストする機能で生成してもらおうかなと思っています。

ほかにはプラットフォームでLangChainやLIamaIndexをMLOpsの基本的な機能としてLangChainを使おうかなと思っています。

Slackと連携するなにかを作ってサーバー管理を楽にしたいと思った

本題に入ります。今回はChatGPTなどを使いながら、ガチャガチャと遊んでいました。やはり昨今、ChatGPTでホスティングするサーバーとしてはLambdaも使えると思いますが、サーバーの管理が面倒くさいなと思いました。

Slackと連携するなにかを作りたいなと思いました。Retailのマネージャーを引き継いだのですが、その「Sentry」のエラーをパッと見てもわからなかったんですね。そのエラーメッセージを解読して、対処方法をChatGPTの普通のUIに聞いたらある程度の回答が返ってきたので、これをSlackと連携したいと思いました。

ただ、そのSlackのWebhookを受けて、OpenAIにリクエストを送るAPIサーバーをホスティングするのをどこで管理しようかなとか、いろいろ考えても面倒くさいなと思ったので、最近ベータ版がリリースされたSlack Platformというものを使ってみました。ですが、コールドスタートしているからか動きが悪かったんです。

そしたら、「Make」というintegromatというんですかね。iPaaSみたいなサービスがあって、それであればWebhookを受けられたことを思い出しました。これだったらサーバーも管理しなくてもいいし、いいなと思って使い始めました。SentryでMakeのWebhookを受け取って、OpenAIで解析、Slackで通知するみたいなことをやってみました。

結果はこんな感じです。「このエラーメッセージは、タイムゾーンのバッチジョブに関する例外が発生したことを示しています」。このエラーに対して「こういう手順で調査を実施してください」みたいな、それっぽいことを言っているような言っていないような感じで書いています。

1回にだいたい500トークンぐらい使っています。OpenAIのAPI利用料だと、1回につき0.001ドルぐらいで、Sentryも爆発する時は、ワーッとループする時があります。それも数十万回ぐらいいって、月5万円ぐらいかかるので、少し高いなと思いました。よく考えたら全部が全部、解析する必要はないかと思いました。

SlackのReactionで解析するようにする

フェーズ2ですね。Slackのリアクションで解析するようにします。毎回解析するのは高いので、Slackの特定のリアクションに反応して解析処理をさせます。

どうせリアクションで反応させるのであれば、複数のリアクションで分岐させようと思って、(スライドを示して)こんな感じで作ってみました。まずSlackのイベントが発生して、Get a Public Channelでどこのチャンネルかを確認して、そこからトラブルシュートの話なのか、要約の話なのかで分岐させて、またSlackに返すみたいなことをやってみました。

ここからは細かい話です。:age1:というスタンプで要約、:error:というスタンプで対処方法、という感じで分岐させる処理を書いています。それ以外のリアクションでは反応しないようになっているのですが、Slackの仕様上、リアクションをHookしてなにか処理しようとした時に、全部のアクションが飛んでくるんですよね。

そこから自分が必要なスタンプだけをフィルタして処理をしないといけないので、毎回、誰かがスタンプを押すたびにイベントが飛んできます。このイベントが飛ぶごとにMakeがかかることになるので、ちょっとお金がかかります。結局のところ、Lambdaなどでもたくさん処理をしないといけないので、必要なスタンプの時だけ動いてくれる仕様にしてほしいなと思いながら作っていました。

リアクションが付いているチャンネルとメッセージを取得して、条件分岐させます。そのトラブルシュートや要約のプロンプトですね。プロンプトで「あなたはシステム管理者です。エラーメッセージを解析して解析方法を提示してください」とか「次の文章を要約してください」みたいなことを入れて、下のほうのメッセージコンテンツで先ほどのSlackの入力された文章をContentに入れている感じです。

あとはSlackに応答させるということで、テキストの対処方法にChatGPTから受け取ったメッセージを流します。スレッドのメッセージIDで、どのメッセージに対してスレッドに返信するかを示します。

実際にできた内容は、:age1:スタンプと、:error:スタンプと、要約と、対処方法の表示です。

2つ前のトピックの図で分岐し始めているので、「あれ? どこかで見たな。これはReActが作れるんじゃない?」と思いました。Microsoftが出しているReActと呼ばれている概念ですね。LangChainでよく使われるツールです。

ReAct(Reasoning and Acting)を作ってみる

フェーズ3です。「野球を始めるんだけど、おすすめの用具を教えて」というところで、まずは「初心者 野球道具 一覧」みたいにWeb検索をして、その内容をもって必要なものを確認する。バットが必要です、グローブが必要です、野球ボールが必要です。それに対して商品DBや検索エンジンに聞きに行って、そのあとに返ってきた数字をお金を計算して、自分で考えて必要なものを揃えていくという概念がReAct(Reasoning and Acting)と呼ばれます。「これができるやん」と思ったんですよね。

先に完成図です。こんな感じです。後ほど説明します。

「要約・Googleカレンダーからの情報取得・トラブルシュート」の完成系

先ほどのような感じではなく、要約とトラブルシュートと、Googleカレンダーから情報を取ってくることを教えてみました。「LLMについてカレンダーで検索してください」と言うと、そのカレンダーでAIについてのカレンダー検索して、要約した状態で出してきます。

それっぽく「〇〇さんと〇〇さんを含め、あらためてやることや進め方について会話する」とか小野寺さんは存在しませんが「主催者は小野寺さん」と、それっぽい文字を生成していました。あとは「2023年4月19日から30分間で」と、30分じゃなかった気がしますがそれっぽく書いてあります。

あと、トラブルシュート系だと「KubernetesがCrashLoopBackOffです。どうすればいいですか?」と、きちんとPodのログを見たり、ディスクリプションを見たり、という回答を返しています。

工夫したこと

Webhookに入力した人のユーザー名やアイコンURLを偽造で投稿する必要があります。スライドには僕の名前が出ていると思いますが、ゴールデンウィークが休みだったので、「休みです」と宣言していました。隅のほうに「アプリ」と書いてあると思いますが、これは自分が投稿したのではなく、アプリが偽造投稿しましたよというメッセージです。アプリが偽造投稿をしています。

ほかには、Reasoningと呼ばれるReActにはReasoningとActionという概念があるのですが、そこで推論をするんですね。「次のケースに当てはまる場合は、次の指示に従ってください」ということで、ケース1「システムエラーを調査している文言だったら『troubleshooting』という文字で応答してください。それ以外のメッセージは不要です」と、プロンプトで制限をしています。

「要約系の作業は『summarize』、「カレンダーの情報取得は『calender』、それ以外のケースはとりあえず『other』など、適当に返信してください」というプロンプトを投げます。回答例としてきちんと「calender」だけの文字を回答してくださいという例を示して処理をしています。そのあとに、「troubleshooting」だったらこのルートに動いてくださいみたいな、条件分岐を行っています。

英語のほうが精度が上がると聞いたことがあったので、条件分岐の時に、「あなたはAdministratorです」など、ステップバイステップを入れてみたりしました。

「要約」と「トラブルシュート」における、取り組みの結果

その結果、トラブルシュートっぽい内容の時には、きちんトラブルシュートのフローに落ち着きました。

「以下の文章を要約してください」であれば、きちんとサマライズをしてくれます。中居くん(中居正広氏)と松本人志さんのお話があったのですが、それもスッと要約してくれました。

「Googleカレンダーからの情報取得」における取り組みで感じたこと

次ですね。「カレンダーのクエリを検索してください」というところだと、カレンダーの連携があります。また、カレンダーの場合はカレンダーの分岐のルートにいきました。

ただ、足りなかったことやできなかったことがありました。処理を順番に実行することはできました。カレンダーであれば、カレンダーのルート、サマライズだったらサマライズ、要約ですね。(要約)のルートみたいな感じにできたのですが、処理の結果をもとに別の処理を推測させることは、できなかったです。よく考えたら「ReActじゃなかったわ」という話ですね。

OpenAIで次の行動……要はカレンダーであればカレンダーのルートに行かせるという分岐はできたのですが、動的に必要なものを考えて、ワークフローを構成するのは難しいんだなと思いました。

ただ、ここ(スライド)に書いているようなことができれば、「それって実現できるよね」と思っています。LangChainみたいに、LangChainのコードを真ん中に書いているのですが、serpapiというんですかね。外の検索をすることができたり、計算をすることができるツールを投入 して、同じようにカレンダーや、要約みたいなLLMを選択しておいて、かつそのクレデンシャルを設定しておく。

Open APIでゴールから逆算してタスクを分解して、分解した時に動的にそのモジュールを選択できるようにして、かつそのモジュールを呼び出す時のGoogle APIの呼び出し方、作法をIndexして解釈することができたら、実現できるよねと思っています。iPaaSだと、APIの仕様などが組み込まれているので、「AutoGPT」みたいなものが組み込まれたらかなり強くなりそうなのかなと思って、すごく期待しているところです。

ここまでやってみて「あ、なるほど。これはiPaaSができるやつじゃん」と思いました。今だと条件分岐ができない、動的にルートを作れないのですが、これさえできれば。これは簡単にできるやろみたいに思いました。

取り組んでみての感想

感想ですね。Description Opsと言って、弊社の藤本さん(藤本敬介氏)が作っているのですが、LangChainは、クエリとLLMを紐付けてくれるのですが、LLMと紐付ける時に「これは何のLLMですか?」みたいにDescriptionという説明文を書きます。その説明文とクエリがマッチしたら、そのLLMを使うようになるんです。

だけど、どうしてもそのクエリや説明の書き方に依存するので、精度は両方に依存します。ただ、このルーティングの仕方だと、「この文章は何ですか?」「トラブルシュートです」「だったらトラブルシュートを書きましょう」みたいにクエリを訳しているんですね。なので、クエリのみに依存することがシンプルにできちゃったのかなと思っています。

あと、このMakeやiPaaSでAPIを叩くことのメリットですが、これをやっている時に見たら1,427個の何かしらのAPIがあったんです。「BigQuery」も「Elasticsearch」もある。たぶんLangChainもBigQueryはまだ使えなかったような気がします。

なので、そういったものを簡単につなげられるのはいいなと(思いました)。サーバー管理が不要なのも楽だなと思っています。

実装していて、LangChainの気持ちになれた、車輪の再発明みたいな感じでした。今、LIamaIndexで「Notion」なり「Google Docs」を検索して、Embeddedして、ベクトルサーチに検索するみたいことが流行っていると思うのですが、このiPaaSベースだとNotionのAPIを使ったり、Slack APIが直接検索しにいくかたちで、Embeddedのほうがもしかしたら性能が良いかもしれません。

たぶんサービス側も、GPT関連で検索の精度をどんどん上げてくれると思います。Notionとかだとデータの更新のたびにおそらくEmbeddedしないといけませんが、そういったものをせずに直接検索をして回答を書いているのをプロンプトに入れて返すみたいなことができるというのも1つのメリットなんだろうなとは思っています。一応プロンプトインジェクション対策も可能です。

試して妄想したり、アンチパターンを共有したり、より良いものを作っていきたい

最後に、AutoGPTでもAPIの仕様を解釈して情報を取得することが可能になりそうだなと思っています。Open API前提で、解釈できる可能性もある。iPaaSは先ほど言ったとおり、インテグ済みなので、AutoGPTなどがそれぞれのAPIを解釈してどうのこうのするよりも早く実装できそうだなと思っています。

なので、AutoGPTなどが優秀になればAPIのドキュメントを読んで実装することも、もしかしたら勝手にやってくれる世界線もあるかもしれません。どちらでもいいとは思いますが、楽に実装できたらなとは思っています。いろいろ試してみて今みたいに「ReActできるんじゃね?」と妄想したり、アンチパターンを共有したりすることでより良いものを作っていきたいなと思っているので、よろしくお願いします。以上です。ありがとうございます。

(会場拍手)