載入中

在 CI/CD 管線中以非互動方式執行 Claude Code,將執行過程沙盒化以確保長時間執行的代理能安全運作,透過 MCP 整合公開部署功能,並在代理真正需要之前預先演練回滾路徑。

有何變化

傳統方式AI 原生方式
管線執行確定性的腳本,任何需要判斷的事項都要等待人類處理:例如,分類不穩定的測試、撰寫變更日誌,或找出建置失敗的原因。部署與回滾是人類在壓力下遵循的操作手冊。Claude 在管線中以非互動方式執行判斷步驟,在具有範圍限定憑證的沙盒中運作。部署工具透過 MCP 公開給代理,因此撰寫並測試變更的工作流程也能發布並回滾該變更,且都在組織針對每個環境定義的關卡之內進行。

開始使用

  • 先決條件:AI 參與 PR 審查循環,以及將 hooks 作為核准關卡,因為在自動化加速通過這些關卡之前,關卡必須先存在。
  • 基礎設施:已安裝 claude-code-action 的 CI 平台,或任何能呼叫 claude -p 的執行器(runner);透過 API、Amazon Bedrock、Microsoft Foundry 或 Vertex AI 存取模型(當流量必須留在組織的雲端合約範圍內時);用於部署目標的 MCP 伺服器;供代理工作使用的沙盒設定檔,且不具備常駐的生產環境憑證。

如何執行

  1. 平台工程師從唯讀的判斷步驟開始。在管線工作中使用 claude -p 來分類失敗的建置、總結不穩定的測試,或草擬變更日誌。
  2. 在現有關卡之後加入寫入步驟,用於修正 lint、更新生成的文件,或透過 @claude 提及來處理審查意見等工作。代理所寫的任何內容都會透過分支保護以 PR 形式送出,代理沒有任何途徑可以直接推送到 main。
  3. 執行過程經過沙盒化。代理工作在容器中執行,受網路政策約束,使用短期且範圍限定的權杖,且預設不持有任何生產環境憑證。
  4. 透過 MCP 公開部署功能。部署、狀態查詢與回滾都成為工具,並依環境設定範圍,因此代理的部署權限是一份允許清單,而不是帶有憑證的 shell 腳本。
  5. 依環境分層自主程度。在開發環境中,代理可自由部署。在生產環境中,代理準備發布版本,由發布經理授權,並由 hook 強制執行生產關卡。預備環境則介於兩者之間。
  6. 回滾應該是管線中演練最多次的路徑,是代理可以執行的單一指令,並在預備環境中定期演練。「收尾循環」策略(第 6 階段:維護)會在控制範圍被突破時呼叫此回滾機制,因此必須事先驗證其可行性。

實際運作方式

管線步驟:

yaml
- name: Triage failed build
  if: failure()
  run: >
    claude -p "Read the build log at out/build.log. Identify the most
    likely cause, say whether the failure looks flaky or real, and write a
    three-line summary for the PR thread." >> triage.md

本範例其餘部分以一家保險公司的客戶入口網站為例,部署功能以工具形式公開,每個環境各有一個 MCP 伺服器。允許使用某個 MCP 工具的規則,是以伺服器名稱與工具名稱來指定,而非工具的參數。因此,每個環境各自獨立的伺服器,正是讓允許清單能夠區分預備環境與生產環境的關鍵。這些伺服器設定於專案的 .mcp.json 中:

json
{
  "mcpServers": {
    "deploy-dev": {
      "type": "http",
      "url": "https://deploy.example.com/mcp/dev",
      "headers": { "Authorization": "Bearer ${DEPLOY_DEV_TOKEN}" }
    },
    "deploy-staging": {
      "type": "http",
      "url": "https://deploy.example.com/mcp/staging",
      "headers": { "Authorization": "Bearer ${DEPLOY_STAGING_TOKEN}" }
    },
    "deploy-prod": {
      "type": "http",
      "url": "https://deploy.example.com/mcp/prod",
      "headers": { "Authorization": "Bearer ${DEPLOY_PROD_TOKEN}" }
    }
  }
}

每個伺服器都提供相同的三種工具:

工具輸入回傳內容
releaseversion,在生產環境中還需要 ticket發布完成後的發布 ID
status無等待至最後一次發布後五分鐘,然後回傳該時間段內每個端點的 5xx 錯誤率
rollback無重新上線的版本

預備環境的工作會在推送到 main 時執行,並預先核准預備伺服器的三種工具,不核准其他任何工具。它只持有預備環境的權杖,因此另外兩個伺服器都沒有有效的權杖,會拒絕該工作。以下是預備環境工作的管線步驟:

yaml
- name: Release to staging and roll back if it is unhealthy
  env:
    ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
    DEPLOY_STAGING_TOKEN: ${{ secrets.DEPLOY_STAGING_TOKEN }}   # no other environment's token
  run: >
    claude -p "Release version ${{ github.sha }} of the claims portal to staging,
    then call status. If the 5xx rate on any endpoint is over 1%, roll back.
    Finish with three lines for the release notes: what you released, what status
    reported, and whether you rolled back."
    --allowedTools "mcp__deploy-staging__release,mcp__deploy-staging__status,mcp__deploy-staging__rollback"
    --permission-mode dontAsk >> release-notes.md

在 dontAsk 模式下,Claude Code 會拒絕任何原本會提示詢問的呼叫,因此不在清單上的部署工具會被拒絕,該工作也永遠不會等待回應。

一個作用於 release 工具的 PreToolUse hook 會依環境做出決定。它在「hooks 作為核准關卡」策略中有詳細說明,並提供三個層級:

環境允許清單上的工具release 會發生什麼事由誰核准
開發release、status、rollbackhook 允許執行無人
預備release、status、rollbackhook 會詢問,或在 main 上的管線中允許執行工程師,或經核准的合併
生產status、rollback除非 hook 允許,否則拒絕發布經理,透過變更工單

在生產環境中,dontAsk 模式仍會執行經 PreToolUse hook 核准的呼叫,因此當 release 不在允許清單上時,hook 的 allow 是唯一的通行方式。因此生產環境採取「失敗即關閉」的原則,因為如果 hook 未能執行,發布就會被拒絕。rollback 仍保留在允許清單上,因為它是事先核准的操作手冊。

如果執行器帶有設定了 allowManagedHooksOnly 的受管理設定,則該 hook 必須定義在受管理設定中;而若設定了 allowManagedMcpServersOnly,則伺服器必須位於受管理的允許清單上。

治理考量

治理原則是:代理可以行動到生產關卡為止,但不能通過該關卡。以下控制措施即用於落實此原則。

  • 分支保護會將代理所寫的任何內容轉換為 PR,沒有直接通往 main 的路徑。
  • 生產部署 hook 會封鎖發布,直到指定的發布經理授權為止。每次非互動式執行都以代理自身的身分進行,因此管線日誌能夠區分代理所做的事與觸發該執行的工程師所做的事。
  • 依環境劃分的權限層級決定代理在通往關卡的過程中可以做多少事。

如何衡量

  • 領先指標:未呼叫人員介入即完成分類的管線失敗比例,取自 CI/CD 管線日誌。
  • 落後指標:DevOps 研究與評估(DORA)指標,這些指標已由 CI 系統與部署工具產生。