说实话这个项目是我被网络逼出来的。去年去一个偏远项目现场网络差到连搜索都打不开临时要查一个设备说明翻遍手机缓存也没找到最后只能打电话回去让人查了再念给我听。那种憋屈感让我下了一个决心——搞一台完全离线的知识服务器把维基百科、可汗学院这些优质内容全量拉下来再塞一个本地AI助手进去让整套知识服务在一个断网环境里也能安静运转。这个项目断断续续折腾了两周踩了不少坑也沉淀了一些经验。如果你也想搭建一台离线知识服务器或者单纯想在局域网里体验本地AI问答这篇文章应该能把弯路帮你省掉大半。下面从方案设计开始一步一步说清楚。1. 项目概述与整体设计为什么需要一台离线知识服务器1.1 先想清楚你的“离线”到底指什么在动手之前我先花了一天时间把需求想明白。所谓“离线”在不同场景下含义差别很大。我要的是绝对意义上的断网可用——整个设备在完全没有互联网接入的局域网里也能完成三件事查资料、看课程、做问答。这个需求并不是凭空想象。远程项目现场、单位内网隔离区、学校机房、甚至只是不想被打扰的家里书房都会遇到类似场景。传统做法是买几本纸质百科书囤着但随着内容量变大纸质方案完全不现实。维基百科仅中文一个语言版本渲染成网页后的体量就远远超过任何一套纸质百科可汗学院的数学、科学类课程视频更是动辄几十GB。所以“离线知识库”必须靠服务器来承载靠软件来索引靠AI来问答。这里有一个很关键的设计决策是选择“阅读型离线库”还是“交互型离线库”。阅读型以Kiwix为核心速度快、索引全适合查找交互型以本地大模型为核心能答疑、能总结但容易“一本正经地胡说八道”。我最终的方案是把两者合并Kiwix负责权威资料检索本地大模型负责基于检索结果的问答也就是典型的RAG检索增强生成思路。1.2 方案选型为什么是Kiwix Ollama Open WebUI确定需求后我开始对比技术方案。维基百科的离线化有两条主流路线一是用MediaWiki自带dump导入本地数据库跑一个完整的维基站点二是用Kiwix把官方ZIM文件挂载起来。前者功能全但极其笨重需要数据库、Web服务器、PHP环境光初始化就要好久后者轻巧得多Kiwix本质上是一个针对ZIM文件的索引和阅读引擎启动一个服务就能搜索浏览整个维基百科。实测下来在同样的机械硬盘环境里Kiwix的搜索响应速度远快于前者。AI助手的选型我一开始考虑过调用云端API后来果断放弃了。离线服务器存在的意义就是摆脱对网络的依赖如果问答环节还要联网整个项目就失去了意义。本地模型方案我选了Ollama作为运行时主要原因有三个安装简单到一条命令模型管理非常直白而且对CPU推理的支持很成熟。模型本身选了通义千问的Qwen2.5系列中文效果好指令跟随能力也稳定。前端交互选了Open WebUI它天然适配Ollama有类似ChatGPT的聊天界面还内置了文档库功能可以直接把知识文本导入进去让AI回答问题时有依据。整体架构非常干净浏览器访问两个端口8080给Kiwix3000给Open WebUI后台由Ollama提供模型推理能力。2. 硬件选型与系统环境准备2.1 别一上来就买服务器先算算账离线知识服务器不是高并发业务不需要发烧级的配置但也不能太寒酸。我给这台机器定的核心指标是低功耗、24小时稳定运行、本身空间足够装下知识库和模型。先说功耗我选了一台Intel N100小主机四核四线程TDP只有6W整机带一块硬盘实测功耗在10W出头。按0.6元一度电算一天电费大概一毛五一年五十几块钱挂角落里根本不用心疼。内存方面CPU推理大模型非常吃内存如果只有8GB就别想跑7B级别的模型了所以我配了16GB跑Qwen2.5 7B量化版加可汗学院查询、Open WebUI日常占用率在60%左右比较从容。存储是一笔大头。先算知识库中文维基百科“无图版”ZIM文件约30GB“带图版”约55GB可汗学院中文ZIM按视频内容算大概20GB上下加起来已经接近80GB。再算模型7B模型的Q4量化版大约4.7GBEmbedding模型不到300MB。系统本身和Docker镜像占10GB左右。我把这些一加觉得至少得准备500GB以上空闲空间最终直接上了1TB NVMe SSD图个省心。如果之后要包含英文维基、古登堡计划藏书等那块2TB机械硬盘也挂进去了。2.2 系统安装的几个细节系统我用了Ubuntu Server 24.04 LTS没有装桌面只留SSH。为什么不用轻量NAS系统因为后面要跑Ollama和DockerUbuntu Server的兼容性最好出问题也容易搜到答案。安装过程有几个影响后续使用的细节。第一磁盘分区时直接把大部分空间分给数据目录我单独分了/data分区让系统盘和数据分开出问题时重装系统也不影响知识库。第二设置静态IP在路由器的DHCP里给这台机器的网卡绑定固定地址例如192.168.1.88这样服务地址永远不变。第三安装Docker后顺手给容器都加上--restart unless-stopped。这台机器不会有人去手动开机万一断电重启服务得自己拉起来。目录结构我提前规划好了后面所有操作都沿这条路径走/data/kiwix # ZIM知识库文件 /data/ollama # Ollama模型存储通过软链接或环境变量 /data/openwebui # Open WebUI的数据目录 /data/download # 临时存放下载文件建议你在动手之前就把目录建好并设置好权限因为后面内容几十个GB来回拷贝目录切来切去非常痛苦。3. 知识库内容落地维基百科与可汗学院离线化3.1 ZIM文件和Kiwix是怎么回事先解释一下ZIM。Kiwix背后用到的ZIM是一种专为离线阅读设计的高压缩比文件格式它把一个网站的页面、图片、视频、索引打包进一个文件。打开页面时近乎原生速度而且条目级压缩比很高。不用解压Kiwix直接流式读取。Kiwix服务的部署方式非常简单官方已经提供了Docker镜像。我先把下载好的ZIM文件放到/data/kiwix目录然后启动容器docker run -d --name kiwix \ -p 8080:8080 \ -v /data/kiwix:/data \ --restart unless-stopped \ kiwix/kiwix-serve \ --port8080 \ --library /data/library.xml这里用到了library.xml这个文件它是Kiwix的内容索引清单。如果只加载一个ZIM文件也可以直接把文件路径传给容器比如docker run -d --name kiwix \ -p 8080:8080 \ -v /data/kiwix:/data \ --restart unless-stopped \ kiwix/kiwix-serve /data/wikipedia_zh_all_nopic.zim我选用库文件方式是考虑到后面会新增多个ZIM文件比如再加英语维基、可汗学院、古登堡计划用library.xml管理起来清晰。生成library.xml需要用Kiwix的命令行工具安装kiwix-tools后执行kiwix-manage /data/library.xml add /data/*.zim需要注意的是library.xml不能手写这个工具会自动扫描目录并写入每个ZIM文件的元信息、条目数等推荐在下载完所有ZIM文件之后统一生成一次之后再启动Kiwix服务。3.2 下载策略怎么把几十GB内容搞回来下载ZIM文件是整个项目里最枯燥也最需要耐心的一步。官方镜像站是download.kiwix.org目录结构很规整wikipedia下面按语言分目录other下面放了可汗学院等非维基资源。中文维基对应的是wikipedia_zh_all.zim系列可汗学院对应的是khanacademy_zh_all.zim。这里我特别要强调下载文件时不要直接用浏览器下载几十GB的文件中断一次就要从头再来非常崩溃。用命令行工具wget加上断点续传参数会可靠得多wget -c -t 5 --progressdot:giga \ https://download.kiwix.org/zim/wikipedia/wikipedia_zh_all_nopic.zim-c参数是断点续传-t 5是失败重试--progressdot:giga是显示友好进度。下载完成后建议对一下官网给出的SHA256校验值防止文件损坏。我第二次下载时就是因为中途断过一次又换个工具重下结果比对校验值发现文件不完整差点把坏数据直接拷进服务器。校验命令sha256sum wikipedia_zh_all_nopic.zim如果你在离线服务器上没有外网最省事的办法是在一台能联网的机器上把文件全部下载好然后用移动硬盘或U盘拷进离线服务器。很多内网环境没法直接连外网这是最通用的一条路。3.3 启动后先测什么Kiwix启动完成后浏览器打开http://192.168.1.88:8080应该能看到一个书橱样式的首页所有已加载的ZIM文件都列在上面。点击中文维基进入先验证三个核心功能目录导航、全文搜索、随机文章。全文搜索是Kiwix的杀手锏它基于ZIM自带索引对中文也支持得不错输入“长江”“勾股定理”都能快速返回条目。可汗学院的内容如果通过ZIM文件加载视频会以文件形式内嵌在库中。第一次打开课程页面时可能会有一点延迟因为它要把对应片段从大文件中读出来但一旦缓存完成后后续浏览就流畅了。这一步实测下来一台N100小主机同时给三个人用基本没有卡顿感。4. 本地AI助手部署从模型到对话界面4.1 模型选型别贪大要贪够用AI助手这部分是项目里最容易让人兴奋也最容易翻车的环节。很多人第一反应是“直接上70B大模型”但机器扛不住。在只有CPU、内存16GB的硬件条件下我的选择是Qwen2.5 7B指令版并采用Q4量化格式。这样模型文件约4.7GB推理时内存占用稳定在6GB左右不影响其他服务。为什么不用Llama 3.1单纯从中文问答场景来说Qwen2.5的中文语料和指令跟随明显更顺。为什么不用3B小模型3B模型的响应速度确实快几秒就能出结果但回答稍长的问题就会出现内容跳跃或事实错误。7B这个档位在体验和效果之间相对均衡。Ollama安装只需要一条命令curl -fsSL https://ollama.com/install.sh | sh随后下载模型ollama pull qwen2.5:7b-instruct-q4_K_M ollama pull nomic-embed-text第二个nomic-embed-text是Embedding模型做语义检索时要用到。如果你对响应速度非常敏感可以再拉一个qwen2.5:3b-instruct-q4_K_M作为快速问答通道把不同模型分配给不同场景。4.2 Open WebUI让对话界面落地命令行里可以用ollama run对话但面向日常使用必须有图形界面。我选了Open WebUI它启动后就是一个整洁的聊天界面支持多轮对话、会话历史、Markdown渲染还能直接在同一页面切换不同模型。我是用Docker跑的docker run -d --name open-webui \ -p 3000:8080 \ --add-host host.docker.internal:host-gateway \ -e OLLAMA_BASE_URLhttp://host.docker.internal:11434 \ -v /data/openwebui:/app/backend/data \ --restart unless-stopped \ ghcr.io/open-webui/open-webui:main这里OLLAMA_BASE_URL指向宿主机上的Ollama服务加--add-host是为了让容器里可以通过host.docker.internal访问宿主机。第一次启动后用注册的本地账号登录即可。注意Open WebUI默认会有个人账号体系如果不想让局域网里其他人随意创建账号记得在管理设置里把注册功能关闭。4.3 让AI真正“读过”你的知识库轻量级RAGOpen WebUI自带的文档库功能可以上传文本文件做问答但面对几十GB的维基百科全量内容预设文档库并不能直接覆盖。我在实际项目中做了一层轻量级RAG把维基百科一些高频条目提取成纯文本用Embedding模型向量化后存进本地问答时先检索相关片段再把片段作为上下文交给大模型。这里做一个最小可运行示例核心逻辑如下import sqlite3 import numpy as np import requests OLLAMA_URL http://127.0.0.1:11434 def embed(texts): resp requests.post(f{OLLAMA_URL}/api/embed, json{model: nomic-embed-text, input: texts}) return resp.json()[embeddings] def search(query, top_k3): q_vec np.array(embed([query])[0]) conn sqlite3.connect(/data/rag.db) rows conn.execute(SELECT content, embedding FROM docs).fetchall() scored [] for content, blob in rows: vec np.frombuffer(blob, dtypenp.float32) score np.dot(q_vec, vec) / (np.linalg.norm(q_vec) * np.linalg.norm(vec)) scored.append((score, content)) scored.sort(keylambda x: x[0], reverseTrue) return [c for _, c in scored[:top_k]] query 勾股定理最早由谁提出 context \n.join(search(query)) prompt f请根据以下资料回答问题\n{context}\n\n问题{query} resp requests.post(f{OLLAMA_URL}/api/generate, json{model: qwen2.5:7b-instruct, prompt: prompt, stream: False}) print(resp.json()[response])这段代码背后的检索方式是余弦相似度本质上就是把问题转成向量和每条文档向量比一个方向是否接近。数据量小的时候直接全表扫描没问题数据量上来建议换向量数据库。我这里只是为了证明RAG思路在离线环境里完全可行真正的生产版本建议用ChromaDB或sqlite-vec。这个环节有一个显著效果直接问模型“勾股定理最早由谁提出”模型可能满嘴跑火车但先检索出维基百科相关条目再让模型基于条目回答它会老老实实复述“毕达哥拉斯学派”以及对应的历史背景和争议。这就是RAG对AI助手可靠性的提升。5. 断网实测与常见问题排查5.1 全流程断网实测部署完成后我做了一次真实的断网测试步骤很粗暴拔掉路由器WAN口网线让整个局域网与外界完全隔离接着用手机连Wi-Fi分别访问Kiwix和Open WebUI。一是查资料测试在手机上打开Kiwix搜索“量子纠缠”返回的条目列表和在线版几乎无差别打开条目后图文排版正常公式和图片都能显示说明无图版ZIM也自带了部分必要图片。二是看课程测试打开可汗学院数学课的某个视频缓冲约半秒开始播放体验接近本地文件。三是AI问答测试在Open WebUI里问“结合知识库讲一下热力学第二定律”模型先检索再回答整个回答约10秒出完整内容在局域网环境下我觉得完全可以接受。整个测试过程没有一条请求需要出网所有服务都由这台小主机提供。为了确认真的没有隐蔽的联网请求我在路由器上观察这台主机的网络连接记录除了局域网内的双向流量之外没有任何外网连接。5.2 常见问题与排查技巧下面把项目实施过程中踩过的坑整理成了速查表后续如果遇到类似问题可以直接翻。现象可能原因解决办法Kiwix首页无法打开容器没启动或端口被占docker ps查看容器状态docker logs kiwix看日志换8081端口试试中文搜索无结果搜索词带有标点或空格用短词搜索不要带引号确认用的确实是中文ZIM文件模型回答特别慢CPU推理上下文过长调低上下文长度或者换qwen2.5:3b模型同时把Open WebUI并发数设小局域网其他设备访问不了防火墙拦截检查ufw状态和规则开放8080/3000端口并确认主机IP没有变化断电后服务不自动启动Docker容器或服务未设开机自启所有容器都加上--restart unless-stopped并确保docker服务开机自启下载的ZIM文件校验失败下载中断后文件损坏用wget -c重新下载下载后sha256sum校验提问时AI经常瞎编没有挂知识库上下文用文档库上传资料或走RAG检索后再让模型回答在这里额外分享一个技巧在Open WebUI里遇到拿不准的问题时可以先在Kiwix里搜出对应条目把条目内容发到对话里再让模型基于这段内容总结。等于把权威资料和大模型的表达能力结合起来准确率最高。6. 落地后的个人复盘与可扩展空间6.1 三周使用后的项目复盘这台知识服务器已经在我手边稳定运行了三周。三周里它被用得最频繁的场景反而是我在写技术文档时查参数量定义、回顾统计公式因为随手一个搜索比打开浏览器再翻收藏夹快得多。家人问过一个冷门的历史人物我也直接甩给本地AI处理答案不乱编这点是最让我满意的。回顾整个项目有三条经验特别想分享。第一内容规划要提前做ZIM文件选哪个版本、要不要带图、英文维基要不要一起放这些问题如果到下载一半再改时间和流量都浪费了。第二部署顺序尽量是先跑通最小可用版本再往里面堆内容。我第一次就是把全部内容都拷进服务器后再启动服务结果启动阶段花了很长时间排查一个小问题非常沮丧。第三一定要留一份“离线服务器使用说明”在设备旁边教会家里人或同事使用后他们才不会天天跑过来问你“为什么能上网也打不开”。6.2 几个值得继续打磨的方向扩展空间其实很大。目前这台机器还挂了英文维基百科和古登堡计划的ZIM文件后续我计划加一个定时任务每个月自动下载增量ZIM更新内容Open WebUI的文档库还可以导入自己积累的行业资料做成私人知识库如果再配一块大容量机械硬盘甚至可以放更多视频课程。整体来说这套架构的扩展性足够关键是在前期把硬件和目录规划做扎实。最后分享一个小细节我在开机自启动脚本里加了一条健康检查每天定时访问Kiwix和Open WebUI的首页如果失败就往日志里写一条。对于一台长期不关机的设备来说这种“自我报告”比任何监控系统都省心。折腾一圈之后你会发现离线知识服务器真正的价值不是把网络“备份”到本地而是让你在任何环境下都拥有自己的知识基础设施这种感觉挺踏实。
