🔮

実務で生成AIサービスを開発してわかったこと

2024/05/10に公開

生成AIを使ったサービスを開発してわかったことをメモしておきます。

開発したもの

  • 業種
    • SaaS
  • 課題
    • 提供サービス内でユーザーがアイディアを考えることが難しかった。様々なデータを人力で集めてくる必要があった
  • 解決策
    • アイディア起案に繋がりそうなデータを自動で集めてきて提示する。手法はベクトル検索、AIによる要約生成。
  • その他
    • チャットUIは作っていない。ユーザーの入力は最初の検索テキスト入力文のみ。

開発前の検証・プロトタイピング

  • 開発する前に生成AIの出力を検証することが必要
    • 生成AIの出力の質はサービスの肝だから
    • 生成AIの出力は事前の予想と違うこともあり早い段階で出力を確認しておかないと後々の仕様変更があったときにキツイから
  • AIに渡すデータの中身を確認しておく
    • 例えばRAGを使って社内ドキュメントやDBを検索する場合、それらのデータの中身を吟味する必要がある
    • 必要なデータと不要なデータが混在していることが多い
    • データの意味や背景を理解するために社内の詳しい人にヒアリングが必要
    • AIによる生成をする場合は生成がしやすいスキーマ定義なのかどうかの確認

検証方法:コードを書いて検証

  • 最初はAzure AI Studio playgroundを使っていたが段々細かい調整をしたくなったのでGoogle Colabに切り替えた
  • Google Colabでの調査
    • 生成の精度の確認
      • スキーマ定義を与えてどの程度生成できるのか確認
        • うまく生成できない場合はpromptチューニング、またはpromptに追加できそうなデータを調査
    • データからembedding vectorを作成
      • semantic searchして出力結果を確認
      • clusteringで精度が出るのか確認

検証のチーム体制:エンジニア以外の人も調査できると良さそう

  • 複数のエンジニア、またはBiz職、デザイナーも調査ができると望ましい
    • 単純にエンジニアの手が足りていないときでも調査のスピードが出せるから
    • Biz職やデザイナーのほうがユーザ理解が深いことがあるから。エンジニアだけでやると扱うデータを何にするかだけに集中しまいがち(個人の感想)
    • 異なる職種の人が検証しやすくする方法
      • API KEY がsecret keyで設定済みのGoogle Colabを作成して誰でもプロトタイピング、調査ができるようにしておく
  • AIサービスのUXデザインができるデザイナーがいることが望ましい
    • 生成、ベクトル検索、埋め込みベクトルなどの簡単な概念を理解しているとエンジニアとの協業がしやすい。
      • ベクトルは怖くない😇
    • 調査の段階で思っていた予想と違う生成結果が出ることがあり、そうなると仕様変更になる。ここでスムーズに改善案について議論できるとスピードが出る。

AI出力に対するユーザの期待値調整

期待値調整をしない場合、ユーザーの期待値は高くなりがち。ユーザーはOpenAIや海外big Techの最新サービスニュースを見聞きしており、それらがベースになってしまうのかもしれない。

高すぎる期待値を下げる方法を挙げていく。

期待値を下げる方法1「ワーディング」

「AIが何でも解決!」や「XXを生成して課題解決」というような謳い文句はハードルが高くなりがち。AIの出力は確率的で不確実性があるのでハードルを越えれないことが多くやめた方が良い。一方でAIと謳うことでユーザは興味を持ってくれるという部分はあるので調整は必要。

  • AIという言葉を使わずに「アシスタント」という言葉で代用する
    • AIの万能感を軽減させる
    • あくまで補助的な機能提供であるというニュアンスを伝える
  • RAGのような検索機能ならば「hoge hoge AI」という名前ではなく「hoge hoge 検索」「hoge hoge サーチ」のような名前にする
    • AIの万能感を軽減させる
    • 検索という体験で該当しない結果が出てもそこまでがっかりしない。
    • 注意点
      • 検索機能は単縦なワード検索だけだと物足りないと思うユーザもいるので「詳細フィルター機能がほしい」という要望が出てくることが予想される

期待値を下げる方法2「チャットUIを使わない」

チャットUI使わないほうがいいんじゃないかと思っている。

理由はユーザーの期待値が高いことと、UIの制約を受けるからだ。

ユーザーの期待値が高い

「チャットUIのAIサービス」と言われたらユーザは日頃使い慣れているWeb版ChatGPTのGPT-4と同じような体験を期待するだろうと思われる。これを実装しようとすると結構大変であり、プロトタイピングレベルだとユーザは使いにくいと感じるだろうから。UIを作り込む手前で価値検証してそのあとにゴリゴリ実装するならアリかも。

Web版ChatGPTのGPT-4のようなサービスに対してユーザが期待する体験の例。

  • ユーザの入力はテキスト、画像に対応していて内容は自由
  • 回答スピードは早くてストリーミング返答してくれる
  • 回答の履歴を保存できる
    • 履歴リスト表示、履歴が大量にあっても遡れる、履歴のタイトル生成
  • 同じチャット内の過去回答コンテキストを踏まえて回答してくれる
  • 回答を複数パターン用意してユーザーに選ばせることもある
  • あるチャットに対して過去の発話を遡れる
    • 上にスクロールすると過去の発話が表示される。ページングの機能が必要そう
    • このとき過去の発話はどれくらいinputに含ませるのか。inputの最大tokenを超えた時どうするのか

UIの制約

おもに吹き出し形式の制約をうけると思う。

  • AI出力が長い時でも読めるような調整
    • 例:チャットの吹き出しを分ける
  • 画像を提示したいケースは普通にある。そのときの見せ方を考える必要がある
    • chat gptでは画像生成を除いて画像は回答出力に含めない。なのでユーザーからすると独自の画像表示UIに慣れてもらう必要がある。
  • チャットを使わない場合、普通のWebの仕様にそって表示を柔軟に変えることができるメリットがあるなーと感じた。

期待値を下げる方法3「inputを限定する」

ユーザーが入力するinputを限定することで回答精度を高めていく方法。

以下のような方法がある。

  • 画像入力はやめてテキスト入力のみとする
  • サジェストワードや入力補助機能などを使ってユーザのinputテンプレートパターンをフロントのUI上で提示する。
  • backend側でユーザーの入力を何らかの方法で正規化するなどしてからpromptに渡す

期待値を下げる方法4「地味AI」

そもそも通常の処理にしれっと生成AI機能を混ぜて既存の機能を向上させる方法。地味AIと呼んでいる。「AIを使っています!」と告知しないのでユーザーの期待値が変にあがることもない。

地味AI例

  • クラスタリング
    • ある大量データに対してラベル付・カテゴリー分けを人力でしていた→embedding vectorを用いて機械的にクラス分けする
  • 検索
    • 単純な文字一致による検索→ベクトル検索でセマンティックに検索できることで今までひっかからなかったあいまいなワードで検索できるようになる。(そもそもAlgoliaのようなサービスを使ったほうがいいケースはある)
  • 検索・要約
    • 例:ブログサービス内の記事検索でこれまではタイトルや記事文を検索対象にしていたがそれをAI生成の要約文に変えることで精度があがるかも(下がるかもしれない)
  • テキスト生成
    • ユーザの業務効率化を図るテンプレートを人力で用意していたが数が足りない→テンプレートの仕様を抽象化してpromptにしてテンプレートを生成する。一発で質の高い生成が難しい場合は叩き台として使用して人力で修正する
  • レコメンド
    • 例:ブログサービスで関連記事を提示する機能に埋め込みベクトルを使って精度を上げる。記事内の画像も埋め込みベクトル化して画像の意味も扱うようにするなど。

開発

Azure

  • Azureを使った
    • 必然性はそんなになかったがOpenAIの最新モデルが使えたから。また新規でモデルが登場した時もタイムラグが短く使えそうだったから
  • Azure AI Search Index
    • 途中でフィールド編集がしづらい、できないので注意
      • Indexを削除して作り直しすることがあった
    • 契約しているプランによって作成できるIndexの上限数が決まっている
    • filter機能にクセがある
    • embeddingのmodel名のフィールドを用意しても良いかも
      • modelは日々進化しており、何のmodelを使ってembeddingしたか後から知りたくなることもあるかもしれないから
  • Azure OpenAI Serviceで使えるモデル
  • OpenAIのモデルを使うか、他社のモデルを使うか
    • 今回はOpenAIのModelを使ったが今後Google,Anthropicsなど別のモデルを使いたくなるケースが出てくるだろうからコード実装上では簡単に切り替えられるようにWrapperクラスなどを用意しておくと良いかも。もちろん早すぎる抽象化は負債になる可能性もある。
  • Embeddingのタイミング
    • ベクトル検索に使うデータが日々更新されるようなデータの場合、embedding作成のタイミングをいつにするかは事前に検討しておいたほうがよい
      • データ更新のたびにembeddingを更新する、日次のバッチ実行にするなど
  • 負荷分散
    • アクセスが多い場合は複数regionでmodelを用意して使うmodelを分散させると良い

OpenAI API

  • JSONを生成するJSON modeはJSONを返さないときもある
    • JSONを返さないときのエラー処理が必要
  • chat completionとcompletion API があるが、completion APIは最新modelによっては対応していない。なので基本的にchat completion APIを使う。
  • 生成の返答スピードにはバラツキがある。体感5~10秒くらいのバラツキが出ることもある。

Prompt

  • OpenAI公式ドキュメントで提示されている書き方を参考にした
  • promptは定数ファイルとして切り出しておくと他の人との協業がしやすいかも
    • 例:コード書けるデザイナーでも編集しやすい
  • inputで渡せるtoken数に対してpromptは短くなりがち
    • Prompt Engineeringするのが不毛だから(個人の感想)
      • こういうエンジニアはなんとなく多い気がしてる
      • Prompt Engineeringをガチればそれだけで価値が出るのかも。例えばtoken数をすごく多くするとか。
  • ちゃんと作るならprompt injection防止などのセキュリティ対策が必要

Node.js

  • azure nodejsのドキュメントが最新でない場合がある
    • npmからgithubレポジトリに遷移してそこから最新のコードを検索した
  • streaming機能を使うためにはNode.js18以上が必須だった
    • node16とかでnpmのバージョンも古いとpackage-lock.jsonのバージョンも古いのでazure openaiのライブラリは一応はinstallできてしまう。azure openaiのライブラリのドキュメントを読むとnode18以上が推奨と書いてある。

Frontend

仕様によっては考える必要がありそうなこと。

  • チャットの履歴リスト機能
    • 履歴のDBが必要
    • 履歴のタイトル付けはどうする?
      • chatgptだとタイトルは要約したタイトルになっている。そこまでやるのか、やらない場合は最後の発話の抜粋を載せるなど
    • 履歴が大量にあるときはページングやスクロール読み込みが必要
    • 履歴が大量にあるときは履歴検索機能が必要
  • AI出力に時間がかかる時はスケルトン・ローディング表示する
    • streaming表示する場合でも最初の表示までに数秒かかることがある
    • loading animationはlottiefilesを使うとかわいく作れる
  • ユーザーのinput補助
    • 選択式質問を提示する、サジェストワードを提示
  • 細かいインタラクション調整ができていないと使いづらいと感じる
    • 例:Enterで送信できる・できない。

法務系

  • AIに渡すデータの種類によっては法務と相談する必要がある
    • 例えば個人情報データは渡さないようにするなど
  • 規約を作ってユーザーからの同意が必要な場合はサービスのオンボーディングUIの最初とかに規約を表示させる必要がある

モニタリング

  • 作成したサービスが実際に使われているかどうかモニタリングできる仕組みが必要
    • 各種操作のイベントログ、データを可視化できるダッシュボードの作成など
  • ユーザーインタビューなどで直接反応を伺った場合、AIサービスという新規性から「結構いいと思います!」という反応をもらえることもあるが、実際ログを見てみると継続して使ってくれているとは限らない

以上です。Happy Hacking LLM!

Discussion