离线优先AI:打造断网也能用的大模型
离线优先AI如何打包量化模型、精选语料与检索,让助手在断网时照常工作,以及它的代价。

停电已经九个小时,手机网络挤爆了,车库冰柜里还塞着你周六买的肉。这还能吃吗?换作平时你会去问聊天机器人。但现在,最先崩掉的是互联网。 这个场景正是一类新兴离线优先AI工具的设计出发点:一个完全运行在你笔记本上的助手和参考资料库。模型、语料、搜索索引,全部本地运行,所以即使网线被拔掉,问“这水怎么净化”照样能得到答案。我觉得这件事作为架构练习比作为应急装备更有意思。去掉网络这个前提,会迫使你做出一系列云端AI可以无视的工程决策,而这些决策在应急场景之外同样有用。如果你考虑过在自己的硬件上运行大语言模型,那离线助手的各种约束,正是这个问题最尖锐的部分。
离线优先AI到底要交付什么
云端助手其实很“薄”:客户端发送文字,数据中心返回token。离线助手则必须在消费级硬件上把整套栈复刻一遍,也就是要交付三个大件,并让它们协同工作。 首先是推理引擎。实践中通常是llama.cpp或它的某个衍生版本,因为它能在Apple Silicon、普通x86 CPU和消费级GPU上用同一套依赖树运行。Mac版应用直接打包它,Windows版则在安装时拉取。无论哪种,都不能假设用户机器上已经有它,你得在首次运行时悄悄自己装好。 其次是模型。这里最有意思,我稍后会展开,因为选对模型是这里的核心设计难题。 第三是资料库。该领域的一款离线助手大约收录了93万篇维基百科条目(阅读量最高的子集)、MedlinePlus和WikiMed等医学资料、FEMA和CDC的应急指南、军方野外生存手册、wikiHow、iFixit维修指南,以及家居维修和业余无线电等主题的Stack Exchange问答数据。全部是纯文本,每篇文章都保留并展示其许可协议。完整下载包约9 GB,安装后膨胀到19 GB;去掉维基百科和iFixit的精简版只有1.3 GB。这既是工程决策,也是编辑决策,得有人决定哪些来源能留下。 整个流程必须压缩成三步安装:点击操作约五分钟,下载最长可能需要两个半小时。这个最后的数字比看上去更重要:下载窗口是你唯一一次获取任何东西的机会,之后再也没有。这种纪律和你对无法重启、也无法连接的软件所要求的一样,只不过这里的“无法连接的环境”变成了暴风雨中漆黑的厨房。
模型分级难题:一个应用,多个大脑
这是云端软件从不需要面对的决策:你不知道用户的硬件配置,无法探测其内存再把他路由到更大的集群,而这个答案会永久决定下载体积以及之后每一次回答的质量。 这类工具的解决方案是按硬件探测分级。首次启动时,应用检查系统内存,选择一个能跑得动的模型: - 128 GB及以上:大型旗舰级模型(某个版本使用NVIDIA Nemotron 3.5 Super,磁盘占用约80 GB),在项目的盲评测试(停电与急救问题)中得分22题中的21题。 - 32–96 GB:约27B参数的中型模型(约18 GB),同样得21/22。 - Windows 32 GB:经过速度调优的约25 GB模型,得19/22。 - 16–31 GB:8B级模型(约6 GB),得14/22。 把最后一行再读一遍。大多数人实际拥有的机器,也就是16 GB的笔记本,分到的大脑在官方指南的核心要点上大约三分之一的时间会答错,而这些问题的核心要点是诸如“室温放了六个小时的鸡肉别吃”之类的内容。 这就是离线优先AI令人不舒服的算术。量化和小模型确实已经相当不错,调校良好的8B模型是不错的写作助手,也是合格的搜索界面。但质量曲线并不会为了迁就你的部署约束而弯曲。云端应用想要更聪明的模型,改个配置开关就行;离线应用想要,就得让用户三年前就买一台更好的笔记本。你交付的是那条曲线,而曲线最终也在塑造你。 这些工具采用的诚实缓解办法是:把小模型当作通往语料的接口,而不是语料的权威。每个回答都会列出具体读了哪些文章,并高亮相关段落,因为设计者清楚8B这一档有时会出错。
检索是信任层,而不只是功能
如今每个检索增强生成(RAG)系统都会展示来源。在云端,这只是一个勾选框功能,有点像透明度的表演。离线场景下,检索则是承重墙。它是唯一能阻止“听起来很合理的幻觉”变成用户在真实紧急情况中据以行动的东西。 由此形成的设计是这样的:模型在纯文本资料库中搜索,阅读排名靠前的段落,然后写出一个带引用的回答。如果用户要求它查一查,即使它已经凭记忆回答过,它也会重新搜索,而界面会标明每个回答来自哪种模式:记忆、打开过的文章,还是从未打开过的搜索结果。最后这个区分很微妙也很重要。“我找到了匹配的片段”和“我读了这篇文章”是可靠性不同的两种说法,界面需要分别对待。 还有一个我很喜欢的失败模式处理细节:当模型去搜索了,却始终没有给出最终答案(小模型确实常干这种事),应用现在会强制把它找到的最佳文章塞回去,让它再试一次,而不是什么都不给用户看。离线环境下,你没法退回到更大的模型,也没有重试队列。你得把重试直接写进智能体循环里。这是人们说LLM智能体的行为类似分布式系统时所指的一个小例子:到处都是局部失败,而编排层的职责就是让失败变得可以承受。 还值得借鉴的一个架构选择是推理预算。应用允许设置模型在回答前可以思考多少token:关闭、1,000、4,000、16,000或不限,达到上限时思考会被截断,模型基于已有内容作答。用电池供电时,一个绕圈子思考的模型不只是答错,还在耗电。硬性上限能把无界的计算问题变成有界的,而当插座只是理论上的存在时,这正是你需要的直觉。

怀疑者说对了一半(说错了另一半)
对这一流派最尖锐的批评是:为什么不干脆跳过LLM,直接做一个可搜索的档案库?Kiwix多年来一直在做这件事:维基百科和医学资料经过压缩、建立索引,可离线搜索,没有幻觉风险,连低配机器都能跑。对于精选文本数据集,搜索引擎在可靠性上可以说更胜一筹。有位测试者问离线助手如何制作弓钻,结果零件说对了,动作却错了:模型描述的是双手间滚动钻杆,完全忽略了弓,还提到“扇风引燃火星”,而摩擦取火并不会产生这种效果。搜索引擎不会犯这种错误,因为它根本不生成任何东西。 但我认为这一批评没有抓住这些系统中LLM真正的用途。对设计最有力的辩护方式,是重新定位它:把模型当作搜索智能,而不是神谕。当你不知道专业术语时,关键词搜索就会失效:你手里有的是症状而不是诊断,是一个坏掉的东西而不是零件名。语义检索擅长“意思相近”,却不擅长“通过机理或因果相连”,而这正是生成式模型能填补的空白:它可以接收“作物叶片边缘发黄”这样的描述,并给出关键词永远找不到的五条查阅路径。模型的任务是把你带到正确的页面,页面的任务是保证正确。 另一种批评是“如果末日来临时你需要LLM,那就直接去学技能吧”。作为人生建议,这没错;作为软件批评,毫无用处。没人的急救知识能涵盖小儿烫伤、水净化化学和发电机维修。书籍涵盖了所有这些内容,争论的只是交互界面。 怀疑者真正打中要害的,是那个22题中答对14题的档次。如果界面层三分之一的时间是错的,而每个回答都附带一句“请核对来源”的免责声明,那么到某个时候,最诚实的产品其实就是带搜索框的档案库。LLM只有在能明确证明它比Ctrl+F更快地把非专业用户带到正确段落时,才值得占有一席之地。这是关于你用户的经验性问题,而不是一种感觉。
一个最小化的离线优先AI技术栈
如果你想自己做一个这样的版本,你应该试试,这是一个非常有启发性的周末项目。骨架比你想象的要小,有意思的是其中的各种选择,而不是代码本身。一个以检索为先的本地Python助手大致如下:
import subprocess
from pathlib import Path
CORPUS_DIR = Path("./library") # plain-text articles, one file each
MODEL = "./models/granite-8b-q4.gguf" # quantized to fit 16 GB RAM
def search_corpus(query: str, k: int = 5) -> list[dict]:
"""Dumb but honest: rank articles by keyword overlap.
Swap in BM25 or embeddings later; the interface is the point."""
terms = set(query.lower().split())
hits = []
for f in CORPUS_DIR.rglob("*.txt"):
text = f.read_text(errors="ignore")
score = sum(text.lower().count(t) for t in terms)
if score:
hits.append({"path": f.name, "score": score, "text": text[:3000]})
return sorted(hits, key=lambda h: -h["score"])[:k]
def answer(question: str) -> str:
sources = search_corpus(question)
context = "\n\n".join(
f"[SOURCE {i}: {s['path']}]\n{s['text']}"
for i, s in enumerate(sources, 1)
)
prompt = (
"Answer ONLY from the sources below. Cite them as [SOURCE n]. "
"If they don't cover it, say so.\n\n"
f"{context}\n\nQuestion: {question}\nAnswer:"
)
out = subprocess.run(
["llama-cli", "-m", MODEL, "-p", prompt,
"-n", "512", "--ctx-size", "8192"],
capture_output=True, text=True,
)
citations = "\n".join(f"[{i}] {s['path']}" for i, s in enumerate(sources, 1))
return out.stdout + "\n\n--- Sources ---\n" + citations
print(answer("how long is food safe in a fridge without power"))
让这东西看起来像产品而不是玩具的,正是那四十来行代码中内置的约束:提示词禁止在来源之外作答,引用由程序机械地附加(从不信任模型来格式化引用,现实中就出过一个bug,模型自己编造了一行“Sources:”,列出的是它自己的搜索命令),而且生成长度有上限。这里缺少但生产环境必需的部分包括:用于语义搜索的向量索引、推理token预算、用于选择模型文件的内存探测,以及让界面能展示的每个文件的许可元数据。 注意这里没有的东西:没有网络调用,没有API密钥,没有遥测。一旦模型文件和语料存在于磁盘上,这个程序就在物理上不可能泄露任何提问。隐私不再是一条政策,而成为依赖图的必然结果。
那些跟随你回家的约束
一旦你做离线优先,几条不起眼的约束就会永久驻扎在你的架构里。 **存储与安装窗口只有一次。** 完整资料库安装时需要约27 GB可用空间,最终稳定在19 GB,而且所有内容都必须在首次下载时到位。飓风期间你无法惰性加载一份缺失的医学参考资料。这会推动你进行激进的筛选:93万篇文章听起来很多,但别忘了维基百科有数百万篇,有人按阅读量排序后砍掉了长尾。 **电力是一等资源。** 在MacBook Pro上测得,回答一次问题约耗电100 W,持续5到40秒,满电大约能支撑100到300次回答。于是,长链思维不只是慢,还变成了燃料决策。推理预算和小模型分级不再是优化项,而成了产品本身。 **你的更新通道就是生命线。** 应用必须能一键更新模型、资料库和二进制文件,并且不破坏本地状态,因为用户下一次有带宽的时间可能是几个月之后。后台资源管理也以一种新的方式变得重要:某个版本的修复让Cmd+Q真正停止了推理引擎,之前窗口关闭后它仍会在内存中常驻一个数GB的模型。用电池时,这不是内存泄漏,而是发热和耗电的泄漏。 **用户文件也纳入信任边界。** 允许用户放入自己的PDF,比如发电机手册或家庭应急计划,意味着你的检索流水线要处理对抗性的杂乱输入:扫描版PDF、奇怪的编码、超大文件。离线状态下,你没法把其中任何一项交给云端解析器。

为什么这种模式超越应急场景仍然重要
隐私不再是一句政策承诺,而成为依赖图的必然结果。一个没有网络调用的程序,永远不可能泄露任何东西。
应急这个框架最吸引眼球,但真正的故事在于架构。同样的技术栈(本地推理、精选语料、带引用的检索、硬性计算预算),也正是以下场景所需要的:诊所里法律上不能离开大楼的患者数据,有气隙隔离机器的工厂车间,在某些国家查询日志就是负债的记者,或者按兆字节计费卫星网络的科考船。讨论中有位从业者描述的正是这种情况:在没有手机信号的房产上,用人工整理的资料库加本地模型,出发前刷新一次,即便有光纤可用,也逐渐取代了他们日常大部分的云端AI使用。 我押注的正是这个走向。量化8B本地模型与前沿API模型之间的差距是真实的,但足够窄,对于以检索为锚点的任务(“找到正确段落并忠实地总结”),本地方案往往已经够用。而足够用、加上零边际成本和有保障的隐私,就是一个极具吸引力的组合。前沿模型会继续变强,量化技术也在进步,小模型则以滞后的节奏搭上同一波扩展浪潮。如果你关注这条曲线的效率一端,Flash级模型正是推理效率故事真正的所在。 如果你正在这个领域设计东西,我的建议是:借鉴模式,而不是末日求生的审美。无情地筛选语料,一个你信任的200篇文档的库,胜过一个你从没读过的93万篇。让引用由程序机械生成,而不是由模型生成。给模型设定硬性的思考预算。并且要明确决定:你的模型是神谕,还是搜索界面。能经受住审视的工具,都是足够诚实、选择了后者的工具。
总结
离线优先AI关乎的不是在末日中生存,而是搞清楚当所有逃生通道都被焊死时,你的架构会变成什么样子:没有更大的模型,没有云端兜底,没有常开的网络,没有无限的电力。剩下的是一个精选语料库、一个按你无法控制的硬件大小量化的模型、承载信任的检索,以及一个为优雅失败而设计的智能体循环。这些在线上同样是好的工程纪律。风暴只是让你学得更快一点。


