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 探測端點並自動偵測傳輸方式 + 模型
# → 從清單中選擇一個模型(或手動輸入部署名稱)
精靈會:
- 嗅探 URL 路徑 — 以
/anthropic結尾的 URL 會被識別為 Microsoft Foundry Claude 路由。 - 探測
GET <base>/models— 如果端點傳回 OpenAI 格式的模型清單,Hermes 會切換到chat_completions並用傳回的部署 ID 填充選擇器。 - 探測 Anthropic Messages 格式 — 當端點未公開
/models但接受 Anthropic Messages 格式時的備用方案。 - 退回手動輸入 — 私有/受保護端點拒絕所有探測仍可運作;你選擇 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 端)
- 在 Azure Portal 中,開啟你的 Foundry 資源 → 存取控制 (IAM) → 新增 → 新增角色指派。
- 選擇 Azure AI User 角色(如果你的租戶有重新命名的角色則選擇 Foundry User)。
- 指派給:
- 你的使用者帳戶,用於搭配
az login進行本機開發。 - 託管識別或工作負載識別,用於 Azure 託管的運算資源(生產環境建議)。
- Foundry Agent Service 託管代理程式的代理程式識別,當 Hermes 在託管代理程式中運行時。
- 服務主體,用於工作負載識別不可用時的 CI/CD 管線。
- 你的使用者帳戶,用於搭配
- 等待約 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/.env — azure-identity 在行程內快取權杖(在可用時,存放在你的作業系統金鑰鏈 / ~/.IdentityService 中)。
認證解析順序
azure-identity 的 DefaultAzureCredential 在每個權杖請求時遍歷此鏈,停在第一個傳回權杖的認證上:
- 環境認證 —
AZURE_TENANT_ID+AZURE_CLIENT_ID+AZURE_CLIENT_SECRET(或AZURE_CLIENT_CERTIFICATE_PATH/AZURE_FEDERATED_TOKEN_FILE)。 - 工作負載識別 —
AZURE_FEDERATED_TOKEN_FILE(AKS 聯合權杖 / OIDC)。 - 託管識別 — 用於虛擬機器的 IMDS 端點(
169.254.169.254);用於 App Service / Functions / Container Apps 的IDENTITY_ENDPOINT。Foundry Agent Service 託管代理程式使用託管代理程式的代理程式識別。 - Visual Studio Code — Azure 帳戶擴充套件。
- Azure CLI —
az login工作階段。 - Azure Developer CLI —
azd auth login。 - Azure PowerShell —
Connect-AzAccount。 - 代理(僅限 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(系統指派的託管識別):
- 在運算資源上啟用系統指派的識別。
- 在 Foundry 資源上授予該識別
Azure AI User(或Foundry User)。 - 在 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_ID、AZURE_CLIENT_ID、AZURE_CLIENT_SECRET。
主權雲端(Government、China)
匯出 AZURE_AUTHORITY_HOST(例如 https://login.microsoftonline.us 用於 Azure Government,https://login.partner.microsoftonline.cn 用於 Azure China)。azure-identity 直接讀取它。
健康檢查
hermes doctor 在 model.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.jsonOAuth 權杖重新整理迴圈在 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_env 和 AZURE_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_KEY | Microsoft 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_ID | Entra ID 客戶端 ID(服務主體、工作負載識別或使用者指派的託管識別) |
AZURE_CLIENT_SECRET | 服務主體密鑰 |
AZURE_CLIENT_CERTIFICATE_PATH | 服務主體憑證(密鑰的替代方案) |
AZURE_FEDERATED_TOKEN_FILE | 工作負載識別聯合代碼路徑(AKS) |
AZURE_AUTHORITY_HOST | 主權雲端授權主機覆寫 |
IDENTITY_ENDPOINT / MSI_ENDPOINT | App 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 範圍。
相關
- 環境變數
- 設定
- AWS Bedrock — 另一個主要雲端供應商整合
- Microsoft:為 Foundry 設定 Entra ID — 無金鑰路徑的上游文件