【AzureOpenAI】PDFの情報を会話形式で質問できるサービスをリリースしました

AzureOpenAIを利用して、PDFドキュメントの情報をもとに回答してくれるチャットサービス「インスタマニュアル」をリリースしました。

https://instamanual.biz/welcome

## サービス概要
アップロードされたPDFをベクトル化しインデックスデータにすることで、質問に対する回答をPDFの情報から作成してくれます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449768/5abaa5e6-2820-52dc-8b5a-e4d8d5749abb.png)

回答の文章中には利用したドキュメントへのプレビューリンクが生成され、回答が正しいものかを確認することができます。
複数のPDFアップロードにも対応しました。

## 実装期間
5月ごろから開始し、サービス構想・方針決定、デザイン、開発の3名体制で進めていき10月下旬での完成となりました。

## 利用技術
- MicrosoftAzure
  - CognitiveSearch
  - AzureFunctions
  - BlobStorage
  - AzureOpenAI
  - AppService
- Laravel
- MySQL
- HTML
- CSS
- JavaScript
## 実装について
サービスの根幹となるAI部分はAzureOpenAIを利用しました。
AzureOpenAI・CognitiveSearchを利用したPDFドキュメントの読み込みやベクトル化については以下の記事を参考にさせていただきました。
とても丁寧に書かれており、構造や仕組みを理解する上で本当に参考になりました。

https://qiita.com/tmiyata25/items/875f563ba7a91f3da823#cognitive-search%E3%81%AE%E3%83%AA%E3%82%BD%E3%83%BC%E3%82%B9%E4%BD%9C%E6%88%90

https://zenn.dev/microsoft/articles/34fdf03208b932

そのほか、基本的なAIへの問い合わせやインデックスの作成については、公式のリファレンスを元に実装しました。

https://learn.microsoft.com/ja-jp/azure/ai-services/openai/reference

## 躓いた点
### Azureの用語
初めてのAzureを利用した開発だったため、各種用語への理解に苦労しました。
S3でいうバケットはBlobStorageでいうコンテナだったり、サブスクリプション、リソースグループなど...
CognitiveSearchを利用する上でのデータソースやインデックスの関係も難しく、現状は
インデクサー = データソースにある情報たちを検索に利用できるようにするためにインデックスに登録していく実行ツール
と理解しました。

### Azureサービスの特性
CognitiveSearchのインデックスはプランによって作成できる上限があり、10, 50...1000というふうに増えていきます。

https://learn.microsoft.com/ja-jp/azure/search/search-limits-quotas-capacity#index-limits

大衆向けのChatサービスとしては規模拡大を考えると全然足りない数字であり、CognitiveSearchの使い方としては、たくさんのユーザーが2,3個ドキュメントを読み込んで利用するというよりは、企業内の組織単位といった比較的少数なグループごとに大量の資料を読み込ませて検索する用途であると感じました。

加えて、料金体系についても検索回数ではなく時間課金のため、サービス継続をする上では相当なコストがかかってしまいます。

これらの点については試行錯誤での進行や機能での選定により、そもそもニーズにあっているかの確認ができておらず反省でした。

### Azureが単純に遅い？
あまり難しいことはせず、AppServiceにLaravelのアプリケーションを載せたぐらいですが通信が確立するまでに3秒ほどかかっている印象です。
初めてのAzureということもあり、ここの原因究明ができず、そのままになってしまっています。。
(解決方法をご存知の方がいらっしゃったらご教示いただけると幸いです。)

### 自分のスキルセットとの相性
自分が普段利用している言語がPHP/Laravelであったため、AIサービスによく利用されているようなPythonやNode.jsのリファレンスやチュートリアルなどをLaravelで利用できるように解釈していくのが難しかったです。
AI分野においてはもともと知見のある言語との相性を確認し、あまり良くなさそうであればPythonなどの相性の良い言語を1から学びつつできる限り実装していくのが結果的に楽だったのかな、と思いました。
フロントエンドにおいてもモダンなフレームワークへの知見がなく、チャットサービスを作るための非同期的な処理などの知見が不足してしまい反省でした。

### マンパワー不足

## 苦労した点
### AzureAppService上でのLaravel QueueWorkerの自動起動
Linux環境のAppServiceにはWindows環境にあるWebjobsという定期実行機能がないほか、
キューワーカーの定期実行、永続化として利用していたsystemdやcronが初期状態でインストールされていなかったため色々と試行錯誤しました。
結果としてAppServiceの起動時のスタートアップコマンドでsupervisorのインストール、必要なconfファイルを配置、supervisorの実行をするシェルスクリプトを実行することで自動起動を実現しました。

### AIの検索精度の改善
AzureOpenAIでは、インデックスを利用したドキュメント情報込みの回答データはCognitiveSearchでヒットした文献とそれを元にした回答文が含まれています。

https://learn.microsoft.com/ja-jp/azure/ai-services/openai/reference#example-response-3

```json
"messages": [
    {
        "role": "tool",
        "content": "{\"citations\": [{\"content\": \"\\nAzure AI services are cloud-based artificial intelligence (AI) services...\", \"id\": null, \"title\": \"What is Azure AI services\", \"filepath\": null, \"url\": null, \"metadata\": {\"chunking\": \"orignal document size=250. Scores=0.4314117431640625 and 1.72564697265625.Org Highlight count=4.\"}, \"chunk_id\": \"0\"}], \"intent\": \"[\\\"Learn about Azure AI services.\\\"]\"}",
        "end_turn": false
    },
    {
        "role": "assistant",
        "content": " \nAzure AI services are cloud-based artificial intelligence (AI) services that help developers build cognitive intelligence into applications without having direct AI or data science skills or knowledge. [doc1]. Azure Machine Learning is a cloud service for accelerating and managing the machine learning project lifecycle. [doc1].",
        "end_turn": true
    }
]
```
※[Azure OpenAI Service REST API 応答の例](https://learn.microsoft.com/ja-jp/azure/ai-services/openai/reference#example-response-3)より引用

それを利用している際に、ドキュメントとしてはヒットしてきているが、回答としては「該当の情報はありませんでした」となることが度々ありました。
ユーザーに反映するのは回答の文章だけでありドキュメントまでは引っ張ってこれているので、この情報をプロンプトに組み込み、その中から回答するように指示した質問を再度投げることで回答精度が向上しました。


# 最後に

今まで社内のエンジニアとしてリリース済みのサービスの追加実装や保守・運用に携わっていましたが、1からサービスを実装していく上という機会に恵まれてリリースまでやり遂げることができたことは素晴らしい経験でした。
一緒にサービスを作らないかと声をかけてくださったメンバーの方には感謝しかありません。

しかし、一から作る上での難しさや新しい技術を利用する上でのスキルの足りなさを痛感しました。
実装の中で直面した問題に対する解決策もまだまだ最適解とは言えないのでこの辺りはどんどん改善していければと思っています。

この経験を活かして個人での開発のモチベーションを絶やさず、新たに挑戦いければなと思います。

本サービスについても、まだまだ改善できる点はあるので知見をためつつ取り組んでいこうと思います。
（全然マンパワーと知見が足りていないので興味がある方いましたらサイトのお問い合わせからお待ちしています！）