博客 • AI / Agent

Claude Managed Agents 2026 新功能解析:AI Agent 如何自動判斷 Tool Call 是否允許?JSON 權限策略與 MCP Security 完整教程

2026 年 9 月 10 日,Anthropic 給 Claude Managed Agents 的權限策略加了一種新類型:auto。同一天,agent.tool_use和agent.mcp_tool_use事件開始帶evaluation字段,和原來的evaluated_permission並排。

模型提出 Tool Call,並不等於這次調用會被執行。真正拍板的是服務器上的策略評估:它讀你寫進 Agent 配置的 JSON policy,再對這一次調用的工具名、輸入和會話內容給出 allow、deny 或 ask。

本文將介紹:

先記住這一點:auto不是「全開」,也不是人工審批。服務器認爲安全時,調用會在你看見之前跑完;認爲高風險時,客戶端連推翻 deny 的機會都沒有。下面按「三種策略 → 按次評估 → 事件 JSON → MCP → 審批流」拆開。

三種策略:always_allow、always_ask、auto

Permission policy 只管服務器代執行的工具:內置agent_toolset_20260401,以及你掛上的 MCP toolset。自定義工具由你的應用執行,不走這套策略。請求要帶 beta 頭managed-agents-2026-04-01。官方說明見

Claude Managed Agents Permission policies。

策略決定的是「這次調用何時跑」,不是「這個工具在不在目錄裏」。要從 Agent 拿掉一個工具,用 disable,不要指望策略替你藏工具。

策略 服務器做什麼 客戶端還要做什麼
always_allow 直接執行,不等人 讀事件即可,沒有確認步驟
always_ask 發出 tool_use 事件後停住 對每個阻塞事件發user.tool_confirmation
auto 按這一次調用評估:跑、拒,或停下來問你 只處理結果爲 ask 的事件;deny 不能推翻

默認值兩邊不一樣。Agent toolset 默認always_allow。MCP toolset 默認always_ask。沒有一個 toolset 默認開auto,要自己寫進 JSON。

已經在跑的 session 繼續用創建時那份 toolset 配置。你改 Agent 之後,新 session 才喫到新策略。發佈說明見

Claude Platform release notes(2026-09-10)。

auto 到底看什麼

以前只有「這個工具永遠放行」或「這個工具永遠問人」。auto把判斷從工具級改成調用級。

官方寫得很具體:評估會看工具本身、這一次的 input,以及到此刻爲止的會話內容。所以同一個bash,兩條不同的command,結果可以一個 allow、一個 deny。

  1. 1
    調用被放行

    服務器認爲這次安全,工具按always_allow那樣執行。沒有暫停,也沒有人工窗口。

  2. 2
    調用被拒絕

    服務器把它評成高風險,工具不跑。Agent 收到一條錯誤 tool result:Permission to use {tool_name} has been denied.,並且is_error: true。會話繼續。你的客戶端不能改這個 deny。

  3. 3
    調用停下來等你

    服務器給不出確定結論,會話按always_ask那樣暫停。你再用確認事件放行或拒絕。

意圖只從你發出的user.message讀。工具結果、抓回來的網頁、MCP Server 的返回、線程之間的消息,服務器會評估內容,但不會把它們當成指令。有些調用無論誰開口都評成高風險。

如果你把不可信的最終用戶原文原樣塞進user.message,服務器也會把它當成你的意圖,可能因此放行一次調用。這種入口上的工具,應單獨配always_ask。

策略寫在哪一段 JSON

策略出現在兩個位置:toolset 的default_config.permission_policy,以及configs裏某一條工具的覆蓋。下面這份配置把 Agent toolset 和 GitHub MCP 都設成auto,再把bash單獨釘成always_ask。

創建 Agent 時的 tools 配置(節選自官方文檔)
{
  "name": "Ops Agent",
  "model": "claude-opus-5",
  "mcp_servers": [
    {
      "type": "url",
      "name": "github",
      "url": "https://mcp.example.com/github"
    }
  ],
  "tools": [
    {
      "type": "agent_toolset_20260401",
      "default_config": {
        "permission_policy": { "type": "auto" }
      },
      "configs": [
        {
          "name": "bash",
          "permission_policy": { "type": "always_ask" }
        }
      ]
    },
    {
      "type": "mcp_toolset",
      "mcp_server_name": "github",
      "default_config": {
        "permission_policy": { "type": "auto" }
      }
    }
  ]
}

mcp_server_name必須和mcp_servers裏那一項的name對上。MCP 側按工具名覆蓋時,name用 Server 報告出來的工具名,不是你自己起的別名。

省略default_config時,Agent toolset 會以always_allow啓用。這是省事的默認值,不是安全默認值。

每次調用留下的 evaluation

不管策略是哪一種,agent.tool_use和agent.mcp_tool_use都會帶頂層字段evaluated_permission,取值是allow、ask或deny。大多數事件再帶一個evaluation對象,用type標明是哪條策略做出的結論。

在auto下,對象裏還會寫下服務器的判定;結果是 ask 或 deny 時,再帶reason_code。官方例子:bash走 auto,一次高風險調用被拒。

被 auto 拒絕的 agent.tool_use 事件
{
  "type": "agent.tool_use",
  "id": "sevt_01pqr...",
  "name": "bash",
  "input": {
    "command": "rm -rf /workspace/reports"
  },
  "evaluated_permission": "deny",
  "evaluation": {
    "type": "auto",
    "evaluated_permission": {
      "type": "deny",
      "reason_code": "high_risk"
    }
  },
  "processed_at": "2026-03-25T14:05:12Z"
}
evaluation 頂層結果 含義
{"type":"always_allow"} allow 解析後的策略是 always_allow,調用已執行
{"type":"always_ask"} ask 解析後的策略是 always_ask,會話在等你
{"type":"auto","evaluated_permission":{"type":"allow"}} allow auto 認爲這次安全,已經跑了
{"type":"auto","evaluated_permission":{"type":"ask","reason_code":"indeterminate"}} ask auto 給不出結論,停下來問你
{"type":"auto","evaluated_permission":{"type":"deny","reason_code":"high_risk"}} deny auto 評爲高風險,已經拒絕

reason_code是給你的客戶端做分支和審計日誌的,不是給人看的文案。官方目前寫明的有indeterminate和high_risk。客戶端必須能容忍以後多出來的type或reason_code。

有兩種情況沒有evaluation。Agent 點了會話裏沒啓用的工具:事件只有evaluated_permission: "deny"。字段出現之前記下的舊事件也沒有它:當時 allow 按 always_allow 讀,ask 按 always_ask 讀。

這和「JSON 是安全邊界」是同一層東西,但切口不同。那邊講的是模型發出去的 arguments 必須先被校驗;這邊講的是平臺自己會再寫一份評估結果,而且這份結果你推不翻。前一篇見

AI Agent 與 JSON 安全邊界。

MCP Tool Call 和默認 always_ask

MCP 把工具目錄從你的倉庫挪到了外面的 Server。Server 用 JSON-RPC 暴露 tool,每個 tool 帶inputSchema。Host 把目錄餵給模型,再把模型的調用轉成tools/call。規範見

MCP Tools。

Managed Agents 對這件事的默認態度很保守:MCP toolset 默認always_ask。新工具被加進某個你已經連上的 Server 時,不會在你的應用裏悄悄執行。這是 MCP Security 在平臺側能落地的第一道閘,比「相信 Server 自己的 description」可靠。

你仍然可以改。信任某個 GitHub MCP、希望它少打斷,就把該 toolset 的default_config.permission_policy改成always_allow或auto。改的是「何時執行」,不是「Schema 還要不要驗」。

層 它回答什麼 它不回答什麼
JSON Schema 參數字段、類型、必填、枚舉對不對 這次調用該不該發生
Tool Calling 模型選出了哪個工具、填了什麼 arguments Host 會不會執行
permission policy 這次調用 allow / ask / deny payload 是否符合 schema、description 有沒有帶偏模型

三層疊在一起纔像一扇門。只開 auto、Schema 仍然是{"sql":{"type":"string"}},評估器看到的輸入面會寬到無法判斷,更多調用會掉進indeterminate,也就是 ask。收緊 schema,是在幫 auto 做出能寫進日誌的結論。誰負責哪一層,見

MCP 安全:爲何 Schema、Tool Calling 和權限不能互相替代。

ask 之後的 JSON 審批流

一次調用評成 ask,只可能來自always_ask,或來自auto的indeterminate。後面的事件順序是固定的。

  1. 1
    先出 tool_use 事件

    會話發出agent.tool_use或agent.mcp_tool_use,裏面已經有evaluated_permission: "ask"。

  2. 2
    再出 idle

    會話暫停,session.status_idle的stop_reason.type是requires_action。被堵住的事件 id 在stop_reason.event_ids。它會一直等。

  3. 3
    你回確認事件

    對每個阻塞 id 發user.tool_confirmation,tool_use_id填那個事件 id,result填allow或deny。拒絕時可用deny_message解釋。一次請求可以帶多條確認。

  4. 4
    會話回到 running

    全部阻塞解開後,被允許的工具執行;被拒絕的不跑,Agent 會收到帶你deny_message的 tool result。

允許或拒絕一次等待中的調用
{
  "events": [
    {
      "type": "user.tool_confirmation",
      "tool_use_id": "sevt_01ask...",
      "result": "allow"
    },
    {
      "type": "user.tool_confirmation",
      "tool_use_id": "sevt_01mcp...",
      "result": "deny",
      "deny_message": "Do not push to main from this session."
    }
  ]
}

如果事件的evaluated_permission不是 ask,你再發確認,API 會回 400。這包括 auto 已經 deny 的調用:客戶端沒有複議通道。交互式處理可以用ant beta:sessions connect,終端裏看到等待中的調用再允許或拒絕。

自己搭審批隊列、把 deny 寫回 Agent、以及如何在 Host 裏落一份可回放的策略,留給後一篇講實現。本篇只把平臺已經替你評估完的那一段 JSON 說清楚。

auto 不是檢查點

官方有一句不宜略過:auto不是人類檢查點。服務器認爲安全時,調用會在任何人看見之前執行,效果可能不可逆。必須有人看的工具,給它配always_ask。

自定義工具也不在這套門裏。agent.custom_tool_use既沒有evaluated_permission,也沒有evaluation。你的應用收到事件,自己決定執行還是拒絕,再回user.custom_tool_result。平臺不會替你評這一跳。

所以「AI Agent 如何自動判斷 Tool Call 是否允許」這句話,範圍其實很窄:只覆蓋服務器代執行的 Agent 工具和 MCP 工具,而且只在你顯式把 policy 寫成auto之後。其餘要麼永遠放行,要麼永遠問人,要麼根本不歸平臺管。

用 JSONNote 覈對策略和事件

策略 JSON、tool_use 事件、確認請求,三份結構長得像,字段卻不是同一層。調試時不要靠眼睛掃。

  1. 1
    先格式化策略

    把 Agent 的tools配置丟進JSON 格式化,確認default_config和configs裏的permission_policy.type沒有寫錯、沒有被覆蓋喫掉。

  2. 2
    再校驗事件形狀

    用JSON Schema給evaluation寫一份最小 schema:type枚舉always_allow / always_ask / auto,auto 時要求嵌套evaluated_permission。未知的reason_code用additionalProperties兼容,不要直接拒掉。

  3. 3
    對比兩次調用

    同一工具一允一拒時,用JSON Diff對齊兩次input和兩次evaluation。差別幾乎總在 command、path 或會話裏剛剛發生的那一步,不在工具名。

  4. 4
    留一份可分享的覆盤

    策略和打碼後的事件可以用Hash 分享遞給同事,數據不過服務器。密鑰和生產 token 不要放進去。

常見問題

auto 會不會把所有 Tool Call 都放行?

不會。auto 是按次評估:同一工具的兩次調用,輸入和會話不同,結果可以不同。判定爲 high_risk 會直接 deny,客戶端不能用 user.tool_confirmation 推翻。

JSON Schema 合法是否等於允許執行?

不等於。Schema 只回答參數長得對不對。permission policy 回答這次調用能不能跑。形狀合法的 bash 命令,auto 仍可能寫成 deny。

MCP Tool Call 默認走哪條策略?

MCP toolset 默認 always_ask。新工具加進 Server 時不會在你的應用裏自動執行。信任某個 Server 再把 default_config.permission_policy 改成 always_allow 或 auto。

自定義工具受不受 permission policy 管?

不受。Custom tools 由你的應用執行。事件是 agent.custom_tool_use,沒有 evaluated_permission 和 evaluation。你自己決定跑不跑,再回 user.custom_tool_result。

auto 能代替人工審批嗎?

不能。官方寫明 auto 不是人類檢查點。服務器認爲安全時,調用會在任何人看見之前執行,副作用可能不可逆。必須人看的工具,單獨配 always_ask。

小結

9 月 10 日加上的auto,把「這個工具能不能用」改成了「這一次調用能不能跑」。判斷依據是你寫進 Agent 的 JSON policy,加上這一次的工具、輸入和會話;判斷結果寫回事件裏的evaluated_permission和evaluation。

模型負責提出調用。策略引擎負責允許、拒絕或停下來問人。MCP 默認先問人。自定義工具你自己管。客戶端推翻不了 deny。

把策略 JSON 和事件 JSON 當成兩份契約來讀,不要把 Schema 合法誤認成已經授權。需要人盯的工具繼續 always_ask;需要少打斷、又能留下審計字段的工具,再打開 auto。

返回博客