你花了几万块调GPT-4的API,苹果却把30亿参数的大模型直接塞进了你的iPhone。不收你一分钱,不用联网,连苹果自己都看不到你的数据。

这不是噱头。WWDC 2025上,苹果放出了一个叫Foundation Models的框架。iOS和macOS开发者可以直接调用,跑在设备本地的AI大模型。

免费。无限调用。零token费用。

今天我带你从零开始,把这个免费AI装进你自己的App里。

不需要买服务器。不需要注册API Key。不需要任何AI开发经验。你只需要一台Mac、一部iPhone 15 Pro、和一个Xcode。


一、先搞清楚:苹果到底给了你什么?

1.1 Foundation Models是什么?

一句话讲透:它是一个Swift框架。让你写的App,能直接调用跑在用户手机上的AI大模型。

没有更多花里胡哨的定义。

你可以把它理解成苹果版的"ChatGPT API"。但有两个致命区别。第一,模型跑在用户设备本地,不经过云端。第二,完全免费,没有token计费,没有月度账单,没有用量上限。

我第一次看到这个消息,第一反应是"苹果疯了吧"。OpenAI靠API调用费一年收几十亿美金。苹果直接把这个入口免费开放给所有开发者。

而且不是阉割版。是一个实打实的30亿参数语言模型。支持中文。支持多轮对话。甚至支持工具调用。

这不是技术预览版,是面向所有开发者的正式框架。

打开浏览器,访问 developer.apple.com,搜索"Foundation Models",把官方文档首页收藏起来。后面每一步实操都对照这个文档来。

1.2 免费的代价:3B模型能干什么?

先泼盆冷水。30亿参数的模型,不是GPT-5。

它干不了复杂数学推理。做不了长链条的逻辑分析。也搞不定需要大量世界知识的专业问答。你让它算"2378乘以4591",它会自信满满地给你一个错误答案。

但它擅长的事情,恰好覆盖了大多数App的核心需求。

  • 文本总结

    ——给它一段500字的开会记录,它能提炼出3条要点

  • 文本分类

    ——给它一堆用户评论,它能自动标注正面/负面/中性

  • 文本改写

    ——把一段口语化的文字改成正式邮件风格

  • 创意生成

    ——根据关键词写一段营销文案

  • 简单问答

    ——回答"这道菜的卡路里大概多少"这种常识性问题

这些事情,占了你日常App功能的80%。剩下那20%需要强推理的场景,你本来就该调云端大模型。端侧模型不是来替代一切的。

我昨天拿它做了个测试。给模型一段300字的周报草稿,让它总结成3句话。结果比我用GPT-4总结的还简洁。不是因为它比GPT-4聪明。而是这种"总结提炼"的任务,3B模型绑绑有余。

拿出一张纸,写下你的App里3个"想让AI帮忙干的事"。对照上面的能力清单,标记哪些能做、哪些做不了。做完这步,你就知道这个免费模型值不值得你花时间学了。

1.3 环境准备:动手前的3个前置条件

别急着写代码。先确认三件事。少一件都跑不起来。

第一,Xcode 26 Beta。 Foundation Models是iOS 26的新框架,稳定版Xcode还不支持。去Apple Developer官网下载Xcode 26 Beta。没有开发者账号也没关系,用免费的Apple ID就能下载Beta版。

第二,一台A17 Pro及以上芯片的设备。 这是硬性门槛。iPhone 15 Pro、iPhone 16全系、iPad Pro M1及以上、MacBook Pro M1及以上都行。但iPhone 14及以下,跑不了。模型需要设备端有足够的NPU算力。

第三,系统升级到iOS 26 Beta。 测试设备必须刷iOS 26 Beta版。Mac也要升级到对应的macOS版本。这步比较折腾,但没办法,新框架只在新系统上跑。

我自己的配置是MacBook Pro M3加iPhone 15 Pro,系统都刷了Beta。第一次配环境花了大概40分钟,主要是下载Xcode 26 Beta太慢了,文件有12GB。

逐条检查上面3个条件,哪条没满足就先解决哪条。别跳过这步,后面每一步都依赖这个环境。


二、Demo起步:5分钟跑通你的第一个端侧AI

贯穿全文的Demo项目

「AI智能便签」——一个能帮你自动总结、分类、改写笔记的App。从最简陋的单行对话开始,一步步进化成功能完整的智能助手。

2.1 创建项目:从Xcode新建到第一个界面

打开Xcode 26 Beta。点"Create New Project"。选"App"。产品名称填"SmartNote"。语言选Swift,界面选SwiftUI。

点Create。Xcode自动生成一堆文件。你只需要关心一个—— [ContentView.swift](http://ContentView.swift) 。双击打开它。

删掉body里预填充的那堆东西。换成最简单的界面:一个TextField让用户输入文字,一个Button触发AI对话,一个Text显示AI的回复。

struct ContentView: View {    @State private var inputText = ""    @State private var responseText = ""    var body: some View {        VStack(spacing: 20) {            TextField("输入你想说的话...", text: $inputText)                .textFieldStyle(.roundedBorder)                .padding()            Button("发送") {                // 这里等下写AI调用            }            .buttonStyle(.borderedProminent)            Text(responseText)                .padding()        }        .padding()    }}

Cmd+R跑一下。你应该能在模拟器或真机上看到一个简陋但能用的界面。输入框、按钮、文字显示区,三件套齐了。

照着上面的代码敲一遍,确保App能正常启动,界面显示正确。别跳过这步,后面所有功能都在这个基础上加。

2.2 检查设备:你的手机能不能跑AI?

别急着调模型。先确认你的设备支不支持。

Foundation Models提供了一个非常方便的检测方法: [SystemLanguageModel.default.isAvailable](http://SystemLanguageModel.default.isAvailable) 。它返回一个布尔值,true表示设备能用,false表示不行。

import FoundationModels@State private var isModelAvailable = 
            false.onAppear
           {    isModelAvailable = 
            SystemLanguageModel.default.isAvailable}
          

然后在界面上显示检测结果。如果返回false,别慌。大概率是两个原因:设备芯片不够(需要A17 Pro以上),或者系统没升到iOS 26 Beta。

我第一次测的时候用的是iPhone 14,直接返回false。换到iPhone 15 Pro之后秒过。

还有一个细节要注意:即使设备支持,首次使用时系统需要下载模型权重文件,大概1.8GB。这个下载是后台静默进行的,下载期间isAvailable会返回false。所以你的App必须处理好"正在加载"的状态,别让用户以为App坏了。

把检测代码加进去,跑在真机上,确认返回true。如果返回false,对照1.3节的三个前置条件逐一排查。

2.3 创建会话+发送请求:三行代码让App开口说话

这是整个教程最核心的三行代码。学完这三行,你就已经跨过了端侧AI的门槛。

import FoundationModelsfunc askAI(question: String) async {    let session = LanguageModelSession(        instructions: "你是一个智能助手,用中文简洁回答。"    )    let response = try await 
            session.respond(to:
           question)    responseText = 
            response.content}
          

就这三行。创建会话,发送问题,拿到回答。

把这段代码放到ContentView里。然后在Button的点击事件里调用它。注意要用Task包裹,因为respond(to:)是异步方法:

Button("发送") {    Task {        await askAI(question: inputText)    }}

跑起来。在输入框里打一句"你好",点发送。等个两三秒,你应该能看到AI的回复出现在屏幕上。

那一刻的感觉,怎么说呢,有点像第一次跑通"Hello World"。但这次你的App不是在打印一行死文字。它在跟一个跑在你手机上的AI大模型实时对话。而且这个对话不花你一分钱。

调OpenAI的API还得配Key、装SDK、处理网络请求。这里三行代码搞定。

把三行核心代码复制进去,跑通你的第一次AI对话。截图保存,这是你的"Hello World"时刻。

2.4 阶段成果验收

第一阶段完成

你的SmartNote已经具备了最基本的能力:用户输入文字,AI返回回复。虽然界面丑,虽然没有任何花哨的功能,但核心链路已经跑通了。

我建议你现在就多做几次测试。输入不同类型的问题,感受一下3B模型的能力边界。比如试试"帮我总结这段话的要点",再试试"算一下2378乘4591",对比一下效果。

对,后者会翻车。这就是1.2节说的"免费代价"。

至少测试5种不同类型的输入,记录哪些效果好、哪些效果差。这个认知会在后面的进阶章节帮你少走弯路。


三、进阶一:给AI一个"人设",输出质量翻倍

3.1 System Prompt怎么写?

你刚才创建会话的时候,instructions参数里写的是一句很普通的话:“你是一个智能助手,用中文简洁回答。”

这个指令太弱了。模型会按照最泛化的方式回答你。什么都能聊两句,但什么都不精。

给模型一个明确的"人设",输出质量会有肉眼可见的提升。

比如你做的是一个便签App。那模型的角色应该是"笔记整理助手",而不是"什么都懂的百科全书"。指令应该明确告诉它:你的输入是随手记的碎片文字,你要做的是提炼、结构化、输出可读的摘要。

let session = LanguageModelSession(    instructions: """    你是一个笔记整理助手。用户会给你一段随手记录的文字,    可能是会议纪要、灵感碎片、待办事项的混合体。    你的任务是:    1. 提炼出3条以内的核心要点    2. 如果有待办事项,单独列出    3. 用简洁的中文输出,每条不超过30字    """)

注意几个要点:指令要具体,不要写"你很聪明"这种废话。用编号列出期望的输出格式。限定输出长度,3B模型在短文本任务上表现最好。

我测试了十几种不同的指令写法,发现效果差异非常大。同样的输入,泛化指令的输出像流水账,定向指令的输出像专业助理写的。尤其是"每条不超过30字"这个限制,直接把废话率降了70%。

把上面这段instructions替换进你的代码,用同一段输入测试新旧两种指令的输出差异。你会直观感受到"好指令"的力量。

3.2 把"人设"做成可切换的

光有一个固定人设还不够。用户的需求是多样的。有时候想总结,有时候想改写,有时候想要创意扩展。

在界面上加三个按钮,每个按钮对应一种模式:

@State private var currentMode = "总结"var modeInstructions: String {    switch currentMode {    case "总结":        return "你是笔记整理助手。提炼3条核心要点,每条不超过30字。"    case "改写":        return "你是文字润色专家。把用户的口语化文字改写成正式、流畅的书面语。"    case "创意":        return "你是创意策划师。根据用户的笔记内容,扩展出3个可执行的行动方案。"    default:        return "你是智能助手,用中文简洁回答。"    }}

界面上用Picker或者三个Button来切换currentMode,创建会话时传入modeInstructions

这个设计的好处是,用户不需要知道什么叫"System Prompt"。他只需要点一个按钮,模型的行为就变了。从产品角度来说,这是把AI能力包装成了用户能理解的功能。

我自己用下来,"总结模式"是最实用的。

开会的时候随手记一堆乱七八糟的东西,会后一键总结,省了至少15分钟的整理时间。

在界面上加三个模式切换按钮,每个按钮绑定不同的instructions。切换模式后用同一段输入测试,确认输出风格确实不同。

3.3 阶段成果验收

第二阶段完成

SmartNote已经从一个"能聊天的玩具"变成了"有点用的工具"。测试一下:粘贴一段200字左右的会议记录,切换到"总结模式",点发送。如果模型返回了3条简洁的要点,恭喜你,核心功能已经跑通了。

再试试"改写模式"和"创意模式"。三种模式都跑通之后,你的App已经比市面上80%的"AI笔记"类产品有差异化了。因为它是端侧运行的,不依赖网络,不收月费,隐私数据不出设备。

用三种模式分别测试至少2段不同类型的输入,确认每种模式的输出都符合预期。截图保存三种模式的输出效果。


四、进阶二:流式输出——让AI"打字"出来

4.1 为什么流式输出是必做的?

你现在用的respond(to:)方法,是阻塞式的。用户点发送之后,要等模型把整个回答生成完,文字才一次性出现在屏幕上。

3B模型生成一段100字的回答,大概需要2到4秒。这2到4秒里,用户看着空白的屏幕,不知道App是卡了还是在思考。焦虑感会成倍放大。

换成流式输出就不一样了。模型每生成一个字,屏幕上就多显示一个字。用户能实时看到AI在"思考",感知等待时间直接砍半。

我做了个对比测试。同样的请求,阻塞式输出用户平均等了3.2秒才看到结果。流式输出用户0.8秒就看到第一个字了。后者被用户评价为"快了很多",实际上总耗时几乎一样。

流式输出不是锦上添花,是必做项。

先用现有的阻塞式输出体验一下"干等"的感觉。输入一段长文本,点发送,盯着空白屏幕数秒。记住这个焦虑感,等下对比。

4.2 实现打字机效果:核心代码拆解

Foundation Models框架原生支持流式输出。把respond(to:)换成streamResponse(to:)就行。

func askAIStream(question: String) async {    let session = LanguageModelSession(        instructions: modeInstructions    )    responseText = ""    do {        let stream = 
            session.streamResponse(to:
           question)        for try await partial in stream {            responseText += 
            partial.content
                  }    } catch {        responseText = "出错了:\(
            error.localizedDescription)"
              }}

核心逻辑就这些。streamResponse(to:)返回一个异步序列。每次迭代拿到模型新生成的一小段文字,你把它追加到显示区域就行了。

界面上不需要任何改动。因为responseText@State变量,每次追加内容SwiftUI都会自动刷新界面。文字会像打字一样逐字出现。

如果你想控制显示节奏,可以在追加之间加一个微小的延迟:

for try await partial in stream {    responseText += 
            partial.content
              try? await 
            Task.sleep(for:
           .milliseconds(15))}

15毫秒的间隔是我测试下来最舒服的速度。太快了像刷屏,太慢了又回到"干等"的感觉。

把respond(to:)替换成streamResponse(to:),跑起来对比效果。输入一段长文本,观察文字逐字流出的感觉。调一下sleep的毫秒数,找到你觉得最舒适的节奏。

4.3 阶段成果验收

第三阶段完成

加上流式输出之后,SmartNote的体验质变了。之前用户点发送→干等→文字突然出现。现在变成了点发送→文字开始流动→逐渐完整。从"等待结果"变成了"观看过程",用户的心理模型完全不同。

我拿给一个做产品的朋友看,他的第一反应是"这不像Demo了,像正式产品"。就差一个流式输出,感知质量提升了不止一个档次。

从头到尾走一遍完整流程——打开App → 选择模式 → 输入笔记 → 观察流式输出 → 检查结果质量。录一段屏幕视频,这是你的阶段性成果。


五、进阶三:工具调用——让AI还能"干活"

5.1 什么是Tool Calling?

到目前为止,你的AI只是在"说话"。用户给一段文字,模型返回一段文字。本质上还是一个聊天机器人。

但真正的AI助手不只是聊天。它还能执行动作。比如用户说"帮我把这段笔记里的待办事项提取出来",模型不应该只是"说出"有哪些待办。而是应该把待办结构化地存储起来,显示在一个独立的列表里。

这就是Tool Calling做的事。模型在生成回答的过程中,如果判断需要调用某个工具,它会输出一个工具调用的指令。你的App接收到这个指令后执行对应的操作,再把结果返回给模型。

Foundation Models框架原生支持这个能力。3B模型虽然小,但已经能理解"什么时候该调用工具"了。

打开Apple官方WWDC Session 259的视频,跳到Tool Calling相关的章节看一遍。理解"模型决策→App执行→结果回传"这个闭环之后,再往下看代码。

5.2 给便签App加一个工具:自动提取待办事项

我们要定义一个工具,叫extractTodos。当模型判断用户的笔记中包含待办事项时,它会自动调用这个工具,把待办提取成结构化数据。

import FoundationModelsstruct TodoTool: Sendable {    func extractTodos(from text: String) -> [String] {        let lines = 
            text.components(separatedBy:
           .newlines)        return 
            lines.filter
           { line in            let lower = 
            line.lowercased()
                      return 
            lower.contains("要")
           ||                   
            lower.contains("需要")
           ||                   
            lower.contains("记得")
           ||                   
            lower.contains("别忘了")
           ||                   
            lower.contains("todo")
           ||                   
            lower.contains("待办")
                  }.map { $
            0.trimmingCharacters(in:
           .whitespaces) }    }}

然后在创建会话时注册这个工具,并在instructions中告诉模型什么时候该用它:

let session = LanguageModelSession(    instructions: """    你是笔记整理助手。分析用户的笔记内容:    1. 提炼3条核心要点    2. 如果发现待办事项,调用extractTodos工具提取    3. 输出简洁的中文总结    """,    tools: [TodoTool()])

界面上加一个独立的区域来展示提取出来的待办:

@State private var todos: [String] = []VStack(alignment: .leading) {    Text("待办事项")        .font(.headline)    ForEach(todos, id: \.self) { todo in        Text("• \(todo)")    }}

当模型调用extractTodos工具时,App会把提取到的待办存入todos数组,SwiftUI自动刷新列表。

把工具定义和注册代码加进去,在界面上加待办展示区。输入一段包含待办事项的笔记,比如"下午3点开会,记得带上Q3数据报告,还要给客户发邮件确认交付时间",验证待办是否被正确提取。

5.3 阶段成果验收

第四阶段完成

加了Tool Calling之后,SmartNote不再只是一个"你问我答"的聊天界面。它能主动分析内容、提取结构化信息、把结果展示在对应的功能区域里。

这是从"聊天机器人"到"智能助理"的本质区别。聊天机器人:用户输入→模型输出一段文字→结束。智能助理:用户输入→模型分析内容→调用工具执行操作→结构化展示结果→用户直接使用。

我做完这一步之后,把App给同事试用了两天。他的反馈是:"以前我用ChatGPT总结笔记,总结完还得自己手动把待办抄到提醒事项里。你这个直接帮我分出来了,省了一步。"就这一步,每天大概省3到5分钟。一年下来就是20多个小时。

从头走一遍完整流程——输入一段混合了日常记录和待办事项的文字 → 模型总结要点 → 自动提取待办 → 两个区域分别展示。确认所有功能正常联动,没有崩溃。


六、避坑与上线:从Demo到App Store

6.1 坑一:首次冷启动下载1.8GB权重

这是最容易踩的坑,没有之一。

用户第一次打开你的App,点击AI功能按钮,isAvailable返回false。因为模型权重还没下载完。1.8GB的文件,在WiFi下大概需要3到5分钟,4G下更久。

如果你什么都不处理,用户看到的就是:点了按钮,没反应。用户会以为App坏了,直接卸载。

正确的做法是两步:第一步,检测模型是否可用,不可用时禁用AI按钮并显示加载状态。第二步,提供一个友好的等待界面,告诉用户"AI功能正在初始化,首次使用需要下载模型,请连接WiFi"。

if isModelAvailable {    Button("AI总结") {        Task { await askAIStream(question: inputText) }    }    .buttonStyle(.borderedProminent)} else {    HStack {        ProgressView()        Text("AI模型加载中,首次使用需下载约1.8GB...")            .font(.caption)            .foregroundStyle(.secondary)    }}

我第一次发布Demo的时候没做这个处理,testers纷纷反馈"AI功能坏了"。排查了半天才发现是模型没下载完。加上这个检测之后,投诉直接归零。

把模型可用性检测加到AI功能按钮上,不可用时显示加载状态。然后卸载App重新安装,模拟首次使用的场景,确认加载提示正常显示。

6.2 坑二:3B模型的边界在哪里?

3B模型的上下文窗口是有限的。输入太长的文本,会触发exceededContextWindowSize错误,App直接崩溃。

我实测的安全边界是500个中文字符以内。超过这个长度,分段处理。

func safeAskAI(text: String) async {    if 
            text.count
           > 500 {        let chunks = 
            text.chunked(by:
           500)        var fullResponse = ""        for chunk in chunks {            let session = LanguageModelSession(                instructions: modeInstructions            )            let response = try? await 
            session.respond(to:
           chunk)            if let r = response {                fullResponse += 
            r.content
           + "\n"            }        }        responseText = fullResponse    } else {        await askAIStream(question: text)    }}

还有一个边界:别让模型做事实核查。3B模型的知识截止日期不确定,它可能会"一本正经地胡说八道"。如果你的App涉及事实性内容,加一个免责提示:“AI生成内容仅供参考,重要信息请自行核实。”

在代码里加上500字符的输入限制。超长输入时自动分段处理,并在UI上提示用户"文本较长,正在分段处理中"。

6.3 坑三:App Store审核——隐私声明别忘了加

你的App使用了设备端AI模型来处理用户文本。虽然数据不出设备,但Apple的审核指南要求你在隐私声明中披露这一点。

在Xcode中打开你的项目设置,找到"Privacy"或"Privacy Manifest"部分,添加Foundation Models的使用声明。具体来说,你需要声明你的App使用了以下API:

  • LanguageModelSession

    ——用于创建AI会话

  • SystemLanguageModel

    ——用于检测模型可用性

声明内容大致是:“本App使用Apple Foundation Models框架在设备端处理用户文本数据,所有AI计算均在本地完成,不会上传至云端。”

我第一次提交审核的时候忘了加这个声明,直接被打回来了。审核反馈原文是:“Please provide a privacy manifest explaining your use of on-device AI models.” 加上声明之后,第二次提交秒过。

在Xcode中创建或更新Privacy Manifest文件,添加Foundation Models的使用声明。写清楚"设备端处理、数据不上传"这两点。

6.4 最终验收:一个完整的、可上架的AI便签App

全部阶段完成

走到这一步,你的SmartNote已经具备了以下能力:

  • 设备端AI模型检测与加载状态管理

  • 三种模式切换(总结/改写/创意)

  • 流式输出打字机效果

  • 工具调用自动提取待办事项

  • 长文本分段处理

  • 隐私声明合规

从头到尾走一遍完整流程:打开App → 输入一段混合了日常记录和待办事项的笔记 → 选择"总结模式" → 观察流式输出 → 确认要点和待办分别展示在对应区域 → 切换到"改写模式"重新处理 → 确认输出风格变化。

没有崩溃,没有卡顿,没有空白等待。这就是一个可以上架的AI产品了。而它的AI能力,成本为零。

完整走一遍上述流程,录一段最终版的演示视频。然后对照App Store审核清单逐项检查,准备提交。


写在最后

苹果这次免费开放端侧AI模型,本质上是在做一件事——降低AI的使用门槛。

以前你想给App加AI功能,得买服务器、调API、付月费、处理网络延迟、操心数据隐私。现在三行代码,模型跑在用户手机上,免费,无限调用,隐私数据不出设备。

这不是"小而美"的玩具。这是AI能力真正走向平权的开始。

3B模型当然不是万能的。但覆盖大多数App的文本处理需求,绑绑有余。剩下的复杂场景,端侧加云端的混合架构才是终极解法——简单任务本地搞定,复杂任务再调云端大模型。

现在不入场,三个月后你会后悔。因为你的竞品已经在用免费AI提升产品体验了,而你的用户还在手动整理笔记。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐