212 212
213### `upstreams`213### `upstreams`
214 214
215`upstreams` 是一個有序清單。閘道將推論轉發到解析所請求模型的第一個上游。215`upstreams` 是有序清單。閘道會將推論轉送到第一個能解析所請求模型的上游,並略過任何其 [`groups` 清單](#send-each-team-to-its-own-upstream)不包含該開發人員的上游。
216 216
217在 `5xx`、`429`、`401`、`403`、`404` 或逾時時,閘道會故障轉移到下一個上游;其他 `4xx` 不會,因為這些錯誤可歸因於請求而不是上游。`401` 或 `403` 表示上游拒絕了閘道使用的憑證,或拒絕其存取,例如存取所請求的模型。`404` 表示該上游不服務所請求的模型,因此清單中稍後的上游仍然可以。217在 `5xx`、`429`、`401`、`403`、`404` 或逾時時,閘道會故障轉移到下一個上游;其他 `4xx` 不會,因為這些錯誤可歸因於請求而不是上游。`401` 或 `403` 表示上游拒絕了閘道使用的憑證,或拒絕其存取,例如存取所請求的模型。`404` 表示該上游不服務所請求的模型,因此清單中稍後的上游仍然可以。
218 218
229閘道返回一個上游的錯誤回應,或其自己的 `502`,取決於上游如何回答:229閘道返回一個上游的錯誤回應,或其自己的 `502`,取決於上游如何回答:
230 230
231* **上游返回閘道不[故障轉移](#multiple-upstreams)的狀態**:該上游的回應。閘道不嘗試進一步的上游。231* **上游返回閘道不[故障轉移](#multiple-upstreams)的狀態**:該上游的回應。閘道不嘗試進一步的上游。
232* **閘道嘗試的每個上游都以閘道[故障轉移](#multiple-upstreams)的方式失敗**:最後一個 `429`。當沒有返回 `429` 時,閘道依序優先選擇最後一個 `401` 或 `403`、最後一個 `404` 和最後一個 `501`。當沒有返回任何這些時,則為閘道自己的 `502`,`all upstreams failed (N attempted)`,其中 N 計算 [`upstreams`](#upstreams) 中的每個項目,包括閘道因不服務所請求模型而跳過的項目。232* **閘道嘗試的每個上游都以會[觸發容錯移轉](#multiple-upstreams)的方式失敗**:回傳最後一個 `429`。若沒有任何上游回傳 `429`,閘道會依序優先採用最後一個 `401` 或 `403`、最後一個 `404`,以及最後一個 `501`。若這些都沒有,則回傳閘道自己的 `502`,`all upstreams failed (N attempted)`。N 計算的是您的 [`upstreams`](#upstreams) 項目數(包括被略過的項目),減去其 [`groups`](#send-each-team-to-its-own-upstream) 清單不包含該開發人員的項目。
233 233
234當閘道返回上游的回應時,它保持上游的狀態碼。它是否保持上游的訊息取決於提供者。Anthropic API 上游的錯誤正文未經更改地到達開發人員。234當閘道返回上游的回應時,它保持上游的狀態碼。它是否保持上游的訊息取決於提供者。Anthropic API 上游的錯誤正文未經更改地到達開發人員。
235 235
287 base_url: https://upstream-gateway.internal.example.com287 base_url: https://upstream-gateway.internal.example.com
288 auth:288 auth:
289 api_key: ${PROXY_KEY}289 api_key: ${PROXY_KEY}
290 forward_user_identity: true # 預設 false290 forward_user_identity: true # default false
291```291```
292 292
293閘道將這些標頭新增到它轉發到該上游的每個請求。293閘道將這些標頭新增到它轉發到該上游的每個請求。
318upstreams:318upstreams:
319 - provider: bedrock319 - provider: bedrock
320 region: us-east-1320 region: us-east-1
321 auth: {} # 首選:AWS 預設憑證鏈321 auth: {} # preferred: AWS default credential chain
322 # 或明確憑證:322 # OR explicit credentials:
323 # auth:323 # auth:
324 # aws_access_key_id: ${AWS_AKID}324 # aws_access_key_id: ${AWS_AKID}
325 # aws_secret_access_key: ${AWS_SK}325 # aws_secret_access_key: ${AWS_SK}
326 # aws_session_token: ${AWS_ST}326 # aws_session_token: ${AWS_ST}
327 # 或 Bedrock API 持有人 token:327 # OR a Bedrock API bearer token:
328 # auth:328 # auth:
329 # aws_bearer_token: ${AWS_BEARER_TOKEN}329 # aws_bearer_token: ${AWS_BEARER_TOKEN}
330 # 覆寫 bedrock-runtime 端點以進行 FIPS 或 VPC 端點部署:330 # Override the bedrock-runtime endpoint for FIPS or VPC-endpoint deployments:
331 # base_url: https://bedrock-runtime-fips.us-east-1.amazonaws.com331 # base_url: https://bedrock-runtime-fips.us-east-1.amazonaws.com
332```332```
333 333
354 region: us-east-1354 region: us-east-1
355 auth: {}355 auth: {}
356 guardrail:356 guardrail:
357 id: gr-abc123 # 防護欄 ID 或完整 ARN357 id: gr-abc123 # guardrail ID or full ARN
358 version: "1" # 已發佈的版本號,或 DRAFT358 version: "1" # a published version number, or DRAFT
359 # 保留引號:裸露的 1 在啟動時失敗359 # keep the quotes: a bare 1 fails at boot
360```360```
361 361
362> [!WARNING]
363>
364> 閘道不支援防護欄輸入標籤。它不向提示詞新增防護內容標籤,因此 Amazon Bedrock 僅應用於標籤輸入的防護欄篩選器不會在透過閘道的流量上執行。對於哪些篩選器取決於輸入標籤,請參閱 Amazon Bedrock 文件中的[輸入標籤](https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails-tagging.html)。
365
366也將該防護欄上的 `bedrock:ApplyGuardrail` 授予簽署此上游請求的主體:閘道的 AWS 主體,或使用 [`assume_role`](#bedrock-in-another-aws-account) 時 `role_arn` 中命名的角色。362也將該防護欄上的 `bedrock:ApplyGuardrail` 授予簽署此上游請求的主體:閘道的 AWS 主體,或使用 [`assume_role`](#bedrock-in-another-aws-account) 時 `role_arn` 中命名的角色。
367 363
368在每個 `bedrock` 上游上都設定 `guardrail`,或都不設定。閘道在混合設定時拒絕啟動,因為[故障轉移](#multiple-upstreams)可能會將請求傳送到沒有防護欄的 Bedrock 上游。364在每個 `bedrock` 上游上都設定 `guardrail`,或都不設定。閘道在混合設定時拒絕啟動,因為[故障轉移](#multiple-upstreams)可能會將請求傳送到沒有防護欄的 Bedrock 上游。
371 367
372當 `/v1/messages` 請求的正文攜帶 `amazon-bedrock-*` 欄位(例如 `amazon-bedrock-guardrailConfig`)到達設定了 `guardrail` 的 Bedrock 上游時,閘道答覆 400 而不是轉發它。368當 `/v1/messages` 請求的正文攜帶 `amazon-bedrock-*` 欄位(例如 `amazon-bedrock-guardrailConfig`)到達設定了 `guardrail` 的 Bedrock 上游時,閘道答覆 400 而不是轉發它。
373 369
370> [!WARNING]
371>
372> 閘道預設不會為提示詞加入輸入標籤,因此 Amazon Bedrock 只對已標記輸入套用的 guardrail 篩選器,不會在經由閘道的流量上執行。若要加入標籤,請設定 [`input_tagging`](#add-guardrail-input-tags)。關於哪些篩選器依賴輸入標籤,請參閱 Amazon Bedrock 文件中的[輸入標籤](https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails-tagging.html)。
373
374##### 加入 guardrail 輸入標籤
375
376若要讓閘道加入 Amazon Bedrock guardrail 之[提示詞攻擊篩選器](https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails-prompt-attack.html)所需的輸入標籤,請在 `guardrail` 區塊中設定 `input_tagging`,然後重新啟動閘道。請在每個 `bedrock` 上游設定相同的值,否則閘道會拒絕啟動。需要閘道伺服器上的 Claude Code v2.1.316 或更新版本。不支援此鍵之版本的閘道會在啟動時以 `Unrecognized key(s) in object: 'input_tagging'` 結束。
377
378> [!WARNING]
379>
380> 根據 [Amazon Bedrock 的文件](https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails-tagging.html),一旦請求帶有輸入標籤,guardrail 中的每個篩選器都會停止評估未標記的內容。在開發者使用的閘道上設定 `input_tagging` 之前,請先在測試閘道上試用。
381
382`input_tagging` 接受下列其中一個值:
383
384| `input_tagging` | 閘道標記文字的位置 | guardrail 封鎖提示詞之後 |
385| :- | :- | :- |
386| `last_message` | 自 Claude 上次回覆以來的 `user` 訊息 | 在 Claude Code 中,下一個提示詞可能通過,而 Claude 隨後會在對話中收到被封鎖的提示詞 |
387| `user_messages` | `user` 訊息 | 工作階段中後續的提示詞也可能被封鎖,直到開發者移除被封鎖的提示詞為止 |
388| `all_messages` | `user` 與 `assistant` 訊息 | 與 `user_messages` 相同 |
389| `all_messages_and_system` | 系統提示詞與每則訊息,包括[對話中途的系統訊息](https://code.claude.com/docs/zh-TW/llm-gateway-protocol.md#feature-pass-through) | 與 `user_messages` 相同 |
390
391採用 `last_message` 時,若自 Claude 上次回覆以來的 `user` 訊息中沒有可標記的文字,閘道會改為標記自該回覆以來的對話中途系統訊息。工具呼叫也算是一次回覆。
392
393Amazon Bedrock 對提示詞攻擊篩選器的建議是[標記使用者輸入,以排除系統提示詞](https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails-prompt-attack.html)。若您設定 `all_messages_and_system`,會標記 Claude Code 自身系統提示詞的篩選器可能會封鎖請求。
394
395下列範例會標記每則 `user` 訊息中的文字:
396
397```yaml theme={null}
398upstreams:
399 - provider: bedrock
400 region: us-east-1
401 auth: {}
402 guardrail:
403 id: gr-abc123
404 version: "1"
405 input_tagging: user_messages
406```
407
408`user` 訊息也可能包含 Claude Code 加入的文字,例如[系統提醒](https://code.claude.com/docs/zh-TW/glossary.md#system-reminder),因此請在測試閘道上確認一般請求不會被封鎖。
409
410在 Anthropic 的測試中,已標記的工作階段在各提示詞之間保留了[提示快取](https://code.claude.com/docs/zh-TW/prompt-caching.md)讀取,且標籤沒有增加任何輸入 token。
411
412##### 輸入標籤未涵蓋的內容
413
414沒有任何 `input_tagging` 值能阻止刻意將文字放在無標籤位置的開發者。請勿期待 guardrail 會評估請求的下列部分:
415
416* **閘道不會標記的內容**:您的 `input_tagging` 值所排除的訊息、工具定義、工具呼叫輸入、圖片與 PDF 等。除非您設定 `all_messages_and_system`,否則系統提示詞也不會被標記。
417* **工具結果**:這些是 Claude 的工具所回傳的內容,例如檔案內容與網頁。在 Anthropic 的測試中,無論有無標籤,字詞篩選器都不會評估它們。
418
419若您的 AWS 帳戶或組織強制執行 guardrail,關於該 guardrail 如何處理輸入標籤,請參閱 [Amazon Bedrock 的文件](https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails-enforcements.html)。
420
421##### 記錄觸發了哪個 guardrail 篩選器
422
423若要找出是哪個 Amazon Bedrock guardrail 篩選器封鎖了開發人員的請求,請在 Bedrock 上游設定 `guardrail_trace: true`、重新啟動閘道,並請開發人員再次傳送請求。然後在[稽核日誌](https://code.claude.com/docs/zh-TW/claude-apps-gateway-deploy.md#logs)中找到該請求的 `guardrail.trace` 事件。閘道伺服器需要 Claude Code v2.1.314 或更新版本。較早的閘道發現 `guardrail_trace` 時會拒絕啟動。
424
425```yaml theme={null}
426upstreams:
427 - provider: bedrock
428 region: us-east-1
429 auth: {}
430 guardrail:
431 id: gr-abc123
432 version: "1"
433 guardrail_trace: true # default false; beside guardrail, not inside it
434```
435
436當篩選器觸發或 guardrail 的動作為 `INTERVENED` 時,閘道會寫入一個不含相符文字的 `guardrail.trace` 事件。請依 `email` 或 `sub` 找出開發人員的事件。一個串流請求可能產生多個事件,其中一個可能具有空的 `filters` 清單,因此請讀取具有相同 `request_id` 的每個事件:
437
438| 欄位 | 內容 |
439| - | - |
440| `request_id` | 請求的 ID |
441| `sub`, `email` | 開發人員的使用者 ID 與電子郵件 |
442| `upstream` | 回覆來自的上游 |
443| `action` | guardrail 的動作,例如 `INTERVENED` |
444| `filters` | 觸發的篩選器。AWS 未傳送篩選器詳細資料時,清單為空 |
445| `filters[].side` | `input` 或 `output` |
446| `filters[].guardrail` | guardrail 的 ID |
447| `filters[].policy` | Bedrock 政策與清單,例如 `contentPolicy.filters` 或 `sensitiveInformationPolicy.piiEntities` |
448| 其他 `filters[]` 欄位 | 項目也可能帶有 `action`、`name`、`type`、`confidence`、`filterStrength`、`score` 與 `threshold` 等欄位 |
449
450事件不包含篩選器比對到的文字,包括 Bedrock 追蹤中的 `match` 欄位。開發人員不會收到 Bedrock 的追蹤資料,因為閘道會從每個回覆中移除它,無論是否為串流。
451
452若用戶端在 `/v1/messages` 請求內容中傳送 `amazon-bedrock-*` 欄位,閘道會在設定了 `guardrail_trace` 的上游上回應 400。
453
374##### 另一個 AWS 帳戶中的 Bedrock454##### 另一個 AWS 帳戶中的 Bedrock
375 455
376在 Bedrock 上游上設定 `assume_role`,閘道僅使用其自己的 AWS 身分識別來呼叫您命名的角色上的 `sts:AssumeRole`,該角色可以在與閘道不同的 AWS 帳戶中。該上游的每個 Bedrock 請求都使用 STS 返回的一小時憑證簽署,因此沒有長期存取金鑰跨帳戶。456在 Bedrock 上游上設定 `assume_role`,閘道僅使用其自己的 AWS 身分識別來呼叫您命名的角色上的 `sts:AssumeRole`,該角色可以在與閘道不同的 AWS 帳戶中。該上游的每個 Bedrock 請求都使用 STS 返回的一小時憑證簽署,因此沒有長期存取金鑰跨帳戶。
382 - name: bedrock-isolated462 - name: bedrock-isolated
383 provider: bedrock463 provider: bedrock
384 region: us-east-1464 region: us-east-1
385 auth: {} # 閘道自己的角色:它僅呼叫 STS465 auth: {} # the gateway's own role: it only calls STS
386 assume_role:466 assume_role:
387 role_arn: arn:aws:iam::222222222222:role/claude-gateway-bedrock467 role_arn: arn:aws:iam::222222222222:role/claude-gateway-bedrock
388 # external_id: ${BEDROCK_ROLE_EXTERNAL_ID} # 當角色的信任原則需要時468 # external_id: ${BEDROCK_ROLE_EXTERNAL_ID} # when the role's trust policy requires one
389```469```
390 470
391`assume_role` 區塊採用三個鍵:471`assume_role` 區塊採用三個鍵:
413* 如果 STS 拒絕或無法到達,閘道不會使用上游自己的憑證傳送請求。它記錄 STS 錯誤以及要檢查的內容,然後嘗試您列出的下一個上游。[上游錯誤訊息](#upstream-error-messages)涵蓋當沒有上游成功時用戶端接收的內容。沒有 `assume_role` 的稍後上游會使用其自己的憑證服務請求,因此僅在這是您想要的情況下才列出這樣的上游。493* 如果 STS 拒絕或無法到達,閘道不會使用上游自己的憑證傳送請求。它記錄 STS 錯誤以及要檢查的內容,然後嘗試您列出的下一個上游。[上游錯誤訊息](#upstream-error-messages)涵蓋當沒有上游成功時用戶端接收的內容。沒有 `assume_role` 的稍後上游會使用其自己的憑證服務請求,因此僅在這是您想要的情況下才列出這樣的上游。
414* 閘道呼叫區域 STS 端點 `sts.<region>.amazonaws.com`,其網路必須能到達。對於 FIPS 端點,在閘道的環境中設定 `AWS_USE_FIPS_ENDPOINT=true`,而不是在 AWS 設定檔中設定 `use_fips_endpoint`。494* 閘道呼叫區域 STS 端點 `sts.<region>.amazonaws.com`,其網路必須能到達。對於 FIPS 端點,在閘道的環境中設定 `AWS_USE_FIPS_ENDPOINT=true`,而不是在 AWS 設定檔中設定 `use_fips_endpoint`。
415* `assume_role` 僅適用於 `provider: bedrock` 並需要 SigV4 來源憑證:當它與 `aws_bearer_token` 一起設定時,閘道拒絕啟動。495* `assume_role` 僅適用於 `provider: bedrock` 並需要 SigV4 來源憑證:當它與 `aws_bearer_token` 一起設定時,閘道拒絕啟動。
416* 閘道允許的每個開發人員都可以使用此上游;[`managed`](#managed) 控制哪些開發人員可以使用哪些模型。若要避免透過該角色服務的模型也從另一個帳戶服務,請給它一個自訂 id,其 `upstream_model` 對應僅具有此上游的名稱。對於這樣的 id,閘道跳過每個其他上游,因此請求和已放棄請求的 token 計數都無法故障轉移到另一個帳戶。內建模型名稱的請求仍可能[到達此上游](#multiple-upstreams),且閘道會使用相同角色簽署它。除非其帳戶也應該服務這些模型,否則請將此上游列在最後。496* 若沒有 [`groups` 清單](#send-each-team-to-its-own-upstream),閘道允許的每位開發人員都可以使用此上游。若要限制開發人員可使用的模型,請在 [`managed`](#managed) 政策中設定 `availableModels`。
497* 若要讓透過該角色提供的模型不會同時由另一個帳戶提供,請為其指定一個自訂 id,且其 `upstream_model` 對應只包含此上游的名稱。對於這樣的 id,閘道會略過所有其他上游,因此無論是請求本身,還是中止請求的 token 計數,都不會容錯移轉到另一個帳戶。
498* 對內建模型名稱的請求仍可能[送達此上游](#multiple-upstreams),且閘道會以同一角色簽署。除非其帳戶也應提供這些模型,否則請將此上游列在最後。
417 499
418此範例給一個模型一個僅由隔離上游服務的自訂 id:500此範例給一個模型一個僅由隔離上游服務的自訂 id:
419 501
420```yaml theme={null}502```yaml theme={null}
421models:503models:
422 - id: restricted-claude-opus-4-8 # 自訂 id,不是內建模型名稱504 - id: restricted-claude-opus-4-8 # a custom id, not a built-in model name
423 upstream_model:505 upstream_model:
424 bedrock-isolated: us.anthropic.claude-opus-4-8 # 唯一服務它的上游506 bedrock-isolated: us.anthropic.claude-opus-4-8 # the only upstream that serves it
425```507```
426 508
427##### 每個開發人員 AWS 成本歸因509##### 每個開發人員 AWS 成本歸因
434upstreams:516upstreams:
435 - provider: bedrock517 - provider: bedrock
436 region: us-east-1518 region: us-east-1
437 auth: {} # 閘道自己的角色:它僅呼叫 STS519 auth: {} # the gateway's own role: it only calls STS
438 assume_role:520 assume_role:
439 role_arn: arn:aws:iam::123456789012:role/claude-gateway-bedrock-user521 role_arn: arn:aws:iam::123456789012:role/claude-gateway-bedrock-user
440 session_name: email # 或 sub522 session_name: email # or sub
441```523```
442 524
443`session_name` 選擇哪個已驗證宣告成為 AWS `RoleSessionName`:`email` 或 `sub`。閘道將 ASCII 字母、數字和 `_+,.@-` 以外的任何字元寫成 `=XX` 十六進位(每 UTF-8 位元組),並將長於 64 字元的結果縮短為前置詞加雜湊,因此每個開發人員的工作階段名稱保持有效且唯一。來自 token 缺少該宣告的開發人員的請求不會透過此上游傳送,操作員日誌會提示切換到 `sub` 或設定 [`oidc.email_claim`](#oidc)。525`session_name` 選擇哪個已驗證宣告成為 AWS `RoleSessionName`:`email` 或 `sub`。閘道將 ASCII 字母、數字和 `_+,.@-` 以外的任何字元寫成 `=XX` 十六進位(每 UTF-8 位元組),並將長於 64 字元的結果縮短為前置詞加雜湊,因此每個開發人員的工作階段名稱保持有效且唯一。來自 token 缺少該宣告的開發人員的請求不會透過此上游傳送,操作員日誌會提示切換到 `sub` 或設定 [`oidc.email_claim`](#oidc)。
458upstreams:540upstreams:
459 - provider: mantle541 - provider: mantle
460 region: us-east-1542 region: us-east-1
461 models: [claude-opus-4-7, claude-haiku-4-5] # 必需543 models: [claude-opus-4-7, claude-haiku-4-5] # required
462 auth: {} # AWS 預設憑證鏈544 auth: {} # AWS default credential chain
463 - provider: bedrock545 - provider: bedrock
464 region: us-east-1546 region: us-east-1
465 auth: {}547 auth: {}
497 region: us-east-1579 region: us-east-1
498 workspace_id: wrkspc_...580 workspace_id: wrkspc_...
499 auth:581 auth:
500 api_key: ${ANTHROPIC_AWS_API_KEY} # 作為 x-api-key 傳送582 api_key: ${ANTHROPIC_AWS_API_KEY} # sent as x-api-key
501 # 或透過 AWS 預設憑證鏈的 SigV4:583 # OR SigV4 via the AWS default credential chain:
502 # auth: {}584 # auth: {}
503 # 或明確的 SigV4 憑證:585 # OR explicit SigV4 credentials:
504 # auth:586 # auth:
505 # aws_access_key_id: ${AWS_ACCESS_KEY_ID}587 # aws_access_key_id: ${AWS_ACCESS_KEY_ID}
506 # aws_secret_access_key: ${AWS_SECRET_ACCESS_KEY}588 # aws_secret_access_key: ${AWS_SECRET_ACCESS_KEY}
507 # 覆寫衍生的端點:589 # Override the derived endpoint:
508 # base_url: https://aws-external-anthropic.us-east-1.api.aws590 # base_url: https://aws-external-anthropic.us-east-1.api.aws
509```591```
510 592
529 - provider: vertex611 - provider: vertex
530 region: us-east5612 region: us-east5
531 project_id: example-prod613 project_id: example-prod
532 auth: {} # 首選:應用程式預設憑證614 auth: {} # preferred: Application Default Credentials
533 # 或服務帳戶金鑰檔案:615 # OR a service account key file:
534 # auth: { service_account_json: /secrets/sa.json }616 # auth: { service_account_json: /secrets/sa.json }
535 # 覆寫 aiplatform 端點以進行私人服務連線:617 # Override the aiplatform endpoint for Private Service Connect:
536 # base_url: https://us-east5-aiplatform.p.googleapis.com618 # base_url: https://us-east5-aiplatform.p.googleapis.com
537```619```
538 620
556upstreams:638upstreams:
557 - provider: foundry639 - provider: foundry
558 resource: example-foundry # https://example-foundry.services.ai.azure.com640 resource: example-foundry # https://example-foundry.services.ai.azure.com
559 auth: { use_azure_ad: true } # 首選:DefaultAzureCredential / 受管身分識別641 auth: { use_azure_ad: true } # preferred: DefaultAzureCredential / Managed Identity
560 # 或 API 金鑰:642 # OR an API key:
561 # auth:643 # auth:
562 # api_key: ${FOUNDRY_API_KEY}644 # api_key: ${FOUNDRY_API_KEY}
563```645```
625 707
626`429` 代表每個上游的容量,因此佈建輸送量 (PT) 耗盡會故障轉移到隨需。如果您在上游上設定 [`forward_user_identity: true`](#per-user-identity-headers-for-a-proxy-you-run),對攜帶開發人員電子郵件的請求的 `429` 則是每個使用者的拒絕,不會故障轉移。708`429` 代表每個上游的容量,因此佈建輸送量 (PT) 耗盡會故障轉移到隨需。如果您在上游上設定 [`forward_user_identity: true`](#per-user-identity-headers-for-a-proxy-you-run),對攜帶開發人員電子郵件的請求的 `429` 則是每個使用者的拒絕,不會故障轉移。
627 709
628每個請求從第一個上游開始。請求僅在它前面的每個上游都失敗或不服務所請求的模型時才到達稍後的上游。710請求只會在以下情況略過某個上游:
711
712* 該上游已失敗
713* 該上游不提供所請求的模型
714* 該上游的 [`groups` 清單](#send-each-team-to-its-own-upstream)未包含該開發人員
629 715
630閘道不保留失敗上游的記錄,因此當上游關閉時,到達它的每個請求仍然會嘗試它,並等待它失敗後再繼續。716閘道不保留失敗上游的記錄,因此當上游關閉時,到達它的每個請求仍然會嘗試它,並等待它失敗後再繼續。
631 717
678| - | - |764| - | - |
679| 不同地區 | 每個地區一個 Amazon Bedrock 上游,每個都有自己的 `region:`。使用 [`auto_include_builtin_models: true`](#models),跨地區推論設定檔會自動路由;對於地區固定部署,使用 `models:` 區塊。 |765| 不同地區 | 每個地區一個 Amazon Bedrock 上游,每個都有自己的 `region:`。使用 [`auto_include_builtin_models: true`](#models),跨地區推論設定檔會自動路由;對於地區固定部署,使用 `models:` 區塊。 |
680| 不同帳戶 | 每個帳戶一個 Amazon Bedrock 上游。預設鏈 (`auth: {}`) 使用 Pod 的身分識別;對於第二個帳戶,新增 [`assume_role`](#bedrock-in-another-aws-account) 以透過短期憑證到達它,或在 `auth:` 中設定明確憑證或持有人 token。 |766| 不同帳戶 | 每個帳戶一個 Amazon Bedrock 上游。預設鏈 (`auth: {}`) 使用 Pod 的身分識別;對於第二個帳戶,新增 [`assume_role`](#bedrock-in-another-aws-account) 以透過短期憑證到達它,或在 `auth:` 中設定明確憑證或持有人 token。 |
767| 不同團隊 | 為每個團隊的上游設定 `groups` 清單,讓只有這些 IdP 群組中的開發人員能存取。請參閱[將每個團隊送往各自的上游](#send-each-team-to-its-own-upstream)。 |
681| 佈建輸送量 | 在 `models:` 中將該上游名稱下的模型對應到佈建輸送量 ARN。其他上游保持隨需 ID,因此 PT 容量在故障轉移前耗盡。 |768| 佈建輸送量 | 在 `models:` 中將該上游名稱下的模型對應到佈建輸送量 ARN。其他上游保持隨需 ID,因此 PT 容量在故障轉移前耗盡。 |
682| VPC / FIPS 端點 | 在上游上將 `base_url:` 設定為您的 VPC 端點或 FIPS 端點 URL |769| VPC / FIPS 端點 | 在上游上將 `base_url:` 設定為您的 VPC 端點或 FIPS 端點 URL |
683| 模型範圍路由 | 只有自訂模型 `id`(不是內建 Claude 模型)會跳過其 `upstream_model:` 對應中不存在的上游。`mantle` 上游僅針對其 [`models` 欄位](#amazon-bedrock-mantle-endpoint)中列出的模型進行嘗試。在其他每個上游上,閘道按順序嘗試內建模型,並在對應中沒有項目時使用提供者的預設 ID,因此對於內建模型,對應改變的是上游接收的 ID,而不是是否嘗試該上游;拒絕 ID 的上游遵循與任何其他上游錯誤相同的[故障轉移規則](#upstreams)。 |770| 依模型範圍路由 | 自訂模型 `id`(非內建 Claude 模型者)會略過其 `upstream_model:` 對應中沒有的上游。具有 `models` 清單的上游([`mantle` 上游](#amazon-bedrock-mantle-endpoint)必須具備此清單)只會針對這些模型進行嘗試。 |
771| 內建模型路由 | 在沒有 `models` 或 `groups` 清單的上游上,閘道會依序嘗試內建模型,並在 `upstream_model:` 對應中沒有項目時使用提供者的預設 ID。對於提供者具有預設 ID 的內建模型,此對應改變的是上游收到哪個 ID,而非是否嘗試該上游。拒絕該 ID 的上游會遵循與其他上游錯誤相同的[容錯移轉規則](#upstreams)。 |
684 772
685在雲提供者之間故障轉移,或故障轉移到直接 Anthropic API,會改變哪些協議、地理位置和其他條款管理該請求。773在雲提供者之間故障轉移,或故障轉移到直接 Anthropic API,會改變哪些協議、地理位置和其他條款管理該請求。
686 774
687無論哪個上游服務給定請求,CLI 對閘道都應用相同的功能閘控,因此預設情況下故障轉移不會傳送上游會拒絕的正文欄位。如果您在原則中設定了[一小時快取 TTL](#one-hour-prompt-cache),它會傳送到清單中的每個上游,因此僅在所有上游都接受它時才設定。775無論哪個上游服務給定請求,CLI 對閘道都應用相同的功能閘控,因此預設情況下故障轉移不會傳送上游會拒絕的正文欄位。如果您在原則中設定了[一小時快取 TTL](#one-hour-prompt-cache),它會傳送到清單中的每個上游,因此僅在所有上游都接受它時才設定。
688 776
777#### 將每個團隊送往各自的上游
778
779若要將每個團隊的請求送往各自的 AWS 帳戶或 Google Cloud 專案,請為每個團隊列出一個上游,並為每個上游設定 `groups` 清單。只有所列 IdP 群組中的開發人員能存取該上游,無論是首次嘗試或[容錯移轉](#multiple-upstreams)時皆是如此。每個提供者都接受 `groups`。閘道伺服器需要 Claude Code v2.1.314 或更新版本。
780
781此範例為 `payments-eng` 與 `search-eng` 群組各提供一個 AWS 帳戶,並新增一個沒有 `groups` 清單、所有開發人員皆可使用的上游:
782
783```yaml theme={null}
784upstreams:
785 - name: bedrock-payments
786 provider: bedrock
787 region: us-east-1
788 auth: {}
789 assume_role:
790 role_arn: arn:aws:iam::111111111111:role/claude-gateway-bedrock
791 groups: [payments-eng]
792 - name: bedrock-search
793 provider: bedrock
794 region: us-east-1
795 auth: {}
796 assume_role:
797 role_arn: arn:aws:iam::222222222222:role/claude-gateway-bedrock
798 groups: [search-eng]
799 - name: bedrock-shared # no groups: open to everyone, so listed last
800 provider: bedrock
801 region: us-east-1
802 auth: {}
803```
804
805使用此範例設定時,每位開發人員的請求會從其所在列的第一個上游開始,並在容錯移轉時移至下一個:
806
807| 開發人員的群組 | 上游(依序) |
808| - | - |
809| `payments-eng` | `bedrock-payments`,然後 `bedrock-shared` |
810| `search-eng` | `bedrock-search`,然後 `bedrock-shared` |
811| `payments-eng` 與 `search-eng` | `bedrock-payments`,然後 `bedrock-search`,然後 `bedrock-shared` |
812| 皆非 | `bedrock-shared` |
813
814當團隊的上游以 `403` 拒絕所請求的模型時,閘道會嘗試該團隊所在列中下一個提供該模型的上游。若要讓團隊只使用一個上游,請為每個上游設定 `groups` 清單,並確保沒有其他上游列出該團隊開發人員所屬的群組。如此一來,該團隊便沒有容錯移轉,而不屬於任何所列群組的開發人員所發出的請求會[以 `400` 失敗](#what-happens-when-a-developer-is-in-no-listed-group)。
815
816若要讓每位開發人員抵達您預期的上游,請撰寫完全相符的項目,並將開放的上游放在最後:
817
818* **項目**:請完全依照您的 IdP 在 [groups 宣告](#oidc)中傳送的內容撰寫每個群組,[`match.groups`](#managed) 也會讀取該宣告。閘道發現空清單或空項目時會拒絕啟動。它不會對照您的 IdP 檢查項目,因此不符合任何人的項目不會產生警告。
819* **順序**:將沒有 `groups` 清單的上游放在最後。它為所有人提供服務,因此若列在較前面,會在團隊自己的上游之前接走該團隊的請求。
820
821> [!WARNING]
822>
823> 早於 v2.1.314 的閘道發現 `groups` 時會拒絕啟動,因此請在新增它之前升級每個副本。
824>
825> 在回復之前,請移除每個具有 `groups` 清單的上游,以及每個指名它的 `upstream_model` 鍵或價格覆寫,並至少保留一個上游。若只移除 `groups` 鍵,該上游會對所有開發人員開放。仍指名已移除上游的鍵或覆寫會使閘道無法啟動,並顯示 `references unknown upstream`。
826
827##### 當開發人員不屬於任何所列群組時會發生什麼事
828
829若每個上游都有 `groups` 清單,不屬於任何這些群組的開發人員會看到此錯誤,且閘道不會聯絡任何提供者:
830
831```text theme={null}
832API Error: 400 you aren't in a group that can use this gateway. Ask your administrator to add you to one
833```
834
835請在您的 IdP 中將該開發人員加入所列的群組,或新增一個沒有 `groups` 清單的上游。
836
837閘道會在每次 token 重新整理時再次讀取開發人員的群組。若您的 IdP 在重新整理時未包含群組,該開發人員便沒有任何群組:
838
839* **已設定 [`oidc.allowed_groups`](#oidc)**:閘道會拒絕重新整理,工作階段隨即結束
840* **否則,若有上游沒有 `groups` 清單**:該開發人員的請求會移至該上游
841* **否則,若每個上游都有 `groups` 清單**:該開發人員的請求會以該錯誤失敗
842
843若您 IdP 的 userinfo 端點會回傳 groups 宣告,且未設定 `oidc.google_groups`,請將 [`oidc.userinfo_fallback`](#oidc) 設為 `true`,以從該處填入群組。
844
689## 選用區段845## 選用區段
690 846
691### `admin`847### `admin`
780 936
781#### 將費率傳送給已登入的用戶端937#### 將費率傳送給已登入的用戶端
782 938
783使用 gateway 伺服器上的 v2.1.268 或更新版本,gateway 也將 `pricing` 中的費率放入它提供的 [`managed`](#managed) 原則中,作為 [`modelPricing`](https://code.claude.com/docs/zh-TW/settings-reference#modelpricing) 受管設定。由原則匹配的開發者隨後在 `/usage`、狀態列和 OpenTelemetry 中看到每個模型 ID 的第一個上游的 `pricing` 費率。與任何原則不匹配的開發者不會收到受管設定,因此其數字保持在清單價格。用戶端在 Claude Code v2.1.242 或更新版本中應用設定。939在閘道伺服器上使用 v2.1.268 或更新版本時,閘道也會將 `pricing` 中的費率放入其提供的 [`managed`](#managed) 政策中,作為 [`modelPricing`](https://code.claude.com/docs/zh-TW/settings-reference#modelpricing) 受管設定。
940
941與政策相符的開發人員便會在 `/usage`、狀態列和 OpenTelemetry 中看到 `pricing` 的費率。不符合任何政策的開發人員不會收到受管設定,因此其數字仍維持定價。用戶端在 Claude Code v2.1.242 或更新版本中套用此設定。
784 942
785* gateway 新增的內容:除非原則的 `cli` 區塊已設定 `modelPricing`,gateway 新增 `multiplier` 和,對於用戶端可以請求的每個模型 ID,提供該 ID 的第一個上游的覆寫列。只有故障轉移上游收費的費率保持在 gateway 上。943* gateway 新增的內容:除非原則的 `cli` 區塊已設定 `modelPricing`,gateway 新增 `multiplier` 和,對於用戶端可以請求的每個模型 ID,提供該 ID 的第一個上游的覆寫列。只有故障轉移上游收費的費率保持在 gateway 上。
944* 具有 [`groups` 清單](#send-each-team-to-its-own-upstream)的上游:當其為提供某模型 ID 的第一個上游時,閘道不會為該 ID 新增資料列。開發人員接著會看到 Claude Code 自身對該 ID 的費率(當 Claude Code 能識別該 ID 時,即為該模型的標準費率)乘以 `multiplier`。
786* 選擇一個原則退出:在該原則的 `cli` 區塊中將 `modelPricing` 設定為 `{}`,其開發者保持在清單價格。945* 選擇一個原則退出:在該原則的 `cli` 區塊中將 `modelPricing` 設定為 `{}`,其開發者保持在清單價格。
787* 保留原則自己的費率:其 `cli` 區塊使用自己的 `multiplier` 或 `overrides` 設定 `modelPricing` 的原則保留該 `modelPricing` 完整,gateway 不向其新增自己的費率。946* 保留原則自己的費率:其 `cli` 區塊使用自己的 `multiplier` 或 `overrides` 設定 `modelPricing` 的原則保留該 `modelPricing` 完整,gateway 不向其新增自己的費率。
788 947
806 965
807### `managed`966### `managed`
808 967
809`managed` 區塊定義基於 IdP 群組或電子郵件網域的角色型存取原則。原則按順序評估;選擇第一個匹配項,然後合併到 `match: {}` 全部捕捉基礎。它們在 `GET /managed/settings` 按使用者提供,具有 ETag/304 快取。968`managed` 區塊定義以 IdP 群組或電子郵件網域為鍵的角色型存取政策。政策會依序評估;預設會選取第一個符合的政策,然後合併到 `match: {}` 全包式基礎上。符合兩項角色政策的使用者只會取得第一項,因此除非您 [套用每一項符合的政策](#apply-every-matching-policy),否則第二項政策的拒絕規則不會生效。政策會依使用者在 `GET /managed/settings` 提供,並使用 ETag/304 快取。
810 969
811```yaml theme={null}970```yaml theme={null}
812managed:971managed:
847 1006
848與任何原則不匹配的已驗證使用者獲得 gateway 的預設值,這意味著目錄中的每個模型和沒有受管設定。如果您想要保證的預設原則,請在最後新增 `match: {}` 全部捕捉。1007與任何原則不匹配的已驗證使用者獲得 gateway 的預設值,這意味著目錄中的每個模型和沒有受管設定。如果您想要保證的預設原則,請在最後新增 `match: {}` 全部捕捉。
849 1008
1009請將全組織的拒絕規則放在 `match: {}` 政策中,因為群組政策的規則只有在使用者的 token 帶有該群組時才會生效。
1010
850> [!NOTE]1011> [!NOTE]
851>1012>
852> gateway 不保留自己的使用者目錄。它從使用者的 IdP token 授權每個請求,從 token 的 `groups` 聲明讀取群組成員資格,並根據它評估原則。沒有名冊可列舉,沒有帳戶可預先建立,因此沒有 SCIM 端點,因為沒有任何東西可供 SCIM 同步到。1013> gateway 不保留自己的使用者目錄。它從使用者的 IdP token 授權每個請求,從 token 的 `groups` 聲明讀取群組成員資格,並根據它評估原則。沒有名冊可列舉,沒有帳戶可預先建立,因此沒有 SCIM 端點,因為沒有任何東西可供 SCIM 同步到。
860>1021>
861> Claude Desktop 依循[其自己的排程](#when-a-policy-change-reaches-claude-desktop)。1022> Claude Desktop 依循[其自己的排程](#when-a-policy-change-reaches-claude-desktop)。
862 1023
1024#### 套用每一項符合的政策
1025
1026符合多項角色政策的使用者只會取得第一項,除非您在 `policies` 旁設定 `policy_mode: layered`。使用 `layered` 時,每一項符合使用者的政策都會套用,直到第一個 `match: {}` 政策為止。
1027
1028`policy_mode` 需要閘道伺服器上為 Claude Code v2.1.316 或更新版本。若閘道版本不支援此鍵,發現該鍵時會拒絕啟動。請在新增此鍵之前升級每個副本,並在回復到較早版本之前移除此鍵。此範例有一個失去 `WebFetch` 的群組,以及一個獲得 Opus 的群組:
1029
1030```yaml theme={null}
1031managed:
1032 policy_mode: layered
1033 policies:
1034 - match: { groups: [no-web] }
1035 cli:
1036 permissions: { deny: ["WebFetch"] }
1037 - match: { groups: [opus-users] }
1038 cli:
1039 availableModels: [opus, sonnet]
1040 - match: {}
1041 cli:
1042 availableModels: [sonnet]
1043 enforceAvailableModels: true
1044```
1045
1046下表顯示同時屬於 `no-web` 與 `opus-users` 的使用者,在預設的 `first_match` 與 `layered` 之下分別會收到什麼。
1047
1048| 設定 | `first_match` | `layered` |
1049| - | - | - |
1050| `availableModels` | `sonnet` | `opus`、`sonnet` |
1051| `enforceAvailableModels` | `true` | `true` |
1052| `permissions.deny` | `WebFetch` | `WebFetch` |
1053
1054閘道會將每項符合的政策合併到列在其下方的政策上,使用與基礎層相同的 [合併規則](#managed):
1055
1056* **允許清單、單一值,以及 `sandbox` 之類的區塊**:每一項都完整取自第一個設定它的符合政策(依列出順序),因此兩個群組的 `availableModels` 清單不會相加。
1057* **拒絕清單與 hook 陣列**:這些會在每項符合的政策之間相加,因此屬於兩個群組的使用者會取得兩個群組的拒絕規則。
1058* **`env`、`modelOverrides` 與 `skillOverrides`**:項目依名稱合併,第一個設定某名稱的符合政策(依列出順序)提供其值。
1059* **`desktop` 鍵**:這些依 [基礎 `desktop` 區塊的規則](#how-a-role-policy-inherits-the-base-desktop-block) 合併。
1060
1061> [!WARNING]
1062>
1063> 多項政策加總後,可能產生比任何單一政策都更寬鬆的規則。例如,`match: {}` 政策設定 `sandbox.enabled: true`,一個群組的政策設定 `permissions.allow: ["Bash"]`,另一個群組的政策設定 `sandbox.enabled: false`。同時屬於這兩個群組的使用者,會在沙箱關閉的情況下獲得允許 `Bash`。在這種情況下,請將允許 `Bash` 的政策列在最前面,並將 `match: {}` 政策的整個 `sandbox` 區塊複製到其中。
1064
1065使用 `layered` 時,閘道會在某些設定上拒絕啟動,包括以下幾項:
1066
1067* **`!` 模式**:任何政策(包括 `match: {}` 政策)的 `permissions.deny` 或 `permissions.ask` 清單中,`Read` 或 `Edit` 規則裡的 [`!` 否定](https://code.claude.com/docs/zh-TW/permissions#special-characters-and-negation)
1068* **全包式政策以外的 hook 限制**:在 `match: {}` 以外的任何政策中設定 `disableAllHooks`、`allowedHttpHookUrls` 或 `httpHookAllowedEnvVars`
1069
863#### 讓工作階段從原則允許的模型啟動1070#### 讓工作階段從原則允許的模型啟動
864 1071
865如果 `availableModels` 未包含 Claude Code 的預設模型,工作階段會收到 `400` 回應,直到開發者選擇列出的模型(例如使用 `/model`)。在 gateway 工作階段中,預設模型是 `opus` 別名解析到的 Opus 模型,而單獨設定 `availableModels` 不會變更它。1072如果 `availableModels` 未包含 Claude Code 的預設模型,工作階段會收到 `400` 回應,直到開發者選擇列出的模型(例如使用 `/model`)。在 gateway 工作階段中,預設模型是 `opus` 別名解析到的 Opus 模型,而單獨設定 `availableModels` 不會變更它。