博客 • AI / App Intents
iOS 27 Siri AI 開放更多能力後,App Actions 的 JSON 數據到底如何流轉?從用戶指令到 API 執行完整解析
一條 Siri 指令能執行,是因爲它先變成 App Intent 的參數,再在 AppIntent 的 perform() 裏決定走本機還是打你的 API。系統不把整段語音原樣發給服務器。
Siri 算不算 Agent,寫在 上一篇。本篇只跟一條指令:短語怎麼對上 Intent,參數怎麼變成 JSON,校驗通過之後才調用 API。
- 短語對上 App Shortcut,而不是把語音當自由文本執行
- 參數分三種:內建類型、編譯期固定的 AppEnum、要查詢的 AppEntity
- 實體只交出穩定 id,查詢用這個 id 找回你的數據
- 你自己記一份參數 JSON,這不是 Apple 的線上協議
- resolved 爲 false 或 Schema 失敗時,不打 API,把對話交回 Siri
先記住這一點:語音不是請求體。Intent 填好的參數纔是。下面按「短語 → 參數類型 → 實體 id → 你的 JSON → API」走一遍。
一條指令經過的五步
官方入口是 App Intents。說明見 App Intents 入門。Siri、快捷指令和應用內按鈕走的是同一套 Intent,差別在誰填參數。
- 1短語命中
你在
AppShortcutsProvider裏登記口語句。系統用這句話選中某個 Intent,不是把原話交給模型自由發揮。 - 2填參數
Intent 上的
@Parameter告訴系統要什麼值、必填還是可選。缺了會向用戶追問,而不是猜一個發出去。 - 3解析實體
用戶數據用
EntityQuery按id解析。參數裏放的是實體,不是一段描述它的文本。 - 4執行
perform() 裏纔讀到已經解析好的值。本機能做完的就在這裏做完。
- 5回給 Siri
用
IntentResult或對話返回結果。失敗也要有一句能說出口的原因,不要只在服務器日誌裏留錯。
參數分三種
參數類型見 爲 App Intent 添加參數。選錯類型,後面的 JSON 就會不穩定。
| 類型 | 適合 | 進 JSON 時 |
|---|---|---|
| 字符串、數字、日期 | 數量、備註這種簡單輸入 | 原樣放進 parameters |
AppEnum | 編譯期就固定的選項,例如到店取還是配送 | 用枚舉值,不要把展示文案當主鍵 |
AppEntity | 會變的用戶數據,例如某件商品 | 只放解析後的 id |
固定集合用 AppEnum。會隨用戶增刪的用 AppEntity 加查詢。把會變的列表寫成枚舉,選項一過期,短語就對不上。
實體只帶走 id
系統要的是可顯示、可查詢的實體。你的數據庫仍是數據源。實體上至少要有穩定 id 和給人看的名字。
{
"entity": "OrderItem",
"id": "sku_42",
"display": "Oat milk"
}
查詢實現 entities(for identifiers:),用 id 找回對象。找不到就不要編一個 id 繼續。
你自己的參數 JSON
下面這份是你在 perform() 裏落盤、再決定要不要打 API 的契約。它不是 Apple 的請求格式,系統也不會替你讀這個文件。
{
"intent": "StartOrder",
"source": "siri",
"parameters": {
"item_id": "sku_42",
"quantity": 1
},
"resolved": true
}
intent用 Intent 類型名,方便和快捷指令裏的動作對上。item_id用實體 id,不用口頭說法。說法會變,id 不該變。resolved爲 false 表示還沒解析完,或用戶取消了追問。這時不打 API。- 不要把原始語音、定位軌跡或令牌寫進這份 JSON。
什麼時候打 API
- 1本機能完成
只改本機狀態的動作,在 perform() 裏做完,不必出網。
- 2先校驗
要用服務器時,先用 Schema 校驗上面的 JSON。缺 item_id、quantity 小於 1,都停在設備上。
- 3再出網
校驗通過且 resolved 爲 true,才把 parameters 發給你的 API。服務器再按 id 查自己的記錄,不信任展示名。
- 4失敗說人話
API 拒絕或超時,用 Intent 對話告訴用戶沒完成。不要讓 Siri 說已經成功。
第三方 App 怎麼聲明 Intent、失敗怎麼回,是下一篇的題目。本篇停在這條數據路徑。
和舊文怎麼分工
| Siri 是不是 Agent | 本篇 | |
|---|---|---|
| 回答 | 系統會不會自己規劃並調用工具 | 一條指令從短語到 API 經過哪些 JSON |
| 不要在這裏找 | 又一篇產品發佈稿 | 把語音原文當成可以落盤的請求體 |
硬件和系統功能的產品敘事見 iPhone 18 爲什麼不只是硬件。那邊不拆參數字段。
在 JSONNote 裏檢查這條 JSON
- 1格式化
用 JSON 格式化 打開這份參數記錄,確認沒有尾逗號。
- 2用 Schema 卡住缺字段
把下面的 Schema 貼進 JSON Schema。缺 intent、item_id,或 quantity 不是正整數,都不應發到 API。
- 3再驗一條樣例
用 JSON 校驗 貼一條真實樣例。重點看
item_id是不是空字符串。
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"additionalProperties": false,
"required": ["intent", "source", "parameters", "resolved"],
"properties": {
"intent": { "type": "string", "minLength": 1 },
"source": { "enum": ["siri", "shortcut", "app"] },
"resolved": { "type": "boolean" },
"parameters": {
"type": "object",
"required": ["item_id", "quantity"],
"properties": {
"item_id": { "type": "string", "minLength": 1 },
"quantity": { "type": "integer", "minimum": 1 }
}
}
}
}
常見問題
系統會把整段語音發給我的服務器嗎?
不會按這條路徑。服務器收到的應是你在 perform() 裏組裝、並校驗過的參數 JSON。語音留在設備側的識別過程裏。
參數裏爲什麼不直接寫商品名?
名稱會改、會重複。AppEntity 用穩定 id,查詢用這個 id 找回對象。API 也只認 id。
Schema 通過就可以打 API 嗎?
還要看 resolved。形狀對了但實體沒解析完,說明用戶還沒選定對象。這時打 API 會把一次追問變成一次錯誤下單。
本機動作和出網動作怎麼分?
只改本機數據的留在 perform()。要進你的後端的,先寫參數 JSON、校驗,再請求。兩種都要用 IntentResult 把結果說回給用戶。
這和快捷指令裏手填參數是同一條路嗎?
是同一套 AppIntent。差別是誰填參數:Siri 按短語填,快捷指令由用戶或上一個動作填。後面的實體解析、JSON 和 API 門閂相同。
總結
一條指令的數據路徑是:短語選中 Intent,參數按類型填入,實體收成 id,你寫成 JSON,校驗通過纔打 API,再用對話把結果交回 Siri。
直接結論:不要上傳原始語音;id 沒解析完就不請求;失敗要說回給用戶,而不是隻寫服務器日誌。
下一步:先用 Schema 卡住這條參數 JSON,再接到 perform()。