Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Azure OpenAIと周辺機能を活用して​ 堅牢なLLMアプリケーションを開発しよう​

07JP27
January 13, 2024

Azure OpenAIと周辺機能を活用して​ 堅牢なLLMアプリケーションを開発しよう​

OpenAIのリリースによりLLMの利用率が爆発的に増えてきました。
当初はChatGPTとの会話形式だけだった利用シーンも独自のナレッジから答えさせるRAGアーキテクチャなど、LLMのアプリケーションへの組み込みがされはじめています。
本資料では主にAzure OpenAIのLLMをアプリケーションへ組み込む際により堅牢かつ安全にアプリケーション実装ができるポイントについて紹介します。

本資料は以下のイベントで発表した内容です。
第1回 Azure Travelers 勉強会 札幌の旅
https://jat.connpass.com/event/303868

07JP27

January 13, 2024
Tweet

More Decks by 07JP27

Other Decks in Technology

Transcript

  1. Azure OpenAIと周辺機能を活用して 堅牢なLLMアプリケーションを開発しよう Junpei Tsuchida | @07JP27 Cloud Solution Architect,

    Microsoft Japan ※所属の表明はステルスマーケティング防止の為であり、本資料で述べられる内容については所属する組織の公式見解ではありません。 #AzureTravelers OK! OK! 第1回札幌の旅
  2. Junpei Tsuchida 日本マイクロソフト株式会社でクラウドソリューションアーキテクトとして主に エンタープライズの顧客支援を担当。 ➢ 山形県在住で基本的にWork from Home ➢ Zennの「Microsoft

    (有志)」Publicationの管理人 ➢ プライベートではピザ「窯」やコックピットを作成中 第二種電気工事士 日本ディープラーニング協会 E資格 他MCP多数 https://zenn.dev/07jp27 https://qiita.com/07JP27 @07JP27 07JP27
  3. 本セッションのスコープ このセッションは・・・ である ではない Azure OpenAIで提供されるLLMを アプリケーションに組み込む時のポイントや 手法の話 • プロンプトエンジニアリング手法の紹介

    • Azureサービスのアーキテクチャ設計に 関する話 想定予備知識 • アプリケーション開発の一般概要 • LLMでできることの概要 • Azureに関する基礎知識
  4. Nadella’s Warning at Microsoft Inspire 2021: Every Company Will Need

    to be a Tech Company | Datamation “Every Company Will Need to be a Tech Company” (すべての企業はテクノロジー企業になる必要がある) Satya Nadella Microsoft CEO
  5. LLMを組み込んだアプリのビジネス的価値 GPT-3.5 GPT-4 Whisper DALL-E Foundation Model Your Prompts Your

    Data つぎの文章を300文字程度で意味を変えずに要約し てください。 あなたは優秀なプログラマーです。次のコードに対してレ ビューを行ってください。 答えを導く事ができない場合は「わからない」と答えて ください。 ユーザー個々人のデータ 組織の内部ナレッジベース アプリケーションデータ + 基本的に世界中の開発者が同じモデルを使っている 独自の価値を出す差別化ポイント
  6. それってWebアプリのChatGPTでもできるんじゃ? ほかにも・・・ Your Prompts あなたは優秀なプログラマーです。次の コードに対してレビューを行ってください。 他の質問には決して答えずに、コードの みをレビューしてください。 + System

    message User prompt 次のコードについて問題点を教えてくだ さい。 ... 好きな食べ物は? 提示されたコードにはいくつかの問題点 があります。まずはじめに… 申し訳ありませんが、コードが提供され ていないため、コードレビューを行うことは できません。 = Response ChatGPTアプリのチャットウインド ウで指定しているのはこの部分 ※System messageはChatGPT PlusのCustom instructionsでは設定可 データを自動で加味させたい! (いちいちコピペしたくない) UIをカスタマイズしたい! 独自のアプリに組み込みたい 会話をロギングされたくない 社内の会履歴を保持したい ここを設定することでより安全で 多様な振る舞いが可能(※)
  7. 目次 OpenAIを組み込んだ堅牢なアプリを構築するためのポイントを紹介 GPT-3.5 GPT-4 Whisper DALL-E Foundation Model Azure AI

    Content Safety Library API App Logic UI UX Monitor User prompt Your Prompts Your Data Azure OpenAI Service Your App ④ ① Libraryの選択 ②モデルインターフェイス ③コンテンツフィルター ④モデルの精度テスト ② ③ ①
  8. ①Libraryの選択 GPT-3.5 GPT-4 Whisper DALL-E Foundation Model Azure AI Content

    Safety Library API App Logic UI UX Monitor User prompt Your Prompts Your Data Azure OpenAI Service Your App
  9. Azure OpenAIへのリクエスト方法 • Azure OpenAIの基本インターフェースはWeb API • メジャーな言語ではライブラリも提供されている • アプリから呼び出す場合、一般的にはライブラリを使用したほうがよい

    • 現在広く使われているOpenAIライブラリは大きく2つの種類 • 単純にWeb APIをラップしただけのライブラリ = 標準ライブラリ • 多段プロンプトやReActを考慮して作られたもの = Copilot向けのライブラリ Web API ライブラリ 標準ライブラリ Copilot向けライブラリ ① Libraryの選択 • OpenAI Python API library • Azure.AI.OpenAI • LangChain • Semantic Kernel
  10. Copilot stackに当てはめて考えてみる ① Libraryの選択 標準ライブラリ Copilot向け Microsoft Build 2023 •

    Web APIと各言語の変換 • Web APIと各言語の変換 (標準ライブラリを利用) • テンプレートエンジン • プラグイン • プランナー • メモリー • テキスト変換
  11. 大は小を兼ねる? 現状 • 比較的高いレイヤーで抽象化されているので単機能のつまみ食いが難しい • Semantic KernelやLangChainはバージョンアップが激しい • それらの中で使っている標準ライブラリのバージョンアップも激しい =「枯れていない」技術→何かしらの変更で動かなくなる可能性が起きやすい

    見解(現時点での) • 必要以上に高機能なライブラリを使わない ① Libraryの選択 Semantic Kernel.CoreはGAしたけどその中で使っている標準ライブラリがまだbetaなんですよね・・・(ボソッ LangChainのリリース履歴 1ヶ月で6リリース
  12. ライブラリ選択のまとめ Copilot向け(LangChain/Semantic Kernel etc…) • 自律駆動してマルチタスクを実行するようなCopilotやReActアプリが欲しい場合は 使ってもいいかも 標準ライブラリ(Azure.AI.OpenAI etc…) •

    Copilot Stackまで必要ないアプリの場合 • 使う言語に対応しているライブラリがある場合 Web API • 使う言語でライブラリが無い場合(なければ作ればいい) ① Libraryの選択 標準ライブラリ Copilot向けライブラリ Web API Azure OpenAI Service • 破壊的アップデートに耐えられる強い心があるなら • アップデート対応と開発工数を天秤にかけてアップデート対応が勝つくらい高度なアプリを作ろうとしているなら
  13. ②モデルインターフェイス GPT-3.5 GPT-4 Whisper DALL-E Foundation Model Azure AI Content

    Safety Library API App Logic UI UX Monitor User prompt Your Prompts Your Data Azure OpenAI Service Your App
  14. LLMのアプリ連携の難しさ LLMは「自然言語」を出力するモデルなのでスキーマ固定が難しい =アプリとの連携が難しいケースがある 例えばRAGアプリの場合 ②モデルインターフェイス Some API (Bing APIなど) App

    Azure OpenAI ①質問 ②クエリ化 ③クエリで検索 ④回答生成 ⑤回答 LLMから生成された出力がAPIのスキー マに厳密に従う必要がある RAG = Retrieval Augmented Generation:検索拡張生成
  15. アプリケーション連携を目的とした機能 そんな問題を確実に解決するために OpenAIではアプリケーション連携を目的とした2つの機能を提供 ②モデルインターフェイス Function calling JOSN Mode 【出力】 はい!こちらが出力になります。

    {”favorit_food”:”ラーメン”} お役に立てると嬉しいです! Azure OpenAI 【プロンプト】 「〜〜〜」っていう入力からユーザーの好きな食べ物をJSONで返してください。 スキーマは{”favorit_food”:”hogehoge”}にしてください。 App いや、JSONだけでいいのに・・・
  16. アプリケーション連携を目的とした機能 ②モデルインターフェイス Function calling Azure OpenAIでFunction Callingを使う! (zenn.dev) モデルが選択できる関数 リストを定義

    入力から呼ぶべき関数があるとモデルが 判断すれば関数名と引数が返ってくる 関数の呼び出し自体はアプリの責任。 モデルが勝手に呼び出してくれる訳では無いこと注意!
  17. アプリケーション連携を目的とした機能 呼び出した関数からの結果を再度モデルに渡して回答を生成することも可能 ②モデルインターフェイス Function calling Azure OpenAIでFunction Callingを使う! (zenn.dev) response

    = client.chat.completions.create( model=deployment, messages=[ {“role”: “user”, “content”: “今日の夕飯はぶり大根を作ろうかな。"}, { “role”: “function”, “name”:”get_recipe”, “content”: “ブリを切って煮て、大根と一緒に醤油、みりん、砂糖…” } ], function=… ) print(response.choices[0].message) 出力 { ”role": ”assistant", ”content“: ”ぶり大根を作るためのレシピです ね。以下は基本的な手順になります。 ¥n 1.ブ リを切ります。適当な大きさに切ってください。 ¥n 2.大根を厚めに切ります。¥n3.鍋にぶりと 大根、水、醤油、みりん、砂糖、酒を入れます …" } 関数の呼び出し結果として messagesに追加
  18. アプリケーション連携を目的とした機能 現時点ではFunction Callingの次期バージョン 従来のFunction callingとの違い: ・プロパティ名 ・複数関数の並列呼び出しに対応 おそらく今後toolsに指定できる種類が増えそう (Code InterpreterやRetrievalとか、本家のAssistants

    APIのイメージ) ②モデルインターフェイス Azure OpenAIのAPIにtoolsプロパティが追加されたぞ! (zenn.dev) # TOOLS変数に次の関数を追加している想定 # ‘switch_airconditioner;エアコンをオンオフする。 # ‘switch_ lamp ;電気ランプをオンオフする。 # 電源状態のbool値のswitchプロパティをそれぞれに追加 response = client.chat.completions.create( model=deployment, messages=[ {"role": "system", "content": "You are a helpful assistant."}, {“role”: “user”, “content”: “エアコンと電気をつけてください。"} ], tools=TOOLS, tool_choice="auto", temperature=0, ) if response.choices[0].finish_reason=='tool_calls': for tool_call in response.choices[0].message.tool_calls: print(tool_call.function) #Function(arguments='{"switch": true}', name='switch_airconditioner') #Function(arguments='{"switch": true}', name='switch_lamp’) #↑一回の呼び出しで複数のFunction Callingレスポンスが取得できる 並列Function calling(toolsプロパティ)
  19. アプリケーション連携を目的とした機能 モデルからのレスポンスがJSON形式になることを保証するモード プロンプトエンジニアリング力は必要だが、JSON出力のみが欲しい場合は簡潔に記述可能 ②モデルインターフェイス JOSN Mode response = client.chat.completions.create( model=deployment,

    messages=[ {"role": "system", "content": "You are a helpful assistant."}, {“role”: “user”, “content”: “次の文章からJSONの配列を生成してください。 地名はlocation、天気はweatherというスキーマを使用してください。 ¥n===¥n今日の東京の天気は晴れでしょう。山形県は曇り、北海道は 雪まじりの雨となる見込みです。"}, ], response_format={ "type": "json_object" } ) print(response.choices[0].message.content) { "weatherData": [ { "location": "東京", "weather": "晴れ" }, { "location": "山形県", "weather": "曇り" }, { "location": "北海道", "weather": "雪まじりの雨" } ] } Azure OpenAIでJSON Modeを使う! (zenn.dev) これを追加 スキーマはプロンプトで指定 出力
  20. 違いと使い所 ②モデルインターフェイス Azure OpenAIのFunction CallingとJSON Modeの違いと使いどころ (zenn.dev) Function Calling JSON

    Mode 従来(非推奨) 次期(tools) リクエスト functionsプロパティに呼び出すことができ る機能の名前や説明、それを呼び出すた めに必要な引数を定義 toolsプロパティに呼び出すことができる機 能の名前や説明、それを呼び出すために 必要な引数を定義 API呼び出し時に response_format={ "type": "json_object" } を付与する(メッセージには「json」を含む必要 あり) レスポンス 定義した機能の中から呼び出すべき1つ の機能名とその引数となる値(JSON文 字列) 定義した機能の中から呼び出すべき1つ 以上の機能名とその引数となる値 (JSON文字列) JSON文字列 タイミング モデルがユーザーの入力に基づいて、定義されている関数を呼ぶべきと判断した時(強 制的に特定関数を呼び出させることも可能) response_format={ "type": "json_object" } をつけて呼び出している限り常に JSONスキーマの指定 方法 functionsプロパティ内で定義 toolsプロパティ内で定義 メッセージ内(プロンプトエンジニアリング)で定義 対応モデル Ver gpt-35-turbo-0613 / gpt-4-0613 〜 gpt-35-turbo-1106 / gpt-4-1106-preview 〜 対応API Ver※ 2023-07-01-preview〜 2023-12-01-preview 〜 2023-10-01-preview 〜 ユースケース Copilot(ReActエージェント)として、ユーザーの入力文によっていつ呼び出されるか不 定な様々な機能を有したアプリケーション 今から使うならtoolsプロパティを使った並列呼び出しを選択 RAGアーキテクチャでユーザーの入力から検索ク エリを作成する際など、必ず実行するシーケン シャルな処理の一部としてLLMからJSONを取 得したい場合 LangChainやSemantic Kernelはここらへんもラップされているのであまり意識しなくてもいい ※2024/4/2に2023-08-01-preview以前のpreview APIがリタイアすることに注意 Azure OpenAI Service API version retirement - Azure AI services | Microsoft Learn
  21. ③不適切な入出力のフィルター GPT-3.5 GPT-4 Whisper DALL-E Foundation Model Azure AI Content

    Safety Library API App Logic UI UX Monitor User prompt Your Prompts Your Data Azure OpenAI Service Your App
  22. 不適切なコンテンツをどう防ぐか • 指示した範囲のみで動作するように システムメッセージを設定 • 敵対的プロンプト(後述)に対して弱い プロンプトエンジニアリング • Azure OpenAI独自の機能で、既定で有効になっている

    • Azure Content Safetyサービスを利用して提供されている (ユーザーは意識する必要なし) • 入出力に対して4つのカテゴリーでフィルターを適用 • ヘイトと公平性 • 性的 • 暴力 • 自傷行為 コンテンツフィルター サービス設計 • 利用範囲を明確にする(ユーザー/ドメイン) • ユーザーが入力範囲を制限する (ドロップダウンやチェックボックス) + Transparency Note for Azure OpenAI - Azure AI services | Microsoft Learn ③コンテンツフィルター
  23. フィルタートリガーのレスポンス ③コンテンツフィルター ユーザー入力でトリガーされた場合 出力でトリガーされた場合 Status:400 { "error": { "message": "The

    response was filtered due to the prom…", "type": null, "param": "prompt", "code": "content_filter", "status": 400, “innererror": { ”code": "ResponsibleAIPolicyViolation", “conztent_filter_result": { ”hate": { "filtered": true, "severity": "high" }, “self-harm": { "filtered": true, "severity": "high" }, "sexual": { "filtered": false, "severity": "safe" }, “violence": { "filtered":true, "severity": "medium" } } } } } Status:200 { "choices": [ { "content_filter_results": { "custom_blocklists": [], "hate": { "filtered": false, "severity": "safe" }, "self_harm": { "filtered": false, "severity": "safe" }, "sexual": { "filtered": false, "severity": "safe" }, "violence": { "filtered": true, "severity": "medium" } }, "finish_reason": "content_filter", … } ], … } Azure OpenAI Service のコンテンツのフィルター処理 - Azure OpenAI | Microsoft Learn
  24. カスタムコンテンツフィルター (プレビュー) ③コンテンツフィルター カスタムコンテンツフィルター + 既定コンテンツフィルターのカスタム アドオンフィルター • 既定コンテンツフィルターカテゴリーに加えて 3つのフィルターをアドオン可能

    • 脱獄(Jailbreak) • テキスト用保護済み素材 • コード用保護済み素材 • コンテンツフィルターの各項目についてフィルターが トリガーされるしきい値を設定 • フィルター無し • 低 • 中(既定) • 高 利用例:医療目的で自傷行為フィルターをOFFにする APIインターフェイスはそのままでフィルターの判定ロジックを調整可能
  25. 敵対的プロンプトによる脱獄 脱獄(Jailbreak)フィルターはすべてのアプリにおすすめ 敵対的プロンプト(Adversarial Prompting) | Prompt Engineering Guide (promptingguide.ai) プロンプトインジェクション

    プロンプトリーク システムメッセージで設定されたプロンプトを上書き し、開発者の想定以外のタスクを実行させる手法 システムメッセージで設定されたプロンプトを自らに 話させることで、重要な情報や資産を窃取しようと する手法 ③コンテンツフィルター
  26. ④モデルの精度テスト GPT-3.5 GPT-4 Whisper DALL-E Foundation Model Azure AI Content

    Safety Library API App Logic UI UX Monitor User prompt Your Prompts Your Data Azure OpenAI Service Your App
  27. LLMのテストは難しい ④モデルの精度テスト 高 (定性的) 低 (定量的) 出力変動性 (評価基準) Random().Next(); ルールベース+α

    乱数処理 外部データ連携 LLM 自然言語生成 画像生成 a + b ルールベース 計算処理 • 入力に対して期待した 出力が得られたか (Assert.AreEqual) • 出力の範囲で判定 (Assert.InRange) • Mockを使った変動性の排除 ここをどうする? 評価手法 処理例
  28. What mean「精度が高い」? 精度が高い = 期待した出力であること → 「期待した」をどう数値化して表現し、判定するか • 指示した文字数になっているか •

    指定したワードが含まれているか • 正解と意味が合っているか • 主張に一貫性があるか • 文法が正しいか • 回答に現実性があるか 定量的(例) 定性的(例) これらを定量化していく手法を模索 数値で表現可能=ルールベースで判定可能 ④モデルの精度テスト
  29. Is ChatGPT a Good NLG Evaluator? LLMを使用して定性指標を定量指標に変換 あなたはAIアシスタントで す。質問応答タスクにお ける回答の質を評価する

    ための評価指標の定義 が与えられます。あなた の仕事は、与えられた評 価指標を使って正確な 評価スコアを計算するこ とです。 + System message User prompt 予測された答えに含まれる情報やコンテンツが正解と似 ているか同等である場合、Equivalenceメトリックの値は 高く、そうでない場合は低くなります。質問、正解、およ び予測された答えがある場合、次の評価スケールを使用 してEquivalenceメトリックの値を決定します: 星1つ: 予測された答えは正解とまったく似ていません。 星2つ: 予測された答えは正解とほとんど似ていません。 星3つ: 予測された答えは正解と多少似ている。 星4つ: 予測された答えは正解とほとんど似ている。 星5つ: 予測された答えは正解と完全に似ている。 質問 {{入力値}} 正解: {{期待値}} 予想された答え {{実測値}} 星4つ = Response ※一部省略 LLM 評価 入力値 期待値 テストデータ ペア 実測値 評価結果 入力 入力 ④モデルの精度テスト Equivalence:同等な,等しい
  30. 実はすでにPrompt Flowに実装済み Prompt Flow • Azure Machine Learningの中の1つの機能(Azure OpenAIの機能ではないことに注意) •

    プロンプトの入出力を接続しながらGPTを使用したデータ処理フローを作成できる。 • 作ったフローはWeb APIとして公開までできるLLM Opsサービス。 • 作成したフローの評価として「組み込みの評価」が実装されている。 OpenAIのモデルアップデートに備えてPrompt Flowでモデルの評価フローを作る (zenn.dev) ④モデルの精度テスト
  31. 実はすでにPrompt Flowに実装済み Prompt Flowでは組み込みの評価指標で精度評価が可能 バッチ実行を送信してプロンプト フロー内のフローを評価する - Azure Machine Learning

    | Microsoft Learn 評価方法 メトリック 説明 LLMで評価? 分類の精度評価 精度 予測値と実測値を比較して分類を評価する No QnA 関連性スコアのペアご との評価 スコア、勝敗 質問応答システムによって生成された回答の品質を評価します。 Yes QnA 現実性評価 現実性 モデルで予測された回答が入力ソースにおいてどの程度現実的なものかを測定します。 Yes QnA GPT 類似性評価 GPT 類似性 ユーザーが提供した実測値の回答とモデルで予測された回答の類似性を測定します。 Yes QnA 関連性評価 関連性 モデルで予測された回答が質問とどの程度関連しているかを測定します。 Yes QnA 一貫性評価 一貫性 モデルで予測された回答内のすべての文の品質と、それらの自然な適合具合を測定します。 Yes QnA 流暢性評価 流暢性 モデルで予測された回答の文法的および言語的な正しさを測定します。 Yes QnA f1 スコア評価 F1 スコア モデルの予測と実測値の間で共有されている単語数の割合を測定します。 No QnA Ada 類似性評価 Ada 類似性 実測値と予測の両方について埋め込みを計算します。そして、それらの間のコサイン類似 度を計算します。 Yes ④モデルの精度テスト
  32. というのは「技術的には可能です」 Completionや1ターンのChat Compleationなら比較的簡単 Completion ④モデルの精度テスト Chat Completion { “prompt”: “日本の首都は”,

    } { "choices": [{ “text”: “東京です", }] } { "messages":[ { "role": "user", “content”: “DALL-Eモデルは何ができますか? “ } ] } { “choices”:[{ "message": { "role":"assistant", “content”:“画像を生成できます“ } }] } 出力 出力
  33. { "messages":[ { "role": "system", “content”: “あなたはAIアシスタントです。“ }, { "role":

    "user", “content”: “Azure OpenAIは何ができますか?“ }, { "role": "assistant", “content”: “Azure OpenAIは様々なモデルを〜.“ }, { "role": "user", “content”: “DALL-Eモデルを使うと何ができますか?“ } ], “temperature”:0.7 … } というのは「技術的には可能です」 複数ターンの会話履歴を含んだ会話の場合、どの段階で入力値/期待値としてテストするか ④モデルの精度テスト { "messages":[ { "role": "system", “content”: “あなたはAIアシスタントです。“ }, { "role": "user", “content”: “Azure OpenAIは何ができますか?“ }, { "role": "assistant", “content”: “Azure OpenAIは様々なモデルを〜.“ }, { "role": "user", “content”: “モデルには何がありますか?“ } ], “temperature”:0.7 … } スタートは同じでも ターンが増えるほど様々な方向に スタートは同じでも ターンが増えるほど様々な方向に発散 パターンは無数にある テスト手法探求の旅は続く・・・
  34. UnitテストとE2Eテスト AI Search Azure OpenAI Azure OpenAI 独自ナレッジの検索と回答生成 つぎの入力からク エリを生成してくだ

    さい === 豪華な家に住み たい! 豪華 家 物件 OO県XX市に ある広さ100 ㎡の広大な〜 つぎの入力から回 答をを生成してくだ さい === OO県XX市にある 広さ100㎡の広大 な〜 あなたにお勧め な物件はOO 県XX市にあり ます。100㎡の 広大な〜 豪華 家 物件 ④モデルの精度テスト あなたにお勧めな物件はOO県XX市にあります。100㎡の広大な〜 豪華な家に住みたい! Unitテスト (LLM+ルールベース) Unitテスト (適合率/再現率など) Unitテスト (LLM) E2Eテスト (LLM) LLMアプリの精度が出ません!の元凶を見つけ出す 例えばRAGアプリの場合
  35. まとめ OpenAIを組み込んだ堅牢なアプリを構築するためのポイントを紹介 GPT-3.5 GPT-4 Whisper DALL-E Foundation Model Azure AI

    Content Safety Library API App Logic UI UX Monitor User prompt Your Prompts Your Data Azure OpenAI Service Your App ④ ① Library選択 ②モデルインターフェイス ③コンテンツフィルター ④モデルの精度テスト ② ③ ①