🦹

Azure AI Agentを動かしてエージェンティックワールドに入門する話

2025/01/25に公開

はじめに

AI Agent、最近話題ですよね。
とはいえまだ実態が掴めていない方も多いかと思います。
そういうわけでAI Agentを動かしてエージェンティックワールドに入門してみようという記事になります。

事前準備

事前に必要なもの

  • Azureアカウント
  • 必要なロール
  • python実行環境(今回はjupyterで動かします。)
  • Azure CLI

環境構築

ローカル

ローカル環境では、Agentの作成と、エージェントが呼び出す関数の実行等行います。
Azure CLIでログインしておいてください。

az login
pip install azure-ai-projects azure-identity

Azure

プロジェクトの作成

まずAzure AI Foundryを作成します。

次に作成したAI Hubを開き、「Launch Azure AI Foundry」をクリックしましょう。

開くとプロジェクト作成画面が表示されるので適当な名前を付けて作成してください。

モデルの作成

次にモデルカタログを開き、gpt-4o-miniを選択しデプロイしてください。
デプロイ時の名称は好きなものをつけていいですが、後ほど参照します。

次にマイアセット - モデル + エンドポイントを選択し、作成したモデルを開き、編集を押下してください。
デプロイの更新という画面が出ると思うので、この中の1分あたりのトークン数レート制限を少し上げてください。100くらいあれば概ね大丈夫だと思います。
ここの件数が不足しているとRate limit is exceededという警告が出る場合があります。

最後に概要の下部からプロジェクトの詳細にあるプロジェクト接続文字列をコピーしておいてください。

動かす

こちらにサンプルコードを置いておきました。
オーケストレータと二つのペルソナを持つエージェントを連結して、回答を生成させる簡単なコードです。

1.clientの定義

user_functionsのget_user_functionsは指定したエージェントに問い合わせを行う関数が入っています。

import os

from azure.ai.projects import AIProjectClient
from azure.ai.projects.models import FunctionTool, ToolSet
from azure.identity import DefaultAzureCredential

# user_functions.py で定義した関数セットを読み込む
from user_functions import get_user_functions

# Azure AI Foundry Project の接続文字列
if "PROJECT_CONNECTION_STRING" not in os.environ:
    os.environ["PROJECT_CONNECTION_STRING"] = ""

conn_str = os.environ["PROJECT_CONNECTION_STRING"]
credential = DefaultAzureCredential()

# クライアント生成
project_client = AIProjectClient.from_connection_string(
    credential=credential,
    conn_str=conn_str
)

2.各エージェントの作成

instructionsにそれぞれのプロンプト?を入れます。
ここではそれぞれユニークな視点とコスパ重視な視点を入れています。

# エージェントの作成
agentB = project_client.agents.create_agent(
    model="gpt-4o-mini",
    name="UniqueAgent",
    instructions="あなたはユニークな視点を持つアシスタントです。一般的ではない特別な視点から回答してください。",
)
print(f"AgentB created: {agentB.id}")

agentC = project_client.agents.create_agent(
    model="gpt-4o-mini",
    name="CostEffectiveAgent",
    instructions="あなたはコスパ重視のアシスタントです。コストパフォーマンスを重視して回答してください。",
)
print(f"AgentC created: {agentC.id}")

3.ツールの定義とオーケストレータの作成

# ツールの定義
funcs = get_user_functions(project_client, agentB.id, agentC.id)
functions = FunctionTool(funcs)  

toolset = ToolSet()
toolset.add(functions)

# エージェント(オーケストレーター)を作成
agentA = project_client.agents.create_agent(
    model="gpt-4o-mini", 
    name="OrchestratorAgent",
    instructions=(
        "あなたはオーケストレーターとして、"
        "UniqueAgent と CostEffectiveAgent のツールを必要に応じて呼び出し、それぞれの回答を統合してください。"
    ),
    toolset=toolset
)
print(f"Agent created, ID: {agentA.id}")

4.スレッドの作成とメッセージ送信

user_message = "東京から行けるおすすめの温泉地を教えて。ユニークな視点とコスパ重視の両方で比較したいです。"

# スレッドの作成とメッセージ送信
thread = project_client.agents.create_thread()
print(f"Thread created, ID: {thread.id}")

msg = project_client.agents.create_message(
    thread_id=thread.id,
    role="user",
    content=user_message
)
print(f"User message created: {msg.id}")

# エージェントに実行を依頼する。また関数もここで実行
runA = project_client.agents.create_and_process_run(
    thread_id=thread.id,
    assistant_id=agentA.id
)

print(f"Run finished with status: {runA.status}")

if runA.status == "failed":
    print(f"Run failed: {runA.last_error}")

5.メッセージの取得

# 7) 結果メッセージを取得して表示
messages_json = project_client.agents.list_messages(thread_id=thread.id)
if not messages_json.get("data"):
    print("No messages returned.")
else:
    data = messages_json["data"]
    for i, m in enumerate(data, start=1):
        role = m["role"]
        text_list = []
        for c in m.get("content", []):
            if c.get("type") == "text":
                text_list.append(c["text"]["value"])
        joined = "\n".join(text_list)
        print(f"[Message {i} | {role}]\n{joined}\n")

出力

### ユニークな視点でのおすすめ温泉地

1. **箱根(神奈川県)**
   - **独自体験**: 芦ノ湖の湖畔に浸かりながら、富士山の美しい景色を楽しむことができる温泉地です。また、アートと温泉を楽しめる美術館も多く存在します。

2. **湯河原(神奈川県)**
   - **文化**: 歴史のある温泉街で、文豪たちが訪れた場所としても知られています。地元の芸術や歴史を感じることができる魅力があります。

3. **草津温泉(群馬県)**
   - **文化的な体験**: 草津は名湯として知られ、「湯もみ」の伝統が残ります。温泉街の中心部では日帰り入浴施設も多く、地元の文化や料理を体験できます。

4. **鬼怒川温泉(栃木県)**
   - **自然との調和**: 鬼怒川沿いに点在する温泉宿からの美しい渓谷の景色が楽しめます。自然の中でリラックスできる環境が魅力です。

5. **鬼怒川温泉(栃木県)**
   - **アート体験**: 鬼怒川温泉では、アートと温泉を融合させた新しい観光スタイルが楽しめます。アート作品を楽しむ散策もできます。

---

### コスパ重視のおすすめ温泉地

1. **箱根**
   - **コスト**: 日帰り入浴が多く、1,000円~3,000円程度で楽しめます。交通の便も良く、気軽に訪れることができます。

2. **湯河原**
   - **コスト**: 日帰り入浴が1,500円程度から利用でき、宿泊施設も多彩なので予算に応じた選択が可能です。

3. **草津温泉**
   - **コスト**: 600円~1,500円程度で日帰り入浴可能。宿泊費がリーズナブルな宿も多く、コストパフォーマンスが良好です。

4. **熱海温泉**
   - **コスト**: 一泊2食付きでも8,000円前後から楽しめる宿も多く、コストパフォーマンスに優れています。

5. **下呂温泉(岐阜県)**
   - **コスト**: 名湯でありながらリーズナブルな宿が多く、日帰り温泉も800円~1,500円程度で利用可能です。

---

このように、ユニークな体験や文化を楽しめる場所と、コストパフォーマンスが優れた温泉地をそれぞれ挙げました。どちらの観点からでも東京周辺の温泉地は魅力的ですので、自分の好みに合った選択ができるかと思います。

本当は意見を集約してほしいんですが、あんまりプロンプトを練ってないので仕方ない。ということにしておいてください。

6.エージェントとスレッドの削除

エージェントとスレッドはどうやら永続的に残るようなので、使い続けるのでなければ削除しておいたほうがいいでしょう。

# (8) 後片付け (エージェント & スレッド削除)
project_client.agents.delete_agent(agentA.id)
print(f"Deleted AgentA: {agentA.id}")

project_client.agents.delete_agent(agentB.id)
print(f"Deleted AgentB: {agentB.id}")

project_client.agents.delete_agent(agentC.id)
print(f"Deleted AgentC: {agentC.id}")

project_client.agents.delete_thread(thread.id)
print(f"Deleted thread: {thread.id}")

ヘッドウォータース

Discussion