View in English

  • 打开菜单 关闭菜单
  • Apple Developer
搜索
关闭搜索
  • Apple Developer
  • 新闻
  • 探索
  • 设计
  • 开发
  • 分发
  • 支持
  • 账户
在“”范围内搜索。

快捷链接

5 快捷链接

视频

打开菜单 关闭菜单
  • 专题
  • 相关主题
  • 所有视频
  • 关于

返回 WWDC25

  • 简介
  • 概要
  • 转写文稿
  • 代码
  • 了解 Foundation Models 框架

    了解如何利用 Apple 智能背后的设备端大语言模型!这个简介讲座涵盖了丰富的主题,从用于生成 Swift 数据结构并结合流式传输实现灵敏响应体验的引导式生成功能,到用于整合数据源和会话以进行上下文管理的工具调用机制,应有尽有。这个讲座不设任何先决条件。

    章节

    • 0:00 - 简介
    • 2:05 - 模型
    • 5:20 - 引导式生成
    • 7:45 - 快照流式传输
    • 11:28 - 工具调用
    • 16:11 - 有状态会话
    • 21:02 - 开发者体验

    资源

    • Human Interface Guidelines: Generative AI
      • 高清视频
      • 标清视频

    相关视频

    WWDC25

    • 探索 Apple 平台上的机器学习和 AI 框架
    • 探索设备端基础模型的提示设计和安全
    • 深入了解 Foundation Models 框架
    • 跟着视频学编程:使用 Foundation Models 框架将设备端 AI 引入你的 App
  • 搜索此视频…

    嗨 我叫 Erik 我是 Yifei 今天 我们很高兴能有幸 向大家介绍 全新的 Foundation Models 框架! FoundationModels 框架 提供了便捷而强大的 Swift API 让你可以访问为 Apple 智能 提供支持的 设备端大型语言模型 这个框架支持 macOS、 iOS iPadOS 和 visionOS! 你可以借助这个框架来增强 App 中的现有功能 例如提供个性化搜索建议 你还可以开发全新功能 例如在旅行类 App 中生成行程规划 整个过程全都在设备端完成 你甚至可以用它 实时生成游戏角色对话

    这个框架针对内容生成、文本摘要 用户输入分析等场景进行了深度优化 所有这些功能均在设备端运行 确保模型的所有输入输出数据 全程保持隐私安全 这也意味着它可以离线运行! 而且它深度集成于操作系统层 因此不会增加 App 的大小 今年意义重大 为了帮助你充分掌握 FoundationModels 框架 我们特别准备了一系列视频教程 在第一个视频中 我们将简要介绍 框架的完整架构体系 我们将从模型的技术细节讲起 接着介绍引导式生成功能 它能让你在 Swift 中 获得结构化输出 另外还有强大的流式 API 它们可将延迟转化为流畅的体验 我们还将详解工具调用功能 这个功能使模型能够 自主执行你在 App 中定义的代码 最后 我们将介绍 框架如何通过有状态会话 实现多轮对话支持 以及如何将框架无缝集成到 Apple 开发者生态系统中 毋庸置疑 这个框架最关键的部分 是它的核心驱动模型 要快速掌握模型提示技巧 最佳方式就是直接上手操作 Xcode 测试多种提示词以寻找最优方案 是大语言模型开发的关键环节 而 Xcode 全新的 Playground 功能 正是实现这一目标的最佳方式 只需几行代码 即可实时调用设备端模型 进行提示交互 现在 我将演示如何让模型 为日本之行生成标题 生成结果将实时显示在右侧画布上 现在 我需要验证这个提示模板 是否同样适用于其他旅行目的地 在 #Playground 环境中 你可以 直接调用 App 中定义的类型 这里我将通过 for 循环遍历 App 中的地标数据 现在 Xcode 会为我显示 所有地标的模型响应数据

    我们刚刚使用的设备端模型 是一个拥有 30 亿参数的 大型语言模型 且每个参数均采用 2 比特量化 这个模型的规模比操作系统内置的 任何其他模型大几个数量级

    但即便如此 仍需谨记 设备端模型始终是设备级模型 这个模型针对摘要生成、信息抽取 文本分类等多种场景进行了专项优化 这个模型并非为通用知识问答 或复杂逻辑推理而设计 这类任务通常可能需要 依赖服务器级大语言模型才能完成

    设备级模型需要将任务拆解为 更小的子任务单元才能处理 在持续使用这个模型的过程中 你将逐步掌握它的 优势场景与能力边界

    针对内容标注等常见场景 我们还提供专用适配器 可充分释放模型在特定领域的潜力

    我们还将持续对模型进行优化 在这个视频的后面 我们将 介绍如何就模型使用情况提供反馈 这些宝贵意见将指导我们 针对实际需求来优化模型

    对模型有了初步了解后 我们旅程的第一站是引导式生成 引导式生成正是 实现你刚才所见功能的核心技术 也是 FoundationModels 框架的 架构中枢 我们将看一个常见问题 并探讨引导式生成如何解决这个问题 默认情况下 语言模型生成的输出 是非结构化自然语言文本 这类输出虽然便于人类阅读 却难以映射到 App 的视图层

    一种常规解决方案是通过特定提示 要求模型生成易解析的结构化数据 如 JSON 或 CSV

    然而 这种做法很快就会陷入 反复调试的恶性循环 你不得不持续追加愈发精确的指令 明确定义系统应执行 与禁止执行的操作边界…… 但这类方法往往收效甚微…… 最终你不得不编写临时适配代码 来提取和修补内容 这种方案并不可靠 因为模型本质是概率驱动的 出现结构性错误的可能性 始终不为零 引导式生成针对这个问题 提供了根本性解决方案

    当你导入 FoundationModel 时 即可使用两个全新的宏: @Generable 和 @Guide Generable 宏用于定义 需要模型生成实例的类型 而 Guide 宏用于 为属性提供自然语言描述 并通过编程方式 来控制可为这些属性生成的数值

    当你定义完 Generable 类型后 就能通过生成这个类型的实例 让模型对提示词作出响应 这真的很强大 注意 现在我们的提示词 不再需要指定输出格式 框架已为你自动处理这一环节

    最关键的是 我们现在获得的是一个 功能完备的 Swift 对象 可以轻松映射到一个引人入胜的视图

    可使用字符串、整型、 双精度浮点型 单精度浮点型、十进制数和布尔型 等基本类型来构造可生成类型 数组同样属于可生成类型 可生成类型还支持组合使用 可生成类型甚至支持递归类型 这种特性在生成式 UI 等领域具有强大的应用潜力 关于引导式生成 务必要理解的是 它通过一种称为约束解码的技术 从根本上保证了 生成结果的结构正确性 使用引导式生成时 提示词可以更加简洁 只需专注于描述预期行为 而无需考虑输出格式 此外 引导式生成 往往能够提升模型的准确性 而且 这项技术还能通过优化 来加速推理过程 这一切都得益于 Apple 操作系统、 开发者工具以及基础模型训练 三者之间的深度协同整合 关于引导式生成 仍有诸多关键技术值得探讨 例如 如何在运行时创建动态模式 要了解更多技术细节 请观看我们的深度解析视频 以上就是引导式生成的全部内容 我们已了解 Swift 强大的类型系统 如何增强自然语言提示 从而实现可靠的结构化输出 接下来我们将探讨流式处理技术 而这一切都建立在你已熟悉的 @Generable 宏的基础上 如果你曾使用过大语言模型 你可能知道它们是以 称为“标记”的短字符组 为单位来生成文本的 通常在流式输出时 标记会以所谓的增量形式逐块传递 但 Foundation Models 框架实际上 采用了不同的实现方式 接下来我将为你展示其中的缘由

    随着增量数据的生成 开发者通常需要负责 对这些片段进行累积整合 你需要实时追加每个到达的增量片段 而响应内容会随着你的操作动态扩展 但当输出结果具有结构化内容时 情况就会变得复杂起来 若要在每次收到增量数据后 显示问候字符串 你必须从累积结果中解析所需内容 这一过程绝非易事 尤其是对于复杂结构而言 在处理结构化输出时 增量流式传输显然并非理想方案 如你所知 结构化输出正是 Foundation Models 框架的核心所在 这也是我们另辟蹊径 开发新方法的原因 我们采用快照流式传输 替代原始增量数据传输

    当模型生成增量数据时 框架会将它们转换为快照 快照表示部分生成的响应 它们的属性都是可选的 并会随着模型 逐步生成响应内容而填充 快照是一种强大且便捷的 流式结构化输出表示方式

    你已经熟悉 @Generable 宏 而实际上 它也是部分生成类型的定义来源 如果展开这个宏 你会发现它生成了一个名为 PartiallyGenerated 的类型 它本质上是外层结构的镜像 只不过所有属性都变成了可选的

    当你调用会话的 streamResponse 方法时 这个部分生成类型就会发挥作用

    streamResponse 返回一个异步序列 而这个序列的元素就是 部分生成类型的实例 序列中的每个元素 都会包含一个更新的快照

    这些快照可与 SwiftUI 等声明式框架完美配合 首先 创建一个持有部分生成类型 的状态 然后遍历响应流 存储它的元素 接着就能观察到 UI 动态更新的效果

    最后 我们来回顾一些 流式处理最佳实践

    首先 通过 SwiftUI 的动画 和过渡效果来巧妙地掩盖延迟 将等待过程转化为愉悦体验 其次 特别是在生成数组时 需要仔细考虑 SwiftUI 的视图标识问题 最后 请记住属性是按 它们在 Swift 结构体上声明的 顺序生成的 这对动画效果和模型输出质量 都有影响 例如 将摘要属性放在结构体末尾时 模型往往能生成最佳结果

    由于涉及内容较多 建议观看关于将 FoundationModels 集成到 SwiftUI App 的专题视频来获取更多详情 以上就是 Foundation Models 流式处理的全部要点 接下来 Yifei 将为大家详细介绍 工具调用功能! 谢谢 Erik! 工具调用是我们的另一项核心功能 它能让模型执行 你在 App 中定义的代码 这项功能对于 充分发挥模型潜力至关重要 因为它为模型提供了 诸多扩展能力 模型可以自主识别 需要额外信息或操作的任务 在难以通过编程决策时 智能选择调用工具的时机和方式 你提供给模型的信息可以是通用知识 近期事件或个人数据 例如在旅行 App 中 可通过 MapKit 获取地理位置信息 这也使模型能够引用事实数据源 既能有效抑制幻觉生成 又支持对模型输出进行事实核查 最后 模型可以执行 App 内操作 系统级操作 或现实世界交互 将模型与 App 中的多源信息集成 是打造卓越用户体验的关键策略 现在你已经了解工具调用的优势 接下来让我们看看它的工作原理 界面左侧是记录完整交互过程的 会话记录 当你为会话配置了工具时 系统会自动将这些工具 及相应使用说明提供给模型 接下来 我们输入目标地点提示词 模型会评估是否需要 调用工具来优化响应 模型会发起一个或多个工具调用 在这个示例中 模型主动发起两个工具调用 餐厅查询和酒店查询工具 在这个阶段 FoundationModels 框架将 自动执行你编写的工具代码 将工具输出结果插入会话记录 最后 模型会整合工具返回数据 及历史会话记录 生成最终响应

    在掌握了工具调用的核心概念后 我们来看看工具的定义方法

    这里我们将定义一个简单的 符合 Tool 协议规范的天气查询工具 天气查询工具俨然已成为 工具调用领域的标准入门示例 它是入门学习的绝佳案例

    这个协议首先要求你 指定工具的名称 和自然语言描述

    框架会自动将这些信息提供给模型 帮助它理解何时应调用你的工具

    当模型调用你的工具时 将执行你定义的调用方法

    调用方法的参数可以是 任意 Generable 类型

    要求参数必须是可生成的原因在于 工具调用功能基于 引导式生成机制构建 这确保了 模型永远不会产生 无效的工具名称或参数 定义完参数类型后 你就可以在方法体内 自由编写所需的逻辑代码了 这里我们使用 CoreLocation 和 WeatherKit 来获取指定城市的温度数据 输出结果通过 ToolOutput 类型呈现 这个类型既可从 GeneratedContent 创建来表示结构化数据 也可直接由字符串生成 后者适用于自然语言输出的工具场景 既然已定义好工具 接下来需要确保模型 能够访问这个工具 为此 请将工具传入会话的构造器 工具必须在会话初始化时进行绑定 并将在整个会话生命周期内 供模型调用

    创建带有工具的会话后 你只需像往常一样 向模型发送提示即可 工具调用过程将自动透明地执行 模型会将这些工具的输出结果 整合到最终响应中 以上示例展示了 如何在编译时定义类型安全的工具 这适用于绝大多数使用场景 但工具同样可以 实现全方位的动态化! 例如 你可以通过动态生成模式 在运行时定义工具的参数和行为 若对此感兴趣 欢迎观看我们的深度解析视频 以了解更多内容 工具调用的讲解就告一段落了 我们已了解工具调用的价值所在 以及如何通过实现工具 来扩展模型能力 接下来 我们聊聊有状态会话 在这个视频中 “会话”一词已多次出现 FoundationModels 框架正是围绕 有状态会话的概念构建的 默认情况下 当你创建会话时 系统会调用设备端通用模型 进行处理 你还可以根据需要提供自定指令 这类指令既可用于 设定模型的角色身份 也能指导模型生成响应内容的方式 例如 你可以指定 响应风格和详细程度等参数 需要注意的是 自定指令属于可选配置 若未指定 系统将采用合理的默认指令

    如果决定使用自定指令 需明确指令与提示的关键区别 指令应由你 即开发者设定 而提示可来自用户输入 这种设计源于模型的训练机制 模型会优先遵循指令而非提示 这个特性虽有助于防范提示注入攻击 但并非万无一失 一般来说 指令大多是静态的 切勿将不可信的用户输入 直接插入指令中 这些就是关于如何更好地 构建指令与提示的基本入门指南 要了解更多最佳实践 请观看我们关于 提示设计和安全性的视频 现在你已完成会话初始化 接下来谈谈多轮交互! 使用之前提到的 respond 或 streamResponse 方法时 模型会将每次交互 作为上下文保留在对话记录中 因此它能够参考并理解 同一会话中的历史多轮交互 例如 当用户说“再来一个”时 模型能理解 这是指继续创作俳句

    通过会话对象的 transcript 属性 你可以查看过往交互记录 或绘制 UI 视图来展示这些内容

    还有一点很重要 当模型正在生成输出时 它的 isResponding 属性 将变为 true 你可能需要观察这个属性 并确保在模型完成响应前 不要提交新的提示 除了默认模型外 我们还提供了一些内置的专门用例 这些用例由适配器提供支持 如果你发现某个内置用例符合需求 可以将它传入 SystemLanguageModel 的构造器 要了解有哪些内置用例可用 以及如何充分利用它们 请查阅我们开发者网站上的相关文档 今天我要重点介绍的是 内容标记适配器 内容标记适配器为标签生成 实体提取 和主题检测提供了一流的支持 默认情况下 它被训练用于输出主题标签 并直接集成了引导式生成功能 因此 你只需使用我们的 Generable 宏定义一个结构体 然后传入用户输入即可从中提取主题

    但它的能力远不止这些! 通过向它提供自定指令 和自定 Generable 输出类型 你甚至可以用它来检测 动作 情感等内容 在创建会话前 请务必检查可用性 因为模型只能在支持区域中支持 Apple 智能的设备上运行 要检查模型当前是否可用 可以访问 SystemLanguageModel 上 的 availability 属性

    可用性是一个双态枚举 包含可用和不可用两种状态 当状态为不可用时 你还会收到具体原因 以便相应调整 UI 界面

    最后需要注意 调用模型时可能会遇到错误 例如 违反安全护栏 语言不受支持 或超出上下文窗口限制 为了提供最佳用户体验 你需要妥善处理这些错误 我们的深度解析视频 将为你详细介绍相关处理方法 以上就是多轮状态会话的全部内容! 我们已经掌握了 会话的创建与使用方法 以及模型的上下文追踪机制 现在你已了解 这个框架的所有核心功能 接下来我们将谈谈 开发者工具与体验优化 首先 你可以在 项目任意 Swift 文件中 使用全新的 playground 宏 来调用模型提示功能

    Playground 功能非常强大 无需重新编译和运行整个 App 即可快速调试提示词 在 Playground 中 你的代码 可直接访问项目所有类型 包括已驱动 UI 的可生成类型

    接下来 我们知道 在构建由大语言模型驱动的 App 体验时 透彻理解底层延迟至关重要 因为与传统机器学习模型相比 大语言模型的运行时间更长 明确延迟产生的环节能帮助你 调整提示词的详细程度 或判断何时调用预热等实用 API

    而我们的全新 Instruments App 性能分析模板 正是为实现这一点而构建的 你可以分析模型请求的延迟 观察优化空间 并量化改进效果

    在开发 App 的过程中 你可能会有 可以帮助我们改进模型和 API 的宝贵意见

    我们诚挚地邀请你 通过“反馈助理”提交反馈 我们还专门提供了 可编码的反馈附件数据结构 你可以直接将它 作为文件附加到反馈中

    最后 如果你是机器学习从业者 有高度专业化的使用场景 和自定数据集 你还可以使用我们的 适配器训练工具包训练定制适配器 但请注意 这伴随着重大责任 随着 Apple 不断优化模型 你需要定期重新训练适配器 要了解更多详情 请访问开发者网站 现在 你已经了解 全新 Foundation Models 框架 提供的众多强大功能 我们迫不及待想看到 你用它构建的精彩作品! 要进一步了解如何 将生成式 AI 集成到你的 App 中 引导式生成等技术的底层原理 以及如何设计最佳提示词 我们为你准备了一系列 精彩的视频和文章 非常感谢你今天的参与! 祝你生成愉快!

    • 2:28 - Playground - Trip to Japan

      import FoundationModels
      import Playgrounds
      
      #Playground {
          let session = LanguageModelSession()
          let response = try await session.respond(to: "What's a good name for a trip to Japan? Respond only with a title")
      }
    • 2:43 - Playground - Loop over landmarks

      import FoundationModels
      import Playgrounds
      
      #Playground {
          let session = LanguageModelSession()
          for landmark in ModelData.shared.landmarks {
              let response = try await session.respond(to: "What's a good name for a trip to \(landmark.name)? Respond only with a title")
          }
      }
    • 5:32 - Creating a Generable struct

      // Creating a Generable struct
      
      @Generable
      struct SearchSuggestions {
          @Guide(description: "A list of suggested search terms", .count(4))
          var searchTerms: [String]
      }
    • 5:51 - Responding with a Generable type

      // Responding with a Generable type
      
      let prompt = """
          Generate a list of suggested search terms for an app about visiting famous landmarks.
          """
      
      let response = try await session.respond(
          to: prompt,
          generating: SearchSuggestions.self
      )
      
      print(response.content)
    • 6:18 - Composing Generable types

      // Composing Generable types
      
      @Generable struct Itinerary {
          var destination: String
          var days: Int
          var budget: Float
          var rating: Double
          var requiresVisa: Bool
          var activities: [String]
          var emergencyContact: Person
          var relatedItineraries: [Itinerary]
      }
    • 9:20 - PartiallyGenerated types

      // PartiallyGenerated types
      
      @Generable struct Itinerary {
          var name: String
          var days: [Day]
      }
    • 9:40 - Streaming partial generations

      // Streaming partial generations
      
      let stream = session.streamResponse(
          to: "Craft a 3-day itinerary to Mt. Fuji.",
          generating: Itinerary.self
      )
      
      for try await partial in stream {
          print(partial)
      }
    • 10:05 - Streaming itinerary view

      struct ItineraryView: View {
          let session: LanguageModelSession
          let dayCount: Int
          let landmarkName: String
        
          @State
          private var itinerary: Itinerary.PartiallyGenerated?
        
          var body: some View {
              //...
              Button("Start") {
                  Task {
                      do {
                          let prompt = """
                              Generate a \(dayCount) itinerary \
                              to \(landmarkName).
                              """
                        
                          let stream = session.streamResponse(
                              to: prompt,
                              generating: Itinerary.self
                          )
                        
                          for try await partial in stream {
                              self.itinerary = partial
                          }
                      } catch {
                          print(error)  
                      }
                  }
              }
          }
      }
    • 11:00 - Property order matters

      @Generable struct Itinerary {
        
        @Guide(description: "Plans for each day")
        var days: [DayPlan]
        
        @Guide(description: "A brief summary of plans")
        var summary: String
      }
    • 13:42 - Defining a tool

      // Defining a tool
      import WeatherKit
      import CoreLocation
      import FoundationModels
      
      struct GetWeatherTool: Tool {
          let name = "getWeather"
          let description = "Retrieve the latest weather information for a city"
      
          @Generable
          struct Arguments {
              @Guide(description: "The city to fetch the weather for")
              var city: String
          }
      
          func call(arguments: Arguments) async throws -> ToolOutput {
              let places = try await CLGeocoder().geocodeAddressString(arguments.city)
              let weather = try await WeatherService.shared.weather(for: places.first!.location!)
              let temperature = weather.currentWeather.temperature.value
      
              let content = GeneratedContent(properties: ["temperature": temperature])
              let output = ToolOutput(content)
      
              // Or if your tool’s output is natural language:
              // let output = ToolOutput("\(arguments.city)'s temperature is \(temperature) degrees.")
      
              return output
          }
      }
    • 15:03 - Attaching tools to a session

      // Attaching tools to a session
      
      let session = LanguageModelSession(
          tools: [GetWeatherTool()],
          instructions: "Help the user with weather forecasts."
      )
      
      let response = try await session.respond(
          to: "What is the temperature in Cupertino?"
      )
      
      print(response.content)
      // It’s 71˚F in Cupertino!
    • 16:30 - Supplying custom instructions

      // Supplying custom instructions
      
      let session = LanguageModelSession(
          instructions: """
              You are a helpful assistant who always \
              responds in rhyme.
              """
      )
    • 17:46 - Multi-turn interactions

      // Multi-turn interactions
      
      let session = LanguageModelSession()
      
      let firstHaiku = try await session.respond(to: "Write a haiku about fishing")
      print(firstHaiku.content)
      // Silent waters gleam,
      // Casting lines in morning mist—
      // Hope in every cast.
      
      let secondHaiku = try await session.respond(to: "Do another one about golf")
      print(secondHaiku.content)
      // Silent morning dew,
      // Caddies guide with gentle words—
      // Paths of patience tread.
      
      print(session.transcript)
// (Prompt) Write a haiku about fishing
      // (Response) Silent waters gleam...
      // (Prompt) Do another one about golf
      // (Response) Silent morning dew...
    • 18:22 - Gate on isResponding

      import SwiftUI
      import FoundationModels
      
      struct HaikuView: View {
      
          @State
          private var session = LanguageModelSession()
      
          @State
          private var haiku: String?
      
          var body: some View {
              if let haiku {
                  Text(haiku)
              }
              Button("Go!") {
                  Task {
                      haiku = try await session.respond(
                          to: "Write a haiku about something you haven't yet"
                      ).content
                  }
              }
              // Gate on `isResponding`
              .disabled(session.isResponding)
          }
      }
    • 18:39 - Using a built-in use case

      // Using a built-in use case
      
      let session = LanguageModelSession(
          model: SystemLanguageModel(useCase: .contentTagging)
      )
    • 19:19 - Content tagging use case - 1

      // Content tagging use case
      
      @Generable
      struct Result {
          let topics: [String]
      }
      
      let session = LanguageModelSession(model: SystemLanguageModel(useCase: .contentTagging))
      let response = try await session.respond(to: ..., generating: Result.self)
    • 19:35 - Content tagging use case - 2

      // Content tagging use case
      
      @Generable
      struct Top3ActionEmotionResult {
          @Guide(.maximumCount(3))
          let actions: [String]
          @Guide(.maximumCount(3))
          let emotions: [String]
      }
      
      let session = LanguageModelSession(
          model: SystemLanguageModel(useCase: .contentTagging),
          instructions: "Tag the 3 most important actions and emotions in the given input text."
      )
      let response = try await session.respond(to: ..., generating: Top3ActionEmotionResult.self)
    • 19:56 - Availability checking

      // Availability checking
      
      struct AvailabilityExample: View {
          private let model = SystemLanguageModel.default
      
          var body: some View {
              switch model.availability {
              case .available:
                  Text("Model is available").foregroundStyle(.green)
              case .unavailable(let reason):
                  Text("Model is unavailable").foregroundStyle(.red)
                  Text("Reason: \(reason)")
              }
          }
      }
    • 22:13 - Encodable feedback attachment data structure

      let feedback = LanguageModelFeedbackAttachment(
        input: [
          // ...
        ],
        output: [
          // ...
        ],
        sentiment: .negative,
        issues: [
          LanguageModelFeedbackAttachment.Issue(
            category: .incorrect,
            explanation: "..."
          )
        ],
        desiredOutputExamples: [
          [
            // ...
          ]
        ]
      )
      let data = try JSONEncoder().encode(feedback)
    • 0:00 - 简介
    • Foundation Models 框架为 macOS、iOS、iPadOS 和 visionOS 提供了访问设备端大型语言模型的能力。借助这个框架,你可以构建个性化的创新功能,例如搜索建议、行程规划、游戏内对话等,同时优先考虑用户隐私,因为所有数据均在本地处理,可离线运行。 这个框架针对内容生成、文本摘要总结和用户输入分析进行了优化。为帮助开发者,Apple 提供了一系列视频,涵盖框架概览、引导式生成、流媒体 API、工具调用、多轮对话支持,以及如何将它无缝集成到 Apple 开发者生态系统中。

    • 2:05 - 模型
    • Xcode 全新推出的 Playgrounds 功能,是试用设备端大型语言模型提示语的最佳起点。只需几行代码,即可测试提示语,并实时查看模型的响应结果。 这款设备端模型虽具备 30 亿参数的强大能力,但它的优化方向聚焦于摘要总结、提取和分类等特定任务,不适用于处理通用知识或高级推理。将任务拆解为更小的子任务,可最大限度地提高模型的有效性。 引导式生成是 FoundationModels 框架的核心组件之一,旨在解决将模型输出集成到 App 中所面临的挑战。它通过提供结构化的模型生成方法,让你更可靠地构建功能,克服了依赖模型直接输出 JSON 或 CSV 等易解析格式所带来的局限性。

    • 5:20 - 引导式生成
    • 导入 FoundationModels 后,引入了两个全新的宏:“@Generable”和“@Guide”。“@Generable”用于描述模型生成实例的数据类型,这些类型可由基本类型、数组以及组合类型或递归类型构成。“@Guide”用自然语言描述属性,并对生成值进行约束控制,通过受限解码确保结构的正确性。 这个引导式生成功能简化了提示语、提升了模型准确性,并加快了推理速度。你可以直接从模型中获取丰富的 Swift 对象,这些对象可以轻松映射到富有吸引力的视图中,无需在提示语中指定输出格式。

    • 7:45 - 快照流式传输
    • FoundationModels 框架不同于传统的大型语言模型中基于令牌的增量流式传输方式。它改为流式传输“快照”(即包含可选属性的部分生成结果),这种方式在处理结构化输出时更加稳定且更易用。 这个方法利用“@Generable”宏生成一个“PartiallyGenerated”类型,这个类型是外层结构的镜像,并具有可选属性。“streamResponse”方法会返回这些部分生成类型的异步序列,方便与 SwiftUI 等声明式框架无缝集成。 在流式传输过程中,结合 SwiftUI 的动画与过渡效果,可进一步提升用户体验。妥善考虑视图的身份标识以及属性的声明顺序,对于获得理想的效果也至关重要。

    • 11:28 - 工具调用
    • 工具调用让 AI 模型能够执行 App 中的自定代码,从而增强它的功能。借助这个功能,模型可根据用户请求的上下文自主决定何时调用外部工具,以获取信息或执行操作,例如查询餐厅、酒店或天气数据。 这个模型可集成诸如 MapKit 等多种权威数据源,提供准确且最新的信息。这个流程涉及模型生成工具调用请求,这些请求随后由 FoundationModels 框架自动执行,并将结果插入对话记录中,供模型用于生成最终响应。

    • 16:11 - 有状态会话
    • Foundation Models 框架支持与设备端通用模型建立有状态的会话。你可以提供自定指令来引导模型的响应,例如指定响应风格和详细程度,但这不是必需的。你负责设置指令 (它们与用户提示有所不同),且模型经过训练会优先遵循指令而不是提示,以增强安全性。 在同一个会话中,模型会保留多轮交互的上下文,使它能够理解并引用先前的提示和响应。Transcript 属性可用于检查这些交互。 这个框架还提供了内建的专用适配器,例如内容标签适配器,它支持标签生成、实体提取和主题识别。可以根据具体需求自定这些适配器。 在创建会话之前,请先确认模型是否可用,因为它只能在受支持地区中支持 Apple 智能的设备上运行。妥善的错误处理,对于应对安全护栏违规、语言不受支持或上下文窗口超限等潜在问题也至关重要。

    • 21:02 - 开发者体验
    • Playgrounds 可在 App 项目中实现对大型语言模型提示语的快速迭代,同时支持访问所有项目类型。全新的 Instruments App 分析模板通过识别模型请求和提示语冗余度方面有待改进的地方,帮助优化延迟表现。 欢迎通过“反馈助理”提交反馈。

Developer Footer

  • 视频
  • WWDC25
  • 了解 Foundation Models 框架
  • 打开菜单 关闭菜单
    • iOS
    • iPadOS
    • macOS
    • Apple tvOS
    • visionOS
    • watchOS
    打开菜单 关闭菜单
    • Swift
    • SwiftUI
    • Swift Playground
    • TestFlight
    • Xcode
    • Xcode Cloud
    • SF Symbols
    打开菜单 关闭菜单
    • 辅助功能
    • 配件
    • App 扩展
    • App Store
    • 音频与视频 (英文)
    • 增强现实
    • 设计
    • 分发
    • 教育
    • 字体 (英文)
    • 游戏
    • 健康与健身
    • App 内购买项目
    • 本地化
    • 地图与位置
    • 机器学习与 AI
    • 开源资源 (英文)
    • 安全性
    • Safari 浏览器与网页 (英文)
    打开菜单 关闭菜单
    • 完整文档 (英文)
    • 部分主题文档 (简体中文)
    • 教程
    • 下载 (英文)
    • 论坛 (英文)
    • 视频
    打开菜单 关闭菜单
    • 支持文档
    • 联系我们
    • 错误报告
    • 系统状态 (英文)
    打开菜单 关闭菜单
    • Apple 开发者
    • App Store Connect
    • 证书、标识符和描述文件 (英文)
    • 反馈助理
    打开菜单 关闭菜单
    • Apple Developer Program
    • Apple Developer Enterprise Program
    • App Store Small Business Program
    • MFi Program (英文)
    • News Partner Program (英文)
    • Video Partner Program (英文)
    • 安全赏金计划 (英文)
    • Security Research Device Program (英文)
    打开菜单 关闭菜单
    • 与 Apple 会面交流
    • Apple Developer Center
    • App Store 大奖 (英文)
    • Apple 设计大奖
    • Apple Developer Academies (英文)
    • WWDC
    获取 Apple Developer App。
    版权所有 © 2025 Apple Inc. 保留所有权利。
    使用条款 隐私政策 协议和准则