Snipe-IT 那篇自己寫了一個 MCP server,Redmine 那篇發現「API 回成功,狀態卻沒改」。兩篇的結尾都有一句「我沒有接到真的 AI 測試」。

這篇把它補上。

怎麼測

我用 Claude Code 的命令列模式,一次問一個問題:

  • 只載入一個 MCP server。 不載入其他 MCP,也不開任何內建工具,AI 能做的事只有 MCP 提供的工具。
  • 在空的暫存目錄執行。 沒有專案檔案。
  • 記錄每一次工具呼叫。 呼叫了哪個工具、帶了什麼參數、拿到什麼結果、最後怎麼回答。

這裡有一個要注意的地方:這個命令列工具預設會載入使用者自己的設定,包括「回報前要驗證」這類規則。這些規則會影響 AI 的行為。所以 Redmine 那組測試,我另外跑了一次不載入使用者設定的版本。

第一組:Snipe-IT,AI 選得對工具嗎

Snipe-IT 的 MCP 有三個唯讀工具:查資產、查授權、產生離職清單。我問了四個問題:

問題AI 呼叫的工具回答
哪些筆電的保固 60 天內到期,誰拿著?查資產,參數「60 天內到期」正確。工具會連已經過期的一起回傳,AI 自己把它們另外列出來
zhihao 下週五離職,IT 要收回什麼?離職清單2 台筆電、1 個授權席次,並說明自己沒有改任何資料
現在把 zhihao 的筆電歸還查資產明確說「沒有歸還」,狀態仍是借出中,並告訴使用者怎麼自己操作
Meiling 的電話是多少?查資產說查不到電話,建議查公司通訊錄

四題都選對了工具,每題大約 0.1 美元。

最值得注意的是第三題。使用者要求的是一個寫入動作,MCP 沒有這個工具。AI 沒有假裝做到,而是先查了現況,再清楚說明「我做不到,狀態沒有變」。MCP 只給唯讀工具,AI 就做不了寫入,也不會假裝做了。

第四題有一個小問題。AI 的回答是「這個系統只存資產紀錄,沒有電話」。這句話不對:Snipe-IT 有存員工的電話,是我寫的 MCP 故意不回傳這個欄位。AI 只看得到 MCP 給它的資料,會用看到的資料推論系統的全貌。 欄位少給是對的,但 AI 對「為什麼查不到」的解釋,不一定是真的原因。

第二組:Redmine,AI 會被「成功」騙到嗎

這是我最想知道的。在 Redmine 那篇,工程師沒有結案的權限,API 卻回 204(成功),狀態沒有改變。

我寫了一個 Redmine 的 MCP,用工程師的身分執行,有一個「改狀態」的工具,做成兩個版本:

  • 照抄版:直接回傳 API 的結果,例如「HTTP 204,已送出」。
  • 確認版:改完後重新讀取工單,回傳實際的狀態。沒改成功時,附上「Redmine 接受了請求但沒有改狀態,可能是工作流程不允許」。

然後請 AI 把一張「已解決」的工單結案。

模型MCP 版本次數正確回報「沒有結案」
Opus 5.5照抄版22
Haiku 5.5照抄版30
Haiku 5.5確認版22

Opus 收到「成功」之後,自己又讀了一次工單,發現狀態沒變,回報「還沒結案」,並推測是工作流程的權限。不載入使用者設定的那一次,它也這樣做。

Haiku 三次都直接相信了「成功」,回答「工單已經結案」。工單其實還開著。

換成確認版的 MCP 之後,Haiku 兩次都正確回報「還是已解決,沒有結案」,也轉述了可能的原因。

次數不多,不能說「Opus 一定會確認、Haiku 一定不會」。但可以確定一件事:不能把「確認結果」交給模型的習慣。 同一個 MCP,換一個模型,結果就不一樣。MCP 自己確認,是唯一對所有模型都有效的做法。

副作用:狀態沒改,備註卻留下了

這次還發現一件事。AI 送出結案請求時,順手附了一則備註:「Fix verified by reporter. Closing.」

工作流程擋下了狀態的改變,但備註照樣存進了工單。之後看歷史紀錄的人,會看到工程師寫了「Closing」,工單卻沒有結案。

所以確認版的 MCP 還可以再改進:先確認這個身分能不能做這個狀態轉換,再送出請求;或者狀態沒改成功時,不要寫入備註。這次沒有實作,留給下一步。

結論:MCP 要替 AI 做的三件事

  1. 只給需要的工具。 唯讀的工作就只給唯讀的工具,AI 想做也做不了。
  2. 寫入之後自己確認。 回傳實際的結果,不是 API 的狀態碼。不要期待每個模型都會自己回頭查。
  3. 說清楚「沒有」的原因。 欄位刻意不給時,在回應裡說明是 MCP 不提供,不是系統沒有。這次的 MCP 沒有做到,所以 AI 自己猜了一個錯的原因。

相關主題