はじめに
こんにちは、工数管理SaaS「クラウドログ」でエンジニアをしている越阪部です。
普段の業務では、Webフロントエンドを中心とした開発を担っています。
この記事では、クラウドログに蓄積された工数データを、生成AIが自然言語で要約してくれる「AI分析サマリレポート」の概要や開発裏話を紹介したいと思います。
AI分析サマリレポートとは
この機能は、「工数レポート」という工数データを集計・分析するためのページに組み込まれています。
工数レポートは、クラウドログに蓄積された工数データをさまざまな切り口で集計して、結果をグラフやテーブル形式で表示することで分析を助けてくれる便利な機能となっています。
しかし、表示されたデータから示唆を得る読み取りに一定の慣れが必要という課題がありました。
そこで、ちょうど生成AIをクラウドログに組み込めないかという話があがっており、この課題を解決できるように活用してみようとなったのが、この機能を開発するに至った経緯です。
使い方
AI分析サマリレポートの使い方は、要約を生成して欲しい時に生成ボタンをクリックするだけです。
生成される内容は生成AIに全てお任せしているというわけではなく、以下の3点となるようにプロンプトでコントロールしています:
システムの構成
この機能の構成についてもう少し説明します。
全体的な構成は以下のような形となっています。
矢印の番号順に処理が流れてこの機能を実現するようになっています:
- フロントエンドアプリから要約の生成をリクエスト
- APIサーバーはプロンプトに乗せるための工数データをデータベースから取得
- APIサーバーは作成したプロンプトをAzure OpenAI Serviceに投げて要約を生成
- 生成された要約をフロントエンドに返す
APIサーバーは azopenai というAzure公式のライブラリを用いて実装されています。
構成としては、LangChainを使用して、より拡張や変更に耐えうる形にする案もあったのですが、まずは最速でスモールに実装してリリースしようという話になり、azopenaiを使う形に落ち着きました。
開発裏話
ここからはこの機能を開発した上でのちょっとした裏話を紹介します。
トークンを節約だ
この機能ではAzure OpenAI Serviceを使用して要約の生成を実装しています。
今回の利用では従量課金式の使用方法をとっており、入力と出力のトークン量に応じて利用料が発生する形となっています。
OpenAIのモデルに関してはこちらのTokenizerでトークン量の計測を事前に行うことができます。
今回この機能を開発していった中で驚いたのは、愚直に機能を実装していくとプロンプトの内容がどんどん膨れ上がり、利用料が高くなっていってしまうことです。
機能の開発当初では、あまり工夫をせずに実装を進めていたため、現在の予算の10倍ほどはかかる見込みとなっていました。
これではユーザーに厳しい利用制限をかけなければ機能を公開できない状況だったため、トークン消費量を減らして、できるだけたくさんこの機能を利用してもらえるよう工夫を重ねて行きました。
実施した調整は大きく2点あります。
1つはプロンプトに添付する工数データをある程度絞るようにしたことです。
工数データは場合によっては最大5,000件プロンプトに載せられる可能性があり、この上振れは予算の試算に大きな影響を及ぼしていました。
そこで、要約の品質が落ちない範囲で、要約の目的にそって載せる工数データをある程度絞ることにより、この問題の影響を小さくしました。
もう1つは、工数データを埋め込む際のフォーマットをJSON形式からCSV形式にしたことです。
JSON形式では構造を多彩に表現できる分、CSV形式に比べてより多くの文字列が必要となります。
手元で簡単に比較したところでも、2.6倍程度トークン数が変わっていました:
これらの工夫によって、月々のトークン消費量を抑えることができ、この機能の利用上限を押し上げることができました。
プロンプトの改善
生成AIを組み込んでいるため、プロンプトの調整は重要な要素でした。
そのなかでも、生成AIのレスポンスをJSON形式に限定することには少し苦労しました。
「返答を、添付したJSON文字列に沿ったJSON形式に限定して」といった指示を追加すると、大体はうまくいくのですが、しばしばそれに沿わない返答を返してきてしまうことがあります。
ここはすごくもどかしさを感じた部分で、通常のコードでの実装であれば、こういったブレは発生しないように抑えられるのに・・・と思っていました。
このブレた返答とは、例えば返答の最初に、「こちらが生成されたJSONです」といった不必要な文言が入ってしまっていたり、コードブロックとしようとして、バックティックでJSON文字列が囲まれていたりなどでした。
これらは一つずつ愚直に回避する指示を追加して取り除いて行きました。
また、もう一点印象的だったことは、日本語での生成内容が、当初はである調だったことです。
この機能の開発は、オフショアのフィリピンメンバーと一緒に行っていたため、プロンプトは英語で作成されていました。
多言語対応するために、要約の生成内容は日本語や中国語で翻訳してねとプロンプトに追記するようにしていたのですが、日本語はである調で出力されており、アプリの他の部分との違いが際立ってしまっていました。
こちらは「Please answer in polite language. (丁寧な言葉で返答してね)」という指示を追加することで修正しました。
提供モデルが使えなくなるだと・・・
※ このセクションの内容は執筆時点での情報になります。実装の際は最新の情報をご確認ください
Azure OpenAI Serviceでは、利用方法にいくつか種類があるのですが、当時の要件を唯一満たしていた方法が使えなくなってしまうということがリリース前に判明しました。
こちらの記事から判明しました、ありがとうございます! zenn.dev
これが判明するまでは、以下の条件の組み合わせでAzure OpenAI Serviceを使おうとしていました:
- データの流れを日本リージョンに限定
- 従量課金モデル
これに対応していたGPTモデルが、リリース後すぐに提供終了になってしまう予定で、全く同じ方法での利用の受け皿がない状態でした。 (Azureにも問い合わせましたが、なかったとのこと)
対応としては、「プロビジョニングされたデプロイを使う」か「日本リージョンを諦めて、グローバルリージョンを使う」の2つがありました。
今回は後者のグローバルリージョンを使うことで対応をすることにしました。Azureはこれからグローバルリージョンでの利用を推していきたいのではないかと推測したためです。
この選択に合わせて、データが海外に送信される可能性があることを、ユーザーに必ず認知してもらうよう設定画面の改修も加えています。
また提供されるモデルは、定期的に最新化され、古いものは提供が終了していくとのことで、こちら忘れずに入れ替えをしていかなければなりません。
まとめ
「AI分析サマリレポート」について、ご紹介させていただきました。
今回自分としても、プロダクトとしても、生成AIを用いた初めての機能の実装になりました。
想像していたよりもチャレンジングな部分が多かったですが、学びもありました。
適切に機能開発に役立てていけるよう、これからも情報のインプットをしていきたいと思います。
We are hiring!
クラウドワークスでは個人がより活躍できる社会を実現するため、仲間を募集しています!
ぜひ募集をご確認ください。