Foundation Models 框架的新功能
What’s new in the Foundation Models framework
2026年6月10日
一句话判断
这场 Session 最值得关注的一件事是:Foundation Models 终于从“调参玩具”变成了“工程基建”,Dynamic Profiles 让 Agent 状态机原生支持,而 LanguageModel 协议让苹果设备端模型、PCC(Private Cloud Compute,私有云计算)和第三方模型实现了真正的无缝热切换。
这场 Session 讲了什么
去年 Foundation Models 刚出时,大家吐槽它像个封装好的黑盒,模型不能换,复杂 Agent 状态难管,评估全靠肉眼。今年 Apple 直接掀桌子,把核心框架开源,并推出了 LanguageModel 协议抽象层。现在你可以通过 SPM(Swift Package Manager)一键把底层模型从 Apple 设备端换成 PCC,甚至直接换成 Anthropic 或 Google 的模型,下游业务代码一行不用改。
更狠的是推出了 Dynamic Profiles(动态配置),用类似 SwiftUI 的声明式语法管理 Agent 的工具和 Prompt 切换,还自带了 Evaluations(评估)框架让你能像写单元测试一样测 AI 的准确率。这对做重度 AI 功能,特别是 Agent 和 RAG(检索增强生成)的开发者是巨大利好,终于不用自己手写一堆状态管理和模型路由的胶水代码了。
值得深挖的点
Dynamic Profiles:Agent 状态管理的“SwiftUI 化”
以前写 Agent,切换模式(比如从“图像分析”切到“头脑风暴”)需要手动拼凑 system prompt,管理 tool 列表,还要处理上下文截断,极其容易出 bug。Apple 这次用声明式语法来描述 Profile,通过 switch 状态返回不同的 Profile,底层自动处理 transcript(对话历史)的保留和 instruction(指令)与 tool 的热替换。
这种设计的好处是代码极其整洁,状态切换原子化。你只需要定义好每个状态下的 Instructions 和 Tools,框架会自动帮你搞定上下文继承。不过坑也很明显:在“保留对话历史”时,如果前后两个 Profile 的 tool 定义差异过大,模型可能会产生幻觉,去调用上一个状态已经移除的 tool。实战中需要在 Prompt 里做好明确的状态隔离,或者在切换时手动 drop 掉部分历史。
LanguageModel 协议与第三方模型无缝接入
开发者苦 Apple 封闭模型久矣。很多复杂任务设备端模型搞不定,接第三方又要重写网络层和解析层。这次 Apple 定义了统一的 LanguageModel 协议,官方下场做了 PCC 的适配(支持 32K 上下文和 reasoning levels),同时让 Anthropic 和 Google 自己出 Swift Package。连 token 计费(response.usage)都统一了接口,甚至区分了 cached(缓存)和 reasoning(推理)token。
这其实就是真正的“面向协议编程”。测试时可以用 mock model,生产环境可以根据设备算力动态路由,比如低端机走 PCC,高端机走本地。但要小心,第三方模型的 streaming 和 structured output(结构化输出)支持程度可能参差不齐。Apple 的 @Generable 宏在第三方模型上可能会 fallback 到 JSON 解析,导致性能下降,接入前一定要跑一遍 Evaluations 框架测一下准确率。
代码片段
1. 用 Dynamic Profiles 路由 Agent 状态
场景:在一个手工艺 App 中,根据用户当前是“分析模式”还是“头脑风暴模式”,动态切换 Agent 的指令和可用工具。
// 定义手工艺 App 的动态配置
struct CraftProfile: LanguageModelSession.DynamicProfile {
let states: CraftProjectStates
var body: some DynamicProfile {
switch states.mode {
case .craftAnalysis:
Profile {
Instructions { "你是一个专业的手工艺分析助手。" }
RecordImageAnalysisTool()
SwitchModeTool(states: states)
}
case .brainstorm:
Profile {
Instructions { "你是一个创意头脑风暴助手。" }
BrainstormRecordTool()
}
// 为不同分支指定不同的模型和推理级别
.model(PrivateCloudComputeLanguageModel())
}
}
}
// 初始化 session,框架会自动处理状态切换时的上下文保留
let session = LanguageModelSession(profile: CraftProfile(states: appStates))
坑:切换状态时,如果 BrainstormRecordTool 和 RecordImageAnalysisTool 的参数结构太像,模型可能会在头脑风暴时错误调用分析工具,建议在 tool 的 description 里加上强烈的排他性描述。
2. 多模态视觉 Prompt 与 Token 追踪
场景:让设备端模型识别图片内容,并精确监控 token 消耗,防止大图撑爆上下文。
let model = SystemLanguageModel()
let session = LanguageModelSession(model: model)
// 直接传入 UIImage,无需手动裁剪或 padding
let response = try await session.respond {
"这张折纸图片里是什么动物?"
Attachment(UIImage(named: "origami")!)
}
// 检查 token 消耗,大图会显著增加 input token
print("输入 token: \(response.usage.input.totalTokenCount)")
print("输出 token: \(response.usage.output.totalTokenCount)")
坑:虽然 API 支持任意尺寸的图片,但大图会疯狂吃 token 并增加延迟。务必在客户端先做降采样(Downsampling),把图片缩放到模型能看清细节的最小尺寸再传入。
3. 使用 PCC 模型进行深度推理
场景:遇到复杂的逻辑推理任务,调用 Private Cloud Compute 模型并开启深度思考。
// 初始化 PCC 模型,无需配置 API Key 或处理鉴权
let pccModel = PrivateCloudComputeLanguageModel()
let session = LanguageModelSession(model: pccModel)
// 开启深度推理,用计算时间换取更好的回答质量
let response = try await session.respond(
to: "帮我规划一个包含5个城市的日本旅行路线,要求不走回头路。",
contextOptions: ContextOptions(reasoningLevel: .deep)
)
// 查看推理过程消耗的专属 token
print("推理 token: \(response.usage.output.reasoningTokenCount)")
坑:.deep 推理会显著增加首字延迟(TTFT)。对于简单的日常对话或 UI 文案生成,千万别开 deep,用默认的或 .light 即可,否则用户会觉得 App 卡死了。
最佳实践
- 重构老项目的状态管理:如果你现在的项目里手写了 System Prompt 拼接、手动维护 Tool 数组,甚至在切换状态时手动截断 Transcript,立刻停下来,重构为 Dynamic Profiles。这能帮你删掉几百行容易出错的胶水代码。
- 拥抱协议抽象:新项目无脑面向
LanguageModel协议编程,不要直接硬编码SystemLanguageModel。写一个工厂方法,根据model.contextSize和设备内存动态决定是走本地、走 PCC 还是走第三方模型。 - 把 Evaluations 接入 CI/CD:别再靠“肉眼 debug” AI 功能了。用新的 Evaluations 框架写几个测试用例,设定好准确率阈值。每次改 Prompt 或换模型,都在 CI 里跑一遍,达标了再发版。
还有什么值得关注
fm命令行工具:macOS 27 终端里直接 pipe 文本给大模型(比如cat log.txt | fm chat "总结报错原因"),写 shell 脚本和排查问题的神器。- 内置系统工具:新增了基于 Vision 的
BarcodeReaderTool和OCRTool,以及基于 Spotlight 的本地 RAG 搜索工具,做本地文档问答直接起飞。 - Python SDK 发布:数据科学家现在可以直接在 Jupyter Notebook 里调用 Apple 设备端模型了,方便做数据清洗和离线分析。