Skill 寫法圖鑑

microsoft-foundry

Microsoft | 雲端與基礎設施 | 原文 | MIT

建置、deploy、評估、微調 Microsoft Foundry 的 agent、模型與資源,含子 skill 路由

中文翻譯

---
name: microsoft-foundry
description: "端到端地建置、deploy、評估、最佳化、微調和管理 Microsoft Foundry 的 agent、模型和資源。USE FOR: foundry, azd ai agent, azd provision/deploy, hosted agent scaffold/develop/run/deploy/troubleshoot, prompt agent, managed harness agent, Copilot harness, voice agent, create/update/invoke/evaluate agent, add tool to agent, agent insights, batch/continuous eval, continuous monitoring, agent CI/CD, optimize/improve prompt, optimize agent instructions, Agent Optimizer, dataset curation from traces, deploy model, model fine-tuning (SFT/DPO/RFT), Foundry project, RBAC, role assignment, permissions, quota, capacity, region, deployment failure, AI Services, create Foundry resource, knowledge index, customize deployment, onboard, availability, training-data, grader, distillation, large file upload。DO NOT USE FOR: Azure Functions、App Service、一般 Azure deploy(用 azure-deploy)、一般 Azure 準備工作(用 azure-prepare)。"
license: MIT
metadata:
  author: Microsoft
  version: "1.2.32"
---

# Microsoft Foundry Skill

這個 skill 協助開發者處理 Microsoft Foundry 的資源,涵蓋模型探索與 deploy、AI agent 的完整開發生命週期、評估流程和疑難排解。

## 執行前要求

在開始對應的動作或流程之前,先遵循下面每個適用的小節。

### 相依套件檢查與設定

**強制:** 這個 skill 載入後的第一步,從這個 skill 的根目錄執行下面的相依套件檢查與設定 script,並等它跑完才能繼續。這個 script 會先檢查,只安裝缺少的相依套件;已經有的不會重新安裝。

**在讀取或進入任何子 skill、流程或流程專屬的參考資料之前,你一定要先完成這個檢查。**

```bash
./scripts/check-and-setup-dependencies.sh     # macOS / Linux
./scripts/check-and-setup-dependencies.ps1    # Windows (pwsh)
```

後續動作要嚴格照 script 的輸出做。

### 流程指引

**強制:** 執行任何流程專屬的步驟之前,你一定要先讀對應的子 skill 文件。沒讀它的 skill 文件,就不准呼叫該流程專屬的 MCP 工具。就算你已經知道 MCP 工具的參數也一樣,因為 skill 文件包含必須遵守的流程步驟、事前檢查和驗證邏輯。每當有新的使用者訊息觸發了不同的流程,這條規則都適用,就算 skill 已經載入也一樣。

### Foundry MCP

**強制:** 使用 Foundry MCP 操作之前,先呼叫 Azure MCP 的 `foundry` 工具,檢視可用的 Foundry MCP 工具和相關參數。把這當作以 MCP 為基礎的流程的探索/說明步驟。

### azd

**強制:** 執行任何 azd 指令之前,你一定要先讀 [azd-guidance](foundry-agent/azd-guidance/azd-guidance.md),並嚴格遵守裡面定義的共用規則,尤其是 `AZURE_DEV_USER_AGENT` 的設定規則。

## 子 Skills

這個 skill 包含針對特定流程的專用子 skill。**當某個子 skill 符合任務時,要嚴格遵循它的流程:**

| 子 Skill | 什麼時候用 | 參考 |
|-----------|-------------|-----------|
| **deploy** | 把 hosted agent deploy 到 Foundry、對 deployment 做 smoke test、建立或更新 prompt agent,以及管理 agent 版本和多環境 deploy。 | [deploy](foundry-agent/deploy/deploy.md) |
| **cicd** | 為 Foundry agent 設定 CI/CD deploy pipeline。 | [cicd](foundry-agent/cicd/cicd.md) |
| **invoke** | 對 agent 送訊息,單輪或多輪對話 | [invoke](foundry-agent/invoke/invoke.md) |
| **routine** | 用 routine 排程或由事件觸發 Foundry agent;用 `azd` 做 CRUD、啟用/停用、手動派送和查看過去的執行紀錄,或在 `azure.yaml` 裡定義 routine。 | [routine](foundry-agent/routine/routine.md) |
| **invocations-ws** | 建置、deploy 並連接使用開發者自訂的雙工即時或媒體串流(透過 `invocations_ws`)的自訂 Hosted agent。 | [invocations-ws](foundry-agent/invocations-ws/invocations-ws.md) |
| **observe** | 評估 agent 品質、跑批次評估、分析失敗、最佳化 prompt、改進 agent 的 instructions、比較版本、設定 CI/CD 監控,以及啟用持續的正式環境評估 | [observe](foundry-agent/observe/observe.md) |
| **insights** | 從現有的 monitor 拉取產生出來的 agent insight、證據和建議;唯讀的取得,不是新的分析執行 | [insights](foundry-agent/insights/insights.md) |
| **trace** | 查詢 trace、分析延遲/失敗,並透過 App Insights 的 `customEvents` 把評估結果關聯到特定的回應 | [trace](foundry-agent/trace/trace.md) |
| **troubleshoot** | 查看 hosted agent 的 log、查詢 telemetry、診斷失敗 | [troubleshoot](foundry-agent/troubleshoot/troubleshoot.md) |
| **validate** | 只有使用者明確要求使用這個驗證子 skill,或要依最佳實務驗證 Microsoft Foundry hosted-agent 程式碼時才用。絕對不要主動呼叫它,也不要把它加進其他流程。 | [validate](foundry-agent/validate/validate.md) |
| **create (quick start)** | 從零開始端到端建立新的 hosted Foundry agent:scaffold、provision 或使用現有的 Foundry 專案、deploy,以及 smoke test。不要用在現有程式碼的任何工作上。quickstart 沒涵蓋的事,請用 **create**。 | [create/quick-start-hosted.md](foundry-agent/create/quick-start-hosted.md) |
| **create** | 標準的端到端順利路徑(quick start)不適用時使用。建立新的 Foundry agent、更新現有 agent 的程式碼、繼續開發現有的 agent、在 scaffold 時接上 connection、使用進階設定或 A2A(Agent2Agent),或從失敗的 quickstart 執行中復原。 | [create](foundry-agent/create/create-hosted.md) |
| **create managed harness** | 建立或繼續開發明確使用 Foundry 託管的 Copilot harness 的 Prompt Agent。使用 `azd` 和 `azure.yaml`,不是一般 Prompt Agent 的 MCP 流程。 | [create-managed-harness](foundry-agent/create/create-managed-harness.md) |
| **create voice** | 建立、設定或擴充 Foundry Voice Agent,一般的請求預設走託管的 Prompt Voice,並支援自行 deploy 的 Prompt Voice 或雙 agent 的 Hosted Voice。 | [create-voice](foundry-agent/create/create-voice.md) |
| **agent-optimizer** | 讓現有的 Python hosted-agent 程式碼達到可最佳化的狀態、設定 eval.yaml、執行 Agent Optimizer job、在本機套用候選方案,並在審查後透過 azd deploy。 | [agent-optimizer](foundry-agent/agent-optimizer/agent-optimizer.md) |
| **eval-datasets** | 把正式環境的 trace 收集成評估資料集、管理資料集版本和切分、追蹤評估指標的長期變化、偵測退化,並維護從 trace 到 deployment 的完整溯源。用於:從 trace 建立資料集、資料集版本管理、評估趨勢、退化偵測、資料集比較、評估溯源。 | [eval-datasets](foundry-agent/eval-datasets/eval-datasets.md) |
| **project/create** | 建立新的 Microsoft Foundry 專案來託管 agent 和模型。在 onboarding Foundry 或建立新基礎設施時使用。 | [project/create/create-foundry-project.md](project/create/create-foundry-project.md) |
| **resource/create** | 用 Azure CLI 建立 Azure AI Services 多服務資源(Foundry 資源)。需要手動 provision AI Services 資源並做細部控制時使用。 | [resource/create/create-foundry-resource.md](resource/create/create-foundry-resource.md) |
| **private-network** | 回答 Foundry 網路隔離的問題,**並且**以 VNet 隔離 deploy Foundry(BYO VNet、Managed VNet、混合)。涵蓋架構概念、範本選擇、deploy 和 deploy 後驗證。 | [resource/private-network/private-network.md](resource/private-network/private-network.md) |
| **models/deploy-model** | 帶智慧路由的統一模型 deploy。處理快速的 preset deploy、完全自訂的 deploy(版本/SKU/容量/RAI),以及跨 region 的容量探索。路由到子 skill:`preset`(快速 deploy)、`customize`(完全控制)、`capacity`(找可用性)。 | [models/deploy-model/SKILL.md](models/deploy-model/SKILL.md) |
| **quota** | 管理 Microsoft Foundry 資源的配額和容量。用於檢查配額使用量、排除因配額不足造成的 deploy 失敗、申請增加配額,或規劃容量。 | [quota/quota.md](quota/quota.md) |
| **rbac** | 管理 Microsoft Foundry 資源的 RBAC 權限、角色指派、managed identity 和 service principal。用於存取控制、稽核權限和 CI/CD 設定。 | [rbac/rbac.md](rbac/rbac.md) |
| **finetuning** | 在 Microsoft Foundry 上微調模型:SFT 蒸餾、DPO 偏好最佳化、帶 grader 和 tool calling 的 RFT。資料集準備、grader 校準、訓練、checkpoint 選擇、deploy、評估。用於:fine-tune、SFT、DPO、RFT、training data、grader、distillation、fine-tuned model、large file upload。 | [finetuning/SKILL.md](finetuning/SKILL.md) |
| **azd-guidance** | 提供管理 Foundry agent 的共用 azd 知識和指引。任何跟 azd 有關的流程都要先讀這個。 | [azd-guidance](foundry-agent/azd-guidance/azd-guidance.md) |

> 💡 **提示:** 完整的 onboarding 流程:`project/create`(公開)或 `private-network`(VNet 隔離)→ `models/deploy-model` → agent 流程(`create` → `deploy` → `invoke`)。

> 💡 **微調:** 所有模型客製化都用 `finetuning`:SFT 蒸餾、DPO 偏好最佳化,以及帶 grader 的 RFT。包含 quickstart、grader 校準和訓練曲線分析。

> 💡 **模型 deploy:** 所有 deploy 情境都用 `models/deploy-model`,它會聰明地在快速 preset deploy、完全控制的客製化 deploy,以及跨 region 的容量探索之間路由。

> 💡 **Prompt 最佳化:** 對於「optimize my prompt」或「improve my agent instructions」這類請求,載入 [observe](foundry-agent/observe/observe.md),並透過那個以評估為導向的流程使用 `prompt_optimize` MCP 工具。

## 基礎設施生命週期

把使用者的意圖對應到正確的基礎設施流程。

| 使用者意圖 | 流程 |
|-------------|---------|
| 「Create Foundry」/「Set up Foundry」(模糊) | 用 `AskUserQuestion` 問:(a) 只要 AI Services 資源、(b) 公開存取的專案,還是 (c) 有網路隔離的專案?路由:(a) → [resource/create](resource/create/create-foundry-resource.md)、(b) → [project/create](project/create/create-foundry-project.md)、(c) → [private-network](resource/private-network/private-network.md) |
| 以 VNet 隔離設定 Foundry | [private-network](resource/private-network/private-network.md) |
| 建立 Foundry 專案(公開) | [project/create](project/create/create-foundry-project.md) |
| 建立單純的 Foundry 資源 | [resource/create](resource/create/create-foundry-resource.md) |

## Agent 開發生命週期

把使用者的意圖對應到正確的 agent 流程。執行之前,依序讀每個子 skill。

| 使用者意圖 | 流程(依序讀) |
|-------------|------------------------|
| 建立或開發 Voice Agent(Prompt Voice 或 Hosted Voice) | [dependency check and setup](#dependency-check-and-setup) → [azd-guidance](foundry-agent/azd-guidance/azd-guidance.md) → [create-voice](foundry-agent/create/create-voice.md) → [deploy](foundry-agent/deploy/deploy.md) → [invoke](foundry-agent/invoke/invoke.md) |
| 建立或開發明確指定的 Managed Harness Agent / Copilot harness agent | [dependency check and setup](#dependency-check-and-setup) → [azd-guidance](foundry-agent/azd-guidance/azd-guidance.md) → [create-managed-harness](foundry-agent/create/create-managed-harness.md) → [deploy](foundry-agent/deploy/deploy.md) → [invoke](foundry-agent/invoke/invoke.md) |
| 端到端建立新的 hosted agent(scaffold + deploy + 測試) | [dependency check and setup](#dependency-check-and-setup) → [azd-guidance](foundry-agent/azd-guidance/azd-guidance.md) → [quick-start-hosted](foundry-agent/create/quick-start-hosted.md)(自成一體的端到端) |
| 任何超出標準 quickstart 的事(現有程式碼、遷移、重新託管、deploy 客製化、scaffold 時的 connection、A2A(Agent2Agent)、復原) | [dependency check and setup](#dependency-check-and-setup) → [azd-guidance](foundry-agent/azd-guidance/azd-guidance.md) → [create](foundry-agent/create/create-hosted.md) → [deploy](foundry-agent/deploy/deploy.md) → [invoke](foundry-agent/invoke/invoke.md) |
| 最佳化現有的 Python hosted agent | [dependency check and setup](#dependency-check-and-setup) → [azd-guidance](foundry-agent/azd-guidance/azd-guidance.md) → [agent-optimizer](foundry-agent/agent-optimizer/agent-optimizer.md) → scaffold/review → eval.yaml → optimize → apply candidate → deploy → invoke |
| Deploy agent(程式碼已存在) | [dependency check and setup](#dependency-check-and-setup) → [azd-guidance](foundry-agent/azd-guidance/azd-guidance.md) → deploy(包含 eval-suite 設定)→ invoke → observe(評估/最佳化) |
| 程式碼改動後更新/重新 deploy agent | [dependency check and setup](#dependency-check-and-setup) → [azd-guidance](foundry-agent/azd-guidance/azd-guidance.md) → deploy(包含 eval-suite 設定)→ invoke → observe(評估/最佳化) |
| 為 hosted agent 設定 CI/CD deploy pipeline | [dependency check and setup](#dependency-check-and-setup) → [azd-guidance](foundry-agent/azd-guidance/azd-guidance.md) → cicd |
| 呼叫/測試/和 agent 對話 | [dependency check and setup](#dependency-check-and-setup) → [azd-guidance](foundry-agent/azd-guidance/azd-guidance.md) → invoke |
| 排程/事件觸發 agent,或對 routine 做 CRUD/啟用/停用/派送 | [dependency check and setup](#dependency-check-and-setup) → [azd-guidance](foundry-agent/azd-guidance/azd-guidance.md) → routine |
| 最佳化/改進 agent 的 prompt 或 instructions | observe(步驟 4:Optimize) |
| 評估並最佳化 agent(完整迴圈) | observe |
| 啟用持續評估監控 | observe(步驟 6:CI/CD 與監控) |
| 拉取 agent insight / 列出產生出來的問題和建議 | [dependency check and setup](#dependency-check-and-setup) → [insights](foundry-agent/insights/insights.md)(所有頁面都帶展開的證據;唯讀) |
| 排除 agent 的問題 | [dependency check and setup](#dependency-check-and-setup) → [azd-guidance](foundry-agent/azd-guidance/azd-guidance.md) → invoke → troubleshoot |
| 修復壞掉的 agent(排除問題 + 重新 deploy) | [dependency check and setup](#dependency-check-and-setup) → [azd-guidance](foundry-agent/azd-guidance/azd-guidance.md) → invoke → troubleshoot → apply fixes → deploy → invoke |

## Agent:.foundry 工作區標準

每個 agent 原始碼資料夾都可以把 Foundry 專屬的快取和 overlay 狀態放在 `.foundry/` 底下:

```text
<agent-root>/
  .foundry/
    agent-metadata.yaml
    agent-metadata.prod.yaml
    suites/
    datasets/
    evaluators/
    results/
```

- 在 azd 專案裡,deploy 的 context(專案 endpoint、agent 名稱/版本、ACR、App Insights)從 `azure.yaml` 加上 `azd env get-values` 推導;azd 已經提供的值,不要在 metadata 裡重複。
- `agent-metadata.yaml` 是偏好的本機/開發 overlay,放非 azd 的值、遠端 Foundry suite 的參照、本機快取路徑、結果摘要和明確的覆寫。選用的 sidecar 檔案(例如 `agent-metadata.prod.yaml`)可以放單一個 prod 或 CI 目標的 overlay,不用把多個環境混在同一個檔案。
- `suites/`、`datasets/` 和 `evaluators/` 是本機快取資料夾。如果還是最新的就重複使用,要重新整理或覆蓋之前要先問。
- 標準的 schema 和流程規則請看 [Agent Metadata Contract](references/agent-metadata-contract.md)。

## Agent:設定參考資料

- [Standard Agent Setup](references/standard-agent-setup.md):給需要資料落地控制的正式環境工作負載的進階設定(透過 Foundry capability host 自帶 Cosmos DB / Storage / AI Search)。預設的 `azd ai agent` 流程使用 **Basic Agent Setup**,**不會** provision `capabilityHosts/agents`,不要把它的缺席當成 bug 回報。預設的 provision 後狀態,請看 [foundry-agent/create/create-hosted.md](foundry-agent/create/create-hosted.md) 裡的「Expected env-var fingerprint」段落。

## Agent:通用的專案 Context 解析

只有在需要還沒有的設定值時,agent skill 才應該執行這個步驟。如果某個值(例如 agent root、環境、專案 endpoint 或 agent 名稱)已經從使用者的訊息或同一個 session 中前一個 skill 得知,就跳過那個值的解析。

### 步驟 1:找出 Agent Root 和 azd Context

先檢查 workspace 有沒有 `azure.yaml`,裡面是否有 `host: azure.ai.agent` 的服務。

- **一個 azd agent 服務** → 從 `kind`、`harness`、`modelType` 和 `conversationEngine` 把它分類,然後使用那個服務的 `project` 資料夾或 `azure.yaml` 所在目錄當作 agent root。
- **多個 azd agent 服務** → 檢查 Voice wrapper 有沒有透過 `conversationEngine.name` 參照一個 `kind: hosted` 的服務:
  - **選了 Hosted Voice wrapper**,代表它指名的 `kind: hosted` 目標是上游相依(`uses: [<target>]`、`conversationEngine.name: <target>`);deploy 和驗證必須分別回報這兩個服務。
  - **只選了 `kind: hosted` 目標**,就把變更/除錯的範圍限定在目標容器,不會自動修改 wrapper。
  - **其他情況** → 要求使用者選擇目標服務/資料夾。
- **沒有 azd agent 服務** → 在 workspace 裡搜尋含有 `agent-metadata.yaml` 或 `agent-metadata.<env>.yaml` 的 `.foundry/` 資料夾。
  - **一個符合** → 使用那個 agent root。
  - **多個符合** → 要求使用者選擇目標 agent 資料夾。
  - **沒有符合** → 對 [insights](foundry-agent/insights/insights.md),只問缺少的遠端輸入,不初始化本機檔案;對 create/deploy 流程,在設定時建立新的 `.foundry/` 資料夾;對其他流程,停下來問使用者要初始化哪個 agent 原始碼資料夾。

選定 agent root 之後,所有本機 `.foundry` 快取的檢視、原始碼的檢視、evaluator 的建議、資料集的建議和 prompt 最佳化的 context,都只限在那個資料夾裡。除非使用者明確切換 root,否則**不要**掃描同層的其他 agent 資料夾。

### 步驟 2:解析環境與 Deploy Context

如果有 `azure.yaml`,先解析 azd 環境:

1. 使用者明確指名的環境
2. `azd env get-values` 的 `AZURE_ENV_NAME`
3. `.azure/config.json` 裡 azd 的預設環境
4. session 稍早已選定的環境

當專案/deploy 的值還不知道時,對選定的環境執行 `azd env get-values`。Deploy context 優先用 azd 的值:

| azd 變數 | 解析成 |
|-------------|------------------|
| `AZURE_AI_PROJECT_ENDPOINT` 或 `AZURE_AIPROJECT_ENDPOINT` | 專案 endpoint |
| `AGENT_<SERVICE>_NAME` | 選定的 azd 服務的 agent 名稱 |
| `AGENT_<SERVICE>_VERSION` | 選定的 azd 服務的 agent 版本 |
| `AZURE_CONTAINER_REGISTRY_NAME` 或 `AZURE_CONTAINER_REGISTRY_ENDPOINT` | ACR registry 名稱 / image URL 前綴 |
| `APPLICATIONINSIGHTS_CONNECTION_STRING` | trace 流程用的 App Insights connection string |
| `AZURE_SUBSCRIPTION_ID`、`AZURE_RESOURCE_GROUP`、`AZURE_AI_ACCOUNT_NAME`、`AZURE_AI_PROJECT_NAME` | Azure 資源查詢和 Playground 連結 |

當 azd 提供這些值時,就把它們當作唯一的事實來源,寫入 metadata 時不要把它們複製進 `.foundry/agent-metadata*.yaml`。

### 步驟 3:選擇 Metadata Overlay 並解析環境

在選定的 agent root 裡,依這個順序選擇 metadata 檔案:
1. 使用者或流程明確提供的 metadata 檔名或路徑
2. 如果已經知道明確的環境,而且 `.foundry/agent-metadata.<env>.yaml` 存在,就用那個檔案
3. `.foundry/agent-metadata.yaml`
4. 如果還有多個 metadata 檔案,而且上面沒有任何規則選出其中一個,就提示使用者選擇

讀取選定的 metadata 檔案,並依這個順序解析剩下的環境選擇:
1. 使用者明確指名的環境
2. 如果選定的 metadata 檔案剛好只定義一個環境,就用它
3. session 稍早已選定的環境
4. metadata 裡的 `defaultEnvironment`

如果選定的 metadata 檔案仍然包含多個環境,而且上面沒有任何規則選出其中一個,就提示使用者選擇。在每個流程的摘要裡,都要讓選定的 agent root、metadata 檔案、環境,以及 context 是來自 azd 還是 metadata 保持可見。

如果選定的環境只有較舊的 `testSuites[]` metadata,沒有 `evaluationSuites[]`,就把 `testSuites[]` 當作這個 session 的來源,並在繼續之前,在記憶體中把每個項目正規化成 `evaluationSuites[]` 的形狀。如果 metadata 更舊,只有舊版的 `testCases[]`,就用同樣方式正規化那個清單。保留資料集和 evaluator 欄位、保留現有的 `tags`,並且只有在 `tags.tier` 缺少時,才把舊版的 `priority` 對應到 `tags.tier`:`P0` -> `smoke`、`P1` -> `regression`、`P2` -> `coverage`。

### 步驟 4:解析 eval.yaml 的本機評估意圖

如果選定的 agent root 裡有 `eval.yaml`,在產生新的 suite 之前先解析它:

- `agent.name` -> 目標 agent 的候選;使用之前,先確認它符合選定的 azd/metadata agent。
- `dataset.local_uri` -> 本機種子資料集的候選;舊版的 `dataset_file` 可以在記憶體中正規化。
- `dataset.name` / `dataset.version` -> 已註冊資料集的候選。
- `validation_dataset` -> 選用的驗證資料集候選。
- `evaluators[]` -> Foundry evaluator 名稱的候選;在當成遠端 evaluator 之前,先用 `evaluator_catalog_get` 驗證。
- `name` -> 本機 eval/suite 的候選;在當成 `suiteName` 保存之前,先遠端驗證。
- `options.eval_model`、`options.optimization_model`、`options.max_candidates`、`options.optimization_config.model_search_space`、`options.pass_threshold`、`max_samples`、`trace_days` 和 `generation_instruction` -> 設定的預設值。

把 `eval.yaml` 當作本機的評估意圖,而不是 Foundry suite 存在的證明。只有在遠端查詢或註冊成功之後,才把同步過的 suite/資料集/evaluator 參照保存到 `.foundry`。

### 步驟 5:解析通用設定

依這個順序疊加來源:

1. 使用者明確的輸入,以及 session 中已選定的值
2. 用於 deploy context 的 azd 環境值
3. `.foundry/agent-metadata*.yaml` 的 overlay 值,以及遠端 suite/快取的參照
4. `azure.yaml` 和 `eval.yaml` 的本機原始設定
5. 對仍然缺少的任何東西,向使用者詢問

如果 azd 和 metadata 都提供同一個值,而且兩者不同,就停下來問哪個來源才是權威。如果它們相符,就用 azd 的值,並避免之後寫入 metadata 時重寫那個重複的值。

| 有效的值 | 偏好的來源 | 使用者 |
|-----------------|------------------|---------|
| 專案 endpoint | azd env | deploy、invoke、observe、trace、troubleshoot |
| Agent 名稱/版本 | azd agent 變數,然後是 `azure.yaml` | invoke、observe、trace、troubleshoot |
| ACR | azd env | deploy |
| 評估 suite 和快取路徑 | `.foundry/agent-metadata*.yaml` | observe、eval-datasets |
| 本機種子資料集/evaluator 的意圖 | `eval.yaml` | observe、eval-datasets |

### 步驟 6:寫入 Metadata Overlay(只限 Create/Deploy/Observe)

在任何 metadata 寫入時(deploy、自動設定、資料集重新整理,或 trace 轉資料集的更新),只在選定的 metadata 檔案中保存無法推導的 overlay/快取狀態:

- azd 綁定(`azd.environmentName`、`azd.service`),有助於之後的解析時
- 帶有遠端 suite/資料集/evaluator 參照和本機快取路徑的 `evaluationSuites[]`
- `lastEval`、結果檔案、比較摘要,或明確的非 azd 覆寫

當 azd 已經提供 azd 擁有的 deploy 值時,不要把它們複製進 metadata。如果選定的檔案是偏好的單一環境檔案,就只重寫那一個環境區塊。如果選定的檔案是舊版的多環境檔案,就只重寫選定的環境區塊。絕對不要自動在同層的 metadata 檔案之間複製或合併環境。如果選定的環境仍然使用舊版的 `testSuites[]` 或 `testCases[]`,就把它重寫成 `evaluationSuites[]`,並從重寫的項目中移除已遷移的 `priority` 欄位。

### 步驟 7:收集缺少的值

只對**沒有**從使用者訊息、session context、metadata 或 azd bootstrap 解析出來的值,使用 `ask_user` 或 `askQuestions` 工具。skill 可能需要的常見值:
- **Agent root**:目標 azd 服務的專案資料夾,或含有 `.foundry/agent-metadata*.yaml` 的資料夾
- **Metadata 檔案**:本機/開發用的 `agent-metadata.yaml`,或明確的 sidecar(例如 `agent-metadata.prod.yaml`)
- **環境**:azd 環境、`dev`、`prod`,或 metadata 裡的其他環境 key
- **專案 endpoint**:Microsoft Foundry 專案的 endpoint URL
- **Agent 名稱**:目標 agent 的名稱

> 💡 **提示:** 如果使用者已經提供 agent 路徑、環境、專案 endpoint 或 agent 名稱,就直接擷取,不要再問一次。

## Agent:Agent 類型

Agent 流程區分四種一級的 agent 類型:

| 類型 | Kind | 說明 |
|------|------|-------------|
| **Prompt** | `"prompt"` | 以模型 deployment 為基礎的 LLM agent;透過 Foundry MCP 或 SDK 管理 |
| **Hosted** | `"hosted"` | 執行自訂程式碼、以容器為基礎的 agent;透過 `azd` 開發和 deploy |
| **Managed Harness Agent** | `"prompt"`,新的撰寫方式帶 `harness.type: "microsoft_copilot_preview"` | 跑在 Foundry 託管的 Copilot harness 上的 Prompt Agent;透過 `azd` 開發和 deploy |
| **Voice** | `"voice"` | 託管的即時 Voice Agent,可以是 **Prompt Voice**(1 個 agent,`modelType: managed` 或 `self_deployed`),或是 **Hosted Voice**(2 個 agent:帶 `conversationEngine.type: hosted_agent` 的 `kind: voice` wrapper + 透過 `invocations_ws` `1.0.0` 和 Voice Live Bridge `1.0` 的 `kind: hosted` 目標);透過 `azd` 開發和 deploy,並透過 `voice` WebSocket endpoint 驗證 |

依定義,按這個確切的順序分類 `azure.yaml` 服務,不要只靠 `host`:

1. `kind: voice` -> **Voice**。為了相容性,要默默把現有的 `kind: prompt-voice` 服務分類為 Voice,並在編輯它的 YAML 時正規化。分類子類型:
   - `conversationEngine.type: hosted_agent` -> **Hosted Voice wrapper**(和一個具名的 `kind: hosted` 目標服務配對)。
   - `modelType: managed` 或 `modelType: self_deployed` -> **Prompt Voice**(Foundry 從 `model.id` 推斷是原生的 speech-to-speech,還是串接的 STT -> LLM -> TTS)。
   - **同時**有 `modelType`/`model` 和 `conversationEngine` 是無效的(停下來修正 `azure.yaml`);**兩者都沒有**是不完整的(不要猜)。絕對不要用已廢棄的 `modelType: hosted_agent`、`targetAgent` 或巢狀的 `config:` 區塊。
2. `kind: hosted` -> **Hosted**。當它在 `kind: voice` wrapper 旁邊,宣告了 `protocols: [{ protocol: invocations_ws, version: 1.0.0 }]` 和 `metadata.voiceLiveCompatible: "true"`,它就是 **Hosted Voice 目標**;否則,把獨立的 `invocations_ws` 服務當作**自訂的 Hosted 即時/音訊 agent**。
3. `kind: prompt` 加上 `harness.type: microsoft_copilot_preview` 或舊版的 `github_copilot_preview` -> **Managed Harness Agent**。
4. 沒有那個 harness 的 `kind: prompt` -> 一般的 **Prompt Agent**。

只有在無法從專案 context 判斷類型時,才用 `agent_get`。要保留現有 Managed Harness Agent 上已經撰寫的 harness 識別值;一般的編輯或重新 deploy 時不要遷移它。不要在 Prompt、Hosted、Managed Harness Agent 和 Voice 類型之間轉換現有的 Agent;請改為建立新的 Agent。建立任何 **Voice Agent** 之前,先依 [create-voice](foundry-agent/create/create-voice.md) 決定模型策略。

## 工具使用慣例

- 每當要向使用者收集資訊時,就使用 `ask_user` 或 `askQuestions` 工具
- 用 `task` 或 `runSubagent` 工具來委派長時間執行或獨立的子任務(例如環境變數掃描、狀態輪詢、Dockerfile 產生)
- Hosted Agent、Managed Harness Agent 和 Voice Agent 優先用 azd;一般的 Prompt Agent 優先用 Foundry MCP。
- 要參照官方 Microsoft 文件的 URL,不要嵌入 CLI 指令語法

## Azure 驗證

- [Azure Authentication Best Practices](references/auth-best-practices.md)

## 其他資源

- [Foundry Hosted Agents](https://learn.microsoft.com/azure/ai-foundry/agents/concepts/hosted-agents?view=foundry)
- [Foundry Agent Runtime Components](https://learn.microsoft.com/azure/ai-foundry/agents/concepts/runtime-components?view=foundry)

## 網路隔離錯誤

適用於對 Foundry 專案或其上層 Foundry 帳戶的**任何**呼叫:Foundry MCP 工具、`azd`、`az` CLI、`curl`、REST 或 SDK。

如果錯誤符合 `Public access is disabled` / `PublicNetworkAccessDisabled` / 來自 private endpoint 的 `403 Forbidden` / 連線 timeout / 專案 endpoint 的 FQDN 解析成公開 IP,通常代表上層 Foundry 帳戶的 `publicNetworkAccess=Disabled` 或是 `Enabled from selected IP addresses`,而目前的 shell 在它的 VNet 之外。

只有當錯誤不明確時,才用管理平面的呼叫(有 reader 存取權的話,從任何地方都能用)對 Foundry 帳戶確認:

```bash
az cognitiveservices account show \
  --name <account> --resource-group <rg> \
  --query "properties.{publicNetworkAccess:publicNetworkAccess, networkAcls:networkAcls, privateEndpointConnections:privateEndpointConnections[].properties.privateLinkServiceConnectionState.status}"
```

`publicNetworkAccess: "Disabled"`,或是 `"Enabled"` 加上非空的 `networkAcls.ipRules` / `virtualNetworkRules`,就確認有網路隔離。如果 `publicNetworkAccess: "Enabled"` 而且 `networkAcls` 是空的,這個失敗是呼叫端的網路問題(例如在有 private endpoint 的 VNet 裡,Private DNS 把 FQDN 解析成公開 IP),不是帳戶設定的問題。

如果確實是網路隔離的問題,支援的連線選項記錄在 [Choose a secure connection method to Foundry](https://learn.microsoft.com/azure/foundry/how-to/configure-private-link#choose-a-secure-connection-method-to-foundry)。

> ℹ️ Foundry MCP 工具就算在 VNet 裡面,也無法連到 VNet 隔離的專案。

英文原文

---
name: microsoft-foundry
description: "Build, deploy, evaluate, optimize, fine-tune, and manage Microsoft Foundry agents, models, and resources end to end. USE FOR: foundry, azd ai agent, azd provision/deploy, hosted agent scaffold/develop/run/deploy/troubleshoot, prompt agent, managed harness agent, Copilot harness, voice agent, create/update/invoke/evaluate agent, add tool to agent, agent insights, batch/continuous eval, continuous monitoring, agent CI/CD, optimize/improve prompt, optimize agent instructions, Agent Optimizer, dataset curation from traces, deploy model, model fine-tuning (SFT/DPO/RFT), Foundry project, RBAC, role assignment, permissions, quota, capacity, region, deployment failure, AI Services, create Foundry resource, knowledge index, customize deployment, onboard, availability, training-data, grader, distillation, large file upload. DO NOT USE FOR: Azure Functions, App Service, general Azure deploy (use azure-deploy), general Azure prep (use azure-prepare)."
license: MIT
metadata:
  author: Microsoft
  version: "1.2.32"
---

# Microsoft Foundry Skill

This skill helps developers work with Microsoft Foundry resources, covering model discovery and deployment, complete dev lifecycle of AI agent, evaluation workflows, and troubleshooting.

## Pre-Execution Requirements

Follow each applicable subsection below before starting its corresponding action or workflow.

### Dependency Check and Setup

**MANDATORY:** As the first step after this skill loads, run the dependency check and setup script below from this skill's root and wait for it to finish before continuing. The script checks first and installs only missing dependencies; it does not reinstall dependencies that are already available.

**You MUST complete this check before reading or entering any sub-skill, workflow, or workflow-specific reference.**

```bash
./scripts/check-and-setup-dependencies.sh     # macOS / Linux
./scripts/check-and-setup-dependencies.ps1    # Windows (pwsh)
```

Strictly follow the script output for subsequent actions.

### Workflow Guidance

**MANDATORY:** Before executing ANY workflow-specific steps, you MUST read the corresponding sub-skill document. Do not call workflow-specific MCP tools for a workflow without reading its skill document. This applies even if you already know the MCP tool parameters — the skill document contains required workflow steps, pre-checks, and validation logic that must be followed. This rule applies on every new user message that triggers a different workflow, even if the skill is already loaded.

### Foundry MCP

**MANDATORY:** Before using Foundry MCP operations, call the Azure MCP `foundry` tool and inspect the available Foundry MCP tools and related parameters. Treat this as the discovery/help step for MCP-based workflows.

### azd

**MANDATORY:** Before executing ANY azd command, you MUST read [azd-guidance](foundry-agent/azd-guidance/azd-guidance.md) and strictly follow the shared rules defined in it, especially the `AZURE_DEV_USER_AGENT` setting rules.

## Sub-Skills

This skill includes specialized sub-skills for specific workflows. **When a sub-skill matches the task, strictly follow its workflow:**

| Sub-Skill | When to Use | Reference |
|-----------|-------------|-----------|
| **deploy** | Deploy hosted agents to Foundry, smoke-test a deployment, create or update prompt agents, and manage agent versions and multi-environment deploys. | [deploy](foundry-agent/deploy/deploy.md) |
| **cicd** | Set up a CI/CD deployment pipeline for a Foundry agent. | [cicd](foundry-agent/cicd/cicd.md) |
| **invoke** | Send messages to an agent, single or multi-turn conversations | [invoke](foundry-agent/invoke/invoke.md) |
| **routine** | Schedule or event-trigger Foundry agents with routines; use `azd` for CRUD, enable/disable, manual dispatch, and viewing past runs, or define routines in `azure.yaml`. | [routine](foundry-agent/routine/routine.md) |
| **invocations-ws** | Build, deploy, and connect to custom Hosted agents that use developer-defined duplex real-time or media streams over `invocations_ws`. | [invocations-ws](foundry-agent/invocations-ws/invocations-ws.md) |
| **observe** | Evaluate agent quality, run batch evals, analyze failures, optimize prompts, improve agent instructions, compare versions, set up CI/CD monitoring, and enable continuous production evaluation | [observe](foundry-agent/observe/observe.md) |
| **insights** | Pull generated agent insights, evidence, and recommendations from an existing monitor; read-only retrieval, not a new analysis run | [insights](foundry-agent/insights/insights.md) |
| **trace** | Query traces, analyze latency/failures, correlate eval results to specific responses via App Insights `customEvents` | [trace](foundry-agent/trace/trace.md) |
| **troubleshoot** | View hosted agent logs, query telemetry, diagnose failures | [troubleshoot](foundry-agent/troubleshoot/troubleshoot.md) |
| **validate** | Use only when the user explicitly asks to use this validation sub-skill or to validate Microsoft Foundry hosted-agent code against best practices. Never invoke it proactively or add it to another workflow. | [validate](foundry-agent/validate/validate.md) |
| **create (quick start)** | Create a new hosted Foundry agent from scratch end-to-end — scaffold, provision or use an existing Foundry project, deploy, and smoke-test. Do not use for any work on existing code. For anything not covered by the quickstart, use **create**. | [create/quick-start-hosted.md](foundry-agent/create/quick-start-hosted.md) |
| **create** | Use when the standard end-to-end happy path (quick start) doesn't fit. Create a new Foundry agent, update code of an existing agent, continue development of an existing agent, wire connections at scaffold time, use advanced setup or A2A (Agent2Agent), or recover from a failed quickstart run. | [create](foundry-agent/create/create-hosted.md) |
| **create managed harness** | Create or continue developing a Prompt Agent that explicitly uses the Foundry-managed Copilot harness. Uses `azd` and `azure.yaml`, not the ordinary Prompt Agent MCP workflow. | [create-managed-harness](foundry-agent/create/create-managed-harness.md) |
| **create voice** | Create, configure, or extend a Foundry Voice Agent, defaulting generic requests to managed Prompt Voice and supporting self-deployed Prompt Voice or two-agent Hosted Voice. | [create-voice](foundry-agent/create/create-voice.md) |
| **agent-optimizer** | Make existing Python hosted-agent code optimization-ready, configure eval.yaml, run Agent Optimizer jobs, apply candidates locally, and deploy through azd after review. | [agent-optimizer](foundry-agent/agent-optimizer/agent-optimizer.md) |
| **eval-datasets** | Harvest production traces into evaluation datasets, manage dataset versions and splits, track evaluation metrics over time, detect regressions, and maintain full lineage from trace to deployment. Use for: create dataset from traces, dataset versioning, evaluation trending, regression detection, dataset comparison, eval lineage. | [eval-datasets](foundry-agent/eval-datasets/eval-datasets.md) |
| **project/create** | Creating a new Microsoft Foundry project for hosting agents and models. Use when onboarding to Foundry or setting up new infrastructure. | [project/create/create-foundry-project.md](project/create/create-foundry-project.md) |
| **resource/create** | Creating Azure AI Services multi-service resource (Foundry resource) using Azure CLI. Use when manually provisioning AI Services resources with granular control. | [resource/create/create-foundry-resource.md](resource/create/create-foundry-resource.md) |
| **private-network** | Answer questions about Foundry network isolation **and** deploy Foundry with VNet isolation (BYO VNet, Managed VNet, hybrid). Covers architecture concepts, template selection, deployment, and post-deployment validation. | [resource/private-network/private-network.md](resource/private-network/private-network.md) |
| **models/deploy-model** | Unified model deployment with intelligent routing. Handles quick preset deployments, fully customized deployments (version/SKU/capacity/RAI), and capacity discovery across regions. Routes to sub-skills: `preset` (quick deploy), `customize` (full control), `capacity` (find availability). | [models/deploy-model/SKILL.md](models/deploy-model/SKILL.md) |
| **quota** | Managing quotas and capacity for Microsoft Foundry resources. Use when checking quota usage, troubleshooting deployment failures due to insufficient quota, requesting quota increases, or planning capacity. | [quota/quota.md](quota/quota.md) |
| **rbac** | Managing RBAC permissions, role assignments, managed identities, and service principals for Microsoft Foundry resources. Use for access control, auditing permissions, and CI/CD setup. | [rbac/rbac.md](rbac/rbac.md) |
| **finetuning** | Fine-tune models on Microsoft Foundry — SFT distillation, DPO preference optimization, RFT with graders and tool calling. Dataset preparation, grader calibration, training, checkpoint selection, deployment, evaluation. Use for: fine-tune, SFT, DPO, RFT, training data, grader, distillation, fine-tuned model, large file upload. | [finetuning/SKILL.md](finetuning/SKILL.md) |
| **azd-guidance** | Provide shared azd knowledge and guidance for managing Foundry agents. Read this first for any workflows related to azd. | [azd-guidance](foundry-agent/azd-guidance/azd-guidance.md) |

> 💡 **Tip:** For a complete onboarding flow: `project/create` (public) or `private-network` (VNet isolation) → `models/deploy-model` → agent workflows (`create` → `deploy` → `invoke`).

> 💡 **Fine-Tuning:** Use `finetuning` for all model customization — SFT distillation, DPO preference optimization, and RFT with graders. Includes quickstart, grader calibration, and training curve analysis.

> 💡 **Model Deployment:** Use `models/deploy-model` for all deployment scenarios — it intelligently routes between quick preset deployment, customized deployment with full control, and capacity discovery across regions.

> 💡 **Prompt Optimization:** For requests like "optimize my prompt" or "improve my agent instructions," load [observe](foundry-agent/observe/observe.md) and use the `prompt_optimize` MCP tool through that eval-driven workflow.

## Infrastructure Lifecycle

Match user intent to the correct infrastructure workflow.

| User Intent | Workflow |
|-------------|---------|
| "Create Foundry" / "Set up Foundry" (ambiguous) | Use `AskUserQuestion`: (a) just an AI Services resource, (b) a project with public access, or (c) a project with network isolation? Route: (a) → [resource/create](resource/create/create-foundry-resource.md), (b) → [project/create](project/create/create-foundry-project.md), (c) → [private-network](resource/private-network/private-network.md) |
| Set up Foundry with VNet isolation | [private-network](resource/private-network/private-network.md) |
| Create a Foundry project (public) | [project/create](project/create/create-foundry-project.md) |
| Create a bare Foundry resource | [resource/create](resource/create/create-foundry-resource.md) |

## Agent Development Lifecycle

Match user intent to the correct agent workflow. Read each sub-skill in order before executing.

| User Intent | Workflow (read in order) |
|-------------|------------------------|
| Create or develop a Voice Agent (Prompt Voice or Hosted Voice) | [dependency check and setup](#dependency-check-and-setup) → [azd-guidance](foundry-agent/azd-guidance/azd-guidance.md) → [create-voice](foundry-agent/create/create-voice.md) → [deploy](foundry-agent/deploy/deploy.md) → [invoke](foundry-agent/invoke/invoke.md) |
| Create or develop an explicitly requested Managed Harness Agent / Copilot harness agent | [dependency check and setup](#dependency-check-and-setup) → [azd-guidance](foundry-agent/azd-guidance/azd-guidance.md) → [create-managed-harness](foundry-agent/create/create-managed-harness.md) → [deploy](foundry-agent/deploy/deploy.md) → [invoke](foundry-agent/invoke/invoke.md) |
| Create a new hosted agent end-to-end (scaffold + deploy + test) | [dependency check and setup](#dependency-check-and-setup) → [azd-guidance](foundry-agent/azd-guidance/azd-guidance.md) → [quick-start-hosted](foundry-agent/create/quick-start-hosted.md) (self-contained end-to-end) |
| Anything beyond the standard quickstart (existing code, migration, re-hosting, deployment customization, scaffold-time connections, A2A (Agent2Agent), recovery) | [dependency check and setup](#dependency-check-and-setup) → [azd-guidance](foundry-agent/azd-guidance/azd-guidance.md) → [create](foundry-agent/create/create-hosted.md) → [deploy](foundry-agent/deploy/deploy.md) → [invoke](foundry-agent/invoke/invoke.md) |
| Optimize existing Python hosted agent | [dependency check and setup](#dependency-check-and-setup) → [azd-guidance](foundry-agent/azd-guidance/azd-guidance.md) → [agent-optimizer](foundry-agent/agent-optimizer/agent-optimizer.md) → scaffold/review → eval.yaml → optimize → apply candidate → deploy → invoke |
| Deploy an agent (code already exists) | [dependency check and setup](#dependency-check-and-setup) → [azd-guidance](foundry-agent/azd-guidance/azd-guidance.md) → deploy (includes eval-suite setup) → invoke → observe (evaluate/optimize) |
| Update/redeploy an agent after code changes | [dependency check and setup](#dependency-check-and-setup) → [azd-guidance](foundry-agent/azd-guidance/azd-guidance.md) → deploy (includes eval-suite setup) → invoke → observe (evaluate/optimize) |
| Set up a CI/CD deployment pipeline for a hosted agent | [dependency check and setup](#dependency-check-and-setup) → [azd-guidance](foundry-agent/azd-guidance/azd-guidance.md) → cicd |
| Invoke/test/chat with an agent | [dependency check and setup](#dependency-check-and-setup) → [azd-guidance](foundry-agent/azd-guidance/azd-guidance.md) → invoke |
| Schedule/event-trigger an agent, or CRUD/enable/disable/dispatch a routine | [dependency check and setup](#dependency-check-and-setup) → [azd-guidance](foundry-agent/azd-guidance/azd-guidance.md) → routine |
| Optimize / improve agent prompt or instructions | observe (Step 4: Optimize) |
| Evaluate and optimize agent (full loop) | observe |
| Enable continuous evaluation monitoring | observe (Step 6: CI/CD & Monitoring) |
| Pull agent insights / list generated issues and recommendations | [dependency check and setup](#dependency-check-and-setup) → [insights](foundry-agent/insights/insights.md) (all pages with expanded evidence; read-only) |
| Troubleshoot an agent issue | [dependency check and setup](#dependency-check-and-setup) → [azd-guidance](foundry-agent/azd-guidance/azd-guidance.md) → invoke → troubleshoot |
| Fix a broken agent (troubleshoot + redeploy) | [dependency check and setup](#dependency-check-and-setup) → [azd-guidance](foundry-agent/azd-guidance/azd-guidance.md) → invoke → troubleshoot → apply fixes → deploy → invoke |

## Agent: .foundry Workspace Standard

Every agent source folder can keep Foundry-specific cache and overlay state under `.foundry/`:

```text
<agent-root>/
  .foundry/
    agent-metadata.yaml
    agent-metadata.prod.yaml
    suites/
    datasets/
    evaluators/
    results/
```

- In azd projects, derive deployment context (project endpoint, agent name/version, ACR, App Insights) from `azure.yaml` plus `azd env get-values`; do not duplicate those values in metadata when azd already provides them.
- `agent-metadata.yaml` is the preferred local/dev overlay for non-azd values, remote Foundry suite references, local cache paths, result summaries, and explicit overrides. Optional sidecar files such as `agent-metadata.prod.yaml` can hold a single prod or CI-targeted overlay without mixing multiple environments in one file.
- `suites/`, `datasets/`, and `evaluators/` are local cache folders. Reuse them when they are current, and ask before refreshing or overwriting them.
- See [Agent Metadata Contract](references/agent-metadata-contract.md) for the canonical schema and workflow rules.

## Agent: Setup References

- [Standard Agent Setup](references/standard-agent-setup.md) — advanced setup for production workloads that need data-residency control (bring-your-own Cosmos DB / Storage / AI Search via a Foundry capability host). The default `azd ai agent` flow uses **Basic Agent Setup** and does **not** provision `capabilityHosts/agents` — do not flag its absence as a bug. For default post-provision state, see the "Expected env-var fingerprint" section in [foundry-agent/create/create-hosted.md](foundry-agent/create/create-hosted.md).

## Agent: Common Project Context Resolution

Agent skills should run this step **only when they need configuration values they don't already have**. If a value (for example, agent root, environment, project endpoint, or agent name) is already known from the user's message or a previous skill in the same session, skip resolution for that value.

### Step 1: Discover Agent Roots and azd Context

First check whether the workspace has `azure.yaml` with services using `host: azure.ai.agent`.

- **One azd agent service** -> classify it from `kind`, `harness`, `modelType`, and `conversationEngine`, then use that service's `project` folder or the `azure.yaml` directory as the agent root.
- **Multiple azd agent services** -> check whether a Voice wrapper references a `kind: hosted` service via `conversationEngine.name`:
  - **Selecting the Hosted Voice wrapper** implies its named `kind: hosted` target as an upstream dependency (`uses: [<target>]`, `conversationEngine.name: <target>`); deploy and verification must report both services separately.
  - **Selecting the `kind: hosted` target alone** scopes changes/debugging to the target container and does not automatically modify the wrapper.
  - **Otherwise** -> require the user to choose the target service/folder.
- **No azd agent service** -> search the workspace for `.foundry/` folders that contain `agent-metadata.yaml` or `agent-metadata.<env>.yaml`.
  - **One match** -> use that agent root.
  - **Multiple matches** -> require the user to choose the target agent folder.
  - **No matches** -> for [insights](foundry-agent/insights/insights.md), ask only for missing remote inputs without initializing local files; for create/deploy workflows, seed a new `.foundry/` folder during setup; for other workflows, stop and ask the user which agent source folder to initialize.

After selecting an agent root, keep all local `.foundry` cache inspection, source inspection, evaluator suggestions, dataset suggestions, and prompt-optimization context inside that folder only. Do **not** scan sibling agent folders unless the user explicitly switches roots.

### Step 2: Resolve Environment and Deployment Context

If `azure.yaml` is present, resolve the azd environment first:

1. Environment explicitly named by the user
2. `AZURE_ENV_NAME` from `azd env get-values`
3. azd default environment from `.azure/config.json`
4. Environment already selected earlier in the session

Run `azd env get-values` for the selected environment when project/deployment values are not already known. Prefer azd values for deployment context:

| azd Variable | Resolves To |
|-------------|-------------|
| `AZURE_AI_PROJECT_ENDPOINT` or `AZURE_AIPROJECT_ENDPOINT` | Project endpoint |
| `AGENT_<SERVICE>_NAME` | Agent name for the selected azd service |
| `AGENT_<SERVICE>_VERSION` | Agent version for the selected azd service |
| `AZURE_CONTAINER_REGISTRY_NAME` or `AZURE_CONTAINER_REGISTRY_ENDPOINT` | ACR registry name / image URL prefix |
| `APPLICATIONINSIGHTS_CONNECTION_STRING` | App Insights connection string for trace workflows |
| `AZURE_SUBSCRIPTION_ID`, `AZURE_RESOURCE_GROUP`, `AZURE_AI_ACCOUNT_NAME`, `AZURE_AI_PROJECT_NAME` | Azure resource lookup and Playground links |

When azd supplies these values, use them as the source of truth and do not copy them into `.foundry/agent-metadata*.yaml` on metadata writes.

### Step 3: Select Metadata Overlay and Resolve Environment

Inside the selected agent root, choose the metadata file in this order:
1. Metadata filename or path explicitly provided by the user or workflow
2. If an explicit environment is already known and `.foundry/agent-metadata.<env>.yaml` exists, use that file
3. `.foundry/agent-metadata.yaml`
4. If multiple metadata files remain and no rule above selects one, prompt the user to choose

Read the selected metadata file and resolve any remaining environment choice in this order:
1. Environment explicitly named by the user
2. If the selected metadata file defines exactly one environment, use it
3. Environment already selected earlier in the session
4. `defaultEnvironment` from metadata

If the selected metadata file still contains multiple environments and none of the rules above selects one, prompt the user to choose. Keep the selected agent root, metadata file, environment, and whether context came from azd or metadata visible in every workflow summary.

If the selected environment exposes older `testSuites[]` metadata but not `evaluationSuites[]`, treat `testSuites[]` as the source for this session and normalize each entry in memory to the `evaluationSuites[]` shape before continuing. If the metadata is older still and only exposes legacy `testCases[]`, normalize that list the same way. Preserve dataset and evaluator fields, keep any existing `tags`, and map legacy `priority` to `tags.tier` only when `tags.tier` is missing: `P0` -> `smoke`, `P1` -> `regression`, `P2` -> `coverage`.

### Step 4: Resolve eval.yaml Local Evaluation Intent

If `eval.yaml` exists in the selected agent root, parse it before generating new suites:

- `agent.name` -> target agent candidate; verify it matches the selected azd/metadata agent before using it.
- `dataset.local_uri` -> local seed dataset candidate; legacy `dataset_file` may be normalized in memory.
- `dataset.name` / `dataset.version` -> registered dataset candidate.
- `validation_dataset` -> optional validation dataset candidate.
- `evaluators[]` -> candidate Foundry evaluator names; verify with `evaluator_catalog_get` before treating them as remote evaluators.
- `name` -> local eval/suite candidate; verify remotely before persisting as `suiteName`.
- `options.eval_model`, `options.optimization_model`, `options.max_candidates`, `options.optimization_config.model_search_space`, `options.pass_threshold`, `max_samples`, `trace_days`, and `generation_instruction` -> setup defaults.

Treat `eval.yaml` as local evaluation intent, not proof that a Foundry suite exists. Persist synced suite/dataset/evaluator references to `.foundry` only after remote lookup or registration succeeds.

### Step 5: Resolve Common Configuration

Layer sources in this order:

1. Explicit user input and values already selected in the session
2. azd environment values for deployment context
3. `.foundry/agent-metadata*.yaml` overlay values and remote suite/cache references
4. `azure.yaml` and `eval.yaml` local source configuration
5. User prompts for anything still missing

If azd and metadata both provide the same value and they differ, stop and ask which source is authoritative. If they match, use the azd value and avoid rewriting the duplicate on future metadata writes.

| Effective Value | Preferred Source | Used By |
|-----------------|------------------|---------|
| Project endpoint | azd env | deploy, invoke, observe, trace, troubleshoot |
| Agent name/version | azd agent variables, then `azure.yaml` | invoke, observe, trace, troubleshoot |
| ACR | azd env | deploy |
| Evaluation suites and cache paths | `.foundry/agent-metadata*.yaml` | observe, eval-datasets |
| Local seed dataset/evaluator intent | `eval.yaml` | observe, eval-datasets |

### Step 6: Write Metadata Overlay (Create/Deploy/Observe Only)

On any metadata write (deploy, auto-setup, dataset refresh, or trace-to-dataset update), persist only non-derivable overlay/cache state in the selected metadata file:

- azd binding (`azd.environmentName`, `azd.service`) when useful for future resolution
- `evaluationSuites[]` with remote suite/dataset/evaluator references and local cache paths
- `lastEval`, result files, comparison summaries, or explicit non-azd overrides

Do not copy azd-owned deployment values into metadata when azd already provides them. If the selected file is a preferred single-environment file, rewrite only that one environment block. If the selected file is a legacy multi-environment file, rewrite only the selected environment block. Never copy or merge environments across sibling metadata files automatically. If the selected environment still uses older `testSuites[]` or legacy `testCases[]`, rewrite it to `evaluationSuites[]` and remove migrated `priority` fields from the rewritten entries.

### Step 7: Collect Missing Values

Use the `ask_user` or `askQuestions` tool **only for values not resolved** from the user's message, session context, metadata, or azd bootstrap. Common values skills may need:
- **Agent root** — Target azd service project folder or folder containing `.foundry/agent-metadata*.yaml`
- **Metadata file** — `agent-metadata.yaml` for local/dev, or an explicit sidecar such as `agent-metadata.prod.yaml`
- **Environment** — azd environment, `dev`, `prod`, or another environment key from metadata
- **Project endpoint** — Microsoft Foundry project endpoint URL
- **Agent name** — Name of the target agent

> 💡 **Tip:** If the user already provides the agent path, environment, project endpoint, or agent name, extract it directly — do not ask again.

## Agent: Agent Types

Agent workflows distinguish four first-class agent types:

| Type | Kind | Description |
|------|------|-------------|
| **Prompt** | `"prompt"` | LLM-based agents backed by a model deployment; managed via Foundry MCP or SDK |
| **Hosted** | `"hosted"` | Container-based agents running custom code; developed and deployed via `azd` |
| **Managed Harness Agent** | `"prompt"` with `harness.type: "microsoft_copilot_preview"` for new authoring | Prompt Agent running on the Foundry-managed Copilot harness; developed and deployed via `azd` |
| **Voice** | `"voice"` | Managed real-time Voice Agent — either **Prompt Voice** (1 agent, `modelType: managed` or `self_deployed`) or **Hosted Voice** (2 agents: `kind: voice` wrapper with `conversationEngine.type: hosted_agent` + `kind: hosted` target over `invocations_ws` `1.0.0` and Voice Live Bridge `1.0`); developed and deployed via `azd` and verified over the `voice` WebSocket endpoint |

Classify an `azure.yaml` service by its definition in this exact order, not by `host` alone:

1. `kind: voice` -> **Voice**. For compatibility, silently classify an existing `kind: prompt-voice` service as Voice, then normalize it when editing its YAML. Classify the subtype:
   - `conversationEngine.type: hosted_agent` -> **Hosted Voice wrapper** (paired with a named `kind: hosted` target service).
   - `modelType: managed` or `modelType: self_deployed` -> **Prompt Voice** (Foundry infers native speech-to-speech vs cascaded STT -> LLM -> TTS from `model.id`).
   - Having **both** `modelType`/`model` and `conversationEngine` is invalid (stop and fix `azure.yaml`); having **neither** is incomplete (do not guess). Never use obsolete `modelType: hosted_agent`, `targetAgent`, or a nested `config:` block.
2. `kind: hosted` -> **Hosted**. When it declares `protocols: [{ protocol: invocations_ws, version: 1.0.0 }]` and `metadata.voiceLiveCompatible: "true"` alongside a `kind: voice` wrapper, it is a **Hosted Voice target**; otherwise treat a standalone `invocations_ws` service as a **custom Hosted real-time/audio agent**.
3. `kind: prompt` plus `harness.type: microsoft_copilot_preview` or legacy `github_copilot_preview` -> **Managed Harness Agent**.
4. `kind: prompt` without that harness -> ordinary **Prompt Agent**.

Use `agent_get` only when the type cannot be resolved from project context. Preserve the harness discriminator already authored on an existing Managed Harness Agent; do not migrate it during ordinary edits or redeploys. Do not convert an existing Agent between Prompt, Hosted, Managed Harness Agent, and Voice types; create a new Agent instead. Before creating any **Voice Agent**, determine the model strategy first per [create-voice](foundry-agent/create/create-voice.md).

## Tool Usage Conventions

- Use the `ask_user` or `askQuestions` tool whenever collecting information from the user
- Use the `task` or `runSubagent` tool to delegate long-running or independent sub-tasks (e.g., env var scanning, status polling, Dockerfile generation)
- Prefer azd for Hosted Agents, Managed Harness Agents, and Voice Agents; prefer Foundry MCP for ordinary Prompt Agents.
- Reference official Microsoft documentation URLs instead of embedding CLI command syntax

## Azure Authentication

- [Azure Authentication Best Practices](references/auth-best-practices.md)

## Additional Resources

- [Foundry Hosted Agents](https://learn.microsoft.com/azure/ai-foundry/agents/concepts/hosted-agents?view=foundry)
- [Foundry Agent Runtime Components](https://learn.microsoft.com/azure/ai-foundry/agents/concepts/runtime-components?view=foundry)

## Network Isolation Errors

Applies to **any** call against a Foundry project or its parent Foundry account — Foundry MCP tools, `azd`, `az` CLI, `curl`, REST, or SDK.

If an error matches `Public access is disabled` / `PublicNetworkAccessDisabled` / `403 Forbidden` from a private endpoint / connection timeout / the project endpoint FQDN resolves to a public IP, this typically means the parent Foundry account has `publicNetworkAccess=Disabled` or `Enabled from selected IP addresses`, and the current shell is outside its VNet.

Only if the error is ambiguous, confirm against the Foundry account using a management-plane call (works from anywhere with reader access):

```bash
az cognitiveservices account show \
  --name <account> --resource-group <rg> \
  --query "properties.{publicNetworkAccess:publicNetworkAccess, networkAcls:networkAcls, privateEndpointConnections:privateEndpointConnections[].properties.privateLinkServiceConnectionState.status}"
```

`publicNetworkAccess: "Disabled"` — or `"Enabled"` together with non-empty `networkAcls.ipRules` / `virtualNetworkRules` — confirms isolation. If `publicNetworkAccess: "Enabled"` and `networkAcls` is empty, the failure is a caller-side network issue (e.g. Private DNS resolving the FQDN to a public IP from inside a VNet with a private endpoint), not an account-config issue.

If it's indeed a network isolation issue, supported connection options are documented in [Choose a secure connection method to Foundry](https://learn.microsoft.com/azure/foundry/how-to/configure-private-link#choose-a-secure-connection-method-to-foundry).

> ℹ️ Foundry MCP tools cannot reach a VNet-isolated project even from inside the VNet.