InfoForge:将离线版维基百科作为本地 AI 代理的 RAG 数据源

发布日期
2026年8月28日
作者
Jacob Lloyd —— 项目完成后,在 AI 协助下撰写
阅读时长
约 9 分钟阅读

简单来说: InfoForge 实际上是我家中电脑上存储的整个英文版维基百科内容,外加一个小型程序,用于让我运行的 AI 助手能够从中检索信息。当您提问时,助手不会仅凭记忆来回答,而是会在这些文章中搜索相关内容,阅读匹配的条目后生成答案,并注明信息来源。如果找不到任何相关资料,它会直接回复“我找不到相关信息”,而不会胡编乱造。整个过程中没有任何数据被发送到任何公司服务器,也没有人记录下这些问题;即便在没有网络连接的情况下,它依然能正常工作。

我询问了本地的一个8B规模的模型:《Kokoro》是谁写的?何时出版的?它回答道:“夏目漱石,1914年。”接着它又说出了我真正关心的内容:它列出了自己查阅的维基百科条目。其实这个模型原本并不知道这些信息;它是通过我家中机器上存储的一份大小达52.69 GB的维基百科数据才查到答案的——整个过程中互联网完全没派上用场。

简而言之

  • 这是什么:完整的英文版维基百科内容被打包进单个ZIM文件里,共包含1919万条条目;这是2026年6月的备份数据,不含图片。该文件在本地运行,再配合约700行Python代码,即可作为本地模型的检索数据源。
  • 需要多少成本:完全免费。只需下载一次即可;占用磁盘空间约53 GB,无需注册账号、无需API密钥,也没有订阅费用。
  • 速度如何:全文搜索仅需3至30毫秒;获取单个条目也只需0.5毫秒;生成带事实依据的完整回答大约需要8秒——其中近7.9秒其实是语言模型自身在思考。
  • 让它实用的关键规则:当无法找到可靠依据时,该工具会返回非零退出码。使用它的AI代理也被要求必须报告查找失败的情况,绝不能自行编造答案。
  • 它绝不会做的事:绝不联网。没有第三方服务商参与,也没有任何API调用或查询日志——我家人向它提出的所有问题都不会被记录为数据集。

既然模型“本就知晓很多信息”,为何还要这么做?

其实它们并不真正知晓事实;其失效模式更是极其危险。小型模型在被问及日期、化学特性或地名时,常会给出流畅、自信且看似合理的回答,却完全不会透露这些信息是否真实可信。它们并非故意撒谎——只是根本不具备区分“记忆内容”与“生成内容”的机制。这种特性对文学创作尚可接受,但对事实性信息而言却是灾难。

检索机制可以解决这个问题,但常规做法往往依赖云端搜索API:用户的提问会被发送至某家公司,该公司会记录下这些请求;于是你使用的AI助手的效果便受制于该公司的运行状况与服务条款。在我家,这套AI系统负责回答孩子们的问题,因此上述两种情形都令我忧心不已。

维基百科恰好能同时解决这两大难题:它是目前最全面、密度最高的通用知识库;在法律与实际操作层面均可完整下载;其数据量也仅需要一块价格低廉的硬盘即可存储。Kiwix项目多年来一直在做这件事——将整个维基百科内容打包成经过压缩且可索引的ZIM格式,供学校、船只以及无网络环境的地区离线使用。我不过是让AI去读取该数据,而非通过浏览器访问罢了。

最终效果如何?

用户输入问题后,系统会输出答案以及对应的引用列表,明确列出支撑该答案的维基百科条目。例如:

$ infoforge "Who wrote Kokoro and when was it published?"

Kokoro was written by Natsume Sōseki and published in 1914.

Sources:
  - Kokoro

从外观上看并无特别之处。关键在于那些“没有发生的事”:没有任何网络请求被发出,没有任何数据被上传至第三方服务器;模型也因机制限制而无法仅凭记忆作答。若搜索未返回任何结果,系统便会显示失败信息并以非零退出码结束运行,而不会强行填补空白。

运作原理

整个过程分为五个步骤,每个步骤都极为简单——这正是最佳实践方式。

关键词提取:问题本身并非理想的查询词。“谁写了《Kokoro》?何时出版的?”这种问法并不适合搜索;而“Kokoro”则更为合适。只需几十行代码剔除停用词并保留关键短语即可实现此功能,我至今也未做改动。

检索环节:Kiwix提供的全文检索其实是基于真正的索引系统,而非简单的grep操作——这正是整个流程得以顺利运行的核心所在。在1919万条条目中,它仅需3至30毫秒便可返回排序后的标题列表。整个系统中没有任何嵌入向量、向量数据库或内容分块存储机制;维基百科的编辑们早已完成了内容分块工作,这些“分块”即被称作“条目”。

提取与压缩:排名靠前的条目会在半毫秒内以完整文本形式返回。压缩环节则需要一定判断能力:文章开头部分通常包含大部分可解答的信息,因此我们会优先保留开头内容;既要保证每条信息相对独立,又需避免过多内容挤占后续指令所需的空间。

基于事实的提示生成:这些文章会被纳入提示文本中,同时附加一条硬性指令:模型只能依据上述资料作答,且必须标注出对应的出处。这便是整个流程的核心技巧——它本质上属于提示模板而非绝对保障措施,所以才有了后续环节的存在。

模型运作:本地推理模型(我家中的GPU服务器运行的是DeepSeek-R1 8B版本)负责生成最终答案。在系统预热之后,整个响应过程约耗时8秒;其中约7.9秒均为模型自身的思考时间。检索环节几乎不消耗资源,但模型思考则需要成本。

以“拒绝机制”实现事实锚定

这是我最坚持的设计理念,但它并非技术层面的决策。

“仅使用这些资料作答”这类提示只是一种请求。多数情况下模型会遵从;但有时也会无视它——尤其是当可用资料有限而模型自身恰好存有相关记忆时。若整个系统的防御手段仅停留在此类提示上,“基于事实”便只能沦为一种表面口号。

因此,事实锚定机制是在模型外部强制执行的。当检索未能返回任何可用信息时,工具不会将原始问题直接转交大型语言模型作为后备方案——它会报错并以非零退出码终止运行。这一特征是所有调用程序都能识别的信号;而使用它的AI代理也被明确要求必须上报查找失败情况,绝不可自行编造答案。如此一来,拒绝机制便能逐级传递下去,不会被上层模块轻易掩盖。

最终得到的便是一个会如实告知“无法找到所需信息”的助手。这看似是功能上的短板,实则不然。一个能明确说出“找不到相关信息”的模型远比一个胡乱编造答案的大型模型更有价值——前者仍值得信赖并加以利用;后者则需逐一核实真实性;倘若每个回答都得经过人工核查,那所谓的效率提升便完全无从谈起。

隐私保护源于架构设计而非单纯政策

各大主流助手均有专门的隐私说明页面。而我这套系统则拥有独特的拓扑结构:用户提问从终端发出后,经由同一局域网内的检索索引传递至本地模型,最终结果再返回原处。整个路径中没有任何第三方服务商能记录相关信息;不存在可识别我身份的密钥;也没有任何可能随时更改的服务条款。我的孩子即便询问些略显尴尬的问题,该过程也和翻阅书架上的书籍一样私密——从功能层面来讲,它确实就是如此。

最妙之处在于:其他人根本无需盲目信任这套机制。只要断开网络后观察其仍能正常运转,便可验证其可靠性。

那些不起眼的90%工作

整个流程搭建只花了周末一点时间;真正的难点则在于容器配置时的三个参数设置。

维基百科服务运行于一个无root权限的容器中,该容器位于启用了SELinux策略的不可变Linux桌面系统上。上述每一项限制都让我耗费了一整晚才搞定:

  • 无root权限的用户映射:容器内部必须以root身份运行,但该身份需映射到外部的非特权用户。稍有差错,服务虽能启动并报告状态正常,却完全无法读取指定文件。
  • SELinux标签重设:在启用了SELinux的系统中,挂载至容器的卷必须设置特定选项以重新标记权限;否则内核层面的安全策略会直接拒绝读取请求。该错误往往表现为“文件缺失”,误导用户去检查本不该查看的位置。
  • 明确指定文件路径:容器内部的文件系统视图中,自动发现ZIM目录的功能并未如文档所述运作。直到我放弃“问题出在其他地方”的假设并手动指定文件名后,才顺利解决问题——整个过程仅耗时三十秒。

仅仅三个参数设置便耗费了近90%的时间。这正是绝大多数自建服务工作的真实面貌;也正是这些内容常被各类教程忽略的原因——正因如此,许多初学者在初次独立操作时便误以为自己不擅长此类工作,其实他们只是遇到了同样的三个难题罢了。

然后它“死”了,却没人注意到

它原本运行正常,速度也很快。我做过测试并记下了相关数据,之后便没再理会。

一周后,当我试图再次使用它时,却发现它不见了。原来机器在某个时刻重启了,但对应的容器并未重新启动;由于没有服务单元、监控机制或健康检查程序,系统根本没给我任何提示。更糟糕的是:本应让 AI 代理知晓此工具存在的技能描述文件其实只是“草稿状态”,从未被安装过。于是整整一周时间里,家里的所有 AI 代理都只能凭记忆回答问题——它们本可以查询资料的,却完全不知道自己缺失了这样一个功能选项。

教训很简单:

一个既无自动启动机制、又无人知晓的功能,其实等同于你根本没开发过的功能。

解决办法就是编写一个 仅12行的服务单元文件 以及一个 Markdown格式的文件。服务单元确保服务器在重启后仍能正常运行;而那个 Markdown 文件则属于 AI 代理栈中的共享技能描述——它告诉各代理该工具的存在方式、调用方法(是执行 shell 命令,还是直接发送 HTTP 请求),以及返回的回答必须附带引用来源。

整个系统原本有700行代码,故事听起来也很美好。但真正让这一切落地的只是区区13行样板代码罢了。这个道理我至今仍在反复领悟。

深度融入 AI 代理栈

我在家中及办公环境中运行着多个本地 AI 代理,如今 InfoForge 已不再是我需要单独记忆的脚本,而是整个系统共有的功能。需要获取信息的代理只需执行相应命令或调用对应接口,即可获得附带引用来源的回答,并继续后续处理。这些引用来源的重要性远超想象:当某个代理向我提供信息并附上相关文章链接时,我只需点击一下就能验证其真实性——正是这种验证机制让一个看似可靠的助手真正变得实用起来。

它还能与家中的其他服务无缝协作。同一台 GPU 服务器既负责响应 InfoForge 查询、撰写邮件,也参与日常对话;而知识层也因此变成了一个无需注册账号即可使用的工具。

注意事项

  • 下载前务必检查磁盘空间。 无图片版的数据包大小约为53 GB;若需要图片内容,所需空间则翻倍。请先确认剩余空间是否充足——否则下载到一半才发现空间不足可就麻烦了。
  • 数据包带有日期标记。 我下载的版本是2026年6月的。维基百科的内容一直在更新,但在本系统中,任何晚于该日期的新内容都会被视作不存在——这一点你若清楚倒也无妨,但疏忽的话可是个大坑。
  • 搜索质量取决于关键词提取效果。 我所遇到的几乎所有错误回答其实都源于糟糕的查询语句,而非模型本身的问题。在考虑升级更大规模的模型之前,务必先优化关键词提取环节。
  • 输出长度需仔细调整。 上下文太少会导致答案缺失;太多则容易让模型偏离指令要求。请根据实际关心的问题来调优,而非仅依赖模拟测试数据。
  • 务必刻意测试异常情况。 试着询问一些维基百科根本没有记载的内容,确认系统会明确拒绝并给出非零退出码——而不是生成一段看似合理的回答。只测试能成功回答的问题只能验证一半的功能而已。
  • 从第一天起就编写服务单元文件。 理由如前所述。想知道我是怎么知道的吗?尽管问我吧。

现状与未来规划

如今我家拥有了一套离线百科全书系统:前面配有搜索索引,还有一个仅被允许基于该库内容发言的 AI。这一切仅需一次下载和周末的时间即可实现。它比互联网响应更快、在断网时也能正常工作、绝不会被随意停用,更不需要我为其支付任何费用。

接下来的计划是:在同一台服务器上添加更多 ZIM 数据包——比如 Kiwix 提供的医学与技术类资料库,还有我自己维护的几个维基站点;毕竟检索层根本不在乎底层知识库的具体内容。当然,我还会加上健康检查机制——毕竟这次我可是付出了惨痛代价才学到这一教训的。

下载

仅限个人使用免费。如果它替你省下了一下午的时间,欢迎点旁边的咖啡按钮支持一下。


← 更多AI 与本地 LLM