Bring your app to Siri
System Frameworks 进阶 20m

将你的应用接入 Siri

Bring your app to Siri

2024年6月10日

在 Apple 官方观看视频

一句话判断

Apple Intelligence 让 Siri 真正能理解自然语言了,而 Assistant Schemas 是你把应用接入这套能力的最短路径——只要一个 Macro,你的 AppIntent 就能被 Siri 的 LLM 理解和调用。

这场 Session 讲了什么

Siri 的底层架构在今年发生了质变。借助 Apple Intelligence 的大语言模型,Siri 获得了三项核心能力:更自然的语音表达、屏幕上下文感知、以及更灵活的语言理解(说错了也没关系)。这意味着用户可以用更随意的口语触发 Siri 操作,而不是背诵固定句式。

对开发者来说,接入方式分两层。老项目如果已经用了 SiriKit,不需要改任何代码,Siri 的理解能力提升自动生效。但如果你的应用功能不在 SiriKit 的预定义域里(比如不是音乐、不是消息),那就应该用 AppIntents 框架。今年 Apple 在 AppIntents 上新增了 12 个 App Intent Domains,覆盖 Books、Camera、Spreadsheets 等场景,每个 Domain 内包含一组预定义的 Schema。

Assistant Schemas 是今年最关键的新 API。它的思路是:Apple 的模型已经针对特定”形状”的 Intent 做了大量训练,你只需要让自己的 AppIntent 符合这个形状,就能白嫖 Siri 的自然语言理解能力。实现方式简单粗暴——在 AppIntent 声明前加一个 @AssistantIntent(schema:) Macro,编译器就能帮你补全大部分样板代码。

值得深挖的点

Assistant Schemas 的设计哲学

Schema 这个词被 Apple 用得很精准。每个 Schema 定义了一组固定的输入输出结构,比如 .photos.createAlbum 就是一个创建相册的 Schema。Apple 的 LLM 在训练时已经学会了”用户说要创建相册时,该匹配哪个 Schema、提取哪些参数”。你只要让自己的 Intent 对齐这个结构,模型就能正确路由到你的代码。

这个设计的聪明之处在于:开发者不需要理解 NLP,不需要处理同义词、口误、歧义。模型的训练成本由 Apple 承担,你只需要写 perform() 方法里的业务逻辑。代价是你的 Intent 必须符合预定义的”形状”——但 Apple 允许你添加 optional 参数来扩展这个形状,给了足够的弹性。

从架构角度看,这套系统的工作流是:用户请求 -> Apple Intelligence 模型推理 -> 匹配 Schema -> 从所有注册了该 Schema 的 AppIntent 中选择 -> 执行。你的应用在设备上的 Intent 组成了一个”工具箱”,模型按需取用。

三种 Macro,统一接入

Apple 为 Intent、Entity、Enum 各提供了一个 Assistant Macro:@AssistantIntent@AssistantEntity@AssistantEnum。三者分工明确:Intent 定义动作,Entity 定义数据模型,Enum 定义枚举值。

有趣的是,@AssistantEnum 不像另外两个那样强制你遵循预定义的形状,允许你自由定义枚举值。这说明 Apple 在语义理解上的策略是:动作和数据结构需要标准化(因为模型需要精确匹配),但枚举这种离散值的表达空间应该留给开发者。

代码片段

用 AssistantIntent Macro 接入 Siri

// 一个 Macro 搞定 Siri 接入,schema 参数指定域和具体动作
@AssistantIntent(schema: .photos.createAlbum)
struct CreateAlbumIntent: AppIntent {
    // Schema 已经定义了输入输出,编译器会自动补全所需属性
    @Parameter(title: "Album Name")
    var name: String

    func perform() async throws -> some IntentResult {
        // 你的业务逻辑,Siri 会在合适的时机调用这里
        let album = PhotoManager.shared.createAlbum(named: name)
        return .result(value: AlbumEntity(album: album))
    }
}

场景:让用户通过 Siri 语音创建相册。坑:如果 Schema 定义了必选参数但你没提供 @Parameter,编译器会报错——这其实是好事,强制你对齐模型预期。

用 AssistantEntity 暴露数据模型

@AssistantEntity(schema: .photos.album)
struct AlbumEntity: AppEntity {
    let id: UUID
    let title: String

    // 可以在 Schema 形状之外扩展 optional 属性
    var accentColor: Color?

    static var typeDisplayRepresentation = TypeDisplayRepresentation(name: "相册")
}

场景:让 Siri 理解你的应用里”相册”这个概念。坑:不要在 optional 属性里塞太多东西,只加用户可能通过语音查询的字段。

AssistantEnum 自由定义

@AssistantEnum(schema: .photos.sortOrder)
enum PhotoSortOrder: String, AppEnum {
    case newestFirst
    case oldestFirst
    case byName

    // 不强制形状,你可以定义任何 case
    static var typeDisplayRepresentation = TypeDisplayRepresentation(name: "排序方式")
}

场景:定义相册排序选项供 Siri 使用。这里没有形状约束,自由发挥。

最佳实践

已有项目: 如果你已经用了 SiriKit,什么都不用做,Siri 的语言理解提升自动生效。如果你用了 AppIntents 但没接 Schema,可以逐步给核心 Intent 加上 @AssistantIntent Macro——这是一次低成本高回报的改造,因为 Schema 定义本身就帮你砍掉了大量样板代码。

新项目: 优先检查你要做的功能是否落在 12 个 Domain 里。如果是,直接用 Assistant Schemas 起步。如果不在,还是用标准 AppIntents,但保持关注——Apple 明确说了这只是开始,后续会扩展更多 Domain。

还有什么值得关注

  • 今年首发的 12 个 Domain 里,Mail 和 Photos 已经可以试用,其余会在未来几个月陆续推出。
  • Siri 现在支持超过 100 种不同动作,覆盖这 12 个 Domain。
  • subscriptionPromotionalOffer 这个新 View Modifier 可以在 SubscriptionStoreView 里直接展示促销优惠。
WWDC 2024