Azure OpenAI Service×Bing SearchでWeb検索に基づいた回答をさせてみる

Azure OpenAI Service の学習モデルはある期間までの情報までをベースとしているため、最新の情報に基づいた回答を返すことができません。

例えば[`gpt-35-turbo`](https://learn.microsoft.com/ja-jp/azure/ai-services/openai/concepts/models#gpt-35-turbo-model-availability)モデルは 2021 年 9 月までの情報を学習しており、下記のような最新の情報を回答させようとすると誤った情報やそもそも取得できない旨の回答が返ってきます。

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398865/71d77a7e-c156-7745-f6aa-b3a9f83cf0fe.png)

ですが、Azure OpenAI Service と Web 検索サービスを組み合わせることにより、上記のような GPT の学習データが保持していない新しい情報に基づいた回答を返すことが可能です。

今回は Azure が提供している「Bing Web Search」を活用し、最新情報に基づいた回答を返す方法をご紹介します。

## Bing Web Search

Bing Web Search とは、Azure が提供している Web 検索エンジン で、APIからWebの情報を取得できます。

Azure Portal でリソース作成する場合、「Bing Search v7」を選択するとリソースの作成が可能です。

参考：https://learn.microsoft.com/ja-jp/bing/search-apis/bing-web-search/overview

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398865/f00c1f3d-7296-d123-e46c-0e2faab99cd1.png)

### リクエスト例

Bing Web Search で検索する API リクエスト例は下記の通りです。

- URL: `https://api.bing.microsoft.com/v7.0/search?q=<検索クエリ>&fressness=day&count=3`
  - クエリパラメータ
    - `q`: 検索クエリ（キーワードなど）
    - `freshness`: 鮮度
    - `count`: 上位何件までを 結果として返すか
- HTTP メソッド: GET
- リクエストヘッダー
  - `Ocp-Apim-Subscription-Key`: <Bing Web Search API キー>
    - Azure Portal の場合、API キーは Bing Search リソースの「キーとエンドポイント」から取得できます

      ![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398865/8dcde4c7-6279-6913-1d1e-f9f983da701c.png)

詳細：https://learn.microsoft.com/ja-jp/bing/search-apis/bing-web-search/reference/endpoints

### レスポンス例（一部）

「本日の為替レート」というクエリで 上記 リクエスト を実行した結果は下記の通りです。

`webPages` > `value`にヒットした URL や Web ページ名などが取得できます。

今回は、Web ページ内でヒットした箇所が抜粋されている`snippet`を活用してみます。

詳細：https://learn.microsoft.com/ja-jp/bing/search-apis/bing-web-search/reference/response-objects

```json
{
  "_type": "SearchResponse",
  "queryContext": {
    "originalQuery": "本日の為替レート"
  },
  "webPages": {
    "value": [
      {
        "id": "https://api.bing.microsoft.com/api/v7/#WebPages.0",
        "name": "リアルタイム為替レート ： 三井住友銀行",
        "url": "https://www.smbc.co.jp/ex/ExchangeServlet?ScreenID=real",
        "snippet": "リアルタイム為替レート. （2024年1月17日 午前5時5分 現在）. 通貨（通貨単位）. 為替レート（円）. 外貨→円貨（TTB）. 円貨→外貨（TTS）. 米ドル（1 USD）. 146.76. 147.76.",
        "dateLastCrawled": "2024-01-16T20:25:00.0000000Z",
        "language": "ja"
      },
      {
        "id": "https://api.bing.microsoft.com/api/v7/#WebPages.1",
        "name": "外国為替相場一覧表（リアルタイムレート）：三菱UFJ銀行",
        "url": "https://www.bk.mufg.jp/ippan/rate/real.html",
        "snippet": "本日の為替レートは、三菱ＵＦＪ銀行の外国為替相場一覧表（リアルタイムレート）で確認できます。各通貨のTTSとTTBの値段やチャート表、外貨預金の取扱方法などを見ることができます。",
        "dateLastCrawled": "2024-01-16T12:04:00.0000000Z",
        "language": "ja"
      },
      {
        "id": "https://api.bing.microsoft.com/api/v7/#WebPages.2",
        "name": "為替レート計算 - Yahoo!ファイナンス",
        "url": "https://finance.yahoo.co.jp/fx/convert",
        "snippet": "本日の為替レートを日本円、コード、ドル、ブラジル、レアルなどの各種為替ペアに分けて計算できるサイトです。最新の取引レートや暗号資産、FX会社比較などの情報も提供しています。",
        "dateLastCrawled": "2024-01-14T23:02:00.0000000Z",
        "language": "ja"
      }
    ]
  }
}
```

## フロー

上記の Bing Search の API を呼び出し、回答を生成させるフローは下記の通りです。

![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398865/ac198689-2c5c-a535-179d-f1a0c490e67a.png)

1. チャット内容の入力
1. クエリの生成
   - ユーザーからの質問文に基づき、Azure OpenAI Service で検索クエリを生成させます。
   - 例えば「本日の為替レートを教えてください」と入力すると、「本日の為替レート」という検索クエリを生成します。
1. Web 検索
   - 2.で生成したクエリで、Bing Web Search の API を呼び出し Web 検索します。
1. 回答生成
   - 3.の Web 検索結果に基づき、再度 Azure OpenAI Service で回答を生成させます。

## プロンプト

「本日の為替レートを教えてください。1 ドルは日本円でいくらですか？」という質問に対してクエリの生成および回答生成をさせてみます。

### ② クエリの生成

まずは質問分からBing Web Searchの検索クエリを、GPTモデルで生成させてみます。

プロンプトは以下の通りで、Bing Web Searchのクエリパラメータ`?q=<検索クエリ>&fressness=day`を生成させます。

#### プロンプト例

```
""
「Question」に基づいて、Bingの検索クエリパラメータを1つ作成してください。

クエリパラメータは以下の形式としてください。
?q=<検索クエリ>&freshness=<鮮度>
・q: 検索クエリ
・鮮度: day or week or month
""

Question:
本日の為替レートを教えてください。1 ドルは日本円でいくらですか？

クエリパラメータ:
```

#### 回答例

下記のようにパラメータが返ってくるため、こちらをBing Web SearchのAPIのURLに組み込み、検索していきます。

```
?q=1ドルの為替レート&freshness=day
```

### ③ 回答生成

次に、検索結果とチャット内容に基づき、回答を生成するプロンプトを作成します。

#### プロンプト例

```
以下の検索結果の抜粋を使用して回答してみてください。
検索結果:
###

"ドル/円は節目の148.00円を上抜けると上昇に弾みが付き、昨年11月下旬以来の高値となる148.53円前後まで上値を伸ばした。なお、英国では12月消費者物価指数（CPI）が再加速したことを受けて英中銀（BOE）の利下げ観測が後退"

"ドル円、一時147.98円と昨年12月1日以来の高値（22:35）. 【速報】米・1月ニユ―ヨーク連銀サービス業活動：－9.7（12月－14.6％）（22:33）. 【速報 ..."

"usdjpy - アメリカ ドル / 日本 円 2024/01/18〜. Yahoo!ファイナンス掲示板は、シンプルで誰でも楽しめる匿名掲示板です。. Yahoo!ファイナンスでは投資判断に役立つ情報を掲載しています。."


###
質問:本日の為替レートを教えてください。1 ドルは日本円でいくらですか？


回答:
```

#### 回答例

AI からは下記のような回答が返ります。

```
現在の情報に基づくと、1ドルは日本円でおおよそ148円前後です。ただし、為替相場は常に変動しているため、正確なレートは変動する可能性があります。最新の為替レートを確認するためには、信頼できる為替情報サイトや金融機関のウェブサイトを参照してください。
```

検索結果に「ドル/円は節目の **148.00 円**を上抜けると...」、「ドル円、一時 **147.98 円**...」といった文言が含まれるため、AI からの回答はきちんと検索結果に基づいた情報が返ってきていますね。

## まとめ

- 今の作りですと一律 Web 検索を実施しているので、Function Calling など活用し Web 検索が不要な質問（「俳句を作って」「○○ を英語に翻訳して」など）についてはそのまま回答を返すなどの工夫は必要です。
- 今回は Bing の Web 検索を生成AIの回答に組み込みましたが、URL やクエリを変更すれば様々な API を組み合わせるといった応用も可能です。
- 質問内容や検索結果によっては意図した情報がうまくヒットしない場合があるため、今後はPrompt Flowなどで回答精度の評価などを試していきたいです。