App Intents 是 Apple 通往你的 App 的全新API
2026 年 2 月 8 日早上,當我雙手在廚房水槽下沖洗時,我請 Siri 從 Apple Watch 為我記錄 8 oz 的飲水量。水量已記錄。手錶上的對話框顯示還剩 32 oz。我完全沒有碰過任何螢幕。1
十一週前,我為 Water(我的補水追蹤 iOS App)新增了一個 Swift 檔案:LogWaterIntent.swift,80 行的 AppIntent 程式碼,加上一個 AppShortcutsProvider 宣告了三種 Siri 詞句變體。這個檔案如今是我手中最熱門的API表面。2
接下來這部分我花了一段時間才真正理解。App Intents 並不是 Siri 的功能。 它們是第三方 App 與 Apple Intelligence 簽訂的契約,而 Apple Intelligence 是 Apple 從 iOS 18 開始推出、並一路在 iOS 26 持續打造的系統 AI 表面。3 如果你推出了一款 iOS App,卻仍把 App Intents 當作「有最好」的語音功能,那你就誤讀了 Apple 所打造的東西。App Intents 是讓 Apple 的 AI 能夠以你的 App 身分代表使用者執行動作的API。其他一切(Siri、Spotlight、Shortcuts、Apple Intelligence 摘要、Watch 與 Vision Pro 表面)都是這份契約的下游產物。Foundation Models 是 iOS 26 隨之推出的裝置端LLM,它公開了一個獨立的 Tool 協定供 App 內部進行工具呼叫;它與 App Intents 平行運行,並非透過 App Intents。
TL;DR
- App Intents 以類型化、結構化的方式宣告你的 App 能做什麼,讓 Apple 的 AI 可以直接呼叫。它們是 Apple 為第三方 App 提供的工具使用API。
- 一個真實的生產範例:Water 中的
LogWaterIntent。80 行程式碼,完整的 SwiftData 寫入、HealthKit 同步、地區感知的單位換算,以及結構化的 Siri 對話回應。 - iOS 26 新增了 Foundation Models,Apple 的裝置端LLM。Foundation Models 公開了自己的
Tool協定供 App 內進行工具呼叫;App Intents 仍然是 Siri / Spotlight / Apple Intelligence 跨 App 呼叫的標準表面。方向相同,兩份平行契約。 - 一款在 2026 年沒有 App Intents 的 App,對 Apple Intelligence 而言是隱形的。AI 結構會透過你宣告的 intents 進行路由,否則就會繞過你的 App,前往競爭對手。
- 三年來 Apple 一直在告訴我們這件事。命名(App Intents、App Shortcuts、Apple Intelligence)是有意為之。每次 WWDC,這份契約都往堆疊上層挪一級。
App Intent 究竟是什麼
以下是 LogWaterIntent 在 2026 年 2 月 8 日 commit e398c58 中推出時的完整原始碼:2
import AppIntents
import SwiftData
struct LogWaterIntent: AppIntent {
static var title: LocalizedStringResource = "Log Water"
static var description: IntentDescription = "Log a glass of water to your daily intake"
@Parameter(title: "Amount", default: 8)
var amount: Int
static var parameterSummary: some ParameterSummary {
Summary("Log \(\.$amount) oz of water")
}
func perform() async throws -> some IntentResult & ProvidesDialog {
let container = try ModelContainer(for: WaterEntry.self, DailyLog.self, UserSettings.self)
let context = ModelContext(container)
let settingsDescriptor = FetchDescriptor<UserSettings>(
predicate: #Predicate { $0.id == "user-settings" }
)
let settings = try context.fetch(settingsDescriptor).first ?? UserSettings()
let amountMl: Double
if settings.unitSystem == .imperial {
amountMl = Double(amount) * 29.5735
} else {
amountMl = Double(amount)
}
let todayKey = DailyLog.todayKey()
let logDescriptor = FetchDescriptor<DailyLog>(
predicate: #Predicate { $0.dateKey == todayKey }
)
let log: DailyLog
if let existing = try context.fetch(logDescriptor).first {
log = existing
} else {
log = DailyLog(date: .now, goalAmount: settings.dailyGoal)
context.insert(log)
}
let entry = WaterEntry(amount: amountMl)
log.entries.append(entry)
try context.save()
if settings.healthKitEnabled {
try? await HealthKitService.shared.logWater(amount: amountMl, date: entry.timestamp)
}
let unit = settings.unitSystem == .imperial ? "oz" : "mL"
let totalDisplay = settings.formatAmount(log.totalAmount)
return .result(dialog: "Logged \(amount) \(unit). Today's total: \(totalDisplay)")
}
}
struct WaterShortcuts: AppShortcutsProvider {
static var appShortcuts: [AppShortcut] {
AppShortcut(
intent: LogWaterIntent(),
phrases: [
"Log water in \(.applicationName)",
"Add water in \(.applicationName)",
"Drink water in \(.applicationName)",
],
shortTitle: "Log Water",
systemImageName: "drop.fill"
)
}
}
(Water 目前正式版的這個檔案進一步擴充了對話內容,加入了「達成目標 / 剩餘量」的條件判斷。上面 2 月 8 日推出的版本,就是我在廚房水槽前測試的那一份。)
這裡有三件事值得特別點名,因為大多數「App Intents 教學」都一筆帶過。
@Parameter 就是 schema。 Apple 的 AI 看到的是 amount: Int,預設值為 8。當 Siri 解析「log 12 oz of water」時,它會生成 LogWaterIntent(amount: 12) 並呼叫 perform()。我這邊完全不需要做字串解析。型別系統就是 schema。5
parameterSummary 是參數的自然語言反映。 Apple 用它在 Shortcuts UI、對話內容,以及 Apple Intelligence 的確認面板中呈現動作。這段摘要會被朗讀回給使用者聽。寫得不好,使用者就會聽到一句拗口的句子;寫得好,整個介面就會感覺渾然天成。6
perform() 回傳 IntentResult & ProvidesDialog。 這就是結構化的回傳值:AI 表面拿回的不只是成功/失敗,還有一段使用者會聽到的對話字串。Apple 越來越期待 ProvidesDialog、ProvidesView 或 ReturnsValue,讓結果能整合進 Siri、Spotlight、Watch,以及(在 iOS 26 中的)Apple Intelligence 的回應鏈。7
底部的 AppShortcutsProvider 區塊則是負責註冊 Siri 詞句的地方。\(.applicationName) 標記就是 Siri 自動插入「Water」的位置。三種詞句變體共用同一個 intent,讓 Apple 的自然語言解析器有更多空間可以比對使用者的說法,而你不必自行維護一套詞句字典。systemImageName 是真實存在的 SF Symbols 名稱;Spotlight、Shortcuts 和 Apple Intelligence 就是依此來呈現動作的圖示。
為什麼這是繼 SwiftUI 之後最重要的 iOS API
iOS API可以分成兩種形態。一種關乎 App 如何繪製自己(UIKit、SwiftUI、Metal)。另一種則關乎 App 如何與系統整合(URL schemes、Universal Links、Widgets)。App Intents 是第三種形態:它是 Apple 的 AI 如何使用你的 App。
這條演進路線值得追溯。
- iOS 10(2016) 引入了 SiriKit Intents(
INIntent),這是第三方 App 第一次能夠透過語音被呼叫。這個表面相當狹窄:只有一個固定的領域清單(訊息、付款、叫車),且 schema 嚴格。8 - iOS 12(2018) 透過 Siri Shortcuts 拓寬了這個表面:任何 App 都能捐贈
NSUserActivity或INIntent,然後寄望 Siri 會主動建議它。 - iOS 13(2019) 加入了 App 內部的 intent 處理機制,讓 App 可以回應 shortcut 呼叫,而不必切換到系統的 Siri UI。
- iOS 16(2022) 引入了 App Intents 框架:類型化、宣告式,搭配
@Parameter和AppShortcutsProvider。對於新開發案而言,前身INIntent實質上已被取代。9 - iOS 18(2024) 推出了 Apple Intelligence,並開始在可行的範圍內把 Siri 請求都路由到 App Intents。Apple Intelligence 的「個人情境」功能會從 App Entities(App Intents 的資料版本)讀取。10
- iOS 26(2025) 推出了 Foundation Models 框架,Apple 的裝置端LLM。Foundation Models 公開了一個獨立的
Tool協定供 App 內部進行工具呼叫。App Intents 仍是 Apple Intelligence 的標準跨 App 表面,而Tool則是直接呼叫LLM的 App 內部表面。兩份契約平行運行。4
每一次發布,這份契約都在堆疊上層延伸。最初 App Intent 的消費者是點擊 Shortcuts 的人。接著是 Siri 語音。然後是 Spotlight。再然後是 Apple Intelligence 摘要。如今 Apple Intelligence 的LLM支援系統表面利用它們來執行使用者的請求。你在 2026 年推出的 App Intent 表面,就是 Apple Intelligence 將會在 iOS 27、28、29 上呼叫的那一套。
當我說 App Intents 不是 Siri 功能時,上面這個模式就是我要表達的意思。它們是整個 Apple AI 結構的結構化工具使用API。SwiftUI 之所以是最重要的 UI API,是因為它變成了 visionOS、watchOS 10+ 與 iOS 17+ 上撰寫 App 的唯一方式。App Intents 在 AI 端正在描繪一條相同的弧線:Apple 把所有賭注都壓在這個表面上。
Foundation Models 推出之後,有什麼改變
Foundation Models 是會在所有支援 Apple Intelligence 的裝置上隨附推出的框架。硬體門檻與 Apple Intelligence 清單相同:iPhone 15 Pro 與 15 Pro Max(A17 Pro)、iPhone 16 系列、iPhone 17 系列、iPhone Air、iPhone 17e、搭載 M1 或更新晶片的 iPad Pro、搭載 M1 或更新晶片的 iPad Air、搭載 A17 Pro 的 iPad mini、搭載 M2 或更新晶片的 Vision Pro,以及搭載 M1 或更新晶片的 Mac。值得注意的缺席者:基本款 iPhone 15 / 15 Plus。412
其中的含意是:如果 Apple 的系統表面(Siri、Spotlight、Apple Intelligence)真的要呼叫你的 App,它們會透過 App Intents 與 App Entities 來呼叫。在系統 AI 結構中,沒有給第三方 App 用的 setSystemPrompt(...) API。有的是 intent 註冊機制。Foundation Models 為想自行建構裝置端LLM功能的開發者新增了一條平行的 App 內部 Tool 表面。跨 App 契約(Apple Intelligence 與 Siri 用來找到你的 App 的那一份)仍是透過 App Intents 運行。
對 App 開發者而言,有三項具體後果:
沒有相關 App Intent 的 App,在它的類別中無法被 Siri 語音指令觸及。 Apple Intelligence 會把「Hey Siri,記錄我的飲水量」這類詞句,優先路由到先宣告了相應 intent 的 App。我在 2026 年 2 月推出了 Water 的 intent。我對框架方向的判斷是:在 2027 年才推出 intent 的補水 App,將進入一個路由權重早已累積在先行者身上的市場。同樣的邏輯也適用於購物清單、運動紀錄、行事曆項目、相片搜尋。我預期 intent 宣告上的先行者優勢會像 Apple 在其他平台級API賭注一樣不斷累積(HealthKit 類別、Spotlight 豐富搜尋結果、Live Activities 標記)。
Apple Intelligence 的個人化讀取自 App Entities,而不只是 intents。 AppEntity 宣告「這個 App 擁有此種形狀的資料」。當使用者問「我加進閱讀清單的最後一本書是什麼」時,Apple Intelligence 會搜尋每一個已安裝 App 中比對 Book 的所有 AppEntity。如果你的 App 有閱讀清單,卻沒有宣告 BookEntity,你的資料對 Apple 的 AI 表面來說就是隱形的。Apple Intelligence 既無法擷取也無法引用你的資料。11
IntentResult & ProvidesDialog 的回傳形狀越來越重要。 Apple Intelligence 正在把 intent 的執行結果,組合成 Siri、Spotlight 與 Watch 上更長的回應。一個 perform() 如果只回傳成功而沒有結構化對話,系統就難以把它組成連貫的回覆。ProvidesDialog 與 ProvidesView 並非可有可無的禮節;它們是讓你的動作得以成為使用者 AI 表面中一條引文的方式。
我會如何不一樣地打造它
Water 在生產環境中跑了十一週,告訴我有三件事我應該更早做。
推出比你以為需要的更多 intents。 我推出了一個。我應該推出四個:LogWaterIntent、CheckTodaysProgressIntent、AdjustGoalIntent、ShowHistoryIntent。每一個都對應到使用者實際會嘗試的 Siri 詞句(像「我今天喝了多少水」這樣的查詢被路由到 Apple 的通用 AI,而不是我的 App 資料)。每一個遺漏的 intent 都是一條 Apple Intelligence 繞過我的查詢。
對話字串不是電子郵件正文。 我從一開始就有 ProvidesDialog,但早期的對話寫得像散文。當使用者透過 CarPlay 或 AirPods 聽到時,他們需要的是簡短、具體、以事實為主的結構:「已記錄 8 oz。還剩 32 oz。」Watch 表面尤其會大幅截斷內容。會話式對話的使用者體驗比自信的事實式對話更糟。我在第 4 週重寫了我的版本。2
App Entities 比我以為的更重要。 我有一個 WaterEntry SwiftData 模型。我也應該宣告 WaterEntryEntity: AppEntity 加上其搭配的 WaterEntryQuery: EntityQuery,讓 Apple Intelligence 能夠回答「顯示我昨天什麼時候喝了水」。最簡的橋接:11
struct WaterEntryEntity: AppEntity {
static var typeDisplayRepresentation: TypeDisplayRepresentation = "Water Entry"
static var defaultQuery = WaterEntryQuery()
var id: UUID
var displayRepresentation: DisplayRepresentation {
DisplayRepresentation(title: "\(amount) oz at \(timestamp.formatted())")
}
var amount: Int
var timestamp: Date
}
struct WaterEntryQuery: EntityQuery {
func entities(for identifiers: [UUID]) async throws -> [WaterEntryEntity] {
// Fetch matching entries from SwiftData
}
func suggestedEntities() async throws -> [WaterEntryEntity] {
// Recent entries Apple Intelligence can suggest
}
}
兩個小型的 Swift 型別,加上 SwiftData 的擷取膠水程式碼。要讓條目能個別出現在 Spotlight 上(讓搜尋「water」的使用者能直接落到正確的條目),需要讓該 entity 遵循 IndexedEntity 並在寫入時捐贈索引更新。這就是 Apple 的 Spotlight 管線在純 AppEntity 暴露之外所期待的。
同樣的形態也適用於我其他的 App。Get Bananas 是我的購物清單 App,它已經有一個 SwiftData @Model ShoppingItem,內含 @Attribute(.unique) var id: UUID、name、amount、section、isChecked,加上一個用於 iCloud Drive 同步的 lastModified 欄位。13 把它包裝為 ShoppingItemEntity: AppEntity,並推出幾個 intents(AddShoppingItem、CheckOffItem、ShowList),就能把 Get Bananas 透過其 .mcpb MCP 伺服器已經暴露給 Claude Desktop 的同一層持久化資料,也暴露給 Apple Intelligence。14 兩個LLM生態系、兩種不同的契約,同一份購物清單。這就是『平行契約』命題在一款已上架 App 上的具體實現:SwiftData 模型是資料,App Intents 是 Apple 的契約,MCP 是 Anthropic 的契約,兩個表面操作的是同一份事實來源。
何時不該推出 App Intent
懂得拒絕也是設計的一部分。
如果你的 App 純粹是消費導向的(讀取使用者的相片、顯示新聞、播放音訊),沒有可變動的使用者狀態,App Intents 可能根本沒有東西可以暴露。Apple 的框架支援 OpenIntent(只是把 App 開啟到某個情境),但若唯一有用的動作就是「開啟這個 App」,那這個 intent 就是多餘的負擔。不要為了有而推出。
如果動作仰賴難以抽象化的 UI 操作(複雜的多步驟畫布工具、3D 編輯 App),那麼 intent 所要求的 parameterSummary 將退化成模糊的偽自然語言,沒人會這樣說話。「用模糊工具以強度 7 編輯我的照片」這句 Siri 詞句技術上可行,但沒有真人會說出這句話。這個 intent 的表面是徒增成本而沒有回報。
正確的判準是:當使用者會自然說出一句觸發動作的話時,App Intent 才有它存在的價值。「Log 8 oz of water」就是那一句。「對圖層 3 套用 sigma 2.4 的高斯模糊」就不是。如果你的 App 動作大多落在第二種模式,那 intents 就不是你的轉換槓桿。
結尾的判斷
過去三年來,Apple 一直在發出訊號:iOS 的系統 AI 結構是透過 App Intents 運行的。WWDC 2024 加入了透過 App Intents 路由的 Apple Intelligence。WWDC 2025 把 Foundation Models 並列加入,作為一個獨立的 App 內部工具呼叫表面,而 App Intents 則繼續作為 Siri / Spotlight / Apple Intelligence 持續使用的跨 App 契約。每一個訊號都指向同一個方向:類型化、宣告式的 App Intent,就是第三方 App 如今與系統簽下的契約。
大多數 iOS App 仍把 App Intents 當作 Siri Shortcuts:有空再做的功能。我的判斷是,這種定位會變得越來越站不住腳。隨著 Apple Intelligence 的系統表面持續延伸(目前已涵蓋 Siri、Spotlight、Shortcuts 與 Apple Intelligence 摘要),沒有宣告 intents 的 App 很可能會發現自己被排除在路由圖之外。我在觀察 Apple 其他平台賭注的經驗中發現,先行者的表面會不斷累積複利。
Water 的 LogWaterIntent 已經上線十一週了。推出一個 App Intent 的程式碼量,小到一個檔案就裝得下。不推出它的代價,則會隨著每一次 Apple Intelligence 發布而不斷增加。
如果你在 2026 年推出一款 iOS App,卻還沒有宣告至少一個 App Intent,那麼你的路線圖上就少了一條項目。把它加上去。
FAQ
在 iOS 開發中,App Intent 是什麼?
App Intent 是一個類型化、宣告式的 Swift 結構,將你 App 的某個動作公開給 Apple 的系統 AI 表面使用。它透過 @Parameter 宣告參數,透過 parameterSummary 提供自然語言摘要,並透過一個 async 的 perform() 主體來執行工作並回傳結構化的結果。Apple 的 Siri、Spotlight、Shortcuts 與 Apple Intelligence 都可以呼叫它。Foundation Models(Apple 的裝置端LLM)則使用一個獨立的 Tool 協定來進行 App 內部直接的工具呼叫。
App Intents 與較早的 INIntent 有什麼不同?
App Intents(於 iOS 16,2022 年推出)取代了 INIntent,成為 Apple 的主要 intent 框架。新框架完全以 Swift 為原生實作,使用 @Parameter 等 property wrapper,透過 AppEntity 支援型別安全的實體查詢,而且是 Siri、Spotlight、Shortcuts 與 Apple Intelligence 所呼叫的表面。較舊的 INIntent 仍受支援,但已不再有新功能投入。
我需要 iOS 26 才能推出 App Intent 嗎?
不需要。App Intents 從 iOS 16 起即可使用。iOS 26 額外加入了 Foundation Models 框架,但 App Intent 宣告本身在 iOS 16+ 都可以運作。上面的範例程式碼使用了 SwiftData(iOS 17+),所以部署目標取決於你的 perform() 主體匯入了什麼。純 App Intents 可一路相容到 iOS 16;以 SwiftData 為基礎的則需要 iOS 17。
App Intent 與 App Entity 有什麼差別?
App Intent 是一個動作(動詞)。App Entity 則是你的 App 所知道的資料(名詞)。LogWaterIntent 是一個 intent。WaterEntry 變成可查詢的型別則是一個 entity。Apple Intelligence 兩者都會用:用 intents 執行動作,用 entities 在回應中擷取與引用資料。
App Intents 與 Foundation Models 的工具呼叫有什麼關聯?
Foundation Models 公開了自己的 Tool 協定,供 App 內部直接進行LLM工具呼叫。App Intents 仍是 Apple Intelligence、Siri 與 Spotlight 呼叫的標準跨 App 表面。同樣的方向(類型化、宣告式的工具使用);兩份平行的契約。想要被系統 AI 表面觸及的 App 推出 App Intents;想要以自訂工具呼叫自己的裝置端LLM的 App 則推出 Tool 遵循。許多 App 兩者都會推出。
App Intents 不是一項功能。它是一份契約。先推出 intent 的 App 取得表面;後推出的 App 會發現表面早已被路由到別處。十一週前,我在 Water 中推出了一個。複利效應已經開始累積。
References
-
Personal field test, February 8, 2026, ~9:15 AM PT. Recorded as the first end-to-end Siri-to-
LogWaterIntent-to-SwiftData write on a paired Apple Watch. ↩ -
Author’s Water iOS app, published by 941 Apps (941apps.com).
LogWaterIntent.swiftshipped in Water 1.4, commite398c58on February 8, 2026. Source code excerpt above is the production version as of that initial commit; the dialog string has been iterated since. ↩↩↩ -
Apple, “Apple Intelligence Foundation Language Models,” machinelearning.apple.com. On-device + Private Cloud Compute hybrid. ↩
-
Apple Developer, “Foundation Models” framework. iOS 26+.
LanguageModelSessionexposes tool calling through theToolprotocol, separate from theAppIntentprotocol used by Siri / Spotlight / Apple Intelligence. The two are parallel contracts in the same direction. ↩↩ -
Apple Developer, “Creating Your First App Intent”. Property-wrapper-based parameter declaration; types are the schema. ↩
-
Apple Developer, “ParameterSummary”. Used by Shortcuts UI, Siri dialog, and Apple Intelligence confirmations. ↩
-
Apple Developer, “Returning a value from your intent”.
ProvidesDialog,ProvidesView,ReturnsValueshapes. ↩ -
Apple, “Introducing SiriKit”, WWDC 2016. SiriKit Intents (
INIntent) shipped in iOS 10. Siri Shortcuts followed in iOS 12 (2018) and in-app intent handling in iOS 13 (2019). ↩ -
Apple, “What’s new in App Intents”, WWDC 2022. Introduction of the typed, declarative App Intents framework. ↩
-
Apple, “Bring your app to Siri”, WWDC 2024. Apple Intelligence routing through App Intents and App Entities. ↩
-
Apple Developer, “AppEntity protocol”. The data type version of App Intents; queryable by Apple Intelligence and other system surfaces. ↩↩
-
Apple, “Apple Intelligence System Requirements”. Eligible devices: iPhone 15 Pro and Pro Max (A17 Pro), the iPhone 16 line, the iPhone 17 line, iPhone Air, iPhone 17e, iPad Pro with M1 or later, iPad Air with M1 or later, iPad mini with A17 Pro, Apple Vision Pro with M2 or later, and Mac with M1 or later. Notably absent: base iPhone 15 / 15 Plus. Foundation Models framework inherits the same hardware gate. ↩
-
Author’s Get Bananas, a SwiftUI + SwiftData shopping list app for iOS, macOS, watchOS, and visionOS.
ShoppingItemSwiftData@Modellives inItem.swift:@Attribute(.unique) var id: UUID,name: String,amount: String,section: String,isChecked: Bool,isOptional: Bool,sortOrder: Int,lastModified: Date?. iCloud Drive sync viaiCloudBackupManager. ↩ -
Get Bananas ships an MCP (Model Context Protocol) server bundled as
get-bananas.mcpbfor Claude Desktop. Tools exposed:get_shopping_list,add_item,remove_item,update_item,update_shopping_list. Anthropic’s MCP spec: modelcontextprotocol.io. ↩