Azure OpenAIのAssistants APIを解説&実装

## はじめに
2022年11月のChatGPT登場から2年近くが経過し、様々な組織で、チャットボットやQAボットの実装が進んでいるかと思います。
そのような中、シングルタスクベースのチャットボットやQAボットにとどまらない、より高度なAIアシスタントの実装が求められるケースも増えてきているのではないかと思います。例えば、既存の社内プロセスとの連携。社内プロセスについて問い合わせたユーザに対し、社内ドキュメントを参照して回答するだけでなく、複数の社内プロセスの中から必要なプロセスを選択し、自律的に実行まで行うAIエージェントを実装する。そのようなシナリオも増えているのではないでしょうか。

そんな中、マルチタスクベースのAIエージェントを実装可能なAzure OpenAIの[Assistants API](https://learn.microsoft.com/ja-jp/azure/ai-services/openai/concepts/assistants)にも注目が集まっています。
Assistants APIはその名の通り、特定の役割を負うAIエージェントを実装可能なAPIで、「あなたは〜を行うAIアシスタントです」というロール設定のもとに実装されます。自動化したいプロセスごとにエージェントを作成し、[AutoGen](https://microsoft.github.io/autogen/)と呼ばれるフレームワークによって複数エージェントを制御することでマルチエージェントを実装することができます。
（こちらの記事では、AutoGenについては詳しく触れず、Assistants APIとは何なのかに焦点を当てて進めていきます。）
## Assistants APIのツール

Assistants APIの単一のチャットUIから、複数のツールに並列でアクセスすることができます。ユーザの要求をもとにAssistants API自身が必要なツールを判断し、アクセスします。呼び出し可能なツールとしては、Pythonコードを実行可能なCode Interpreter(Preview)、ユーザ自身のファイルデータをもとにしたRAGを実装可能なFile search(Preview)に加え、必要なfunctionを呼び出すことで、外部のAPIやプロセスと連携できるFunction calling、Function calling with Azure Logic Appsがサポートされております。(2024年8月時点)

この記事では、Pythonを用いたAssistants APIの実装に関し解説します。今回は、ツールとしてCode Interpreter(Preview)を呼び出し、[OpenAI公式ドキュメント](https://platform.openai.com/docs/assistants/quickstart)にある通り、数学の問題をサポートするチューターを作成します。ご興味のある方は、この記事を通じてPythonでのAIアシスタント作成に挑戦してみてください。


## 準備
パッケージのインストール
```
python-dotenv
openai
```

## 実装
それでは実際に実装していきましょう。
オブジェクト及び実装の流れは以下の通りになります。

**オブジェクト**
・Assistant：特定の役割を持つAIエージェント
・Thread：Assistantとユーザのメッセージを展開
・Message：Thread上に投げられるテキストや画像、ファイル等のメッセージ
・Run：Assistantの構成とThreadのMessageをもとにアシスタント機能を実行する
・RunStep：Run内でAssistantによって取られたステップ

**実装の流れ**
①Assistantの作成
②Threadの作成及びMessageの追加
③Threadの実行

下記、[OpenAI公式ドキュメント](https://platform.openai.com/docs/assistants/overview)からの抜粋画像になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3872169/ec2123f5-9410-020d-dbb0-ede224bd696c.png)



## 準備：モジュールのインポート
```
import os
import json
from openai import AzureOpenAI
from dotenv import load_dotenv

load_dotenv(verbose=True)

client = AzureOpenAI(
    api_key=os.getenv("AZURE_OPENAI_API_KEY"),  
    api_version="2024-05-01-preview",
    azure_endpoint = os.getenv("AZURE_OPENAI_ENDPOINT")
    )
```

## ①Assistantの作成
Assistantを作成する際に、instructionsで、「あなたは〜を行うAIアシスタントです」というロールを設定することができます。
今回は、数学の問題をサポートすると共に、実行したPythonコードも表示するよう指示します。
toolsとしては、code_interpreterを指定します。
```
assistant = client.beta.assistants.create(
    name="math-assistant",
    instructions=f"You are a helpful AI assistant who helps the user solve math questions
    .List the executed Python code at the end of of the output",
    tools=[{"type": "code_interpreter"}],
    model=f"{os.getenv('AZURE_OPENAI_MODEL_NAME')}"
)
```
**Assistantの出力**
```
print(assistant.model_dump_json(indent=2))
```
下記の出力が返され、Assistantの構成を確認できました。
`{
  "id": "asst_BYVVBhRco69fXWBWKzceCFZ0",
  "created_at": 1725288024,
  "description": null,
  "instructions": "You are a helpful AI assistant who helps the user solve math questions.List the executed Python code at the end of of the output",
  "metadata": {},
  "model": "gpt-4o",
  "name": "math-assistant",
  "object": "assistant",
  "tools": [
    {
      "type": "code_interpreter"
    }
  ],
  "response_format": "auto",
  "temperature": 1.0,
  "tool_resources": {
    "code_interpreter": {
      "file_ids": []
    },
    "file_search": null
  },
  "top_p": 1.0
}`

## ②スレッドの作成及びメッセージの追加
AIエージェントと会話を行うためのスレッドを作成し、スレッド上にメッセージを追加していきます。このスレッドをAIエージェントに渡し、実行する流れとなります。

**スレッドの作成**
```
thread = client.beta.threads.create()
thread_id = thread.id
print(thread.model_dump_json(indent=2))
```
下記の出力が返され、Threadの構成を確認できました。
`{
  "id": "thread_vX45K8yEt162Rk1b3oauk9yy",
  "created_at": 1725288026,
  "metadata": {},
  "object": "thread",
  "tool_resources": {
    "code_interpreter": null,
    "file_search": null
  }
}`

**メッセージの追加**
「3x + 11 = 14の方程式を解くのをサポートしてほしい」というユーザのメッセージを追加していきます。
```
message = client.beta.threads.messages.create(
    thread_id=thread.id,
    role="user",
    content="Please help me solve the equation `3x + 11 = 14`. "
)
```
## ③スレッドの実行
実際にスレッドを実行し、AIエージェントの回答を確認してみましょう。
**スレッドの実行**
```
run = client.beta.threads.runs.create_and_poll(
  thread_id=thread.id,
  assistant_id=assistant.id,
  ##instructionsで更に詳細な指示を与えることができる
)
run_id = run.id
print("run_id:", run_id)
```
**ステータスの確認**
```
print(run.status)
```
`completed`の出力が返されました。

**メッセージの取得**
```
messages = client.beta.threads.messages.list(
  thread_id=thread.id
)
print(messages.model_dump_json(indent=2))
```
やや冗長なため、出力は省略します。下記でAssistantから返されたメッセージのみ確認していきましょう。

## 実行結果
Assistantから返されたメッセージは以下の通りとなりました。 実行したPythonコードを表示したのち、方程式の解き方をステップバイステップで解説してくれています。
AIアシスタントが Pythonコードを実行し、ロールで指示した役割を果たしたことが分かります。
今回は、数学の問題を手助けする、というロールを指示したため、答えを教えるのではなく、答えに辿り着くためのステップを解説していますね。

```
python
# Calculation to solve the equation 3x + 11 = 14
x = (14 - 11) / 3
x

assistant: Let's solve the equation \(3x + 11 = 14\).

First, we need to isolate \(x\). Here are the steps:

1. Subtract 11 from both sides of the equation:

\[3x + 11 - 11 = 14 - 11\]

2. Simplify the equation:

\[3x = 3\]

3. Divide both sides by 3 to solve for \(x\):

\[x = \frac{3}{3}\]

Let's find the value of \(x\).
```
## 責任あるAI
皆さんは、Azure OpenAIの[責任あるAI](https://www.microsoft.com/ja-jp/ai/responsible-ai#tabs-pill-bar-oce365_tab1)の原則を知っていますか。お客様のデータはAIモデルのトレーニングに利用されないこと、強固なセキュリティ及びコンプライアンスで保護されることなどにはじまり、信頼できるAIのための様々なルールが整備されています。
また、信頼できる入出力のための機能もあります。コンテンツフィルタリングを行う[Azure AI Content Safety](https://azure.microsoft.com/ja-jp/products/ai-services/ai-content-safety/)などがそれに当たりますが、今回のように、LLMによってコードが生成されるケースでは、Azure Container Appsの[動的セッション](https://learn.microsoft.com/ja-jp/azure/container-apps/sessions?tabs=azure-cli)機能を活用することで、生成されたコードの信頼性を担保することができます。
Code Interpreter動的セッションでは、Hyper-V境界によって他のワークロードから完全に分離されたサンドボックス上でコードを実行し、テストすることができます。そのため、生成されたコードに潜む、正確性、セキュリティ、コンプライアンス等のリスクへの対策を行うことができます、是非、こうしたAzure OpenAIの機能を活用し、責任あるAI、信頼できるAIの実装を進めてください。

## まとめ
この記事では、OpenAIのAssistants API（Code Interpreter）の実装に関し、解説を行いました。Code Interpreter単体であっても、Assistants APIによる、データ分析分野の可能性を大幅に広げることができます。
今後、file search(Preview)、function calling、Function calling with Azure Logic Apps　の実装及び、AutoGenによるマルチエージェント実装に関してもアップデートしていきたいと思います。
皆さんもぜひ、Assistants APIを活用したマルチタスクベースのAIエージェントの実装に関し、調べてみてください。