Azure AI Agent学習記録

Microsoft Azureについて調べたことを発信しています。

AIエージェント構築基盤「Dapr Agents」をAzure AI Servicesで試す

この動画を視聴したことがきっかけで、マイクロサービスで活用できる大規模AI Agent基盤「Dapr Agents」に興味を持ちました。

www.youtube.com

Dapr Agentsは2025/3/12に情報が公開されたばかりの新しいフレームワークです。

Dapr Agentsのサンプルは、初期設定としてOpenAIのAPIを使うよう設定されています。今回Dapr AgentsをAzure AIサービスで動かす手順を試してみたので、ここではその内容を紹介します。

(Dapr Agentsの豊富な機能、例えばマルチエージェント、ワークフロー動作などについて詳しく知りたい場合は、次回の記事もしくは、上記の動画をご覧ください。)

Daprとは

Daprは、Distributed Application Runtime(分散アプリケーションランタイム)の略で、マイクロサービスや分散システムの開発を簡素化するためのオープンソースです。

dapr.io

これにより複雑なインフラを意識することなくビジネスロジックに専念することができます。

Dapr Agentとは

Dapr Agents は、Dapr上に構築された開発者向けフレームワークで、スケーラブルなAIエージェントシステムの構築を目的としています。

dapr.github.io

Readmeの概要の翻訳ですが、 Dapr Agentsには次のような特徴があります。

  • エージェントの効率的なスケール:
    • 単一コアで数千のエージェントを動作させられる仕組みを持ち、クラスタ全体にタスクを分散します。
  • 耐障害性の高いワークフロー:
    • ネットワーク障害やノードクラッシュなど予期せぬ障害が起きても、タスク再試行や状態の復元でエージェントのワークフローが確実に完了するよう設計されています。
  • Kubernetes ネイティブ:
    • Kubernetes 環境へのデプロイや管理が容易です。
  • データ駆動型エージェント:
    • 多数のデータソース(データベースやドキュメントなど)と直接連携でき、構造化されたデータや非構造化データを活用します。
  • マルチエージェントシステム:
    • エージェント間の安全で観測可能な連携が可能で、複雑な協調動作を実現します。

これらの特徴により、複雑な分散システムの構築と運用が簡素化され、開発者がAIエージェント開発に集中できることが期待されています。

Dapr Agentsのクイックスタート

GitHubリポジトリの中に、クイックスタートのフォルダがあります。

github.com

今回は、この中のサンプル02_llm_call_open_aiのチャットext_completion.pyを動かしてみます。

GitHub Codespacesで起動

ローカル環境での構築も可能ですが、ここではGitHub Codespacesで試します。

差分管理を容易にするため、Forkした別Branch環境を利用していますが、dapr-agents本家での操作も同様です。

Codespaceを作成

.devcontainerフォルダのdevcontainer.jsonの設定に従って、環境が構築されます。

{
    "image": "mcr.microsoft.com/devcontainers/python:1-3.12-bullseye",
    "features": {
        "ghcr.io/devcontainers/features/docker-in-docker:2": {},
        "ghcr.io/dapr/cli/dapr-cli:0": {}
    },
    "postCreateCommand": "bash .devcontainer/post-create.sh"
}

post-create.shでdaprとPythonモジュールを設定します。

dapr uninstall
dapr init
pip install --upgrade pip
pip install mkdocs
pip install mkdocs-material
pip install "mkdocs-material[imaging]"
pip install mkdocs-jupyter

ここでは、daprがインストールされます。 あわせて、mkdocsmkdocs-jupyterといった、Markdownサイトに関するモジュールがインストールされます。 これらはMarkdown形式で書かれたドキュメントから静的ウェブサイトを生成できます。

環境準備

クイックスタートの各サンプルフォルダにはReadmeがあり、基本的にはその説明に従うのが良いでしょう。 ReadmeではPython3.10が推奨されていますが、DevContainer側では3.12が設定されています。そのため、この環境では3.12のvenvを使用します。

# フォルダの移動
cd quickstarts/02_llm_call_open_ai

# Python環境の作成
python3.12 -m venv .venv

# Python環境の起動
source .venv/bin/activate

# 必要なモジュールをインストール
pip install -r requirements.txt

サンプルの起動

OpenAIでシンプルなチャットを行うサンプルを実行します。

python text_completion.py

本来はOpenAIの環境変数を必要とするため、残念ながら以下のエラーで動作しません。

Traceback (most recent call last):
  File "/workspaces/dapr-agents/quickstarts/02_llm_call_open_ai/text_completion.py", line 9, in <module>
    llm = OpenAIChatClient()
          ^^^^^^^^^^^^^^^^^^
...
...

openai.OpenAIError: The api_key client option must be set either by passing api_key to the client or by setting the OPENAI_API_KEY environment variable

# エラーメッセージの機械翻訳
#openai.OpenAIError: api_key クライアント オプションは、api_key をクライアントに渡すか、OPENAI_API_KEY 環境変数を設定することによって設定する必要があります。

Azure Open AIの環境作成

OpenAIのAPIキーがあれば、OPENAI_API_KEY環境変数を設定するだけで問題ないはずです。

ここではAzure AI Serviceを利用するために、Protalから新しいAzure AI Serviceを作成します。

Azure AI Serviceの作成

お好みで、使いたいモデルを利用できるリージョンを選択します。

今回は、オーストラリア東にAI Serviceを作成

AI Serviceが作成されたら、AI Foundryへ移動します。

AI Foundry

モデルの作成

AI Foundryのタブでデプロイを選択し、その後モデルのデプロイをクリックします。

基本モデルのデプロイ

今回はgpt-4oを選択します。

LLMの選択

必要に応じて設定変更ができますが、今回は、今回はグローバル標準のままデプロイします。

モデルのデプロイ

以上で、呼び出されるAIサービスの準備は完了です。

環境変数の設定

.envファイルを作成して、デプロイしたモデルのURLと、APIキー、バージョン、デプロイ名を設定します。

Azure AIサービスの環境変数を設定します。

環境変数で設定する箇所については、ターゲットURLから、URLやパラメータを抜き出して設定してください。

/* ターゲットURL */
https://ai-dapr-agent-sample.cognitiveservices.azure.com/openai/deployments/gpt-4o/chat/completions?api-version=2025-01-01-preview

/* ↓ 環境変数で設定する箇所 */

{AZURE_OPENAI_ENDPOINT}/openai/deployments/{AZURE_OPENAI_CHAT_DEPLOYMENT_NAME}/chat/completions?api-version={AZURE_OPENAI_API_VERSION}

今回の例では、次のような.envファイルとなります。

AZURE_OPENAI_ENDPOINT="https://ai-dapr-agent-sample.cognitiveservices.azure.com"

AZURE_OPENAI_CHAT_DEPLOYMENT_NAME="gpt-4o"

AZURE_OPENAI_API_VERSION="2025-01-01-preview"

AZURE_OPENAI_API_KEY="{モデルのキー部分のコピーボタンから取得}"

サンプルのソースコードの修正

今回動作させるサンプルtext_completion.pyファイルへ、import osの追加を行います。

次にllm = OpenAIChatClient()部分をコメントアウトして

llm = OpenAIChatClient(
    api_key=os.getenv("AZURE_OPENAI_API_KEY"),
    azure_endpoint=os.getenv("AZURE_OPENAI_ENDPOINT"),
    api_version = os.getenv("AZURE_OPENAI_API_VERSION"),
    azure_deployment = os.getenv("AZURE_OPENAI_CHAT_DEPLOYMENT_NAME")
)

とパラメータを付与します。これで.envファイルの環境変数を読み込み、Azure AIサービスを呼ぶことができます。

変更後のコードは次のようになります。

from dapr_agents import OpenAIChatClient
from dapr_agents.types import UserMessage
from dotenv import load_dotenv
import os

# .env から環境変数を読み込む
load_dotenv()

# (1)基本のチャット応答
# llm = OpenAIChatClient()
llm = OpenAIChatClient(
    api_key=os.getenv("AZURE_OPENAI_API_KEY"),
    azure_endpoint=os.getenv("AZURE_OPENAI_ENDPOINT"),
    api_version = os.getenv("AZURE_OPENAI_API_VERSION"),
    azure_deployment = os.getenv("AZURE_OPENAI_CHAT_DEPLOYMENT_NAME")
)

response = llm.generate("Name a famous dog!")

if len(response.get_content()) > 0:
    print("Response: ", response.get_content())

# (2)コンテキスト情報を含むプロンプトファイルを使用したチャット応答
llm = OpenAIChatClient.from_prompty('basic.prompty')
response = llm.generate(input_data={"question":"What is your name?"})

if len(response.get_content()) > 0:
    print("Response with prompty: ", response.get_content())

# (3)ユーザー入力を用いたチャット応答
# llm = OpenAIChatClient()
llm = OpenAIChatClient(
    api_key=os.getenv("AZURE_OPENAI_API_KEY"),
    azure_endpoint=os.getenv("AZURE_OPENAI_ENDPOINT"),
    api_version = os.getenv("AZURE_OPENAI_API_VERSION"),
    azure_deployment = os.getenv("AZURE_OPENAI_CHAT_DEPLOYMENT_NAME")
)
response = llm.generate(messages=[UserMessage("hello")])


if len(response.get_content()) > 0 and "hello" in response.get_content().lower():
    print("Response with user input: ", response.get_content())

コード全体としては、dapr_agentsというクライアントを使って、LLMを呼び出しています。

(1)と(3)の部分で、Azure AI Servicesを呼び出すようになります。

text_completion.pyの修正

プロンプトの修正

上記コードの(2)で OpenAIChatClient.from_prompty('basic.prompty') にて、プロンプト定義ファイルを読み込んでいる部分があります。

この中で、typeとnameの部分を

        type: openai
        name: gpt-4o

次のように値とキーを次のように変更します。

        type: azure_openai
        azure_deployment: gpt-4o

これで、Azure AIサービスを呼び出して、このプロンプトが動作するようになります。

basic.promptyの変更

変更したコード

コードの変更内容は、このコミットからも確認できます。

github.com

実行結果

先ほどエラーとなっていた、コマンドを再度実行してみましょう。

$ python text_completion.py

Response:  
    Sure! **Lassie** is one of the most famous dogs of all time, known for her heroic adventures in movies and TV shows.

Response with prompty: 
    I don't have a personal name, but you can call me Assistant!

Response with user input:  
    Hello! 😊 How can I assist you today?

今度は正しく実行することができました!

Pythonでチャットを実行

サンプルコードの説明

このサンプルではAzure AIサービスへ3回チャット問い合わせをしています。

(1)基本のチャット応答

今回の最初の依頼では、response = llm.generate("Name a famous dog!")にて、有名な犬の名前を聞いています。

その回答が、以下です。

応答:

もちろんです! Lassie は、映画やテレビ番組での英雄的な冒険で知られる、史上最も有名な犬の 1 匹です。

(2)コンテキスト情報を含むプロンプトファイルを使用したチャット応答

次にllm.generate(input_data={"question":"What is your name?"})にて、名前を聞く質問をプロンプトファイルで問い合わせています。

プロンプトによる応答:

個人名はありませんが、アシスタントと呼んでください!

という回答が返ってきています。

(3)ユーザー入力を用いたチャット応答

最後に、llm.generate(messages=[UserMessage("hello")])にて、ユーザー入力として挨拶を示した内容をLLMに問い合わせています。

ユーザー入力による応答:

こんにちは!😊本日はどのようなご用件でしょうか?

3回とも正常に呼び出せたことがわかります。

まとめ

以上、新しいDapr Agentsについて、Azure AIサービスで簡単に動作確認してみました。

Dapr基盤のPub/Subをバックエンドで利用することで、簡単にマルチエージェントの環境を構築できそうだと感じました。

今回は、Azure AIサービスで動作させましたが、他のクラウド・AIサービスでも動作するはずです。

また、機会を見て、今後も触ってみたいと思います。