跳到主要內容

Microsoft Foundry

Hermes Agent 的 azure-foundry 提供程序支持 Microsoft Foundry(前身為 Azure AI Foundry)和 Azure OpenAI。單個 Foundry 資源可以託管具有兩種不同線路格式(wire formats)的模型:

  • 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 門戶的“Keys and Endpoint”下獲取),要麼如果你計劃使用 Microsoft Entra ID(微軟推薦的無密鑰路徑),則需要擁有該 Foundry 資源上的 Azure AI User RBAC 角色。在微軟的重命名推廣期間,某些租戶可能將該角色顯示為 Foundry User

快速入門

hermes model
# → Select "Azure Foundry"
# → Enter your endpoint URL
# → Choose Authentication:
# 1. API key
# 2. Microsoft Entra ID (managed identity / workload identity / az login)
# → (Entra) Hermes probes DefaultAzureCredential; on success it never asks for a key
# → (API key) Enter your API key
# Hermes probes the endpoint and auto-detects transport + models
# → Pick a model from the list (or type a deployment name manually)

嚮導將執行以下操作:

  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 中,以便模型能夠正確調整其上下文窗口的大小。

微軟建議在生產環境的 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),並且微軟為兩者記錄了相同的推理範圍(https://ai.azure.com/.default)。在底層:

  • OpenAI 風格使用 OpenAI Python SDK 原生的可調用 api_key= 契約 — SDK 會自動為每個請求生成一個新的 JWT。
  • Anthropic 風格使用帶有由 agent.azure_identity_adapter.build_bearer_http_client 安裝的請求事件鉤子的 httpx.Client,因為 Anthropic SDK 原生不支持可調用 auth_token。該鉤子會在每個出站請求中重寫 Authorization: Bearer <fresh-jwt>。相同的微軟 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 門戶中,打開你的 Foundry 資源 → Access control (IAM)Add → Add role assignment
  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
# → Select "Azure Foundry"
# → Enter your endpoint URL
# → Authentication: 2 (Microsoft Entra ID)
# → (optional) user-assigned managed identity client ID
# → (optional) Azure tenant ID
# → Hermes probes DefaultAzureCredential() and reports which inner
# credential succeeded (e.g. 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 # only when overriding the default

Hermes 僅在 config.yaml 中管理一個特定於 Entra 的選項:

  • scope — OAuth 資源範圍。默認為 Microsoft 文檔中記錄的推理範圍(https://ai.azure.com/.default)。僅當你的資源是針對非標準受眾配置時,才需要覆蓋此值。

其他所有內容(租戶、服務主體密鑰、聯合令牌文件、主權雲權威機構、代理偏好)均由 azure-identity 直接從標準的 AZURE_* 環境變量中讀取——請參閱下方的憑據解析順序。請按照 Microsoft SDK 參考文檔的描述,在 ~/.hermes/.env 或你的部署環境中設置這些變量。

在 Entra 模式下,~/.hermes/.env 中不會存儲任何機密信息——azure-identity 會在進程內緩存令牌(如果可用,還會緩存在操作系統密鑰鏈或 ~/.IdentityService 中)。

憑據解析順序

azure-identityDefaultAzureCredential 在每次令牌請求時會遍歷以下鏈,並在第一個返回令牌的憑據處停止:

  1. 環境變量憑據AZURE_TENANT_ID + AZURE_CLIENT_ID + AZURE_CLIENT_SECRET(或 AZURE_CLIENT_CERTIFICATE_PATH / AZURE_FEDERATED_TOKEN_FILE)。
  2. 工作負載標識 (Workload Identity)AZURE_FEDERATED_TOKEN_FILE(AKS 聯合令牌 / OIDC)。
  3. 託管標識 (Managed Identity) — 虛擬機的 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. 代理 (Broker)(僅限 Windows / WSL)— Web Account Manager。

默認情況下,無人值守的 Hermes 運行排除交互式瀏覽器憑據;請改用 Azure CLI、Azure Developer CLI、託管標識、工作負載標識或服務主體憑據。

部署模式

本地開發:

az login
hermes model # pick Azure Foundry → Entra ID
hermes # uses your az login token

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

主權雲(政府雲、中國雲)

導出 AZURE_AUTHORITY_HOST(例如,Azure Government 為 https://login.microsoftonline.us,Azure China 為 https://login.partner.microsoftonline.cn)。azure-identity 會直接讀取該變量。

健康檢查

model.auth_mode: entra_id 時,hermes doctor 會對 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 中不持久保存 bearer JWT。 Hermes 不會複製 azure-identity 的內部令牌緩存;冷啟動時在首次推理時會遍歷憑據鏈。

配置(寫入 config.yaml

運行嚮導後,你將看到類似以下內容:

model:
provider: azure-foundry
base_url: https://my-resource.openai.azure.com/openai/v1
api_mode: chat_completions # or "anthropic_messages"
default: gpt-5.4-mini # your deployment / model name
context_length: 400000 # auto-detected

以及在 ~/.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

重要行為:

  • 從基礎 URL 中剝離 /v1 Anthropic SDK 會將 /v1/messages 附加到每個請求 URL 後面 —— 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
  • 使用 Bearer 認證而非 x-api-key Azure 的 Anthropic 兼容路由要求使用 Authorization: Bearer <key>,而不是 Anthropic 原生的 x-api-key 標頭。Hermes 檢測到基礎 URL 中包含 azure.com 時,會將 API 密鑰通過 SDK 的 auth_token 字段進行路由,以確保正確的標頭到達上游。
  • 保留 1M 上下文窗口 Beta 標頭。 Azure 仍然通過 anthropic-beta: context-1m-2025-08-07 標頭對 1M token 的 Claude 上下文(Opus 4.6/4.7、Sonnet 4.6)進行 gating。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 令牌鏈,直接使用 x-api-key 認證方式使用 Azure 密鑰。

key_env 是規範的 snake_case 字段名稱;api_key_env(以及 camelCase 形式的 keyEnv / apiKeyEnv)作為別名被接受。如果同時設置了 key_envAZURE_ANTHROPIC_KEY/ANTHROPIC_API_KEY,則以 key_env 命名的環境變量優先。

模型發現

Azure 暴露僅使用 API 密鑰即可列出已部署模型的端點。枚舉部署需要通過 Azure AD 主體進行 Azure Resource Manager 身份驗證(az cognitiveservices account deployment list),而不是使用推理 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_KEYprovider: 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 的託管標識端點;VM 通常改用 IMDS

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

故障排除

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

/v1/messages?api-version=.../v1/messages 出現 404。 這是修復前 Azure Anthropic 設置中的 malformed-URL(URL 格式錯誤)bug。升級 Hermes — api-version 參數現在通過 default_query 傳遞,而不是硬編碼到基礎 URL 中,因此 SDK 在連接 URL 時不會破壞它。

嚮導顯示“自動檢測不完整。” 端點拒絕了 /models 探測和 Anthropic Messages 探測。對於位於防火牆後或具有 IP 允許列表的私有端點,這是正常現象。回退到手動 API 模式選擇並輸入你的部署名稱 — 一切仍然有效,只是 Hermes 無法預填充選擇器。

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

model:
provider: azure-foundry
api_mode: anthropic_messages # or 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。 驗證 Foundry 資源上是否分配了相同的 Azure AI User(或 Foundry User)角色(它涵蓋 /openai/v1/anthropic 路徑)。如果嚮導期間 OpenAI 風格探測成功,但 claude-* 請求在運行時失敗,最常見的原因是早期嚮導運行留下的過時 model.entra.scope — 從 config.yaml 中刪除 entra.scope 行,以便運行時回退到默認的 https://ai.azure.com/.default 範圍。