Azure OpenAI (v1.0) をpythonで利用してみる

# Azure OpenAI をpythonで利用してみる

2023-11-20 時点で、Azure OpenAI を試そうとして、[公式ドキュメント](https://learn.microsoft.com/ja-jp/azure/ai-services/openai/quickstart?tabs=command-line%2Cpython-new&pivots=programming-language-python)通りに動かしても、ちっとも動かなかったので個人的に修正点をメモしておく。

## 前提

この記事では、以下の前提で記載する。

* 使用言語はPython 3.10.11
* 利用モデルはgpt-35-turbo
* デプロイは作成済み
* エンドポイントは環境変数「AZURE_OPENAI_ENDPOINT」に設定済み
* API_KEYは環境変数「AZURE_OPENAI_KEY」に設定済み

## 問題点

[Azure AI Studio](https://oai.azure.com/portal/) で表示されるサンプルコードは以下の通り、バージョンが0.28.1以下を想定していて、そもそも v1.0以降には対応していない。

```python:Sample in Azure AI Studio
#Note: The openai-python library support for Azure OpenAI is in preview.
      #Note: This code sample requires OpenAI Python library version 0.28.1 or lower.
import os
import openai

openai.api_type = "azure"
openai.api_base = "https://<account名>.openai.azure.com/"
openai.api_version = "2023-07-01-preview"
openai.api_key = os.getenv("OPENAI_API_KEY")

message_text = [{"role":"system","content":"You are an AI assistant that helps people find information."}]

completion = openai.ChatCompletion.create(
  engine="tosumi-gpt35t",
  messages = message_text,
  temperature=0.7,
  max_tokens=800,
  top_p=0.95,
  frequency_penalty=0,
  presence_penalty=0,
  stop=None
)
```

[公式ドキュメント](https://learn.microsoft.com/ja-jp/azure/ai-services/openai/quickstart?tabs=command-line%2Cpython-new&pivots=programming-language-python#create-a-new-python-application) では、v1.0に対応したコードを示していて、clientの作成方法は合っているが、completionsの呼び出し方とresponseからのメッセージの取り出し方が間違っているため、このまま試そうと思っても動かない。


```python:Sample in MS Documents
import os
from openai import AzureOpenAI
    
client = AzureOpenAI(
    api_key=os.getenv("AZURE_OPENAI_KEY"),  
    api_version="2023-10-01-preview",
    azure_endpoint = os.getenv("AZURE_OPENAI_ENDPOINT")
    )
    
deployment_name='REPLACE_WITH_YOUR_DEPLOYMENT_NAME' #This will correspond to the custom name you chose for your deployment when you deployed a model. 
    
# Send a completion call to generate an answer
print('Sending a test completion job')
start_phrase = 'Write a tagline for an ice cream shop. '
response = client.completions.create(model=deployment_name, prompt=start_phrase, max_tokens=10)
print(response.choices[0].text)
```

## 修正点

v1.0対応の completions の呼び方は、client.chat.completions.create() に messages, model を渡してやるだけでいい。(deploymentやapi_versionはエンドポイントに入っているので、model=でdeploymentを指定するのではなく、deploymentで指定可能なモデルを選択してやる）  
またresponse の受け方も、テキスト部分はresponse.choices[0].message.content に入っているので、それらを踏まえたサンプルコードは以下のようになる。


```python:azuregpt.py

import os
from openai import AzureOpenAI
    
client = AzureOpenAI(
    api_key=os.getenv("AZURE_OPENAI_KEY"),  
    api_version="2023-10-01-preview",
    azure_endpoint = os.getenv("AZURE_OPENAI_ENDPOINT")
    )
   
# Send a completion call to generate an answer
# messages = [{'role': 'system', 'content': 'You are an AI assistant that helps people find information.'}, {'role': 'user', 'content': 'Which is the biggest city in the world?'}]
messages = [{'role': 'system', 'content': 'あなたはAIアシスタントです。ユーザーからの質問に、可能な限り回答してください。ただし明確に回答出来ない場合は、「わからない」と回答してください。また回答するときは、語尾をすべて「にゃん」として回答してください。'}]

prompt = 'こんにちは'
while prompt != 'end':
  messages.append({'role': 'user', 'content': prompt})
  response = client.chat.completions.create(messages = messages, model='gpt-35-turbo')
  print('\nAI:', response.choices[0].message.content)
  messages.append({'role': 'assistant', 'content': response.choices[0].message.content})
  print('[質問を入力してください。 end と入力すると終了します]\n===')
  prompt = input()
```

* messages の構造は、[{'role': xxx, 'content': yyy},{},{},,] となっている
* 最初のmessages で、role='system' として、インストラクションを与えて、チャットの基本ルールを設定する
* ユーザーの入力を促し、入力された文字列を role='user'としてmessagesに追加する
* client.chat.completions.create() をコールして、パラメータとしてmessages, modelを与える
* response.choices[0].message.contentに格納されたレスポンス テキストを、role='assistant' として、さらにmessagesに追加する
* ユーザーが'end' と入力するまで繰り返す

最初に示した前提となる情報を環境変数に設定し、上記サンプルコードを適当なファイル名（例：azuregpt.py）に保存してから、以下のコマンドを実行することで、検証できる。

> python3 .\<ファイル名>.py

例：
> python3 .\azuregpt.py

## まとめ

Azure OpenAI v1.0 対応での注意事項

* インポートするクラスは AzureOpenAI
* completion コールは、AzureOpenAI.chat.completions.create()
* responseの取り出しは、response.choices[0].message.content

Azure OpenAI に限らず、AIに関連するテクノロジーは分進秒歩なので、上記はあくまでも2023年11月時点の情報です。