美奈只請 AI 幫三個人找一段 30 分鐘的共同空檔。幾秒後,時段確實找到了;但客戶也收到一封她還沒看過的會議邀請,主管的行事曆上多了一個忙碌時段,會議名稱甚至沿用了內部工作用語。
問題不是 AI 不會看行事曆,而是團隊把三個動作混成一個「排會議」:查空檔、準備提案、送出邀請。前兩步可以沒有對外承諾;第三步會碰到別人的行事曆、收件匣與時間。找得到時間,只證明排程上可行,不代表有人授權 AI 以主辦人身分發信。
一句「幫我約時間」,其實跨了三道門
第一道門是唯讀查詢。AI 只需要知道哪些區段忙碌,未必需要會議名稱、參與者名單或完整說明。對大多數找空檔任務,回傳兩三個候選時段已經足夠。
第二道門是私人草稿或暫留。AI 可整理會議名稱、長度、時區與候選來賓,甚至替使用者準備一個「加入行事曆」連結;但東西仍停在本人可檢查的地方,沒有成為別人的通知或承諾。Microsoft 的 Graph 權限指南就建議,若使用者不授予 Calendar.ReadWrite,可用加入行事曆的 deep link 當替代方案,讓人自己完成建立動作。
第三道門才是建立含來賓的事件並送出更新。Google Calendar 的 events.insert 會建立事件,來賓名單是可寫欄位;sendUpdates 還會決定通知所有來賓、只通知外部來賓,或不發通知。Microsoft Graph 也明確寫著,事件送出後,伺服器會向所有 attendees 寄出邀請。這不是草稿多一個欄位,而是對外動作已經發生。
把授權寫成這一次能做的事
OAuth 同意畫面只能回答「這個應用程式可能取得哪些能力」,不能代替每一次會議的決定。Google 要求應用程式只申請完成工作所需的最窄 scope;Microsoft 也把唯讀與 Calendars.ReadWrite 分開。即使產品確實需要寫入權限,執行時仍要再問:這一次是只找空檔、替本人建立暫留,還是代表本人邀請特定對象?
- 這一次,AI 被授權做到哪裡?
- 只比較共同空檔唯讀查詢,回傳少量候選時段,不建立事件也不通知任何人
- 只替我保留時間建立本人可見的私人暫留,不加入來賓,標明仍待確認
- 邀請指定來賓先顯示完整預覽,取得綁定本次參數的批准後,只執行一次
這個分支要落在工具層,不只寫進提示詞。只找時間的 agent 不應拿到寄送工具;需要完整排程功能的產品,也可以把唯讀查詢、建立私人暫留、送出來賓邀請做成三個不同工具,由政策元件檢查可用範圍。OWASP 的 AI Agent Security Cheat Sheet 同樣建議區分 read-only 與 write、替對外可見動作做預覽,並把批准綁到具體工具、目標、參數、時間與期限。
預覽要讓人看見「誰會被影響」
「要建立這場會議嗎?」太模糊。真正可放行的預覽至少要列出:
- 以哪個帳號與哪一本行事曆當主辦人;
- 每位來賓的身分,以及必要、選填或會議室資源等角色;
- 開始與結束時間、時區、是否重複;
- 標題、說明、地點、線上會議連結與可見性;
- 哪些人會收到新增或更新通知;
- 這次批准何時失效,以及重試時如何避免重複建立。
不用為了顯示身分而把完整信箱地址寫進一般日誌;預覽可讓批准者確認具體對象,稽核紀錄則保存受控的識別碼與遮罩資訊。重點是批准不能只綁「排一場會議」這個意圖,而要綁到這一組主辦人、來賓、時間、時區與通知方式。任何一項在批准後改變,就回到預覽。
重複執行也要設防。Microsoft 的建立事件範例使用 transactionId 減少伺服器上的不必要重試;這提醒我們,網路逾時不等於第一次沒有成功。agent 遇到不確定結果時,應先用交易識別碼或事件 ID 查回狀態,不要直接再送一次。若系統無法確認是否建立成功,就停下來交給人處理。
從只能提案的版本開始
第一週先讓 AI 做一件窄事:讀取必要的 free/busy 區段,輸出兩個候選時段,附上時區與衝突來源,然後停止。不要讀會議說明,不要建立事件,也不要寄通知。這能先測出時區、工作時間、跨日與既有暫留是否被正確處理。
第二階段才加入本人私人暫留,而且要有明顯的「待確認」狀態與自動到期。最後若真的需要代發邀請,再限定可用的主辦帳號、來賓網域、人數、會議長度與時段範圍,並要求逐次預覽。敏感、人資、醫療、法律或尚未公開的會議,不應因為找得到共同空檔就自動揭露主旨與名單。
若唯讀權限被拒絕,讓人手動提供兩三個時段;若寫入權限被拒絕,產生 deep link 或可複製的會議草稿。少一點自動化仍能完成協調,沒有必要為了省下一次點擊,把讀取能力直接升成對外代表權。
這和每日摘要裡的邀請不等於已承諾是同一條責任線的兩端:收到邀請的人要保留接受權,送出邀請的人也要保留代表自己承諾的權力。若要把原則擴到信箱、檔案與付款工具,可再搭配常駐 AI 助理的讀取、草擬與停手分層。
AI 整理卡
請從我目前已授權你查看的一個 AI 排程流程開始,維持唯讀;不要建立、修改、取消事件,不要加入來賓、寄送通知或變更任何權限。先列出流程中的每個工具呼叫,依序標明它讀取的欄位、寫入的資源、會影響的帳號、可能寄出的通知、所需 scope,以及目前是否有逐次批准。把動作分成「比較共同空檔」「建立本人私人暫留」「建立含來賓的事件並送出邀請」三層;任何同時跨兩層的工具都標成邊界過寬。接著設計一個只能輸出兩個候選時段的最小版本,包含時區、衝突來源與缺值,不讀取不必要的會議內容。若流程需要寫入,另外產生完整預覽欄位:主辦帳號、行事曆、來賓與角色、開始/結束、時區、重複規則、標題、地點、可見性、通知對象、批准期限與防重複識別碼。缺少任一項就停在提案,不要替我補值或執行。
四格看懂:先問朋友,再發晚餐邀請

- 美奈和三位朋友正在群組裡約晚餐,桌上三份週間行程各有不同的忙碌時段。
- AI 對齊三人的行程,只把唯一重疊的空檔標成候選時段,沒有替任何人發出邀請。
- 美奈先把候選時段丟回群組詢問;一人已答應,另兩人的回覆仍在等待中。
- 三位朋友都確認可以之後,美奈才按下行事曆事件,把正式晚餐邀請送給大家。
美奈先拿到的不是一場已經替所有人決定好的聚餐,而是一個可以拿去問朋友的候選時段。AI 把受指派的找時間工作做完;等大家都確認、用什麼名稱、是否真的送出,仍由她決定。多一次群組確認,保住了每個人的行事曆與她自己的對外承諾。
參考來源
- Google Calendar API:Events: insert — https://developers.google.com/workspace/calendar/api/v3/reference/events/insert [updated: 2026-07-07]
- Google for Developers:Sensitive scope verification — https://developers.google.com/identity/protocols/oauth2/production-readiness/sensitive-scope-verification [updated: 2026-07-17]
- Microsoft Learn:Best practices for using Microsoft Graph permissions — https://learn.microsoft.com/en-us/graph/best-practices-graph-permission [updated: 2024-11-07]
- Microsoft Learn:Create event — https://learn.microsoft.com/en-us/graph/api/user-post-events?view=graph-rest-1.0 [updated: 2024-04-04]
- OWASP Cheat Sheet Series:AI Agent Security Cheat Sheet — https://cheatsheetseries.owasp.org/cheatsheets/AI_Agent_Security_Cheat_Sheet.html [accessed: 2026-07-31]



