---
title: 04-Pro-Code Multi-Agent實戰演練
---
# Day3 - Pro-Code Multi-Agent 實戰演練
---
## 一、前置需求
### 1. 己完成本機開發環境準備
+ Python環境
+ Vistual Studio Code環境
+ Azure CLI
### 2. Azure OpenAI Endpoint 建立
+ dall-e-3模型現行只有這三個區域可用 `East US` `Australia East` 及`Sweden Central`
+ 需另外建立獨立 Azure OpenAI Endpoint
+ Azure Portal Search bar 輸入 `Azure OpenAI`

+ Create

+ Resource Group: 選擇Resrouce Group
+ Region: 建議選擇`Sweden Central`
+ Name: 輸入您的名稱
+ Pricing Titer: Standard S0
+ Next

+ Network 及 Tags 都保持預設值,點選Next
+ Create

+ Go to resource

+ Explore Azure AI Foundry portal

+ Deployments

+ Deploy base model

+ Deploy `dall-e-3` model
+ Confirm

+ Deploy

### 3、Azure Storge Account 建立
+ 打開azure portal

+ 搜尋Storage Accounts

+ 建立Storage Account

+ Region: 建議選擇 同一個Region


+ 建立Storage Account建立完成

+ 新增Container

+ 新增Container - 名稱請輸入 "files"

+ 授予存取Storage Account 角色權限
- 左側選單 → 「Access Control (IAM)」
- Add role assignment

- 選擇「Storage Blob Data Contributor」角色 → 「Next」

- Add role assignment
- 選擇「User, group, or service principal」
- + select member
- 選擇 您的帳號 (或需要存取Storage的使用者帳號)
- 點擊 select
- 點擊 review+assign

### 4、申請 OpenCage Geocoding API Key
+ 登入 https://opencagedata.com/api 選取 **Sing up for your geocoding API key** 獲取 API Key

### 5. Download Code & Create Python venv
+ 請下載[Sample Code](https://1drv.ms/u/c/8302862bf709a02b/EdUE-6ghqUhOoVbMq3-OaWkBxT5pTpJ6_HXddTCZVS3sfQ?e=hQGMro)
+ Create a Virtual Environment
1. 切換Sample Code資料夾
```bash
cd "您的專案資料夾路徑"
```
建立python venv
```bash
python -m venv .venv
```
2. Activate venv
```bash
# For Windows
.\.venv\Scripts\activate
```
3. Install Dependency**
```bash
# For Windows
pip install -r requirements.txt
```
### 6. Env 資訊填寫
#### AI Project
+ AIPROJECT_ENDPOINT

#### Azure OpenAI
+ AZURE_OPENAI_ENDPOINT
+ AZURE_OPENAI_API_KEY

#### dalle
+ AZURE_DALLE_ENDPOINT
+ AZURE_DALLE_KEY

#### Azure Blob Storage
+ BLOB_ACCOUNT_NAME

#### GEOCODING
+ GEOCODING_API_KEY: 您申請的API Key
#### broswer-automation
+ PLAYWRIGHT_RESOURCE_NAME

#### bing-search
+ BING_RESOURCE_NAME

#### mcp_url
Day2 建立的 Web App Service SSE endpoint
+ MCP_AIRBNB_URL
+ MCP_BAZI_URL
#### Custom Remote MCP
+ MCP_SSE_URL: 保持空白
---
### 7. Test Your Project Setting
手動執行`00_test\test-ai-agent.ipynb` 確認沒有錯誤訊息
請確認右上角的Kernel已切換至您建立的Virtual Environment

---
## 二、 🚀 Quick Start
---
### 1. 📁 專案檔案說明
- `.env`
儲存環境變數,例如 API 金鑰、執行環境參數等。
- `requirements.txt`
定義本專案所需的 Python 套件列表。
- `agent_config.py`
定義 AI Agent 的資料結構。
+ **name**: Agent 名稱
+ **description**: Agent 描述
+ **instruction**: Agent 人設
+ **user_functions**: 本地客製化Function
+ **sk_plugins**: Semnatic Kernal Plugin名稱
+ **mcp_tools**: MCP Tool Name
+ **bing_search**: 是否啟用Bing Search
+ **browser_automation**: 是否啟用Browser Automation
+ **code_interpreter**: 是否啟用Code Interpreter

- `tools.py`
提供各類工具函式,供 AI Agent 呼叫以完成任務。
+ **get_lat_long**: 取得指定地區的經緯度資訊
+ **get_weather_forecast**: 根據經緯度查詢該地的天氣預報
+ **dale**: 使用 DALL·E 進行圖像生成
+ **upload_file_to_blob**: 將檔案上傳至 Azure Blob Storage
- `storage_token.py`
透過 **User Delegation Key (UDK)** 生成 Azure Blob Storage 的 **User Delegation SAS URL**。
+ **get_cached_user_delegation_key**: 從快取或 Azure Blob Service 取得 **User Delegation Key (UDK)** 控制 UDK 的存活時間(最長 7 天 )
+ **generate_user_delegation_sas_url**: 產生指定 Blob 的 **User Delegation SAS URL**
- `utils.py`
此模組包含兩個主要類別,分別處理 Azure Blob 儲存與 AI Agent 的基本操作邏輯。
+ **AzureBlobManager**: 支援檔案上傳與 SAS URL 產生
+ **AIServiceAgent**: 封裝 Azure AI Agent 的操作流程,支援自定義工具、Bing 搜尋、Code Interpreter、Browser Automation 等功能。
- `travel_configs.py`
---
### 1. `TaskPlanner` - 任務總規劃師
- **描述**:Master planner that divides the task into subtasks.
- **角色定位**:團隊的總指揮官,負責將使用者需求拆解為子任務並分派給最適合的 Agent。
- **執行限制**:
- ❌ 不得執行任何子任務。
- ✅ 每一步都必須指派給一位 Agent。
- ✅ 回應需整合與說明,不可直接轉發原始輸出。
- **格式規範**:
- 任務分派格式:`[__AgentName__] {task}`
- 任務完成格式:`[Finished] {final reply}`
- **工具設定**:
---
### 2. `TravelPlanner` - 行程規劃助手
- **描述**:A helpful assistant that can plan trips.
- **角色定位**:根據使用者需求,產生具體的旅遊行程建議。
- **任務重點**:
- ✅ 行程中需標示每一天的實際日期。
- ✅ 每個景點需包含「城市內的區域或地段名稱」。
- **工具設定**:
---
### 3. `RouteMaster` - 動線優化專家
- **描述**:An assistant that improves travel plans using real-world geography and transit.
- **角色定位**:針對既有行程提供交通與住宿動線的專業優化建議。
- **任務重點**:
- ✅ 避免頻繁轉乘與跨公司跳線。
- ✅ 檢查飯店與行程地點的地理合理性。
- ✅ 提供具體修改建議(如替代景點、飯店名稱、交通路線)。
- ✅ 必須重新產生完整行程表。
- **工具設定**:
---
### 4. `HotelFinder` - 住宿推薦與黃曆顧問
- **描述**:Helps users find accommodations via Airbnb and provides Chinese calendar insights.
- **角色定位**:根據行程與預算推薦住宿,並提供傳統農民曆的旅遊建議。
- **任務重點**:
- ✅ 根據地點、預算與偏好推薦住宿。
- ✅ 提供住宿名稱、地址、聯絡方式與訂房連結。
- ✅ 查詢農民曆,提供是否適合旅遊的建議。
- **工具使用規則**:
- 所有回應必須使用工具,禁止直接回答。
- 工具呼叫語言需使用英文,回應可翻譯。
- Airbnb 搜尋結果需使用 `id` 呼叫 `airbnb_listing_details` 取得詳細資訊。
- **工具設定**:
- MCP 工具:✅ `mcp_airbnb_server`, `mcp_bazi_server`
---
### 5. `WeatherAdvisor` - 天氣顧問
- **描述**:An assistant that uses weather data to adjust travel plans.
- **角色定位**:根據每日天氣預報,協助使用者調整行程安排。
- **任務重點**:
- ✅ 使用 `get_weather_forecast` 查詢指定日期與地點(需為英文地名)的天氣。
- ✅ 若天氣不佳,建議改為室內景點;若天氣良好,推薦戶外活動。
- ✅ 建議內容需具體、合理,並配合原本動線。
- **工具設定**:
- 使用函式:✅ `get_weather_forecast`
---
### 6. `TripBudget` - 預算規劃師
- **描述**:Evaluates real travel costs and fills in Microsoft Forms budget.
- **角色定位**:根據完整行程進行成本分析、填寫預算表單並產出報告。
- **任務流程**:
1. ✅ 成本分析(使用 Bing 搜尋)
2. ✅ 表單填寫(使用瀏覽器自動化)
3. ✅ 預算報告產出
- **完成檢查**:
- 回應需包含:「成本分析 ✔️、表單填寫 ✔️、預算報告 ✔️」
- 若有步驟未完成,必須補足。
- **工具設定**:
- 瀏覽器自動化:✅
- Bing 搜尋:✅
---
### 7. `TravelStoryHTMLnImage` - HTML 行程故事產生器
- **描述**:Formats a complete travel plan into styled HTML, embedding image and Google Maps.
- **角色定位**:將完整行程轉換為 HTML 文件,包含地圖、天氣、圖片與排版。
- **任務重點**:
- ✅ 每日需包含天氣、交通方式、飯店名稱(加粗)。
- ✅ 使用 `get_lat_long` 取得座標並嵌入 Google Maps iframe。
- ✅ 使用 `dalle` 產生一張代表整趟旅程的圖片並嵌入。
- ✅ 產出 HTML 檔案並提供 Markdown 下載連結。
- ✅ 回應結尾必須包含 `TERMINATE`。
- **PDF 支援**:
- ✅ 若產出 PDF,需使用內建中文字型(如 STSong-Light)避免相容性問題。
- **工具設定**:
- 使用函式:✅ `dalle`, `get_lat_long`
- Code Interpreter:✅
---
### 2. 🧠 single_agent 模組
此模組包含Single Agent的應用範例:
1. `01_Travel_Planner.ipynb`
- [ ] 在**user_text**中輸入您的旅遊計劃,例如:
```shell
明天要從台北出發去東京,請規劃一個2天1夜從成田機場進, 羽田機場出的行程,以下是要點:
1. 每天晚上不同飯店入住,請提供名稱;
2. 依天氣安排行程;
3. 提供行前注意事項提醒;
```
- [ ] 請記住**thread id** `thread_xxxxxx`.

2. `02_Weather_Advisor.ipynb`
- [ ] 置換Travel Planer產生的Thread id

- [ ] 在**user_text**中輸入您的請求,例如:
```shell
請根據實際天氣狀況進行行程調整
```
3. `03_Route_Master.ipynb`
- [ ] 置換Travel Planer產生的Thread id
- [ ] 在**user_text**中輸入您的請求,例如:
```shell
請從你的觀點來檢視這份行程,若有不同區域頻繁來回移動的問題,也請提出建議與批評,並重新產生行程表
```
4. `04_Hotel_Finder.ipynb`
- [ ] 置換Travel Planer產生的Thread id
- [ ] 在**user_text**中輸入您的請求,例如:
```shell
請從你的觀點來依據使用者的需求找到目前可預定且預算為100~200美元的Hotel及農民曆的旅遊資訊,並更新行程表
```
5. `05_Trip_Budget.ipynb`
- [ ] 置換Travel Planer產生的Thread id
- [ ] 在**user_text**中輸入您的請求,例如:
```shell
根據完整的旅遊行程,分析所有預算項目,並依照今天最新匯率統一換算為台幣。請將預估的旅遊預算填寫至指定表單
```
6. `06_TravelStory_HTML_Image.ipynb`
- [ ] 置換Travel Planer產生的Thread id
- [ ] 在**user_text**中輸入您的請求,例如:
```shell
請參考各位專家的意見後, 將最終版本的行程產生為HTML檔案
```
- [ ] Agent產生的HTML檔案儲存在Sandbox 例如:**sandbox:/mnt/data/travel_plan.html**,需將檔案拉出後儲存至Azure Storage Account (sas token於七天後失效)

```shell
bot_reply1 = app.retrieve_message()
```
- [ ] 已將Sandbox檔案取出後載入Azure Blob Storage

7. `07_Task_Planner.ipynb`
- [ ] 在**user_text**中輸入您的旅遊計劃,Planner Agent不執行任務只負責分派工作,例如:
```shell
明天要從台北出發去富國島請規劃八天七夜的行程:
1. 依天氣安排行程;
2. 提供行前注意事項提醒
3. 前三天住Vinpearl Wonderworld Phu Quoc, 接下來住二天 Premier Residences Phu Quoc Emerald Bay Managed by Accor, 最後二天住 InterContinental Phu Quoc Long Beach Resort by IHG
```

### 3. 🤖 multi-agent 模組
---
1. A_orchestration_planner\ **01_orchestration_planner**
- `team.py`: Orchestration Planner的主程式:`01_orchestrate_foundry_agents_planner.ipynb`
+ **模組說明**: 此模組定義了一個 `Team` 類別,用於協調一個由多個 AI Agent 組成的團隊,透過一個「Planner」與多個「Workers」的架構,實現多步驟的任務分工與協作。
+ **參數說明**:
- `planner_config`:負責任務規劃的 Agent 設定(繼承自 `AgentConfig`)。
- `worker_configs`:一組工作者 Agent 的設定清單。
- `max_steps`:最大執行步驟數,預設為 10。
+ **流程說明**:
1. 將使用者的Input傳給Planner。
2. Planner回應後,若包含 `[__AgentName__]` 標記,則將任務交由對應Worker處理。
3. Workwer執行後回傳結果,並將結果回饋給Planner。
4. 若Planner回應以 `[Finished]` 開頭,則流程結束並回傳最終結果。
5. 若超過 `max_steps` 步驟仍未完成,則拋出例外。
+ **邏輯說明**:
1. 所有Worker共用一個對話 thread(`shared_worker_thread_id`),以利上下文共享。
2. Planner使用獨立 thread,避免干擾。
3. 支援自定義工具(如 MCP、Bing、Code Interpreter、Browser Automation)。
4. 每次Worker回應後,若有生成檔案會自動上傳至Azure Blob Storage並將結果回傳給Planner。
---
- `01_orchestrate_foundry_agents_planner.ipynb`
- [ ] 在**user_text**中輸入您的請求,例如:
```shell
明天要從台北出發去普吉島,請規劃四天三夜的行程:
1. 行程需依據天氣狀況安排;
2. 確保整體行程合理、順暢;
3. 推薦的飯店需可實際預訂且預算為100~200美元
4. 參考農民曆資訊調整行程
5. 請以今天的匯率將預估的旅遊預算換算為台幣後填寫指定電子表單
6. 將終版本的行程產生為HTML檔案
```
## 三、 📝 對話紀錄:普吉島四天三夜行程規劃任務
---
### 🧑💼 USER → Planner [`thread_To25qaIXIg9z8XlFoZ4pioVJ`]
明天要從台北出發去普吉島,請規劃四天三夜的行程:
1. 行程需依據天氣狀況安排;
2. 確保整體行程合理、順暢;
3. 推薦的飯店需可實際預訂且預算為100~200美元;
4. 參考農民曆資訊調整行程;
5. 請以今天的匯率將預估的旅遊預算換算為台幣後填寫指定電子表單;
6. 將終版本的行程產生為HTML檔案。
---
### 🤖 [Step 0] Planner 回覆
好的,為了規劃一個合理且順暢的台北出發普吉島四天三夜行程,並滿足您的所有需求,我將依照以下步驟分配任務:
1. 先由 TravelPlanner 規劃初步行程架構。
2. 再由 WeatherAdvisor 根據最新天氣狀況調整每日活動。
3. RouteMaster 檢查並優化行程動線,確保順暢合理。
4. HotelFinder 推薦可預訂且符合預算的飯店,並參考農民曆資訊調整行程。
5. TripBudget 依據今天匯率,預估旅遊總預算並填寫指定電子表單。
6. 最後由 TravelStoryHTMLnImage 產生完整HTML檔案。
首先,請 TravelPlanner 規劃台北出發普吉島四天三夜的初步行程架構(不考慮天氣與住宿細節,僅列出每日主要活動與交通)。
[__TravelPlanner__] 規劃台北出發普吉島四天三夜的初步行程架構,包含每日主要活動與交通安排。
---
### 🔁 任務轉交:Planner → TravelPlanner
Handing off to 'TravelPlanner' with payload:
'規劃台北出發普吉島四天三夜的初步行程架構,包含每日主要活動與交通安排。'
---
### 🤖 TravelPlanner 回覆
```
當然可以!以下是台北出發普吉島四天三夜的初步行程架構,包含每日主要活動、交通安排,以及每一天的實際日期(假設你9月10日從台北出發):
...
```
---
### 🤖 [Step 1] Planner 回覆
TravelPlanner 已完成初步行程架構,接下來需要根據最新天氣狀況調整每日活動,確保行程安全且舒適。
[__WeatherAdvisor__] 根據普吉島未來四天的天氣預報,調整上述行程每日活動安排,並提供建議(如需更改海灘或戶外活動時間,請明確說明)。
---
### 🔁 任務轉交:Planner → WeatherAdvisor
Handing off to 'WeatherAdvisor' with payload:
'根據普吉島未來四天的天氣預報,調整上述行程每日活動安排,並提供建議(如需更改海灘或戶外活動時間,請明確說明)。'
---
### 🛠️ 工具呼叫紀錄
- **Tool Call ID**: `call_nl63dX3Dz7jVOj5mDoOdcRgY`
- **函式名稱**:`get_weather_forecast`
- **參數**:
```json
{
"location_name": "Patong Beach",
"start_date": "2025-09-10",
"end_date": "2025-09-10"
}
```
- **地理資訊**:
- `location name`: Patong Beach
- `latitude`: 7.8966319
- `longitude`: 98.2954295
- **天氣預報結果**:
```json
{
"temperature_2m_min": 25.4,
"temperature_2m_max": 29.2,
"rain_sum": 0.0,
"precipitation_probability_max": 73,
"precipitation_sum": 4.4,
"weather_code": 53
}
```
---
### 🤖 WeatherAdvisor 回覆
```
根據普吉島各主要地點未來四天的天氣預報,以下是針對原行程的調整與具體建議:
...
```
---
### 🔁 Worker → Planner 回饋
(Speaker: WeatherAdvisor)
根據普吉島各主要地點未來四天的天氣預報,以下是針對原行程的調整與具體建議:
---
### 🤖 [Step 2] Planner 回覆
WeatherAdvisor 已根據天氣預報調整每日活動,建議以室內活動為主並彈性安排海灘及出海行程。接下來需要 RouteMaster 檢查並優化行程動線,確保交通安排合理且順暢。
[__RouteMaster__] 根據最新行程(含天氣調整),優化每日交通動線,並提供具體交通方式與時間建議。
---
### 🔁 任務轉交:Planner → RouteMaster
Handing off to 'RouteMaster' with payload:
'根據最新行程(含天氣調整),優化每日交通動線,並提供具體交通方式與時間建議。'
---
### 🤖 RouteMaster 回覆
```
以下是根據天氣調整後的普吉島四天三夜行程,針對每日交通動線進行優化,並提供具體交通方式與時間建議:
...
```
---
### 🔁 Worker → Planner 回饋
(Speaker: RouteMaster)
以下是根據天氣調整後的普吉島四天三夜行程,針對每日交通動線進行優化,並提供具體交通方式與時間建議:
...
---
### 🤖 [Step 3] Planner 回覆
RouteMaster 已優化行程動線並提供具體交通方式與時間建議。接下來需要 HotelFinder 推薦可預訂且符合預算(每晚100~200美元)的飯店,並參考農民曆資訊調整行程(如有不宜出行或特殊建議請明確說明)。
[__HotelFinder__] 推薦普吉島Patong Beach區可預訂且每晚100~200美元的飯店,並根據農民曆資訊調整行程(如有不宜出行或特殊建議請明確說明)。
---
### 🔁 任務轉交:Planner → HotelFinder
Handing off to 'HotelFinder' with payload:
'推薦普吉島Patong Beach區可預訂且每晚100~200美元的飯店,並根據農民曆資訊調整行程(如有不宜出行或特殊建議請明確說明)。'
---
### 🤖 HotelFinder 回覆
```
根據您的需求,以下是普吉島Patong Beach區可預訂且每晚100~200美元的飯店推薦,並結合農民曆資訊給予行程調整建議:
```
### 🔁 Worker → Planner 回饋
(Speaker: HotelFinder)
根據您的需求,以下是普吉島Patong Beach區可預訂且每晚100~200美元的飯店推薦,並結合農民曆資訊給予行程調整建議:
...
---
### 🤖 [Step 4] Planner 回覆
HotelFinder 已推薦可預訂且符合預算的飯店,並根據農民曆資訊確認行程安排皆宜出行,無需重大調整。接下來需要 TripBudget 依據今天匯率,預估旅遊總預算並換算為台幣,並填寫指定電子表單。
[__TripBudget__] 根據最新行程、住宿選擇(以Ocean Front View | Huge Condo為例)、交通與活動安排,預估總旅遊預算,並以今日匯率換算為台幣後填寫指定Microsoft Forms電子表單。
---
### 🔁 任務轉交:Planner → TripBudget
Handing off to 'TripBudget' with payload:
'根據最新行程、住宿選擇(以Ocean Front View | Huge Condo為例)、交通與活動安排,預估總旅遊預算,並以今日匯率換算為台幣後填寫指定Microsoft Forms電子表單。'
---
### 🤖 TripBudget 回覆
```
### 普吉島四天三夜旅遊預算報告(以 Ocean Front View | Huge Condo 為例)!
...
```
---
### 🤖 [Step 5] Planner 回覆
TripBudget 已完成預算估算並填寫指定電子表單。最後,請 TravelStoryHTMLnImage 將最終版本行程產生為HTML檔案,包含圖片與Google Maps地點。
[__TravelStoryHTMLnImage__] 產生普吉島四天三夜最終行程的HTML檔案,包含每日活動、飯店資訊、交通建議、圖片與Google Maps地點。
---
### 🔁 任務轉交:Planner → TravelStoryHTMLnImage
Handing off to 'TravelStoryHTMLnImage' with payload:
'產生普吉島四天三夜最終行程的HTML檔案,包含每日活動、飯店資訊、交通建議、圖片與Google Maps地點。'
---
### 🛠️ 工具呼叫紀錄
- **Tool Call ID**: `call_abfxxBGaKtfJcYGmhgsoxUyu`
#### 📍 `get_lat_long`
```json
{
"location_name": "Patong Tower, Patong Beach, Phuket"
}
```
- 結果:
- `latitude`: 7.89059
- `longitude`: 98.3981
#### 🖼️ `dalle`
{
"prompt": "A vibrant tropical travel collage showing Patong Beach, Phi Phi Islands, Thai food, and lively nightlife in Phuket, Thailand. The image should evoke a sense of adventure, relaxation, and exotic beauty."
}
---
### 🤖 TravelStoryHTMLnImage 回覆
```
Download Travel Plan
```
TERMINATE
- ✅ blob upload 成功:
```
https://universalagstorage.blob.core.windows.net/files/assistant-6Z9fnNcMMvdiTktR7if8UH.html?se=2026-01-26T09%3A21%3A33Z&sp=r&sv=2025-07-05&sr=b&sig=MDmVRH2gu0rlb%2B85on4nLwLtUBl5LuPMXoCMaPj0vio%3D
```
---
### 🤖 [Step 6] ✅ Planner claims finished
[Finished] 您的普吉島四天三夜行程規劃已完成,包含天氣調整、交通動線優化、可預訂飯店推薦、農民曆建議、預算換算與表單填寫,以及精美HTML檔案(含圖片與Google Maps地點)。
請點擊以下連結下載您的完整旅遊計畫書:
```
(Speaker: TravelStoryHTMLnImage)
```
---
## 四、 📝 普吉島四天三夜行程規劃最終版本
