DIVX テックブログ

catch-img

はじめてのAIチャット開発:Azure OpenAIを使ってみよう


目次[非表示]

  1. 1.はじめに
  2. 2.「Azure OpenAI Service」とは?
  3. 3.Azure OpenAIの導入
    1. 3.1.「Azure OpenAI」リソースの作成
    2. 3.2.モデルのデプロイ
  4. 4.APIの中身
    1. 4.1.curlコマンドの構成
    2. 4.2.jsonの構成
      1. 4.2.1.system とは?
  5. 5.curlコマンドでAPIを叩く
  6. 6.まとめ
  7. 7.感想

こちらの記事はDIVXアドベントカレンダー2023の23日目の記事です。

はじめに

こんにちは、株式会社divxの渡部です。

今回は、Azure OpenAIのAPIを利用したチャットメッセージを試してみようというテーマです。

なぜこのテーマを選んだかというと、現在私が開発しているサービス内に、AIがユーザーの質問に答えてくれる機能があるのですが、それをAzure OpenAIを使って実装したからです。

当時の状況を軽く説明しますと、私(と所属しているチーム)はAIについて開発経験が全くありませんでしたが、サービスとしてAIを組み込むことが急遽きまりました。そして、言い渡された納期は2週間後とのこと。「できるのか、これ?」と思った私でしたが、チームや上司からの助けもあり、2週間(と少し)で実装することができました!

当時の私のように、AIの開発に挑戦したい、または、しないといけないけどどうしたらいいかわからないという人たちが最初の一歩を踏み出す助けになればと思い記事を書くことにしました。

「Azure OpenAI Service」とは?

正確な説明は公式のリンクを参照していただきたいですが、ざっくり言ってしまえば”Azure のリソース・セキュリティの範囲内でOpenAIのサービスが使える”ということです。最新機能をいち早く使いたいのであれば本家本元のOpenAIのサービスを使うほうがいいと思いますが、こちらの場合はAzureで運用されているのでより安定性が高く、入力データが学習に使われないなどの違いがあります。

体感ではありますが、本家のOpenAIとAzure OpenAI Serviceを比べると、障害などで使えなくなる頻度は明らかにAzureのほうが少ないです。

Azure OpenAIの導入

「Azure OpenAI」リソースの作成

Azure そのものの導入まで説明すると長くなるので、アカウントの登録などは完了した前提で話を進めます。

AIにリクエストを投げるため、まずはAzure OpenAI(以下、AOAI)のリソースを用意しましょう。Azureのホーム画面からAOAIをクリックし、その後の画面で「作成」ボタンをクリックします。

プロジェクトやインスタンスの設定画面ではAOAIを用意したいリソースグループやリージョンを選択します。2023年12月現在、価格レベルは「Standard S0」のみのようです。設定が終われば「次へ」を押します。

ネットワーク設定に移ります。アクセスできるネットワークを限定したい場合この画面で設定してください。今回はAPIを通してレスポンスがもらえることを確認したいだけなので、ネットワークの限定は行わずに進みます。その後のタグ設定も今回は飛ばします。

最後に、入力内容の確認画面が表示されます。問題なければ「作成」ボタンを押しましょう。

リソース管理画面に飛んで、設定したAIのリソースが表示されているはずです。

これでAOAIのリソースの作成は終わりです。

モデルのデプロイ

次に、用意したリソースでどのモデルをデプロイするかを決めましょう。簡単に言い換えれば、GPT-3.5か4かどれを使うか決めて初期設定をするということです。コストを重視するかより正確性の高いレスポンスを重視するかで何を選ぶかは変わりますが、今回はAIとのやり取りができればいいのでGPT-3.5のモデルを使用します。価格差が気になる方は公式の案内をご覧ください。

それでは、デプロイしていきます。

まずは、さきほど作成したリソースをクリックしてください。リソースの設定画面が開きます。その中から「Azure Open AI Studio に移動する」をクリックしてください。

画面が変わり、Azure Open AI Studioが開きます。AIに関する設定はほぼこの画面で行いますので、ブックマークしておくことをおすすめします。

次に、左の欄にある「モデル」を選択しましょう。ここで、自分が使いたいAIのモデルを選択します。今回はGPT-3.5を使うので「gpt-35-turbo」を選択しデプロイしてください。

設定画面が開きますので、デプロイ名だけ決めて作成しましょう。詳細設定オプション内のトークンレート制限は後で自由に変更可能ですので今はどのような値でもかまいません。

作成完了の通知が出たら、左の欄にある「デプロイ」を選択することでデプロイした一覧が表示されます。これによりAPIを使用するためのエンドポイントも用意されました。

ここからはデプロイしたAIと実際にやり取りをして正しく機能しているか確かめましょう。AOAIでは、ブラウザ上でAIの動作を事前に確かめることができるプレイグラウンドを用意してくれています。確かめたいデプロイ名が選択されていることを確認して、「プレイグラウンドで開く」をクリックしましょう。

画面が変わりチャットプレイグラウンドが開きました。この画面で実際にAIとやり取りを試すことができます。さっそく質問してみましょう。

画面右側の入力欄にチャットメッセージを入力するとそれに合わせてAIが返事をしてくれます。見た目はよくあるチャットサービスと同様です。返事が返ってきているので正しくデプロイできているようです。

APIの中身

curlコマンドの構成

先程はブラウザ上でAIとやり取りができましたが、APIとして利用する場合はどうしたらよいでしょうか?

AOAIではAPIを利用するためのサンプルコードも用意してくれていますので、その中身を確認していきましょう。

チャットセッションの上部にある「コードの表示」をクリックすると、クライアントからどのようにリクエストを送ればよいか例文を紹介してくれています。今回はcurlコマンドでAPIを利用するときのサンプルコードを見てみましょう。

curl "エンドポイントのURL" \
  -H "Content-Type: application/json" \
  -H "api-key: APIキー" \
  -d "{
  \"messages\": [
   {\"role\":\"system\",\"content\":\"You are an AI assistant that helps people find information.\"},
   {\"role\":\"user\",\"content\":\"こんにちは。\"},
   {\"role\":\"assistant\",\"content\":\"こんにちは!ご質問やお手伝いはありますか?\"}],
  \"max_tokens\": 800,
  \"temperature\": 0.7,
  \"frequency_penalty\": 0,
  \"presence_penalty\": 0,
  \"top_p\": 0.95,
  \"stop\": null
}"

上記のcurlコマンドをざっくり説明すると、宛先となるエンドポイントのURLが指定され、ヘッダーでは、リクエストの中身がjson形式であることと、APIを利用するさいのAPIキーが指定されています。その後に、会話内容となるmessagesとAIの返答内容を調整するパラメータを渡しています。

このAPIではユーザーの属性などを判別・保存するような機能はなく、今までの会話履歴を毎回リクエストに載せて渡すことになります。

一見すると不親切なように見えるかもしれませんが、同じ宛先に同じ形でひたすらリクエストを投げれば良いだけなので、アプリ内に実装することを考えればすごく楽になる構成です。

jsonの構成

AIとのチャットをしたい場合、このリクエストの中のmessagesに新しい会話を付け加えていけばいいだけなのです。では、そのmessagesの中身を見ていきましょう。

「コードの表示」で、形式をjsonにするともう少し見やすくなります。

{
  "messages": [
    {
      "role": "system",
      "content": "You are an AI assistant that helps people find information."
    },
    {
      "role": "user",
      "content": "こんにちは。"
    },
    {
      "role": "assistant",
      "content": "こんにちは!ご質問やお手伝いはありますか?"
    }
  ],
  "temperature": 0.7,
  "top_p": 0.95,
  "frequency_penalty": 0,
  "presence_penalty": 0,
  "max_tokens": 800,
  "stop": null
}

ここで登場するのがrolecontentです。

roleとは直訳すれば”役割”となるとおり、会話の内容が誰によるものかを定義します。contentは実際に入力された文章そのものです。

roleには、system, user, assistantの3種類があります。

userは文字通りユーザー、つまり質問した人間を指します。そして、assistantはAIのことを指します。

system とは?

systemはAIに与える事前説明のようなもので、この項目を編集することでAIの回答方針をある程度制御することができます。どのような文章でどのように回答内容が変わるか、チャットプレイグラウンドで試すことができます。

一旦ブラウザに戻り、チャット欄の左側にある「システムメッセージ」を変えてみましょう。こうすることで、systemロールのcontentの中身が変わり、AIの回答内容が変わります。

現在はデフォルトのままだと思いますので、これを適当な指示に変えてみます。今回は料理以外の質問には答えないよう指示を出します。

変更を保存し、さっそく質問してみましょう。料理以外の質問をすると回答を断られてしまいました。

このように、AIチャットを提供する側があらかじめ回答内容の方針を決めておくための設定がsystemなのです。

curlコマンドでAPIを叩く

では、実際にターミナルからコマンドを実行して、自ら用意したAOAIにリクエストを投げてみましょう。curlのサンプルコードをコピーして、正しいAPIキーを挿入しましょう。サンプルでは「YOUR_API_KEY」となっている部分を、コードの下に伏せ字で表示されているAPIキーに置き換えます。

後は、質問したい内容を追加してコマンドを実行するだけです。

messagesは配列になっているので、最後尾に質問内容を追加します。

# 以上省略
\"messages\": [
    {\"role\":\"system\",\"content\":\"あなたは寡黙なアシスタントです。料理の質問以外には回答を控えてください。\"},
    {\"role\":\"user\",\"content\":\"こんにちは。\"},
    {\"role\":\"assistant\",\"content\":\"こんにちは。どのような料理についてお尋ねですか?\"},
    {\"role\":\"user\",\"content\":\"料理について質問する気はありません。昨日の東京の天気を教えてください。\"},
    {\"role\":\"assistant\",\"content\":\"申し訳ありませんが、私は料理に関する質問にのみ回答することができます。天気については正確な情報を提供することができません。天気予報サイトやアプリをご利用いただくことをおすすめします。\"},

    # 以下の行を追加
    {\\"role\\":\\"user\\",\\"content\\":\\"それでは、肉じゃがのおいしい作り方を教えてください。\\"}
  ],

# 以下省略

では、コマンドを実行します。すると以下のようなレスポンスが返ってきました。

{
  "id":"*", //固有のidが割り振られます
  "object":"chat.completion",
  "created":*, //unix時間が表示されます
  "model":"gpt-35-turbo",
  "prompt_filter_results":[
    {
      "prompt_index":0,
      "content_filter_results":{
        "hate":{"filtered":false,"severity":"safe"},
        "self_harm":{"filtered":false,"severity":"safe"},
        "sexual":{"filtered":false,"severity":"safe"},
        "violence":{"filtered":false,"severity":"safe"}
      }
    }
  ],
  "choices":[
    {
      "finish_reason":"stop",
      "index":0,
      "message":{
        "role":"assistant",
        "content":"肉じゃがのおいしい作り方をお伝えします。\n\n【材料】\n- 牛肉(切り落としや薄切り肉):300g\n- じゃがいも:3個(中サイズ)\n- にんじん:1本(中サイズ)\n- 玉ねぎ:1個(中サイズ)\n- しょうが:1片(細切り)\n- にんにく:2片(みじん切り)\n- 醤油:3大さじ\n- みりん:2大さじ\n- 砂糖:1大さじ\n- だし汁:300ml\n- サラダ油:適量\n- 塩:少々\n- こしょう:少々\n- ごま油:数滴(仕上げ用)\n\n【作り方】\n1. じゃがいもとにんじんを皮をむき、一口大の乱切りにします。玉ねぎも薄切りにします。\n2. 牛肉を一口大に切ります。\n3. 鍋にサラダ油を熱し、しょうがとにんにくを炒めます。\n4. 牛肉を加えて炒め、色が変わるまで焼きます。\n5. じゃがいも、にんじん、玉ねぎを加え、さらに炒めます。\n6. 醤油、みりん、砂糖を加え、全体に絡めます。\n7. だし汁を加え、煮立ったらアクを取り除きます。\n8. 中火で約20分ほど煮込み、じゃがいもが柔らかくなるまで煮ます。\n9. 塩とこしょうで味を調え、最後にごま油を数滴垂らして仕上げます。\n\nこれでおいしい肉じゃがの完成です。ご家族やお友達と一緒にお召し上がりください。"
},
    "content_filter_results":{
      "hate":{"filtered":false,"severity":"safe"},
      "self_harm":{"filtered":false,"severity":"safe"},
      "sexual":{"filtered":false,"severity":"safe"},
      "violence":{"filtered":false,"severity":"safe"}
    }
  }
],
"usage":{"prompt_tokens":232,"completion_tokens":582,"total_tokens":814}}

回答内容は、choices配列の0番目の要素messageキーに対応する値の中のcontentにあります。チャットサービスで回答内容を表示したければ、上記の値をとりだしてしまえばよいのです。

また質問したければ、取り出したAIの回答と質問したい文章の2つを、さきほどと同じ様にリクエストのmessages配列に加えてあげましょう。

まとめ

このように、質問と回答をひたすら配列に格納してリクエストを送るという処理をすればAIに回答してもらうことができます。なので、チャットサービスにこのAPIを組み込む場合は簡単に表すと以下のような流れになります。

1. 会話履歴を取得し、role, contentの内容を決めて配列内に並べる。

2. ユーザーの入力内容を配列の最後に入れる。

3. 会話履歴の配列をリクエストにのせて送信。

4. レスポンスからAIの生成文章を取り出して会話履歴として保存。

一つ注意点として、リクエストで渡された会話履歴を全て読み込んで回答が生成されることになりますので、messages配列にAIの回答と質問したい文章を追加し続けるとトークンの消費量が増大してしまいます。トークンの消費量を考えれば読み込ませる会話履歴の文字数は少ないほうが良いですので、古い会話履歴は捨てて最新10件のみ読み込ませるなどの処理を考える必要があります。レスポンスの最後にあるusageでどれだけのトークンを消費したかを確認することができますので、どの程度の会話履歴であれば保持しても問題ないか確認しておきましょう。

感想

今回はcurlコマンドを手動実行する形になりましたが、各プログラミング言語に合わせたライブラリがあるのでそれが使えるのであればそのほうが確実に楽です。しかし、最終的なリクエストがどのような形で送られるのかを理解できていることで、チャットサービス内に実装するときもどのような処理を書けばよいかあまり迷わずに作業できると感じています。

私も、最初はライブラリを使用して実装しようと試していましたが開発対象のアプリケーションにはうまく適応させることができず、リクエストとレスポンスを形作る処理を考えるため公式ドキュメントを読み漁りました。AIという未知のサービスの利用にどのような情報がどのような形で必要なのか、それを理解するのに時間はかかりました。しかし、その理解に時間をかけたことで、開発に成功し内容を記事にできる程度に成長できたのだと思います。概念や原理原則を理解しておくことの重要性を感じられた事例の一つでした。

記事の内容はAPIの基本的な使い方の解説ですので、これからAzure OpenAIを使い始める人の理解に役立つ内容になっていると思います。今回の記事を読んで実践していただいたときに、AIを使った開発が「意外と簡単じゃん」と思ってもらえたら嬉しいです。

divxでは一緒に働ける仲間を募集しています。

興味があるかたはぜひ採用ページを御覧ください。

  採用情報 | 株式会社divx(ディブエックス) 可能性を広げる転職を。DIVXの採用情報ページです。 株式会社divx(ディブエックス)


お気軽にご相談ください


ご不明な点はお気軽に
お問い合わせください

サービス資料や
お役立ち資料はこちら

DIVXブログ

テックブログ タグ一覧

採用ブログ タグ一覧

人気記事ランキング

GoTopイメージ