【Azure OpenAI 40日】Day2:Prompt Flowからgpt-4o-miniを呼び出す

に公開

✍️ TL;DR

  • Prompt FlowでAzure OpenAIを呼び出すには、@tool 関数と辞書形式YAMLが必須
  • outputs には reference: を使い、ノード名+.output を指定
  • 動作確認は pf flow test --flow . でOK

🧭 今日のゴール

  • Prompt Flow から Azure OpenAI (gpt-4o-mini) を呼び出せるようにする
  • YAML 形式のフロー定義 (flow.dag.yaml) と Python ツール (flow.py) の構成を理解する

🔧 手順(そのまま実行可)

1. ディレクトリ準備

mkdir day2
cd day2

2. .env の配置

Day1で使用した .env をコピー

Copy-Item ..\day1\.env .\

3. Pythonツールファイル作成(flow.py)

# flow.py - Prompt FlowからAzure OpenAIを呼び出す関数を定義

# Azure OpenAI SDK(openaiパッケージ)をインポート
from openai import AzureOpenAI
import os
from promptflow.core import tool  # 推奨のimport方法
from dotenv import load_dotenv

# .envファイルから環境変数を読み込み
# 必要なキー:
#   AZURE_OPENAI_ENDPOINT
#   AZURE_OPENAI_KEY
#   AZURE_OPENAI_DEPLOYMENT
#   AZURE_OPENAI_API_VERSION
load_dotenv()

# AzureOpenAIクライアントを初期化
client = AzureOpenAI(
    azure_endpoint=os.getenv("AZURE_OPENAI_ENDPOINT"),  # エンドポイントURL
    api_key=os.getenv("AZURE_OPENAI_KEY"),              # APIキー
    api_version=os.getenv("AZURE_OPENAI_API_VERSION")   # APIバージョン(例: 2024-07-18)
)

@tool # ★このデコレーターを付けることで「ツール」として認識される
def ask_gpt4o(prompt: str) -> str:
    """
    Azure OpenAI (gpt4o-mini-chat) に質問を送り、応答テキストを返す関数
    - prompt: ユーザーからの質問文
    - 戻り値: モデルの応答(文字列)
    """
    resp = client.chat.completions.create(
        model=os.getenv("AZURE_OPENAI_DEPLOYMENT"),  # デプロイ名
        messages=[
            # システムメッセージ(AIの振る舞いを定義)
            {"role": "system", "content": "あなたは簡潔な日本語アシスタントです。"},
            # ユーザーメッセージ(質問内容)
            {"role": "user", "content": prompt}
        ]
    )
    # 最初の応答メッセージの本文を返す
    return resp.choices[0].message.content # 文字列1つを返す

4. フロー定義ファイル作成(flow.dag.yaml)

# flow.dag.yaml - Prompt Flowのフローモデル設定ファイル

nodes:
  - name: gpt_answer         # ノード名(任意)
    type: python             # 実行タイプ(Python関数)
    source:
      path: flow.py          # 関数定義ファイル
      function: ask_gpt4o    # 実行する関数名
    inputs:
      prompt: ${inputs.user_input}  # ユーザー入力を関数の引数に渡す

# ← ここは辞書(マップ)形式にする
inputs:
  user_input:
    type: string
    default: "Prompt FlowからAzure OpenAIを呼び出せた?"

# ← ここも辞書(マップ)形式にする
outputs:
  answer:
    type: string
    reference: ${gpt_answer.output}  # gpt_answerノードの結果を出力に設定

5. 動作テスト

pf flow test --flow .

✅ 検証チェック

  • 実行結果で answer に日本語応答が含まれる
  • 例:
{
    "answer": "はい、Prompt FlowからAzure OpenAIを呼び出すことが可能です..."
}

pf flow test 結果スクリーンショット


🧯 つまずき&対処

  • NoToolDefined@tool デコレーターを付与し、関数が1つだけになるよう修正
  • EmptyOutputReferenceoutputs 定義で value: ではなく reference: を使用
  • CommentedSeq object has no attribute 'items'inputs/outputs をリスト形式ではなく辞書形式に修正


📌 Day2のやったこと振り返り

Day2では、Azure OpenAIをPrompt Flow経由で呼び出すことを実現しました。
具体的には以下のステップを踏みました。

  1. 環境準備

    • day2/ ディレクトリを作成
    • Day1の .env をコピーしてAPIキーやエンドポイントを再利用
  2. Pythonツール作成

    • flow.py@tool 関数 ask_gpt4o() を実装
    • Azure OpenAI SDK経由でgpt-4o-miniに質問を投げる処理を記述
  3. フロー定義(YAML)作成

    • flow.dag.yaml に nodes/inputs/outputs を辞書形式で定義
    • outputsには reference: ${ノード名.output} を指定
  4. エラー対応

    • YAML形式エラー(CommentedSeq) → 辞書形式に修正
    • NoToolDefined@tool を付与、関数を1つに限定
    • EmptyOutputReferenceoutputs の参照方法を修正
  5. 動作確認

    • pf flow test --flow . 実行で answer にモデル応答を取得
    • 実際に日本語での応答を得られ、成功を確認

❓ なぜDay2でPrompt Flowを使ったのか

Day2でPrompt Flowが登場した理由は、Day1のコード直書き方式から「再利用可能なフロー構築」へ進化させるためです。

背景

  • Day1:Pythonスクリプトで直接 Azure OpenAI API を呼び出し、シンプルに動作確認
    • メリット:最短で動く
    • デメリット:
      • 入出力の流れがコードに埋め込み
      • 処理の追加や変更がしにくい
      • 複数人・複数環境で共有しづらい

Day2でPrompt Flowを導入した理由

  1. ワークフロー化
    • モデル呼び出し部分を「ツール」として切り出し
    • flow.dag.yaml にノードや入出力の構造を定義
    • GUIや定義ファイルから流れを管理できる
  2. 拡張性の確保
    • 後でデータ前処理、複数API連携、RAG追加などをノード追加だけで対応可能
    • コードを大きく書き換えずに拡張できる
  3. 再利用・共有性
    • Pythonコード+YAMLだけで環境を再現でき、GitHubで共有可能
    • .env に秘密情報を分離して安全に公開できる
  4. 次のステップへの橋渡し
    • Day3以降で予定している「外部ファイルからの入力」「複数質問の一括処理」「出力整形」の土台になる

💰 コストメモ

  • 今回の実行は1回の呼び出しあたり数十トークン程度でごく低コスト
  • 削減策:デフォルト入力の短縮、モデルを gpt-4o-mini 維持

🔮 次回の予告

Day3では Prompt Flow の入力を外部ファイル(CSV)から読み込み、
複数の質問を一括処理できるようにします。
さらに、Azure OpenAI の応答を整形して出力ファイルに保存する方法も実装予定です。


📚 参考リンク

GitHubで編集を提案

Discussion