新しくなった ChatGPT × Cognitive Search を使ったエンタープライズサーチ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/54ffd026-b343-4abf-7514-9ce0ebff5132.png)
2023/3/10 の公開から 5 か月経ちましたが、モデル廃止計画の発表などもあり例の RAG アーキテクチャの[レポジトリ](https://github.com/Azure-Samples/azure-search-openai-demo/)がいろいろ改良されています。

1. 検索キーワードの生成を `gpt-35-turbo` で行う
1. ドキュメントの検索に**ハイブリッド検索**が利用できる
1. PDF ファイルのページ分割に **Document intellingence（旧 Form Recognizer）** を利用できる
1. 自動デプロイ**コマンドの改良**（東日本リージョンも選択可能）
1. Python venv 仮想環境の利用で**環境を汚さずに実行可能**
1. Quart サーバー使用で**ネイティブ非同期処理化**
1. モデル選択の幅が広がった

https://github.com/Azure-Samples/azure-search-openai-demo/

# 1. 検索キーワードの生成を gpt-35-turbo で行う
検索キーワードの生成に用いていた `text-davinci-003` が非推奨となり新規デプロイできなくなった影響で、今後は ChatCompletion API を使うモデルで代替する必要があります。コードでは、`gpt-35-turbo` を用いて検索キーワードを生成しています。本来、 `text-davinci-003` の移行先モデルは `gpt-35-turbo-instruct` のはずですが、このモデルがいまだに登場していないため、一時的に `gpt-35-turbo` を用いています。

https://qiita.com/nohanaga/items/db5de65963c0abd8ecfb

# 2. ドキュメントの検索にハイブリッド検索が利用できる
「Developer settings」から Azure Cognitive Search の検索クエリーモードを変更することができます。これによって、検索キーワードだけではヒットしない質問をベクトル検索と組み合わせてヒットさせることができるようになります。オプションでセマンティックランカーも利用できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/d6f2df4d-f9f8-e9ba-2e73-951efe2afad9.png)

https://qiita.com/nohanaga/items/e156d8be60622b42e8eb

ちなみに `app\backend\approaches\chatreadretrieveread.py` では下記のように `gpt-35-turbo` で生成した検索クエリーを Embeddings API に投入していますが、ユーザーからの生の質問文を使うのか、生成検索クエリーを使うのかでまた検索結果が変わってくるかと思います。

```python
if has_vector:
    query_vector = (await openai.Embedding.acreate(engine=self.embedding_deployment, input=query_text))["data"][0]["embedding"]

```

# 3. PDF ファイルのページ分割に Document intellingence（旧 Form Recognizer） を利用できる
初期構築の際に自動実行されるサンプル PDF ファイルの分割に [Azure AI Document intellingence](https://learn.microsoft.com/azure/ai-services/document-intelligence/studio-overview?view=doc-intel-3.1.0)（旧 Form Recognizer）をデフォルトで使用するようになりました。サンプル PDF ファイルのアップロードは以下のプロセスで行われます。

1. Document intellingence を用いて複数ページの PDF からページごとにテキスト抽出
1. ページごとのテキストをにチャンクに分割
1. PDF に表が含まれていた場合、 HTML タグ化（表であるという意図を保持）して保存
1. チャンクごとに `text-embedding-ada-002` で Embeddings を生成
1. ページごとに分解した PDF を Azure Blob Storage へアップロード
1. Azure Cognitive Search のインデックスにベクトル＋テキストを登録

https://github.com/Azure-Samples/azure-search-openai-demo/blob/main/scripts/prepdocs.py

# 4. 自動デプロイコマンドの改良（東日本リージョンも選択可能）
初期のコードは `azd up` の際に小技が必要でしたが、最新版ではスムーズに Azure 上に必要リソースがデプロイされます。下図のように **Japan East** を選択すれば、すべてのリソースを東日本リージョンに閉じることができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/844478c8-95ee-bd8c-82ca-35e8527d1a29.png)

自動的にリソースグループが作成され、以下のようなリソースがデプロイされます。デフォルトで各リソースには Microsoft Entra ID (Azure AD) 認証で接続できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/eb37b959-2157-6715-6095-3cfa2e18eecd.png)

# 5. Python venv 仮想環境の利用で環境を汚さずに実行可能
バックエンドサーバーおよび `prepdocs.py` の実行に venv の仮想環境を作成してその環境で実行することにより、ご自分の Python 環境を汚さずに運用できるようになりました。

Windows の場合、`app/start.ps1` でバックエンドサーバーとフロントエンドビルドを起動しますが、事前に実行に使う Python venv 仮想環境の作成も行っています。すでに Anaconda などで複数環境を使い分けている場合、`$pythonCmd = Get-Command python -ErrorAction SilentlyContinue` でうまく指定の Python が取得できなかったため、直接使いたい python.exe のフルパスを指定する必要がありました。

また、Windows では Microsoft Store 経由でインストールした Python では `azd up` に失敗するという報告もあります。その場合 https://www.python.org/downloads/ からベースとする Python をインストールすれば OK です。バージョンは 3.9 以降が必要です。

# 6. Quart サーバー使用でネイティブ非同期処理化
初期のころはバックエンドサーバーに [Flask](https://msiz07-flask-docs-ja.readthedocs.io/ja/latest/) を使っていましたが、最新版では [Quart](https://pgjones.gitlab.io/quart/) に置き換えられました。Quart は、Flask の asyncio 再実装です。つまり非同期処理にネイティブ対応しているため、並列処理の効率化が期待できます。ちなみに ChatCompletion API のコールも非同期版を使用しています。

```python
chat_completion = await openai.ChatCompletion.acreate(
    deployment_id=self.chatgpt_deployment,
    model=self.chatgpt_model,
    messages=messages,
    temperature=overrides.get("temperature") or 0.0,
    max_tokens=2048,
    n=1)
```

# 7. モデル選択の幅が広がった
昔は `gpt-35-turbo` だけでしたが、今は `gpt-35-turbo-16k` や `gpt-4`、`gpt-4-32k` の `0613` バージョンが利用可能になりました。これによりチャンクのサイズを拡大させたり、これまで失敗していた ReAct 周りの精度が向上しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/1c3b2822-035a-aa23-d391-0f4154aec2c8.png)
複数の ChatGPT プラグインを呼ぶような AI オーケストレーターを実装できるようになりました。

# 武将ブランチ
最新版のコードで戦国武将 Wikipedia を検索するブランチを作成しました。

https://github.com/nohanaga/azure-search-openai-demo/tree/busho


# さいごに
`gpt-35-turbo`  `gpt-4` のファインチューニングに備えよ！

すでに対話履歴は IN/OUT セットで保存していますよね？その生の対話履歴こそが高品質のトレーニングデータのベースになるのです！

https://qiita.com/nohanaga/items/18baccb843b4148e6a77