
我做了一个本地 AI 学习软件免费开源完全本地运行这两年 AI 工具满天飞ChatGPT、Claude、各种国内大模型助手确实能帮上不少忙。但作为一个平时喜欢折腾学习软件的人我一直有个不舒服的点不管是做题、总结文档还是背诵知识点只要用在线 AI就意味着我的学习记录、提问习惯甚至我上传的笔记文稿都要过一遍别人的服务器。对于学习这种私密性很强的事多少有点心里没底。所以大概两个月前我决定自己做一个 AI 学习辅助软件。核心思路就三条完全本地运行、免费开源、专注学习场景而不是通用聊天。用下来这段时间它已经成了我日常背单词、整理错题和啃技术文档的主要工具。这篇文章就干脆从我选型、设计、实现到踩坑完整复盘一遍希望能给也想做本地 AI 应用的朋友一点参考。1. 内容整体设计与思路拆解1.1 为什么不做成普通聊天机器人而是“学习软件”先说一个很容易踩的坑很多人一提到本地 AI第一反应是用 Ollama 跑个大模型然后套个网页聊天壳子美其名曰“本地版 ChatGPT”。但作为学习工具聊天模式其实是效率最低的形态。你想啊学习这件事核心是“输入—加工—提取”三个环节聊天机器人只能覆盖“输入”和“提取”的皮毛真正关键的“加工”环节比如生成练习题、做间隔重复复习、对错题进行归因分析它完全不做。我设计这个软件时给自己定了几个硬指标能导入我自己的学习资料Markdown、Word、PDF、纯文本构建一个私有知识库能基于知识库自动出题包括选择题、填空题、简答题能跟踪我的答题记录用间隔重复算法安排复习全程离线可用断网也能学开源代码任何人可以审查不会在后台偷偷上传任何东西。1.2 技术选型一切从“能在普通电脑上跑起来”出发关于运行平台我一开始想过用嵌入式设备或手机端方案毕竟现在开源硬件生态也确实热闹。但考虑到学习资料处理和知识库构建的复杂度最终还是选择了 Windows 11 笔记本作为主运行环境。这个选择的核心逻辑是本地 AI 应用的瓶颈往往不在模型本身而在文档解析、向量检索这些周边环节桌面端的环境成熟度最高。模型推理端我用了 Ollama 作为运行时然后在上面跑 Qwen2.5 7B 的量化版本。为什么选 7B 而不是 13B 或者 70B因为我的笔记本是 16G 内存外加一张 6G 显存的入门级显卡。7B 量化后大概占 5-6G 显存还能留出空间跑知识库检索组件。如果硬上 13B显存装不下就得回退到 CPU 推理那个速度基本就是“点一下等三分钟”学习体验会非常糟糕实属得不偿失。知识库部分我用了当前开源生态里比较成熟的一套组合文本解析用 PyMuPDF、Pandoc 和 python-docx 混合处理向量化用 sentence-transformers 里的小型中文嵌入模型存储检索用 ChromaDB。整套架构都是开源组件组合起来非常轻。这里有个很重要的选型心得向量检索和推理模型要分开跑。很多新手会把嵌入模型也丢给 Ollama 统一管理实际做下来你会发现分开跑不仅性能更好而且调试更方便哪个环节出了问题一眼就能看出来。1.3 学习场景的闭环设计这个软件的核心逻辑其实不是“AI 回答问题”而是“AI 辅助构建学习闭环”。整个闭环分成四步导入资料、生成题目、答题评估、安排复习。这四个环节里只有“答题评估”阶段需要大模型高负荷推理其他环节的 AI 模型调用都很轻量。这样设计有一个实际好处用的时候功耗低笔记本风扇不至于一直狂转也不会有那种“AI 应用电老虎”的困局。我把这个思路称作“最小必要智能”原则——不是所有步骤都塞给大模型而是只在传统程序代码处理不好的地方比如语义理解、题目生成、答案开放性评判才启用模型推理其余环节用常规算法就能完成。这样既保证了体验也控制了资源开销。2. 核心模型与知识库构建解析2.1 Ollama 环境搭建和模型选择先说 Ollama 的安装。我在 Windows 11 上用的是官方安装包直接下载安装即可完全离线安装好后模型下载还需要联网一次后续使用全程离线就没问题了。装完后在命令行跑一句确认ollama list如果正常输出模型列表说明服务已经跑起来了。Windows 版 Ollama 有个特性安装后会在后台自动启动一个本地服务默认监听在 11434 端口。这一点后面写代码时要记住因为 Python 端不是直接调用命令行而是通过 HTTP API 访问模型的。然后是拉取模型。我选的是新版 Qwen2.5 7B Instruct 量化版拉取命令ollama pull qwen2.5:7b-instruct-q4_K_M这个 q4_K_M 后缀很重要代表 4-bit 量化格式能用接近 70% 的模型能力换取约 25% 的体积。如果显存更低可以考虑 q3 或者直接把模型丢到 CPU 上跑但真心不建议速度感人。拉取过程中如果网络不稳定导致中断ollama pull是支持断点续传的重复执行同一条命令即可不用删掉重来。2.2 文档解析最容易翻车的环节说实话整个项目里最让我头疼的不是 AI 模型而是文档解析。本地学习资料的文件格式五花八门—— PDF、Word、Markdown、纯文本、甚至网页导出的 HTML。不同类型的文档要用不同的解析策略PDF用 PyMuPDF 按页提取纯文本。但这里有个坑很多扫描版 PDF 实际上是图片PyMuPDF 提出来的是空字符串。这种情况我先用 OCR 工具兜底开源方案用的是 PaddleOCR识别中文效果不错Word.docxpython-docx 可以直接读取段落文本但表格内容需要单独处理把每一行单元格内容拼成结构化文本Markdown 和纯文本最省心直接按行读取就行。不过要注意代码块和表格的保留格式否则喂给模型的内容会乱七八糟HTML先用 Pandoc 转成 Markdown 再解析比直接处理 HTML 标签干净得多。所有文本最终都会按规则切分成适合向量化的片段。我的经验是每段 500 个字符左右、重叠 50 字符比较合适。太长的话检索精度下降太短的话片段语义不完整模型生成题目时会感觉“知识点残缺”。2.3 向量化与知识库管理文本切分完成后接下来是向量化。这里我用了开源的中文小型嵌入模型体积只有 400MB 左右在普通电脑上运行毫无压力。向量化的本质是把一段文字变成一串数字让计算机能算“哪两段文字意思接近”这样当你提问“什么是贝叶斯定理”时系统能快速从几万段笔记里找出相关的几个片段。ChromaDB 作为存储层支持本地持久化数据就放在一个文件夹里。它的 API 设计非常直观核心操作就是两个collection.add(documentschunks, idsids, metadatasmetadatas) results collection.query(query_texts[question], n_results3)每次导入新的学习资料后只要调用一遍add新知识点就自动进入知识库了。这个设计的妙处在于——知识库越用越厚AI 的出题质量也会随之提升因为可参考的上下文更丰富了。3. 实操过程与核心环节实现3.1 整体代码架构整个项目采用模块化设计各模块之间职责划分得很清楚llm_client.py统一封装 Ollama API 调用负责与模型交互document_parser.py不同格式文档的解析与文本切分knowledge_base.py向量库管理负责库存档和检索quiz_generator.py题目生成逻辑大模型输出后转成结构化数据review_scheduler.py间隔重复算法决定每个知识点何时复习app.py基于 Gradio 的图形界面把以上模块串起来代码量不算大核心逻辑加在一起不到两千行对于一个完整的应用来说这个规模控制得还不错。3.2 调用本地模型出题出题是核心功能逻辑其实不复杂先从知识库里检索和用户设定主题最相关的 3 个文本片段然后把它们拼成提示词扔给本地模型生成题目。我给模型设计了一段结构化提示词你是一名教学经验丰富的老师请根据以下资料出2道选择题和1道简述题。 要求 1. 题干必须严格基于给定资料不可超出资料范围 2. 选择题需提供4个选项标明正确项 3. 简述题需附带参考答案要点 4. 以JSON格式输出。 资料内容 {context}为什么要限制“不可超出资料范围”这是我在实际测试中踩出来的坑大模型有一个通病就是“自由发挥”。如果不加约束模型会自己脑补某些概念出一些资料里根本没有的题目。对于学习工具来说这是致命的——如果把错误内容当成学习材料学进去比不学更糟糕。加上约束后虽然不能 100% 杜绝但出题跑偏的概率大幅下降。获取模型输出后我还要用 Python 做一步“急救式解析”。因为 Ollama API 返回的是纯文本流即使提示词要求 JSON 格式模型偶尔也会在 JSON 外面包一层 markdown 代码块标记或者夹杂几句解释的话。所以我的解析逻辑是先剔除所有不在{}范围内的文本再尝试用不同参数调用 json.loads实在解析失败就标记为异常重新让模型生成一遍。这个容错机制在反复实测中帮助非常大。3.3 间隔重复复习算法的实现间隔重复的核心思想是如果一个知识点你答对了就降低它的出现频率如果答错了就提高频率。听起来简单但实现细节里有几个关键决策。我给每个知识点维护了两个关键字段easiness_factor难度系数和interval复习间隔单位是天。每次答题之后答对且信心度高间隔天数 ×1.7难度系数不变答对但信心不足间隔天数 ×1.2难度系数降 0.1答错间隔重置为 1 天难度系数降 0.4。这个算法参考了经典的 SM-2但没有完全照搬。因为 SM-2 原本用于卡片式记忆而这里面对的是“知识点”难度因素波动更大所以我对参数做了适配。实测效果是一个知识点如果连续答对三次复习间隔可以 1 天 → 2 天 → 3.4 天到达一周左右的稳定期。间隔重复算法还有一个很多人忽略的配套功能复习提示的时机。我加了一个“该复习了”的推送逻辑每天早上打开软件时如果当天有应复习知识点界面会弹出一个复习清单引导先复习再学新内容。这个设计虽然简单但对于坚持学习习惯的养成帮助非常明显。3.4 图形界面与交互设计界面我用的是 Gradio因为它是纯 Python 方案不需要额外写前端对于本地小工具来说足够优雅。主界面只保留了四个 Tab学习资料导入拖拽上传自动解析入库自动出题选择主题和题型点击生成答题与评估显示题目接收输入给出反馈复习安排展示今天该复习的知识点列表这里给一个设计建议本地工具不需要好看只需要功能清晰。之前我用的是更炫酷的 React 客户端后来果断砍掉了。原因很简单单机软件的重点是稳定和快速迭代Python Gradio 这一套组合改一个按钮逻辑只需要刷新页面开发效率比前后端分离高出一条街。对你如果真的想复用这套代码而不是看花架子这一条绝对是救命建议。3.5 从本地到扩展知识库导出和分享软件还有一个不算核心但很实用的功能知识库导出。ChromaDB 的原始数据是二进制格式不方便迁移和交流。我做了个导出模块可以把向量库中的文本片段和题目记录汇总成标准 Markdown 文件方便在其他软件里二次加工。为什么做这个因为我观察到学习资料的管理往往是长期的需求如果哪天这个软件不好用了用户至少能把自己积累的知识资产搬走这种“数据自由”理念在我看来是开源工具的基本修养。4. 常见问题与排查技巧实录4.1 模型回答中文夹杂英文或乱码这个问题是量化模型的通病尤其是在 4-bit 量化下。如果只是偶尔出现不用太在意。但如果频繁出现优先检查是不是temperature参数太高。我在代码里把生成参数设定为temperature0.5 top_p0.8 top_k40记住一条经验学习类场景AI 的回答需要稳定、可靠不需要天马行空的创意所以温度参数应该调到 0.5 以下。如果你用的是默认的 0.8实测出题内容会带上很多无意义的发散回答质量肉眼可见地变差。4.2 显存不够怎么办如果运行时报 OutOfMemoryError或者推理开始时明显卡顿大概率是显存不够。我的建议优先级排序是换更小量化格式q3→ 减少上下文长度 → 换更小参数模型3B。不要一上来就考虑“扩大内存”或者“换显卡”因为学习辅助工具的核心是语义理解3B 模型在日常出题场景下其实完全够用犯不着为了追求“数字大”而牺牲流畅度。还有个实用技巧Ollama 支持设置模型在显存和内存之间动态切换。在环境变量里指定set OLLAMA_MAX_LOADED_MODELS1 set OLLAMA_GPU_OVERLAPtrue这样可以让不用的模型自动从显存卸载避免多个模型层叠导致的显存爆掉。4.3 向量检索结果不准确这是很影响实际体验的问题。搜索“什么是梯度下降”返回的却是“梯度消失”的内容。排查思路从两个方向入手第一是检查文本切分方式如果片段过长语义会被稀释建议把切分值降下来比如 500 字符切分恢复为 300 字符第二是检索引擎的返回数量我把n_results设为 3如果资料比较碎建议提高到 5让大模型有更多上下文可以参考生成题目时也能更全面。4.4 首次启动速度慢得让人怀疑死机这通常是两个原因。一是向量化模型首次加载要花时间这个没法避免后面我会优化成启动时后台预热二是如果电脑内存吃紧操作系统会做页面交换表现为“点什么都要卡一下”。另一个容易被忽视的大坑是杀毒软件实时监控Python 脚本运行时动态生成临时文件杀毒软件扫描会让启动时间多出好几倍。体验差到崩溃的时候我排查了很久最后发现是 Windows Defender 的实时保护在搞事把项目目录加入排除列表后启动时间从 40 秒降到了 10 秒。这个经验真心值得推广。项目目前的完整代码我已经开源了包括全部 Python 源码、依赖清单、一份 Windows 11 下的部署说明和常见问题文档。如果你也想在本地跑一个自己的 AI 学习工具直接从仓库拉代码会比从零开始省掉大量试错时间。我个人做完这个项目后有个很深的体会本地 AI 应用真正的门槛其实都在 AI 之外。文档解析的繁琐、向量检索的参数调优、交互逻辑的设计每一项都比“调用大模型 API”这一点耗费更多精力。但反过来想正因为这部分不可替代的加工逻辑软件才能真正贴合自己的学习习惯而不是一个“什么都能聊两句但什么都留不下”的通用聊天框。数据在自己手里代码在自己手里这种踏实感应该是所有折腾开源本地应用的人最核心的追求吧。