社内用AIアシスタント「おっさんずナビ」を作った話、そして人間らしく振る舞う重要性を認識した話
こんにちは、羽山です。
みなさんは業務に LLM(生成AI)を活用していますか?ラクーングループでは生成系AI LT大会を開催するなど、積極的な利用を推し進めています。
そこで今回は私がその生成系AI LT大会で発表し、隙間時間で開発して、社内で幅広く利用されるに至った AIアシスタント「おっさんずナビ」を紹介します。
おっさんずナビは LLM + RAG(Retrieval-Augmented Generation)を利用した Slackボットで「ラクーンホールディングスの社風を教えてください」という質問に 社内事情を踏まえた回答 をしてくれます。
ファインチューニングを利用せず RAG のみで精度を高めているのと、ベクトルDBなどの外部リソースを必要としないのがポイントで、使い込まれた Slack ワークスペースさえあればアプリを起動するだけで 社内事情通のAIアシスタント ができあがります。
また、おっさんずナビの開発・運用を通して得た、「人間らしく振る舞う」ことの重要性も合わせてお伝えできればと思います。
※ 2024-10-21追記 本記事で紹介するおっさんずナビ(OssansNavi)のソースコード及びコンテナイメージを OSS として公開しています。どなたでもご利用いただけるので是非ご活用ください。
おっさんずナビの紹介
まずは先ほどの質問、「ラクーンホールディングスの社風」をどのように回答してくれたのか確認してみましょう。
ラクーンホールディングスの社風は?
以下のやりとりから、ラクーンホールディングスのいくつかの社風が見て取れます。
1. リモートワークの活用: リモートワークの積極的利用や、労働時間とコストの節約を重視しています。例えば、小方 功さんの発言では、リモートワークを効果的に利用しつつ、物理的な空間を共有する重要性も認識していることがわかります。
2. ワークライフバランスの重視: **さんのコメントや、**さんの「バランス取るべきワークとライフのライフって、生活じゃなくて人生だなぁと改めて」といった発言から、社員のワークライフバランスを尊重していることが伺えます。
3. コミュニケーションと協力: **さんが「アウトプットを増やそう」と呼びかけたように、知識の共有や社内勉強会などを通じて社員同士のコミュニケーションを重視していることがうかがえます。
4. 従業員エンゲージメント: **さんの「フェアトレードの学び」といった社会貢献活動への関心や、**さんの「組織力の継続的な向上」といった発言から、ほかの社員とのつながりを大切にし、従業員のエンゲージメントを高める努力が見受けられます。
5. 多様性と成長のサポート: **さんの「心理的安全性のつくりかた」といった読書内容や発言からも、社員個々の成長をサポートし、多様性を尊重する文化があることがわかります。
具体的なやりとりは以下のリンクよりご確認ください:
•コロナ後の会社の方針に関して(小方 功)
•**のバランスについて
•心理的安全性のつくりかた(**)
•リモートワークのコミュニケーション(**)
その他のやりとりや詳細についてはSlackの各チャンネルでご確認ください。
**さん、この内容で合っていますでしょうか?他に追加するべき情報があれば教えてください。
分かりやすく5項目でラクーンホールディングスの社風を説明してくれて、返答内容もエモいですね。
上図はスペースの関係でトリミングしていますが、リンクが Slack UI上で展開されて視認性も高いです。
社内の人間に相談するかのように、共通のコンテキストで相談をできるのが素晴らしいです。
次は弊社の運営する仕入れのECサイトスーパーデリバリーの集客について相談してみました。
スーパーデリバリーの集客プランは?
羽山さん
ご質問ありがとうございます。
スーパーデリバリーの集客プランについての具体的な戦略は、過去に共有された以下のリンクにて詳しく記載されていますので、参考にしてください。
https://slack.com/archives/C01--------/p17--------------
また、最近の事例として、 **さんが関わったプレスリリースやウェビナーの運営についての情報も参考になると思います。詳細は以下のリンクでご覧いただけます。
https://slack.com/archives/G7F------/p16--------------
さらに他の具体的なアクションプランについては、内部ディスカッションの場で共有されているリソースや、特定のプロモーション活動の推進に携わっているメンバーから直接アドバイスを受けることをお勧めします。
関連する施策を考えている場合には、**さんやマーケティングチームのメンバーと会議を設定することもご検討いただけると良いかと思います。
最近の集客についての動向を踏まえて回答してくれました。
ただし求める内容と微妙に違ったので「あなたの意見も教えてください」と返信してみました。
スーパーデリバリーの集客プランについて、以下のようなポイントを考慮することをお勧めします。
1. ターゲットユーザの明確化 :
• どのような顧客層をターゲットにするかを明確にしましょう。例えば、小売店やオンラインショップなど。
2. コンテンツマーケティング :
• ターゲットユーザーの興味を引く記事や動画を作成します。例えば、新商品の紹介やユーザー事例など。
3. SEO対策 :
• ウェブサイトやブログのSEO対策を行い、検索エンジンでの表示順位を上げます。特に「スーパーデリバリー」や「仕入れ」などのキーワードを狙いましょう。
4. SNSマーケティング :
• Instagram, Twitter, FacebookなどのSNSを活用して、定期的にコンテンツを発信し、ファンとのコミュニケーションを図ります。
5. ウェビナー・オンラインイベント :
• ウェビナーやオンラインイベントを開催し、ユーザーに直接情報を提供する場を作ることも効果的です。
具体的な事例や参考になるリソースが「ラクーングループ」内に多く存在しますので、ぜひ確認してみてください。
ご参考になれば幸いです。
「あなたの意見も教えていただけますか?」と聞いただけですが、会話のコンテキストを考慮して適切にスーパーデリバリーの集客に対する意見をまとめてくれました。
LLM では当たり前の挙動ですが、こういった自然な応答が可能なのは利用体験を向上してくれます。
LLM は創造力が低い傾向にありますが、豊富な知識に加えて ラクーングループ固有の知識も利用 できるため壁打ち相手として有能です。
次は 人を結びつける働き を紹介します。
業務中に出た疑問を質問したいけど詳しい人が分からないとか、詳しい人は分かるけど直接話したことはないから DM やメンションで話しかけづらいケースはありませんか?
おっさんずナビは質問内容に詳しい人を探してメンションしてくれる場合があるので、その事例を紹介します。
GTM(Google Tag Manager)の権限付与は?
**さん
お疲れさまです。
外部へのGTMの権限付与については、以前に羽山 純さん(@hayama.jun)が対応されていたようです。
該当するスレッドはこちらです:リンク
羽山さんにご相談してみてはいかがでしょうか?
羽山さん(@hayama.jun)、**さんから外部へのGTM権限付与についてのご相談がありました。以前対応されていた内容と似ていると思いますので、お手隙の際にご確認いただけないでしょうか?URLはこちらです:リンク
これは私がおっさんずナビに呼ばれて質問へ回答した事例です。
私としても自分が詳しい質問には積極的に対応したいのですが、不特定多数に対して送られた多くメッセージの中から自分が回答すべき質問に目を光らせるのは無理があります。
またバイネームで質問されたわけではないのに、でしゃばって回答するのも気がひけます。そこで おっさんずナビが仲介役としてメンション してくれるとボールの持ち主が明確になって回答のハードルが下がるメリットもあります。
ラクーングループの Slack には情報システム担当へ質問するためのチャネルがありますが、現在は 半数以上の質問におっさんずナビが一次対応 してくれています。
過去の事例を元にうまく回答した上で担当者に確認したり、「外部ディスプレイに画面が映りません」という質問に対して
- モニターとPCのタイプCケーブルを一度抜いて、再度しっかり差し込み直す。
- モニターの電源ケーブルを抜き、数秒待ってから再度差し込む。
- 両方のケーブルが確実に接続されていることを確認し、モニターの電源を入れ直す。
といった、一般的な対処法も案内してくれます。
またおっさんずナビが定着しつつある最近は、質問チャネルに投稿する前におっさんずナビへ DM で相談して自己解決するケースもあるようです。
会話が始まらない問題
LLM ベースのチャットボットの設計では、メンションに応答する仕様を採用するのが一般的だと思われます。そうしないとチャネルに投稿された、あらゆるメッセージに 無差別応答マシーン になってしまうからです。
しかしメンションでしか起動しない仕様には大きな問題があり、それは 利用者が明示的に使おうと思わなければ使えない ことです。せっかく便利なチャットボットを作ってもさほど使われず、徐々にみんなの記憶から忘れられ、「そういえばそんなボットもいたね」という存在になってしまいかねません。
そこで私はおっさんずナビが、人間に近い挙動を模倣するように設計しました。
まるでラクーングループの一員であるかのように自然にメンバーのなかに溶け込んで愛される存在になってほしい、そういう想いを込めています。
そのためにはメンションされなくても適切なタイミングで応答する必要があります。
例えば人間なら、困っている人がいて、その答えを自分が持っていればお節介で回答するし、答えを持っていないなら無理に回答せずにスルーするでしょう。それと同様に、ほどよい力加減で回答する/しないを判断してくれるのがおっさんずナビの特徴のひとつです。
実は先程の GTM に権限付与する件では、質問した人はおっさんずナビをメンションしていません。しかしおっさんずナビはこの案件について詳しい人(=私)を見つけたのでお節介で返信して私にボールを投げてくれました。
もし詳しい人を見つけられていなかったら、おっさんずナビはスルーしたはずです。とっても人間っぽい動きですよね。
ここで重要なのは メンションという業を代わりに引き受けてくれる 点です、メンションするのって少しだけ勇気が必要ですよね。
そのほかの事例として、ラクーングループには日報を送るチャネルがあり、日々100通以上のメッセージが投稿されています。
当然ながら日報は報告チャネルなので回答の必要はなく、実際におっさんずナビはほぼすべてのメッセージをスルーしています。
しかし、最近1通だけ返信していたのが以下のメッセージです。
こんにちは、**さん!平日のお休み、いいですね~。
以前、**さんが江ノ電1日乗車券と500-700円相当のチケット*4がついて平日1750円のチケットをお勧めしていました。「めちゃ最高でした」ということなので、検討されてはいかがでしょうか?
詳細はこちらのリンクから確認できますよ:
江ノ電1日乗車券
お休みを楽しんでくださいね!
999通のメッセージをスルーしているのに、たった1通の「平日休みのオススメ教えて!」というメッセージを見逃さずに反応するあたり、とても良いですよね。
会話が終わらない問題
LLM との会話は終わりどころが難しいケースがあります。LLM はあらゆるメッセージに返答を生成するので、単純に設計すると「ありがとうございます!」のようなメッセージにも応答してしまいます。
1:1 のやりとりならまだ良いのですが、Slack のやりとりは N:N なので、そのすべてに応答されたらユーザー同士の会話の邪魔になります。
実は LLM のチャットボットでは良質の応答よりも 応答しない動作の設計 がより重要です。
そこでおっさんずナビはメッセージに何らか反応した方が自然だけど、応答までは必要ないケースをリアクション絵文字で済ませてくれたりします。
以下はおっさんずナビも参戦した複数人の雑談スレッドですが、なんと「草」というカスタム絵文字をおっさんずナビが押しています。
私はカスタム絵文字について教えていませんが、メッセージ内で使われたカスタム絵文字を利用したようです。開発者の想定を超えた動作でシンギュラリティを感じた瞬間でした。
定期実行で日報生成を自動化
面白い使い方として、Slack のリマインダーからおっさんずナビに定期タスクを実行してもらう活用方法もあります。
Slack のリマインダーを平日の毎17:10 に設定しておっさんずナビをメンションして、私がその日に送信したメッセージから日報を自動生成してもらっています。
羽山 純さん
以下、本日のメッセージまとめとなります。
■本日の一言----------
VSCodeでDev Containerを使用する際のワークスペースの見分け方について、工夫次第で解決できます!
■本日の業務----------
- VSCodeのワークスペースの見分け方に関する質問とその解答
- 今日の予定の確認依頼とその完了
- STG環境におけるAPI接続先の確認と対応策の検討
- **********************
- *******************
- ************
- ********のテストとAPI仕様についての確認
@hayama.jun
Slack 上で見える形で業務を遂行していないと有効に機能しないのですが、逆に言うと Slack から見える業務はこのテンプレで担保して、それ以外の場で実施した業務だけ追加すれば良いのである程度は助かっています。
では、実際の事例を元に様々な機能を紹介したので、ここら辺でいったんまとめてみましょう。
おっさんずナビの仕組み・特徴
- Slack ワークスペースに蓄積された情報を知識として活用する
- メンション(またはDM)で話しかけると、必ず回答をする
- メンション(またはDM)でなくても、レスポンスを必要とするメッセージ(質問/相談/依頼)ならばお節介で応答を試みる
- 生成した応答によって質問/相談/依頼が解決する場合は応答する
- 質問/相談/依頼の内容について詳しい人が見つかった場合は応答して詳しい人へパスする
- 上記に当てはまらない場合はスルーする(なんら反応しない)
- おっさんずナビのメッセージにスレッドで返信した場合
- 質問/相談/依頼ならば前述の仕様通り応答を試みる
- 質問/相談/依頼以外ならば絵文字でリアクションする
- ほどほどのAPI利用料で回答を生成できる
これらを LLM + RAG で実現するには様々な工夫が必要でした。そこで3つの工夫ポイントを挙げます。
- プロンプトを英語で入力
- GPT-3.5 と GPT-4o の両モデルを併用
- 逆ベクトル検索(仮称)を採用
1. プロンプトを英語で入力
API利用料金は GPT-4o で 1000トークン入力あたり 0.786円(※執筆時点)ほどかかるため、費用を節約するには可能な限りトークン数を少なくしたいです。
そこで日本語と英語で同じ意味の文章を GPT-3.5/4 へ入力した場合のトークン数を比較してみます。
入力するのは
後述の「出力形式」に従い、JSON形式で回答を出力してください。
という意味を示す、日本語と英語の文章です。
日本語(GPT-3.5/4)
>>> print("トークン数: " + len(tiktoken.encoding_for_model('gpt-35-turbo').encode(
'後述の「出力形式」に従い、JSON形式で回答を出力してください。'
)))
トークン数: 27
英語(GPT-3.5/4)
>>> print("トークン数: " + len(tiktoken.encoding_for_model('gpt-35-turbo').encode(
'Please output your response in JSON format according to the "Output format" described below.'
)))
トークン数: 17
GPT-3.5/4 では日本語の1文字がおよそ1トークンとなり、英語はおよそ1単語で1トークンです。
結果として日本語では 27トークンに対して英語は 17トークンで済み、英語にすれば4割ほどトークン数を節約できます。
ちなみに GPT-4o は日本語トークンが強化されたので、同じ日本語の文章を入力すると 21トークンと 2割ほど削減されますが、それでも英語には及びません。
日本語(GPT-4o)
>>> print("トークン数: " + len(tiktoken.encoding_for_model('gpt-4o').encode(
'後述の「出力形式」に従い、JSON形式で回答を出力してください。'
)))
トークン数: 21
英語でプロンプトを入力すると英語で返答されるケースがあるため、Please think in Japanese and respond in Japanese.
という指示も入れておきます。
2. GPT-3.5 と GPT-4o の両モデルを併用
ミニマムで LLM ベースのチャットボットを作るには、1メッセージに対して1回のAPIコールで応答を生成すれば完成します。
しかし、より自然な振る舞いや精度の高い RAG を実現するには、複数の APIコールを組み合わせて最終的な応答を生成する必要があります。
執筆時点での API使用料は以下のようになっていて、GPT-3.5 と GPT-4o では10倍の価格差があります。
- GPT-3.5: 1000トークン入力に対して 0.0787円
- GPT-4o: 1000トークン入力に対して 0.786円
そこで、おっさんずナビは「難易度が低いけど処理するデータ量が多いタスク」に GPT-3.5 で活用することでトータルのコストを下げています。
具体的な使い分けは後述します。
3. 逆ベクトル検索を採用
LLM + RAG で PoC(Proof of Concept) を越えて、実際に活用する事例ではベクトルDBが登場しがちです。
しかし必要な情報を保持したベクトルDBを用意して常に最新に保つ難易度は高く、これが RAG の最大のネックだと言えます。
そこでおっさんずナビが活用しているのは、私が勝手に命名した 逆ベクトル検索 という手法です。
ベクトルDBは意味の近い単語も含めてヒットしてくれます。それならば知りたい事象に対する 類似ワードをたくさん生成して何度も検索 すれば普通のDBでもベクトルDBのような検索結果が得られるはずです。
検索対象をベクトル化するのではなく、 検索ワード側をベクトルライクな手法で多重化 することから「逆ベクトル検索」と表現しています。
類似ワードを求める部分はまさに LLM が得意とするところです。
おっさんずナビのプロンプトでは「単純なキーワードマッチなので幅広い検索結果を得るために似た意味の単語で何度も検索したいです、似た意味や近い表現でたくさんの検索キーワードを生成してください」という意味の依頼をしています。
さらに多種多様な検索ワードを得るための小技で Chat Completion API の n パラメータに n: 5
を入力して 5通りの異なるバリエーションを生成した上でその全てを結合して利用しています。必要に応じて temperature
を上昇させると当たり外れが大きくなる分、様々な結果が得られたりします。
n パラメータの活用例として「○○について、たくさん提案してください」系のタスクで機械的にバリエーションを増やせる他にも、複数のバリエーションで投票してもらった結果を多数決や全会一致で採用するのも有用です。
回答までの4つのタスク
おっさんずナビは大きく以下の4つのタスクで応答を生成します。
- 分類タスク
- 情報収集タスク
- 情報整理タスク
- 回答タスク
1. 分類タスク
受け取った メッセージの意図を把握するタスク で、おっさんずナビが人間っぽく動作するために重要な役割を担っています。
また最も多くのメッセージを受け取るタスクなので、費用削減のために GPT-3.5 でも無理なくこなせる簡単なタスクとして設計しています。
指示は単純でメッセージの意図を「質問」「相談」「依頼」「同意」「共感」「確認」「感嘆」「失望」「その他」のいずれかに分類してもらいます。
具体的なプロンプトは以下です。
Consider the intent of the last message sent by the user. Then output the message intent by selecting from the options below. Be sure to select from only the following options.
- question
- consultation
- request
- agreement
- empathy
- confirmation
- admiration
- disappointment
- other
また同時に「応答に適切なリアクション絵文字を出力して」とも依頼しています。
分類例としては「ありがとうございます!」は「感嘆」に、「なるほど」は「同意」になります。
この分類結果を元に以下の順に処理を進めます。
- メンションまたはDMの場合
- 次のタスクへ進む
- 「質問」「相談」「依頼」の場合
- 次のタスクへ進む
- おっさんずナビへの返信メッセージである場合(※Slack のスレッドでおっさんずナビのメッセージの次に投稿されたメッセージかどうか)
- 生成してもらったリアクション絵文字を送って終了する
- 上記以外
- 終了する
分類結果をさほど活用していないと感じるかもしれませんが、このタスクは 十分に多い選択肢から選ばせることが重要 です。
例えば「『質問』『相談』『依頼』だと判断した場合は true と出力してください」という指示では十分な精度の回答を得られません。なぜならば、「○○ということですね、ありがとうございます!」という若干曖昧なメッセージを「質問」と拡大解釈して true を出力するケースが多発するからです。
人間相手でも有効ですが、選択肢は望む応答を得るために相手を誘導する手段となります。
おっさんずナビが利用するリアクション絵文字は Output the name of the appropriate slack emoji to react to.
としか指示してないので、変わった絵文字を選択することがあって面白いです。
ちなみに LLM からの応答は JSON mode を利用して JSON で生成してもらっています。
2. 情報収集タスク
メッセージの意図から 検索ワードを生成して Slack API で検索するタスク です。
ここで必要なのは逆ベクトル検索を実現するために似た意味の多種多様なワードや表現を生成してもらうことです。
回答の精度に直接影響する重要なタスクなので、多少費用がかかっても GPT-4o に担当してもらっています。
利用しているプロンプトを抜粋して紹介します。
- Think of many search terms that might yield an answer and output them to an array.
- We would like to search for words with similar meanings, as information may be recorded with different wording. Please provide as many search terms as you can.
- If "after:yyyy-mm-dd" is specified as a search word, it searches after that date.
- If "before:yyyy-mm-dd" is specified as a search word, it searches before that date.
- Specify "user_id" in the form "from:<@UXXXXXXXX>" to search messages by sender.
after:yyyy-mm-dd
from:ユーザーID
のような Slack の検索モディファイアを教えると、GPT-4o はしっかり使ってくれるので賢いです。例えば2024年7月時点で「スーパーデリバリーで先月リリースされた機能を教えてください」と聞くと
スーパーデリバリー リリース after:2024-06-01 before:2024-07-01
スーパーデリバリー システム after:2024-06-01 before:2024-07-01
スーパーデリバリー デプロイ after:2024-06-01 before:2024-07-01
といった検索ワードをたくさん生成してくれます。
今現在の日時をプロンプトに含めているので、「先月の」などの時系列も適切な検索条件に変換します。
RAG の情報収集タスクでは一般に Function calling を利用するケースが多いと思いますが、試行錯誤の結果 Function calling はプロンプトでの制御が効きにくい一方で、通常の応答として生成してもらった方が素直に従ってくれると分かりました。そこでプロンプトでは「この件について Slack 検索して調べたいから、私の代わりに検索ワードの候補を考えてください」という方向で組み立てています。もちろん実際には Slack検索をボットの処理内で行うのでプロンプトの指示は嘘ですが、LLM は状態を持たないので 都合の良いシチュエーションをでっち上げて指示 した方がより精度の高い応答を得られます。
ちなみに GPT-3.5 で試すと類似の検索ワードを生成する精度が若干低いのに加え、日付の絞り込み条件をうまく扱えませんでした。
3. 情報整理タスク
情報収集タスクで得た 膨大な検索結果から必要な情報を選び出すタスク で、安価な GPT-3.5 を利用します。
本タスクの指示は「元メッセージの意図と関係のあるメッセージのIDを出力してください」です。
LLM はモデルごとに最大トークン数が設定されているため、Slack検索の結果を一度で全て入力することはできません。
そこで最大トークン数制限を考慮しながら、何度かに分けて入力するのが本タスクの一つ目の役割です。
二つ目の役割は Slack 検索でヒットした膨大なメッセージを仕分けて必要なメッセージだけを残すことで、高価は GPT-4o を利用している次のタスクに入力しなければいけないトークン数を減らしています。
ただし本タスクで利用する GPT-3.5 の理解度は決して高くないので、n パラメータを n: 5
として、5種類のバリエーションどれかで引っかかった情報を OR条件で採用しています。余計な情報が含まれるのは許容できますが、必要な情報を取りこぼすのは最小限にしたいからです。
「3. 情報整理タスク」では「2. 情報収集タスク」も同時に実行します。「ラクーンホールディングスの特徴は?」→「福利厚生に『いつでも長期休暇』という仕組みがある」→「いつでも長期休暇ってなに?」のように検索結果から情報を得て、新たな情報収集が必要になるケースがあるからです。現時点ではこのタスクを GPT-3.5 が担っているのでおまけ程度の動作ですが、いずれ全体的にAPI使用料が下がって GPT-4o 相当の賢さを持つモデルが担当すると回答精度がさらに上昇するはずです。
ところで、前述の通り Function calling を利用していないので、「どうやって情報を入力するのか?」という疑問を持つ方がいらっしゃると思います。実はこの問題は簡単で、LLM は状態を持たないので LLM 自身が生成した Function calling なのかを見分ける手段を持っていません。
そのため本来は assistant
の生成する tool_calls
を含む JSON を開発者が組み立てて、一意の tool_call_id
を勝手に生成すれば LLM は何の疑問もなく処理してくれます。
実際に tool_calls
をでっち上げて応答を得る例を以下に示します。この JSON は全て手作業で作ったものです。
入力
{
"tools": [
{
"type": "function",
"function": {
"name": "slack_search",
"description": "Slack検索します",
"parameters": {
"type": "object",
"properties": {
"term": {
"type": "string",
"description": "検索ワード"
}
},
"required": [
"term"
]
}
}
}
],
"messages": [
{
"content": "now: 2024-07-01 13:35:25",
"role": "system"
},
{
"content": "先月スーパーデリバリーでリリースされた機能を教えて",
"role": "user"
},
{
"content": null,
"role": "assistant",
"tool_calls": [
{
"function": {
"arguments": "{\"term\": \"スーパーデリバリー リリース after:2024-06-01 before:2024-07-01\"}",
"name": "slack_search"
},
"id": "call_1",
"type": "function"
}
]
},
{
"role": "tool",
"name": "slack_search",
"tool_call_id": "call_1",
"content": "[{\"timestamp\": \"2024-06-10 15:10:00\", \"text\": \"商品リコメンド機能の改善\"}, {\"timestamp\": \"2024-06-20 10:05:00\", \"text\": \"画像編集機能の改善\"}]"
}
]
}
出力
{
...
"message": {
"content": "先月(2024年6月)にスーパーデリバリーでリリースされた機能は以下の通りです:\n\n1. **商品リコメンド機能の改善**(2024年6月10日にリリース)\n2. **画像編集機能の改善**(2024年6月20日にリリース)",
"role": "assistant"
}
...
}
さらに言うと、Function calling の利用は必須ではないので、単純に system プロンプト内に JSON形式で入力しても問題ありません。
4. 回答タスク
精査された情報を元に回答を生成するタスク です。
利用者の目に直接触れる文章を生成する重要な役割なので GPT-4o に担当してもらいます。
前タスクで GPT-3.5 に情報の精査してもらったので入力される情報は最小限となり、GPT-4o を利用しても費用を抑えられます。
ただし、このタスクに到達したら必ず応答するわけではありません。応答するのは以下のいずれかの条件に合致した場合のみです。
- メンションまたはDMの場合
- 分類が「質問」「相談」「依頼」で、応答内容のクオリティが高いと GPT-4o 自体が判断した場合
- 分類が「質問」「相談」「依頼」で、他の詳しい人を見つけてパスできる、かつパブリックチャネルへの投稿の場合
- 分類が「質問」「相談」「依頼」で、おっさんずナビのメッセージへの返信の場合
応答内容のクオリティの判断は、出力フォーマットのルールを伝えた上で、応答クオリティ用の項目を作っています。
しかし「応答内容のクオリティが高いですか?」と聞いても主観的な質問なので望む答えを得られません。どういう状態なら応答内容のクオリティが高いと言えるのかを人間が考えて、より 客観的な質問に変換 する必要があります。おっさんずナビでは「この応答で質問内容を解決できる場合は true を出力してください」 という指示をしています。
応答に利用する文章は「本文」と「他の詳しい人を見つけてパスするメッセージ」の二つに分けて出力してもらっています。この工夫によってパス機能を利用するべきかを開発者が判断できます。例えばおっさんずナビと DM しているのに「○○さん分かりますか?」というパス機能が発動すると挙動としておかしいので、そういった制御をしています。
まとめ
LLM を利用したチャットボットを設計・開発・運用したのは今回が初めてでしたが、試行錯誤のすえにたどり着いた結論は、応答の精度よりも 利用者が意識しなくても自然と使える 方がより重要ということでした。そして、その実現にもっとも効果的なのは人間っぽい挙動を追求です。
LLM は非常に素晴らしい技術ですが、使い方次第では有効に機能しないので、上手に活用したいところですね。
ちなみにおっさんずナビの名称は、冒頭の生成系AI LT大会にて同い年2名でおっさんコンビを組んだことに由来します。「我々のようなおっさんは質問をしづらい空気を出してしまっているかもしれない、それを払拭したい」と考え、質問にバリバリ答える新しいおっさんのステレオタイプで上書きすることを願って命名しています。
さて、ラクーンホールディングスではエンジニアを大募集中です!
興味を持っていただいた方は是非、お話ししましょう!私たちだけでなく、おっさんずナビもあなたを歓迎しています。