Azure OpenAI Assistants APIで自社のデータをチャット形式で分析する

Azure OpenAI Studioに新たに追加されたAssistants機能により、独自のドキュメントベースで質問に回答したり、Pythonコードを実行してGPTモデルの能力を強化したりすることが可能になりました。

この記事では、Assistants APIの使い方、コードインタープリター機能を活用したデータ分析を解説します。また実際のデータを使用してAssistantsを構築・機能のテストを行い、使用するまでの一連の流れを紹介します。

概要

Azure OpenAI StudioにAssistants(Preview)の機能が実装されました。

learn.microsoft.com

Assitants APIとは、簡単に言うと、ChatGPTの回答を強化する仕組みです。

RAGの仕組みをOpenAIに任せて自分でアップロードしたドキュメントに基づいて回答を生成することができたり、内部でPythonを使用することでチャットボットAI単体では難しい計算をさせたりすることができます。

2024年2月8日時点ではSweden Central, East US 2, Australia Eastの3リージョンで利用可能です。

地域によって使用できるGPTモデルが異なっているため、さらに詳細な情報は以下のドキュメントを確認してください。

learn.microsoft.com

API Versionは2024-02-15-previewを指定する必要があります。

主要な機能であるコードインタープリターと、Function Callingについて解説します。

コードインタープリター

内部でPythonコードを作成して実行することで、GPTモデルの振る舞いを強化することができます。

公式ドキュメントのユースケースでは、難しいコードや数学の問題を繰り返し解決すること、複数の形式でユーザーが追加したファイルに対して高度なデータ分析を実行すること、チャートやグラフなどのデータ視覚化を生成することが示されています。

今回はこの機能を使用して、サンプルデータを分析する例を示します。

Function Calling(関数呼び出し)

Function Callingと呼ばれる機能で、自然言語から関数呼び出しのためのデータを作成します。Assistants APIではこちらの機能を使用できます。

詳細は次のリファレンスを参照します。 learn.microsoft.com

より細かい解説は以下の記事をご参照ください。 blog.jbs.co.jp

Assistantsの作成

実際にAssistants APIを使用してみます。本記事ではAustralia EastリージョンのAzure OpenAI Serviceを使用します。

まずはAzure OpenAI Studioを開き、アシスタント(プレビュー)を選択します。

以下の設定に従って値を入力します。

名前 説明 入力例
Assistants名 Assistants API 任意のデプロイ名 TitanicAnalyzeAssistant
手順 システムプロンプトのような役割を持つ項目で、Assistantsの振る舞いを定義する タイタニック号の乗客に関する属性情報と、沈没した際の生存に関係するデータを分析するAIです。ユーザーからの入力に回答します。
デプロイ Assistants APIで使用するGPTモデルを指定する gpt-4-turbo
関数 Assitants APIのデータ構造を定義したい場合、function callingに基づいた既定のスキーマを設定する なし
コードインタープリター コードインタープリンターの機能をON/OFFで設定する ON
ファイル Assitants APIの回答で使用するファイルをアップロードする。※1
(上限は20個、最大ファイルサイズは512MB)
アップロード可能な拡張子についてはdocsを参照
今回はタイタニック号の学習用csvファイルをアップロードしました

※1 : 2024年2月8日時点で、アップロードしたファイルの保存方法や保存場所ついて明記されていない点には注意する必要があります

設定後に[save]を選択すると、Assistantsが作成されます。

[Open]を選択するとこれまでに作成したAssistantsの一覧を表示できます。

機能のテスト

Azure OpenAI Studio UI上から実行する

最初に以下の質問をしてみました。

タイタニック号には何人乗っていた?

AIは次のように回答しました。

アップロードされたデータセットには、合計で891人の乗客が記録されています。ただし、これはタイタニック号に乗っていた全ての乗客を表すわけではなく、データセットがどの範囲の情報を含むのかによって異なる可能性があることに注意してください。実際にタイタニック号には約2,200人の乗客と乗組員が乗船していました。

アップロードしたcsvファイルは学習用に加工したものですが、実際のタイタニック号の乗客人数も考慮した回答を生成しました。

(※Wikipediaによると、「氷山に衝突した時には2,224人を乗せていた」との記述があるため正しい回答といえます)

次はコードインタープリターの機能を確認するため、細かくデータ分析をさせてみます。

どのような乗客が生存することができましたか?

アップロードしたCSVには乗客の属性と事故後の生存可否が示されていますが、この質問に回答するためにはどの列に注目して、どのようにユーザーに情報提示を行うのかを考える必要があります。

実際の回答を見てみると、次の通りになりました。

タイタニック号事故の生存確率は主に性別、年齢、船室のグレードによって影響を受けることが知られており、列の抽出は高い精度で機能していることが分かります。また自動でパーセンテージ表記を使用し、年齢層を区切ることで見やすく分析を行ってくれました。

最後には年齢が若く、女性であり、上位階級に属していた乗客が生存する可能性がより高かったと結論づけることができます。という考察を示しました。

データ分析後に独自に予測をさせてみます。

1等船室のチケットで乗船した、5歳男児の生存確率はどの程度になると思いますか?

通常は細かくデータ分析を実施したり、AIを使用して入出力を定義してモデル作成を行うことで結果を予想しますが、Assistants APIは以下のようにデータに基づいた考察を述べました。

データセット内で、1等船室に乗船していた5歳以下の男児は2人おり、その生存率は100%でした。これは、全員が生き残ったことを示しています。ただし、この結果に基づいて将来予測を行う際には慎重さが必要であり、これは極めて限られたサンプルサイズ(2人のみ)に基づいているためです。しかし、分析された属性と一致する当時の1等船室に乗船していた5歳の男児は、非常に高い生存確率を持っていたと言えそうです。

最後にFunction Callingの機能をテストしてみます。 以下のように、ユーザーの独自の乗客の属性をもとに生存可否を予測するようなJSONスキーマを定義します。

    {
        "name": "get_survived",
        "description": "Predicts survival based on information about the occupants.",
        "parameters": {
            "type": "object",
            "properties": {
                "survived": {
                    "type": "number",
                    "description": "Survival status of those on board (survived:1, dead:0)"
                }
            },
            "required": ["survived"]
        }
    }

次のように再度質問してみます。

1等船室のチケットで乗船した、5歳男児は生存しますか?

内部でfunction callingを使用し、定義した通りの結果が返ってきました。

ソースコードから実行する

ドキュメントに掲載されているサンプルを参考に、PythonからAssistants API を叩いてみます。 learn.microsoft.com

今回は既に作成したAssistants API に対して、外部からスレッドを作成して回答を取得する例を示します。

import os
import json
import time
from IPython.display import clear_output
from openai import AzureOpenAI

# Azure OpenAI ServiceのキーとエンドポイントURLを設定
API_KEY = ""
RESOURCE_ENDPOINT = ""

# Azure OpenAI StudioからAssitants IDを取得する
assistant_id = ""

client = AzureOpenAI(
    api_key=API_KEY,
    api_version="2024-02-15-preview",
    azure_endpoint=RESOURCE_ENDPOINT,
)

# Create a thread
thread = client.beta.threads.create()
thread_id = thread.id

# Add a user question to the thread
message = client.beta.threads.messages.create(
    thread_id=thread_id,
    role="user",
    content="どのような乗客が生存することができましたか?"
)
thread_messages = client.beta.threads.messages.list(thread_id)
print(thread_messages.model_dump_json(indent=2))

# Retrieve the status of the run
run = client.beta.threads.runs.create(
  thread_id=thread_id,
  assistant_id=assistant_id,
)

start_time = time.time()
status = run.status
while status not in ["completed", "cancelled", "expired", "failed"]:
    time.sleep(5)
    run = client.beta.threads.runs.retrieve(thread_id=thread_id,run_id=run.id)
    print("Elapsed time: {} minutes {} seconds".format(int((time.time() - start_time) // 60), int((time.time() - start_time) % 60)))
    status = run.status
    print(f'Status: {status}')
    clear_output(wait=True)

messages = client.beta.threads.messages.list(
  thread_id=thread_id
)

print(messages.model_dump_json(indent=2))

Assistant IDは、UI上から取得することができます。

次のように結果が取得できます。

おわりに

Azure OpenAI ServiceでAssistants APIが解放されて、独自のファイルに基づいた回答、コードインタープリターによる分析が利用できるようになりました。

データ量に制限がありますが、小規模であれば独自にRAGのシステムを構築しなくても独自の回答をさせることができます。

ただし現状のAzure OpenAIではアップロードしたファイルがどのように扱われているのかが明確になっていないため、公式の続報を待ちたいと思います。

執筆担当者プロフィール
西野 佑基

西野 佑基(日本ビジネスシステムズ株式会社)

機械学習系ソリューション開発、業務Webアプリ開発、開発環境自動化などを担当。

担当記事一覧