离线配置:一次弄好,之后断网也能问
首次访问要下载什么、Service Worker 缓存了哪些文件、怎么自己确认已经缓存、飞行模式怎么测,以及模型缓存被回收和 persist 到底解决了什么。
· 8 分钟阅读
离线用法的定义是这样的:在有网络的情况下访问一次,应用外壳进入 Service Worker 缓存,模型权重进入 Cache Storage,此后解析、分块、向量化、检索、抽取式回答全部在断网状态下运行。有两件事变不出来——你从没下载过的模型,和一台从没访问过本站的全新设备。
首次访问到底下载了什么
第一次访问取回两类文件,分开看更清楚。
一类是应用本身:你打开的那些页面的 HTML、样式、脚本、编译进包里的 PDF 与 Word 解析器,以及执行模型的 ONNX 运行时。运行时由本站托管在 /ort/ 下,不走第三方 CDN,所以文件清单很短,也方便你自己核对。
另一类是嵌入模型的权重,按你的文档语言选一组。
| 档位 | 模型 | 首次下载 | 什么时候选它 |
|---|---|---|---|
| 中文默认 | bge-small-zh-v1.5 | 约 25MB | 文档以中文为主 |
| 英文默认 | all-MiniLM-L6-v2 | 约 23MB | 文档以英文为主 |
| 中英混排 | multilingual-e5-small | 约 120MB | 同一个库里中英文混着放 |
加一份几百 KB 的短文档不会改变这些数字。权重是一次性固定成本,与你放进去多少文件无关。
可选的生成档是另一档、也是更大的一档。跑在处理器的模型约 400MB,WebGPU 版本约 1.0GB。两者都必须经过一次写明模型名和体积的确认才会开始,而且都不是离线使用的前提——抽取式回答本身就能离线跑。
数据分别放在哪里
Service Worker 是一段位于页面与网络之间的小脚本,它在这里的职责很窄:把应用外壳从缓存里端出来,让刷新在没有连接时也能工作,并且不碰用户数据。
| 内容 | 存放位置 | 什么会清掉它 |
|---|---|---|
HTML、CSS、脚本、解析器、/ort/ 运行时 |
Service Worker 缓存 | 清除站点数据 |
| 模型权重 | 本站源下的 Cache Storage | 清除站点数据,或存储压力下的浏览器回收 |
| 文本块、向量、文档元信息、设置 | 本站源下的 IndexedDB | 清除站点数据 |
| 你导入的原始文件 | 不存在这里。导入时从磁盘读一次,之后不复制进存储 | 没有任何东西会清掉它,因为没有东西写过它 |
最后一行需要单独说清楚。工具存的是从文档里推导出来的东西——文本块,以及由这些文本算出的向量——所以刷新页面不必重新导入。它不保留 PDF 或 DOCX 的第二份拷贝。原文件请留在原处:索引里是抽出来的文本,不是版面,所以要核对盖章的签名、图表的刻度、页边的手写批注,都得回到文件本身去做。换模型或缓存被回收之后需要重新导入时,原件还在你放它的地方,意味着一拖就好,而不是去邮箱里翻附件。
还有一件事提前知道比较好。索引是推导出来的、不是拷贝出来的,所以同一份文件导入两次会得到两套文本块。不确定某个文档是否已经在库里时,拿它第一页里某个有辨识度的短语搜一下,比再导一遍稳妥。
自己动手确认缓存
两个面板,三十秒。
- 打开开发者工具,切到 Application 面板。
- 展开 Cache Storage,应该能看到模型文件的条目。它们加起来的大小应当大致等于你选的档位:约 25MB、23MB 或 120MB。
- 展开 IndexedDB,找到本站的数据库,里面会有文档、文本块和向量三个存储。文本块和向量随文档库增长,其中向量更大。
- 想要精确数字,在控制台执行
navigator.storage.estimate(),它会返回整个源的usage与quota,单位是字节。
读这些数字有个经验值:每 1000 个文本块约占 1.5MB 向量存储,还没算其他开销。一份 200 页的报告大概产生 1500 到 2500 个文本块,所以是几兆的量级,而不是几百兆。
飞行模式测试
这是唯一能直接给出答案的测试。
- 带网络打开页面并等它稳定下来,让外壳和权重都进缓存。
- 打开飞行模式,或者把 Network 面板的限速下拉框切到 Offline。飞行模式更严格,因为它同时关掉了移动数据的通路。
- 刷新页面。界面应该出现。如果没有出现,就再联网刷新一次,让 Service Worker 完成首次安装,然后重新断网测一遍。
- 提一个问题。回答和引用应该照常出现。
- 如果启用了生成档,再问一个需要生成的问题。只要它的权重下载完了,离线同样能跑。
两种失败属于预期行为,不是故障。没下载过的模型在离线时取不回来,下载面板会直接失败并提供重试。从没访问过本站的浏览器没有任何缓存,所以第一次访问必须联网。
测试通过之后有个习惯值得养成:在可能断网的时段里把标签页保持打开。关掉再重新打开,可能让那些外壳不在预缓存里的页面重新去取一次 HTML,这是整套离线配置里仅有的缺口。
浏览器把缓存收回去的时候
浏览器把站点数据当作自己可以管理的东西。磁盘紧张时,它可能清掉缓存,包括那几兆它认为你可以重新下载的模型权重。站在用户这一侧,这看起来就是一次莫名其妙的重复下载。
申请持久化是缓解手段。工具在自我配置的过程中会发出这个请求,底层调用你也能随时自己执行:
navigator.storage.persist()
调用它会请求浏览器把这个源标记为持久,意味着只有在万不得已时才会被回收,而不是日常清理时顺手清掉。两点如实的说明:批不批由浏览器自己决定;就算批了,持久化也不等于永久。清除站点数据永远优先,这是设计如此——正是这个特性保证了删除是彻底的。
真的被回收了,代价跟第一次一样,就是那次固定体积的下载。文档库没有损失:IndexedDB 里的文本块和向量不在这轮回收范围内,重新下载权重也不会让它们失效。
离线之后哪些事情变了
检索质量完全没有变化,因为检索从来没用过网络。向量与关键词的混合检索、融合步骤、去冗余、相关度门控,全部在你本机的索引上执行。
有三件事仍然需要连接,提前知道比较好:
- 清除站点数据之后的第一次访问,或者在一台新设备上第一次打开。
- 切换到权重还没下载过的模型档位。
- 首次打开本站的其他页面,如果它们的 HTML 不在缓存的外壳里。
其余的事情——导入一份已经在磁盘上的文档、重新索引、提问、导出回答——断网都能做。