不联网、不上传、断了网也能用的桌面 AI 助手,技术上要过哪几道坎?一次选型和落地的完整复盘。
一、起点:为什么非得"本地离线"
做桌面工具箱产品的同行应该都想过同一个问题:要不要在客户端里加个 AI 助手?
走云端 API 的路线最省事:接个大模型接口,做点 Prompt 工程,两天就能上线。但对我们这种以"本地离线"为产品底线的工具类软件来说,云端方案从第一天就是否决项------用户用批量文件处理、加密、文本转换这类工具,图的就是数据不出本机。AI 助手如果反而要把用户的问题、上下文、甚至文件内容传到第三方服务器,等于亲手拆掉产品最重要的承诺。
所以目标定了:CPU 推理、零新增 DLL、断网可用、随安装包分发。这四个约束,几乎决定了后面所有的技术选择。
二、选型:为什么是 llama.cpp
主流可选路径大概三条:
- 云端 API------前述原因,直接否决。
- ONNX Runtime / 自己导出模型------灵活,但部署链路复杂,模型格式管理成本高。
- llama.cpp------纯 C/C++,无 Python 依赖,CPU 推理是第一公民,MIT 协议可商用,GGUF 量化格式成熟。
最终选了 llama.cpp(我们 vendored 的是 v0.5.0),理由展开讲三点:
其一,纯 C/C++ 意味着可以静态链接。 我们的客户端是 C++/Qt6 的,如果引入 Python 运行时或者一坨动态库,安装包体积和分发复杂度都会失控。llama.cpp 编译成静态库直接链进主程序,安装包里零新增 DLL------这一点对桌面产品太重要了,DLL 版本地狱谁踩谁知道。
其二,CPU-only 是刻意为之。 不做 GPU 加速,把基线压在 SSE4.2 指令集,换来的是"在任何一台近十年的机器上都能跑"的确定性。桌面工具的用户画像太散了,核显老笔记本是真实存在的绝大多数,为少数人做 GPU 加速不如把 CPU 路径的量化模型调好。选小参数量的量化模型(Q4 级别),8GB 内存机器可以稳跑。
其三,MIT 协议没有法务负担。 桌面产品要考虑商用分发,协议干净是硬指标。模型权重本身是自研资产,与推理引擎解耦。
三、工程问题比算法问题多

真正花时间的地方,全在工程侧。
1. 线程模型:推理绝不能上 UI 线程。
我们的架构里有统一的后台任务管理器(单例 CoreManager),页面的业务线程一律通过 acquireWorkerThread(ownerPageId, name) 获取,Worker 是 QObject + moveToThread 的事件驱动模型,不继承 QThread。推理任务自然也走这条路:对话请求投递给 Worker,流式输出通过信号逐 token 发回 GUI 线程渲染。
配套的停机纪律是老三样:优雅停止 → wait(3000) → 超时强杀兜底。推理这种长任务尤其要处理"用户关窗口时正在生成"的场景,否则退出转圈、堆损坏都会找上门。
2. 编译开关隔离。
vendored 的 llama.cpp 全量参与编译会明显拉长构建时间,我们用 7AA7_ENABLE_XIAODOU 开关把它整个包起来:OFF 时不编 llama.cpp、AI 模块的源码整体不参与编译,入口运行时提示"未就绪"。Linux CI 上想快速验证主工程时这个开关是救命的------顺带说一句,沙箱 cgroup 内存只有 8GB,编译记得 -j4,全并行会被 OOM Killer 杀进程。
3. 内存与上下文的账要提前算。
GGUF 模型加载后是"模型权重 + KV Cache"两块大头。上下文长度翻倍,KV Cache 跟着翻倍,8GB 机器上不是随便给 32K 的。我们的做法是根据物理内存分档:低内存机器收敛上下文、提示词做裁剪,宁可助手"记性差点",不能让用户的系统被一个工具箱拖死。
4. 失败兜底要"诚实"。
模型文件损坏、内存不足、推理超时,都要有明确的降级路径。我们给助手的定位写进了产品文案:它是本地小模型,能力边界明显------答不上来的就直说答不上来,不做幻觉兜圆。桌面工具的用户是来干活的,一个一本却说瞎话的助手不如没有。
四、效果与取舍
最终形态:一个完全离线的对话助手,首字响应秒级(小模型 + CPU 的正常水平),安装包增量约几百 MB(主要是模型权重),内存占用按机器分档控制在可接受范围 , 而此次7AA7工具箱便是一个行业开头 , 一个离线工具的开头。
坦白说,它不聪明------和云端旗舰模型比差得远。但在"数据不出本机"这个前提下,它是当前技术约束里能给到的最优解。本地 AI 的正确预期不是"更强",而是"够用且放心"。
这套选型(llama.cpp + GGUF 量化 + 事件驱动 Worker + 编译开关隔离)对任何想给桌面端加离线 AI 能力的团队应该都有参考价值。踩过坑的同行欢迎评论区交流,尤其是内存分档和停止纪律这两块,我猜各家的做法差异会很大。