こんにちは、CTOの小林です。
ChatGPTをはじめとした生成AI、便利ですよね。素のChatGPTでも十分に便利なのですが、業務で使うには社内ドキュメントにも対応して欲しいと誰もが思うのではないでしょうか。すでにOpen AIのAPIを使って社内ドキュメントに対応したAIボットを開発している事例は多数ありますが、kickflowでも社内用AIボットを開発して社員に展開しました。今日はこのAIボットのアーキテクチャや実装についてご紹介します。
Retrieval Augmented Generation (RAG)
今回開発したAIボットでは、社内ドキュメントに対応した回答のために、検索と生成を組み合わせたアプローチであるRetrieval-Augmented Generation(RAG)を採用しました。具体的には、ユーザーのクエリに対して関連するドキュメントを検索し、そのドキュメントを元に生成モデルが回答を生成します。このアプローチにより、モデルが持つ知識とドキュメントの具体的な情報を組み合わせた、より正確で詳細な回答が得られるようになります。
アーキテクチャの紹介
RAGに対応したSlack AIボットのアーキテクチャは以下のようになります。インフラにはGCPを採用し、OpenAIのChat Completion APIを呼び出しています。
このシステムは、社内文書をBigQuery経由でVertex AI Search(GCPのAIサービス)に登録するサブシステムとSlackからの問い合わせに応答するサブシステムの2つで構成されます。
社内文書をVertex AI Searchに登録するサブシステム
このサブシステムでは、社内ドキュメントを毎晩BigQueryに同期し、さらにVertex AI Searchに同期します。kickflowでは社内のドキュメントツールとしてesaを使用しており、esaの特定カテゴリの記事をAIボットから参照できるようにします。
大まかな処理の流れは以下のようになります。
- Cronの実行
- GCPのCloud Schedulerが、毎晩決められた時刻にPub/Sub経由でCloud Functionsを起動します。
- データの抽出と変換
- Cloud Functionsでは、esaのAPIを利用して事前に指定した特定カテゴリ以下のドキュメントを取得し、記事の情報をBigQueryにインポートします。
- データの同期
- BigQueryにインポートされたデータをVertex AI Searchに同期します。これにより、最新のドキュメント情報が常に検索可能な状態になります。
Slackからの問い合わせに応答するサブシステム
このサブシステムは、ユーザーのSlackからの問い合わせに対して、関連する社内ドキュメントをVertex AI Searchで検索し、検索結果のドキュメントをセットにしてOpenAIのAPIに問い合わせ、整形した回答をSlackに返すところまでを行います。
大まかな処理の流れは以下のようになります。
- 問い合わせの受け取り
- ユーザーがSlack上のAIボットに問い合わせると、SlackからCloud Functionsが呼び出されます。
- ドキュメントの検索
- Cloud FunctionsからVertex AI Searchを呼び出し、ユーザーのクエリに関連する社内ドキュメントを検索します。
- 回答の生成
- 取得したドキュメントの内容(タイトルや本文)をもとに、OpenAIのChat Completion APIに問い合わせて回答を生成します。
- 回答の加工・返却
- OpenAIからの回答をSlackのmrkdwn形式に変換し、ユーザーに返します。
Function callingによる機能拡張
OpenAIのAPIでは、function callingという機能を活用することで、特定のタスクを実行するための関数を呼び出すことができます。例えば、特定のURLのページ内容を取得したり、PDFなど各種ファイルの内容を読み取ったりすることが可能です。
今回開発したAIボットでは、function callingを使ってユーザーがSlackに貼り付けたPDF、Word、Excelなどの添付ファイルの中身を読み取ってOpenAIに問い合わせる機能や、DALL-EのAPIを呼び出して画像を生成する機能を追加しました(後者はネタ機能ですが...)
その他細かいテクニック
以上でAIボットとしてのコアな部分はほぼ完成なのですが、実際に業務で使ってもらうにはいくつか注意すべき実装ポイントがあったので以下に紹介します。
Slack mrkdwnへの変換
Slackに投稿するテキストはMarkdownとは似て非なるmrkdwnというフォーマットで装飾することができます。はじめはOpenAIのChat Completion APIへのプロンプトに「Slack mrkdwnで回答して」と指示すればmrkdwnで出力できるかと思ったのですが、試行錯誤してもうまく出力してくれませんでした。しょうがないので、Chat Completion APIでは通常のMarkdownで回答を生成してもらい、Markdownを一度HTMLに変換してからmrkdwnに変換するようにしました。mrkdwnへの変換は既存のライブラリだと一部要件が合わなかったため、html-to-mrkdwnというライブラリをフォークしてパッチを当てて使用しています。
共有チャンネルでは動かないようにする
AIボットは社内ドキュメントの内容を下に回答できるので、Slackに招待された社外のユーザーが使ってしまうことで社外秘が漏洩するリスクがあります。社外秘の漏洩を防ぐために、AIボットは共有チャンネルでは動作しないようにCloud Functions内にバリデーションを追加しました。
他のボットからの問いかけには反応しないようにする
今回開発したAIボット以外にも似たようなボットが使用されていると、ボット同士で無限に会話しつづけてOpenAIのAPI利用量が跳ね上がる恐れがあります(実際は途中でRate Limitに引っかかって動かなくなりますが)。 Cloud Functions内で他のボットからの問いかけには反応しないようにバリデーションを追加することでで、無限ループや誤動作を防いでいます。
実際の利用例
ここからは、AIボットを社員がどのように利用しているかの事例をいくつかご紹介します。
技術的な質問への回答
AIボットはRuby、TypeScriptなどのプログラミングに関する質問に回答してくれます。素のChatGPTではユーザーの入力が学習されるため実際のソースコードを渡して質問することができませんが、API経由であれば学習されないため安心してソースコードを貼り付けて質問することができます。
セキュリティチェックシートを自動的に埋める
SaaS企業の営業チームでは、よくお客様からセキュリティチェックシートの入力を依頼されることがあります。社内ドキュメントにあらかじめ過去のセキュリティチェックシートの質問と回答例をまとめておくことで、AIボットが過去の回答例を元にセキュリティチェックシートの回答を自動的に作成してくれます。回答精度は体感で70%くらいなのでAIボットの出力を営業マンがもう一度すべて見直す必要はあるのですが、すべて0から入力するのに比べて大幅に負担を削減できました。
ブログのアイキャッチ作成
ブログ記事のアイキャッチ画像を生成するために、AIチャットにネタで搭載したDALL-Eによる画像生成を利用しています。この記事のアイキャッチもDALL-Eが生成した画像です。
まとめ
今回は社内用のAIボットを開発することで、社内のドキュメント検索やナレッジ共有が大幅に便利になった事例を紹介しました。今後も、さらなる機能追加や改善を行い、社内の生産性向上を追求していこうと思います。
今回は社内利用を目的としたボットの開発をご紹介しましたが、プロダクト本体にも生成AIを活用して新しいユーザー体験を提案できないか検討しています。新しい技術を用いてプロダクトの価値を高めることに興味があるエンジニアの皆様、カジュアル面談や選考のご応募をお待ちしております!