---
# System prepended metadata

title: 04-Pro-Code Multi-Agent實戰演練

---

---
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`
![image](https://hackmd.io/_uploads/BJtYYW4cgg.png)
+ Create
![image](https://hackmd.io/_uploads/ryCsKZV5ge.png)
+ Resource Group: 選擇Resrouce Group
+ Region: 建議選擇`Sweden Central`
+ Name: 輸入您的名稱
+ Pricing Titer: Standard S0
+ Next
![image](https://hackmd.io/_uploads/By2m5ZE9eg.png)
+ Network 及 Tags 都保持預設值，點選Next
+ Create
![image](https://hackmd.io/_uploads/HJeeoZVcee.png)
+ Go to resource
![image](https://hackmd.io/_uploads/rJc_jWEcxx.png)
+ Explore Azure AI Foundry portal
![image](https://hackmd.io/_uploads/BJZhoZVcgx.png)
+ Deployments
![image](https://hackmd.io/_uploads/HJCx2bNcle.png)
+ Deploy base model
![image](https://hackmd.io/_uploads/rkGE3W4qll.png)
+ Deploy `dall-e-3` model
+ Confirm
![image](https://hackmd.io/_uploads/HySYh-Nqxe.png)
+ Deploy
![image](https://hackmd.io/_uploads/HJQan-N5xe.png)

### 3、Azure Storge Account 建立
+ 打開azure portal
![image](https://hackmd.io/_uploads/rJgUwVrzgg.png)
+ 搜尋Storage Accounts
![image](https://hackmd.io/_uploads/r1Xl2vtGll.png)
+ 建立Storage Account
![image](https://hackmd.io/_uploads/HJ5r2PFzee.png)
+ Region: 建議選擇 同一個Region
![image](https://hackmd.io/_uploads/HJrMjDYGgx.png)
![image](https://hackmd.io/_uploads/B1IDhPKGlx.png)
+ 建立Storage Account建立完成
![image](https://hackmd.io/_uploads/BJrIlOFzle.png)
+ 新增Container
![image](https://hackmd.io/_uploads/HJi62wYGgx.png)
+ 新增Container - 名稱請輸入 "files"
![image](https://hackmd.io/_uploads/ryCk6PKzge.png)
+ 授予存取Storage Account 角色權限
    - 左側選單 → 「Access Control (IAM)」
    - Add role assignment
    ![image](https://hackmd.io/_uploads/HyT--sHilx.png) 
    - 選擇「Storage Blob Data Contributor」角色 → 「Next」
    ![image](https://hackmd.io/_uploads/B1SvZsriee.png)
    - Add role assignment
    - 選擇「User, group, or service principal」
    - + select member
    - 選擇 您的帳號 (或需要存取Storage的使用者帳號)
    - 點擊 select
    - 點擊 review+assign
    ![image](https://hackmd.io/_uploads/SkL7foSoeg.png)

### 4、申請 OpenCage Geocoding API Key
+ 登入 https://opencagedata.com/api 選取 **Sing up for your geocoding API key** 獲取 API Key
![image](https://hackmd.io/_uploads/Hk4w4CYzee.png)


### 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
    ![image](https://hackmd.io/_uploads/H1YTFGNqge.png)
#### Azure OpenAI
+ AZURE_OPENAI_ENDPOINT
+ AZURE_OPENAI_API_KEY
    ![image](https://hackmd.io/_uploads/r1VO5MV5el.png)
#### dalle
+ AZURE_DALLE_ENDPOINT
+ AZURE_DALLE_KEY
![image](https://hackmd.io/_uploads/HkN6nME9gx.png)
#### Azure Blob Storage
+ BLOB_ACCOUNT_NAME
![image](https://hackmd.io/_uploads/By_jzsBsxx.png)
#### GEOCODING
+ GEOCODING_API_KEY: 您申請的API Key
#### broswer-automation
+ PLAYWRIGHT_RESOURCE_NAME
![image](https://hackmd.io/_uploads/r1eCTMV5el.png)
#### bing-search
+ BING_RESOURCE_NAME
![image](https://hackmd.io/_uploads/BJJrAMNcxx.png)
#### 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 
![image](https://hackmd.io/_uploads/BJ5RxXEqgg.png)

---

## 二、 🚀 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
![image](https://hackmd.io/_uploads/SJgXqQV9xg.png)

- `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`.
![image](https://hackmd.io/_uploads/rJqhrmVcgg.png)

2. `02_Weather_Advisor.ipynb`
- [ ]      置換Travel Planer產生的Thread id
     ![image](https://hackmd.io/_uploads/SJYHw_TGxx.png)
- [ ]    在**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於七天後失效)
![image](https://hackmd.io/_uploads/HkYSdQNcex.png)

```shell 
bot_reply1 = app.retrieve_message()
```  
- [ ]    已將Sandbox檔案取出後載入Azure Blob Storage 
![image](https://hackmd.io/_uploads/SyRhOX45ge.png)
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
```
![image](https://hackmd.io/_uploads/SJZRFXNqxl.png)

### 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)
```
---

## 四、 📝 普吉島四天三夜行程規劃最終版本
![image](https://hackmd.io/_uploads/H1VPFON5gx.png)
