H繁中版
<!-- Source: https://hermesbible.com/docs/guides/azure-foundry -->

Hermes Agent 的 azure-foundry 供應商支援 Microsoft Foundry(前身為 Azure AI Foundry)和 Azure OpenAI。一個 Foundry 資源可以承載兩種不同傳輸格式的模型:

  • OpenAI 風格 — 在 https://<resource>.openai.azure.com/openai/v1 等端點上使用 POST /v1/chat/completions。適用於 GPT-4.x、GPT-5.x、Llama、Mistral 及大多數開放權重模型。
  • Anthropic 風格 — 在 https://<resource>.services.ai.azure.com/anthropic 等端點上使用 POST /v1/messages。當 Microsoft Foundry 透過 Anthropic Messages API 格式提供 Claude 模型時使用。

設定精靈會探測你的端點,自動偵測其使用的傳輸方式、可用的部署,以及每個模型的上下文長度。

前置需求

  • 一個 Microsoft Foundry 或 Azure OpenAI 資源,且至少有一個部署
  • 部署的端點 URL
  • 以下擇一:一個 API 金鑰(從 Azure Portal 的「金鑰和端點」取得),或在 Foundry 資源上具有 Azure AI User RBAC 角色(如果你想使用 Microsoft Entra ID,這是 Microsoft 推薦的無金鑰路徑)。某些租戶在 Microsoft 重新命名推出期間可能會將角色顯示為 Foundry User

快速開始

hermes model
# → 選擇 "Azure Foundry"
# → 輸入你的端點 URL
# → 選擇認證方式:
#     1. API 金鑰
#     2. Microsoft Entra ID(託管識別 / 工作負載識別 / az login)
# →(Entra)Hermes 探測 DefaultAzureCredential;成功後再也不會要求金鑰
# →(API 金鑰)輸入你的 API 金鑰
# Hermes 探測端點並自動偵測傳輸方式 + 模型
# → 從清單中選擇一個模型(或手動輸入部署名稱)

精靈會:

  1. 嗅探 URL 路徑 — 以 /anthropic 結尾的 URL 會被識別為 Microsoft Foundry Claude 路由。
  2. 探測 GET <base>/models — 如果端點傳回 OpenAI 格式的模型清單,Hermes 會切換到 chat_completions 並用傳回的部署 ID 填充選擇器。
  3. 探測 Anthropic Messages 格式 — 當端點未公開 /models 但接受 Anthropic Messages 格式時的備用方案。
  4. 退回手動輸入 — 私有/受保護端點拒絕所有探測仍可運作;你選擇 API 模式並手動輸入部署名稱。

所選模型的上下文長度透過 Hermes 的標準元資料鏈(models.dev、供應商元資料和硬編碼的系列備用值)解析,並儲存在 config.yaml 中,以便模型能正確設定自己的上下文視窗大小。

Microsoft Entra ID(無金鑰、RBAC)— 建議

Microsoft 建議在生產環境的 Foundry 工作負載中使用無金鑰的 Microsoft Entra ID 認證。Hermes 同時支援 兩個 API 介面的 Entra ID:

  • OpenAI 風格api_mode: chat_completions / codex_responses)— GPT-4/5、Llama、Mistral、DeepSeek 等。
  • Anthropic 風格api_mode: anthropic_messages)— Microsoft Foundry 上的 Claude 模型。

Foundry 的 RBAC 是按資源的(Azure AI User 授權兩個介面;某些租戶可能顯示為 Foundry User),Microsoft 對兩者使用相同的推論範圍(https://ai.azure.com/.default)。底層機制:

  • OpenAI 風格使用 OpenAI Python SDK 原生的可呼叫 api_key= 契約 — SDK 自動為每個請求鑄造新的 JWT。
  • Anthropic 風格使用 httpx.Client 並安裝由 agent.azure_identity_adapter.build_bearer_http_client 設定的請求事件鉤子,因為 Anthropic SDK 原生不接受可呼叫的 auth_token。鉤子為每個出站請求重寫 Authorization: Bearer <fresh-jwt>。相同的 Microsoft RBAC、相同的 Foundry 範圍 — 唯一的差異是 SDK 契約。

為什麼要使用 Entra ID?

  • 沒有需要輪替或撤銷的長期 API 金鑰。
  • RBAC 驅動的存取 — 授予或移除 Foundry 資源上的 Azure AI User,無需重寫設定。
  • 存取和審計日誌按受派者分隔,而非所有呼叫者共享一個靜態金鑰。
  • 透過託管識別為 Azure VM、AKS Pod、App Service、Functions、Container Apps 和 Foundry Agent Service 提供單一認證介面。
  • 工作負載識別和服務主體流程用於 CI/CD 管線。

一次性設定(Azure 端)

  1. 在 Azure Portal 中,開啟你的 Foundry 資源 → 存取控制 (IAM)新增 → 新增角色指派
  2. 選擇 Azure AI User 角色(如果你的租戶有重新命名的角色則選擇 Foundry User)。
  3. 指派給:
    • 你的使用者帳戶,用於搭配 az login 進行本機開發。
    • 託管識別或工作負載識別,用於 Azure 託管的運算資源(生產環境建議)。
    • Foundry Agent Service 託管代理程式的代理程式識別,當 Hermes 在託管代理程式中運行時。
    • 服務主體,用於工作負載識別不可用時的 CI/CD 管線。
  4. 等待約 5 分鐘讓角色生效。

Azure CLI 等效指令:

az role assignment create \
  --assignee <principal-or-agent-identity-client-id> \
  --role "Azure AI User" \
  --scope <foundry-resource-id>

一次性設定(Hermes 端)

hermes model
# → 選擇 "Azure Foundry"
# → 輸入你的端點 URL
# → 認證:2 (Microsoft Entra ID)
# →(選擇性)使用者指派的託管識別客戶端 ID
# →(選擇性)Azure 租戶 ID
# → Hermes 探測 DefaultAzureCredential() 並報告哪個內部
#    認證成功(例如 AzureCliCredential、ManagedIdentityCredential)

精靈執行有界線的預檢探測(10 秒逾時)。失敗時會提供「仍然儲存,稍後驗證」— 當你在尚無認證但運行時有的機器上進行設定時很有用(例如為託管識別部署準備設定)。

azure-identity 在首次使用時透過 Hermes 的延遲安裝路徑自動安裝。要預先安裝:

pip install azure-identity

寫入 config.yaml 的設定

model:
  provider: azure-foundry
  base_url: https://my-resource.openai.azure.com/openai/v1
  api_mode: chat_completions
  auth_mode: entra_id
  default: gpt-4o
  context_length: 128000
  entra:
    scope: https://ai.azure.com/.default        # 僅在覆寫預設值時使用

Hermes 在 config.yaml 中只管理一個 Entra 專屬設定項:

  • scope — OAuth 資源範圍。預設為 Microsoft 文件記載的推論範圍(https://ai.azure.com/.default)。僅在你的資源使用非標準受眾時才覆寫。

其他所有設定(租戶、服務主體密鑰、聯合代碼檔、主權雲端授權端、代理偏好設定)由 azure-identity 直接從標準 AZURE_* 環境變數讀取 — 請參閱下方的認證解析順序。在 ~/.hermes/.env 或你的部署環境中設定它們,正如 Microsoft SDK 參考文件所述。

Entra 模式下沒有密鑰會進入 ~/.hermes/.envazure-identity 在行程內快取權杖(在可用時,存放在你的作業系統金鑰鏈 / ~/.IdentityService 中)。

認證解析順序

azure-identityDefaultAzureCredential 在每個權杖請求時遍歷此鏈,停在第一個傳回權杖的認證上:

  1. 環境認證AZURE_TENANT_ID + AZURE_CLIENT_ID + AZURE_CLIENT_SECRET(或 AZURE_CLIENT_CERTIFICATE_PATH / AZURE_FEDERATED_TOKEN_FILE)。
  2. 工作負載識別AZURE_FEDERATED_TOKEN_FILE(AKS 聯合權杖 / OIDC)。
  3. 託管識別 — 用於虛擬機器的 IMDS 端點(169.254.169.254);用於 App Service / Functions / Container Apps 的 IDENTITY_ENDPOINT。Foundry Agent Service 託管代理程式使用託管代理程式的代理程式識別。
  4. Visual Studio Code — Azure 帳戶擴充套件。
  5. Azure CLIaz login 工作階段。
  6. Azure Developer CLIazd auth login
  7. Azure PowerShellConnect-AzAccount
  8. 代理(僅限 Windows / WSL) — Web Account Manager。

互動式瀏覽器認證在無人值守的 Hermes 執行中預設被排除;請改用 Azure CLI、Azure Developer CLI、託管識別、工作負載識別或服務主體認證。

部署模式

本機開發:

az login
hermes model   # 選擇 Azure Foundry → Entra ID
hermes         # 使用你的 az login 權杖

Azure VM / Functions / App Service / Container Apps(系統指派的託管識別):

  1. 在運算資源上啟用系統指派的識別。
  2. 在 Foundry 資源上授予該識別 Azure AI User(或 Foundry User)。
  3. 在 config.yaml 中設定 model.auth_mode: entra_id — 不需要環境變數。

Azure VM / Functions / App Service / Container Apps(使用者指派的託管識別):

  • 設定 AZURE_CLIENT_ID 為使用者指派識別的客戶端 ID,以便 DefaultAzureCredential 選擇正確的識別。

Foundry Agent Service 託管代理程式:

  • 建立託管代理程式並在 Foundry 資源上授予該代理程式的識別 Azure AI User(或 Foundry User)。Hermes 從託管代理程式內部使用 ManagedIdentityCredential;角色指派屬於代理程式識別,而不僅是父專案或你的使用者。

AKS 工作負載識別(取代 AAD Pod Identity):

  • 使用工作負載識別客戶端 ID 為 Pod 的服務帳戶加註解。
  • Pod 的聯合代碼檔透過 AZURE_FEDERATED_TOKEN_FILE 自動偵測。
  • model.auth_mode: entra_id 無需進一步設定變更即可運作。

CI 中的服務主體:

  • 在執行環境中設定 AZURE_TENANT_IDAZURE_CLIENT_IDAZURE_CLIENT_SECRET

主權雲端(Government、China)

匯出 AZURE_AUTHORITY_HOST(例如 https://login.microsoftonline.us 用於 Azure Government,https://login.partner.microsoftonline.cn 用於 Azure China)。azure-identity 直接讀取它。

健康檢查

hermes doctormodel.auth_mode: entra_id 時對 DefaultAzureCredential 執行 10 秒探測,報告哪個內部認證成功(環境變數存在、託管識別端點可達等)。

hermes auth 顯示結構化狀態區塊:

azure-foundry (Microsoft Entra ID):
  Endpoint: https://my-resource.openai.azure.com/openai/v1
  Scope: https://ai.azure.com/.default
  Status: configured; live token probe is skipped here

限制

  • Anthropic 風格端點使用 httpx 事件鉤子。 Anthropic Python SDK 原生不接受可呼叫的 auth_token(≤ 0.86.0)。Hermes 在自訂 httpx.Client 上安裝請求事件鉤子,為每個出站請求鑄造新的 JWT 並重寫 Authorization: Bearer <jwt>。這在功能上等同於 OpenAI SDK 的原生 Callable[[], str] 契約,但增加了一層間接。如果 Anthropic SDK 在未來版本中新增一級可呼叫認證支援,Hermes 將透明地切換。
  • 批次作業和 multiprocessing.Pool Entra 權杖提供者是一個無法跨行程界線 pickle 的閉包。batch_runner.py 自動從工作者設定中移除可呼叫物件,讓每個工作者行程從 config.yaml 重建自己的提供者 — 無需使用者操作,但每個工作者在啟動時付出一次鏈遍歷的代價。
  • auth.json 中沒有承載 JWT 持久化。 Hermes 不複製 azure-identity 的內部權杖快取;冷啟動在首次推論時遍歷認證鏈。

設定(寫入 config.yaml

執行精靈後你會看到類似這樣的內容:

model:
  provider: azure-foundry
  base_url: https://my-resource.openai.azure.com/openai/v1
  api_mode: chat_completions         # 或 "anthropic_messages"
  default: gpt-5.4-mini              # 你的部署 / 模型名稱
  context_length: 400000             # 自動偵測

以及在 ~/.hermes/.env 中:

AZURE_FOUNDRY_API_KEY=<your-azure-key>

OpenAI 風格端點(GPT、Llama 等)

Azure OpenAI 的 v1 GA 端點接受標準 openai Python 用戶端,只需最少的變更:

model:
  provider: azure-foundry
  base_url: https://my-resource.openai.azure.com/openai/v1
  api_mode: chat_completions
  default: gpt-5.4

重要行為:

  • GPT-5.x、codex 和 o 系列自動路由到 Responses API。 Microsoft Foundry 將 GPT-5 / codex / o1 / o3 / o4 模型部署為僅限 Responses API — 對它們呼叫 /chat/completions 會傳回 400 "The requested operation is unsupported."。Hermes 透過名稱偵測這些模型系列並透明地將 api_mode 升級為 codex_responses,即使 config.yaml 仍顯示 api_mode: chat_completions。GPT-4、GPT-4o、Llama、Mistral 和其他部署保持在 /chat/completions
  • max_completion_tokens 自動使用。 Azure OpenAI(如同直接的 OpenAI)對 gpt-4o、o 系列和 gpt-5.x 模型需要 max_completion_tokens。Hermes 根據端點傳送正確的參數。
  • 需要 api-version 的 v1 之前端點。 如果你有類似 https://<resource>.openai.azure.com/openai?api-version=2025-04-01-preview 的傳統基礎 URL,Hermes 會提取查詢字串並在每個請求上透過 default_query 轉發(OpenAI SDK 在連接路徑時會丟棄它)。

Anthropic 風格端點(透過 Microsoft Foundry 的 Claude)

對於 Claude 部署,使用 Anthropic 風格路由:

model:
  provider: azure-foundry
  base_url: https://my-resource.services.ai.azure.com/anthropic
  api_mode: anthropic_messages
  default: claude-sonnet-4-6

重要行為:

  • /v1 從基礎 URL 中移除。 Anthropic SDK 在每個請求 URL 上附加 /v1/messages — Hermes 在將 URL 交給 SDK 之前移除任何尾部 /v1,以避免重複的 /v1 路徑。
  • api-version 透過 default_query 傳送,而非附加到 URL。 Azure Anthropic 需要 api-version 查詢字串。將其嵌入基礎 URL 會產生格式錯誤的路徑如 /anthropic?api-version=.../v1/messages 並傳回 404。Hermes 改為透過 Anthropic SDK 的 default_query 傳遞 api-version=2025-04-15
  • 使用承載認證而非 x-api-key Azure 的 Anthropic 相容路由需要 Authorization: Bearer <key> 而非 Anthropic 原生的 x-api-key 標頭。Hermes 在基礎 URL 中偵測 azure.com 並透過 SDK 的 auth_token 欄位路由 API 金鑰,使正確的標頭到達上游。
  • 1M 上下文視窗 Beta 標頭保留。 Azure 仍將 1M 代幣的 Claude 上下文(Opus 4.6/4.7、Sonnet 4.6)置於 anthropic-beta: context-1m-2025-08-07 標頭之後。Hermes 在 Azure 路徑上保留該 Beta 標頭(它從原生 Anthropic OAuth 請求中移除,因為某些訂閱會拒絕它,但 Azure 需要它)。
  • OAuth 權杖重新整理被停用。 Azure 部署使用靜態 API 金鑰。適用於 Anthropic Console 的 ~/.claude/.credentials.json OAuth 權杖重新整理迴圈在 Azure 端點上被明確跳過,以防止 Claude Code OAuth 權杖在工作階段中途覆蓋你的 Azure 金鑰。

替代方案:provider: anthropic + Azure 基礎 URL

如果你已經設定 provider: anthropic 且只想將其指向 Microsoft Foundry 使用 Claude,你可以完全跳過 azure-foundry 供應商:

model:
  provider: anthropic
  base_url: https://my-resource.services.ai.azure.com/anthropic
  key_env: AZURE_ANTHROPIC_KEY
  default: claude-sonnet-4-6

~/.hermes/.env 中設定 AZURE_ANTHROPIC_KEY。Hermes 在基礎 URL 中偵測 azure.com 並繞過 Claude Code OAuth 權杖鏈,使 Azure 金鑰直接與 x-api-key 認證一起使用。

key_env 是規範的 snake_case 欄位名稱;api_key_env(以及 camelCase keyEnv / apiKeyEnv)作為別名被接受。如果 key_envAZURE_ANTHROPIC_KEY/ANTHROPIC_API_KEY 都被設定,key_env 命名的環境變數優先。

模型發現

Azure 公開純 API 金鑰端點來列出你的已部署模型部署。部署列舉需要 Azure Resource Manager 認證(az cognitiveservices account deployment list)搭配 Azure AD 主體,而非推論 API 金鑰。

Hermes 能做的:

  • Azure OpenAI v1 端點(<resource>.openai.azure.com/openai/v1)公開 GET /models,傳回資源的可用模型目錄。Hermes 使用此清單填充模型選擇器。
  • Microsoft Foundry /anthropic 路由:透過 URL 路徑偵測,模型名稱手動輸入。
  • 私有 / 防火牆端點:手動輸入並附帶友善的「無法探測」訊息。

你隨時可以直接輸入部署名稱 — Hermes 不會根據傳回的清單進行驗證。

環境變數

變數用途
AZURE_FOUNDRY_API_KEYMicrosoft Foundry / Azure OpenAI 的主要 API 金鑰(api_key 模式)
AZURE_FOUNDRY_BASE_URL端點 URL(透過 hermes model 設定;環境變數作為備用)
AZURE_ANTHROPIC_KEY用於 provider: anthropic + Azure 基礎 URL(ANTHROPIC_API_KEY 的替代方案)
AZURE_TENANT_ID服務主體流程的 Entra ID 租戶
AZURE_CLIENT_IDEntra ID 客戶端 ID(服務主體、工作負載識別或使用者指派的託管識別)
AZURE_CLIENT_SECRET服務主體密鑰
AZURE_CLIENT_CERTIFICATE_PATH服務主體憑證(密鑰的替代方案)
AZURE_FEDERATED_TOKEN_FILE工作負載識別聯合代碼路徑(AKS)
AZURE_AUTHORITY_HOST主權雲端授權主機覆寫
IDENTITY_ENDPOINT / MSI_ENDPOINTApp Service、Functions 和 Container Apps 的託管識別端點;虛擬機器通常改用 IMDS

Azure SDK 直接讀取 AZURE_* 環境變數。Hermes 除了在 hermes doctor 輸出中報告哪些來源存在之外,不會檢查它們。

疑難排解

gpt-5.x 部署上出現 401 Unauthorized。 Azure 在 /chat/completions 上提供 gpt-5.x,而非 /responses。當 URL 包含 openai.azure.com 時 Hermes 會自動處理此問題,但如果你看到 401 且內容為 Invalid API key,請檢查 config.yaml 中的 api_mode 是否為 chat_completions

/v1/messages?api-version=.../v1/messages 出現 404。 這是修復前的 Azure Anthropic 設定的格式錯誤 URL 問題。升級 Hermes — api-version 參數現在透過 default_query 傳遞而非嵌入基礎 URL,因此 SDK 在 URL 連接時無法損壞它。

精靈顯示「Auto-detection incomplete。」 端點拒絕了 /models 探測和 Anthropic Messages 探測。對於防火牆後或有 IP 允許清單的私有端點,這是正常的。退回手動 API 模式選擇並輸入你的部署名稱 — 一切仍然運作,Hermes 只是無法填充選擇器。

選擇了錯誤的傳輸方式。 再次執行 hermes model,精靈會重新探測。如果探測仍然選擇錯誤的模式,你可以直接編輯 config.yaml

model:
  provider: azure-foundry
  api_mode: anthropic_messages   # 或 chat_completions

Entra ID:切換到 auth_mode: entra_id 後出現「credential chain exhausted」或 401 Unauthorized。

  • 執行 az login 刷新你的開發者工作階段(快取的權杖可能已過期)。
  • 驗證 Azure AI User(或 Foundry User)角色指派是否生效:az role assignment list --assignee <user-or-identity-id> 應該在你的 Foundry 資源上列出它。角色傳播最多需要 5 分鐘。
  • 對於使用者指派的託管識別,仔細檢查 AZURE_CLIENT_ID 是否與附加到運算資源的識別相符。
  • 執行 hermes doctor — Azure Entra 探測報告權杖取得是否成功,並包含修復提示。

Entra ID:精靈預檢掛起或逾時。 10 秒預檢是軟性檢查。選擇「仍然儲存,稍後驗證」並在部署到目標環境後執行 hermes doctor。常見原因包括不可達的代碼服務或過時的本機登入狀態 — 在 CI 中優先使用工作負載識別,使用服務主體時設定 AZURE_TENANT_ID+AZURE_CLIENT_ID+AZURE_CLIENT_SECRET,或為本機開發執行 az login

使用 Entra ID 時 Anthropic 風格端點出現 401。 驗證相同的 Azure AI User(或 Foundry User)角色已指派到 Foundry 資源(它涵蓋 /openai/v1/anthropic 路徑)。如果在精靈期間 OpenAI 風格探測有效但 claude-* 請求在運行時失敗,最常見的原因是較早的精靈執行留下的過時 model.entra.scope — 從 config.yaml 中刪除 entra.scope 行,使運行時回到預設的 https://ai.azure.com/.default 範圍。

相關



僅限腳本的定時任務(無 LLM)