ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

本地知识库搭建指南:ollama+langchain+chroma,旧电脑也能跑

本地知识库搭建指南:ollama+langchain+chroma,旧电脑也能跑 1. 为什么我劝你别急着开云会员去年年底我把自己那台老笔记本翻出来装了个本地知识库跑了大半年最大的感受就一句话云会员的钱大部分是白花的。我身边不少朋友手机是华为的平板是小米的电脑又是另一家的结果为了用上AI问答一年下来开了三四个会员加起来小一千块。但实际用起来问个文档、查个笔记还得联网、还得排队、还得担心资料传上去安不安全。这就是我想聊这件事的起点。AI PC这个词今年被喊得很响华为、小米这些厂商都在推端侧大模型宣传语都差不多——本地运行、隐私安全、不联网也能用。但真到自己动手很多人就卡住了本地知识库到底怎么搭端侧大模型是不是必须买新电脑我手里这台旧机器能不能跑先说结论能跑而且门槛比你想的低得多。核心思路就三步——装一个本地模型运行工具、接一个向量数据库、把你要问的资料喂进去。这套组合里最常被提到的就是ollama langchain chroma这个技术栈。ollama 负责跑模型langchain 负责把流程串起来chroma 负责存你的资料向量。三个东西都是开源的装完不花一分钱。这篇文章我打算把整套流程拆开讲透。不管你是华为电脑管家用户还是小米生态的重度依赖者只要你的机器有 8GB 内存、能装 Python就能跟着做下来。我会把每一步为什么这么做、参数怎么选、踩过哪些坑都写清楚让你少走弯路。适合谁看三类人一是被云会员续费烦到的普通用户二是想入门本地大模型但不知道从哪下手的技术爱好者三是手里有旧设备想榨干剩余价值的人。提示本文所有操作均在本地完成不涉及任何联网服务资料全程不出你的硬盘。2. 整体方案设计为什么是这三件套2.1 端侧大模型和云端的本质区别要理解为什么本地知识库值得搭得先搞清楚端侧大模型和云端大模型到底差在哪。云端模型就像一个超级图书馆书多、人多、算力强但你每次去借书都得排队、登记、还得把你要查的问题告诉管理员。端侧模型则是你自己家里的小书架书没那么多但随时能翻没人知道你看了什么。具体到技术层面差异体现在三个维度。第一是延迟云端模型每次请求都要走网络快则几百毫秒慢则几秒本地模型一旦加载进内存响应基本在毫秒级。第二是隐私你的合同、笔记、聊天记录传到云端就意味着脱离了你的控制本地跑则完全不出设备。第三是成本云端按 token 计费或者包月用得越多越贵本地只有电费。当然本地也有短板。模型参数量小通用知识不如云端大模型复杂推理能力弱一些。但知识库场景恰好扬长避短——你不需要模型什么都懂只需要它读懂你给的那几份资料。这就好比考试云端模型是博闻强识的老教授本地模型是只复习了你这本教材的学生但考的就是这本教材学生反而答得更准。2.2 ollama、langchain、chroma 各自扮演什么角色很多人一上来就被这三个名词吓到其实用生活化的类比一下就清楚了。ollama 是发动机。它负责把大模型文件加载起来对外提供一个简单的接口。你可以把它理解成一个模型播放器下载好模型文件后一条命令就能跑起来。它的优势是跨平台Windows、macOS、Linux 都能装而且对硬件要求相对友好量化后的 7B 模型在 8GB 内存的机器上也能跑。chroma 是仓库。它是个向量数据库专门存你把文档切碎之后生成的向量。为什么需要它因为大模型本身记不住你的资料你得先把资料转成向量存起来提问的时候再去仓库里找最相关的几段喂给模型。chroma 的好处是轻量纯 Python 实现不用单独装服务几行代码就能建库。langchain 是流水线。它把读文档→切块→转向量→存库→检索→喂给模型→生成回答这一整套流程串起来。没有它你得自己写几百行胶水代码有了它核心逻辑几十行就能搞定。它就像乐高积木的连接件把发动机和仓库拼成一台完整的机器。这三者的组合之所以流行是因为每一层都足够简单、足够开放。ollama 换模型只要改个名字chroma 换存储路径只要改个参数langchain 换流程只要改几行链式调用。对比那些打包好的商业软件这套方案的可控性高得多。2.3 华为、小米设备在这套方案里的定位这里要澄清一个常见误解本地知识库跟你的电脑品牌关系不大。华为电脑管家、小米澎湃 OS 这些是厂商做的系统级工具它们提供的是驱动、电源管理、生态互联跟你能不能跑本地模型是两码事。那为什么标题里要提华为和小米因为这两家的用户基数大而且很多人手里有闲置的旧设备。华为的笔记本、小米的迷你主机甚至一些配置还行的旧手机都能拿来当本地知识库的载体。厂商推的端侧大模型更多是营销概念真正落地还得靠 ollama 这类通用工具。我实测下来一台 16GB 内存的华为 MateBook跑 7B 量化模型加 chroma 检索日常问答完全够用。小米的迷你主机如果内存加到 32GB甚至能跑 13B 的模型。所以别被AI PC的营销话术绑架你手里的设备大概率已经够用了。注意判断能不能跑关键看内存和硬盘不是看 CPU 品牌。模型加载后常驻内存7B 量化模型大约占 4-6GB13B 大约占 8-10GB。3. 环境准备从零到能跑通的完整清单3.1 硬件门槛到底在哪先给个明确的硬件参考免得你装到一半发现跑不动。配置项最低要求推荐配置说明内存8GB16GB 及以上模型常驻内存7B 量化约 4-6GB硬盘20GB 空闲50GB 以上模型文件单个 4-8GB多存几个就吃紧CPU近五年主流支持 AVX2 指令集老 CPU 可能不支持某些量化格式显卡无也行6GB 显存以上有显卡推理快 3-5 倍没有也能跑这里解释一下为什么内存比 CPU 重要。大模型推理时模型权重需要全部加载到内存里CPU 只负责计算。如果内存不够系统会频繁把数据换到硬盘速度直接掉到没法用。所以加内存是性价比最高的升级比换 CPU 划算得多。至于显卡有当然好。NVIDIA 的显卡配合 CUDA推理速度能快好几倍。但如果你只是偶尔问几个问题纯 CPU 也能接受就是等的时间长一点。我试过在纯 CPU 的旧笔记本上跑 7B 模型一个问题大概等 10-20 秒日常用能忍。3.2 软件环境安装步骤软件这块核心就三样Python、ollama、几个 Python 库。我按顺序说。第一步装 Python。建议 3.10 或 3.11太新的版本有些库还没适配。去官网下载安装包安装时记得勾选Add Python to PATH否则后面命令行找不到。装完在终端输入python --version验证。第二步装 ollama。去官网下载对应系统的安装包Windows 是 exemacOS 是 dmgLinux 有一键脚本。装完之后终端输入ollama --version能显示版本号就成功了。第三步拉模型。ollama 装好后用ollama pull命令下载模型。新手建议从qwen2.5:7b或llama3.1:8b开始这两个中文支持好、体积适中。命令是ollama pull qwen2.5:7b下载完用ollama run qwen2.5:7b测试能对话就说明模型跑起来了。第四步装 Python 库。建个虚拟环境然后装这几个pip install langchain langchain-community langchain-ollama chromadb如果要用 PDF 解析再加pypdf要处理 Word加python-docx。这些库版本更新快建议用pip install时不要锁死版本让它自动选兼容的。提示ollama 默认把模型存在 C 盘用户目录下如果 C 盘空间紧张可以设置环境变量OLLAMA_MODELS指向其他盘。3.3 目录结构和文件组织搭之前先把目录规划好后面维护省心。我习惯这样组织local_kb/ ├── docs/ # 放原始文档 ├── db/ # chroma 数据库文件 ├── scripts/ # 脚本 │ ├── ingest.py # 导入文档 │ └── query.py # 提问 └── requirements.txtdocs目录里放你要问的资料PDF、txt、md 都行。db目录是 chroma 自动生成的不用手动建。脚本分两个一个负责把文档灌进数据库一个负责提问。这样职责清晰改起来方便。为什么要分开因为导入文档是个耗时操作文档多了可能要跑几分钟。提问是高频操作每次都要快。分开之后导入一次之后提问就不用重复导入了。4. 核心实现三步搭起你的本地知识库4.1 第一步文档加载与切块文档加载的核心问题是格式兼容。不同格式的文档读取方式不一样。langchain 提供了统一的加载器接口但实际用起来还是要注意细节。PDF 是最麻烦的。有些 PDF 是扫描件本质是图片直接读出来是空的得先做 OCR。有些 PDF 排版复杂读出来顺序乱。我一般先用PyPDFLoader试读出来内容不对再换pdfplumber。txt 和 md 最简单直接读就行。切块是这一步的关键。为什么要切因为大模型有上下文长度限制而且检索时只需要最相关的几段整篇文档喂进去既浪费又低效。切块的核心参数是chunk_size和chunk_overlap。chunk_size是每块的字数太小了语义不完整太大了检索不准。中文场景我一般设 500-800 字符。chunk_overlap是相邻块的重叠字数防止一句话被切断导致语义丢失一般设 chunk_size 的 10%-20%。from langchain_community.document_loaders import PyPDFLoader, TextLoader from langchain.text_splitter import RecursiveCharacterTextSplitter # 加载文档 loader PyPDFLoader(docs/manual.pdf) docs loader.load() # 切块 splitter RecursiveCharacterTextSplitter( chunk_size600, chunk_overlap100, separators[\n\n, \n, 。, , , , ] ) chunks splitter.split_documents(docs) print(f切出 {len(chunks)} 块)注意separators参数中文场景一定要把中文标点加进去否则会按空格切中文没空格就切不动。这个坑我踩过切出来全是超长块检索效果很差。4.2 第二步向量化与入库切完块下一步是把每块文本转成向量存进 chroma。向量化用的是嵌入模型ollama 也能跑嵌入模型比如nomic-embed-text。ollama pull nomic-embed-text然后代码里这样用from langchain_ollama import OllamaEmbeddings from langchain_chroma import Chroma embeddings OllamaEmbeddings(modelnomic-embed-text) vectorstore Chroma.from_documents( documentschunks, embeddingembeddings, persist_directory./db )这里有个关键点嵌入模型和生成模型是两回事。嵌入模型负责把文本转成向量生成模型负责根据检索结果回答问题。两者可以不同但嵌入模型一旦选定后续所有文档都得用同一个否则向量空间不一致检索会乱。入库之后chroma 会在db目录生成文件。下次启动直接加载不用重新导入vectorstore Chroma( persist_directory./db, embedding_functionembeddings )注意如果换了嵌入模型必须删掉 db 目录重新导入否则新旧向量混在一起检索结果会莫名其妙。4.3 第三步检索与问答链最后一步是把检索和生成串起来。langchain 提供了RetrievalQA这类现成的链但新版本更推荐用 LCELLangChain Expression Language自己拼灵活度更高。from langchain_ollama import ChatOllama from langchain_core.prompts import ChatPromptTemplate from langchain_core.runnables import RunnablePassthrough from langchain_core.output_parsers import StrOutputParser llm ChatOllama(modelqwen2.5:7b, temperature0) retriever vectorstore.as_retriever( search_kwargs{k: 4} ) prompt ChatPromptTemplate.from_template( 根据以下资料回答问题如果资料里没有相关信息就说不知道不要编造。 资料 {context} 问题{question} ) def format_docs(docs): return \n\n.join(doc.page_content for doc in docs) chain ( {context: retriever | format_docs, question: RunnablePassthrough()} | prompt | llm | StrOutputParser() ) answer chain.invoke(这份文档里提到的保修期是多久) print(answer)k4表示检索最相关的 4 块。这个值可以调文档多、问题复杂就调大但太大反而会引入无关内容干扰模型。我一般 3-5 之间试。temperature0是让模型输出稳定不要发挥。知识库问答要的是准确不是创意所以温度设 0。5. 参数调优与效果提升的实战经验5.1 检索质量差怎么调搭起来容易调好难。最常见的抱怨是答非所问。原因通常有三个。第一是切块不合理。如果一块里混了好几个主题检索时匹配到这块但模型看到的内容一半相关一半不相关就容易答偏。解决办法是切块时尽量按语义边界切比如按段落、按标题。langchain 的MarkdownHeaderTextSplitter可以按标题层级切对结构化文档效果很好。第二是嵌入模型不合适。nomic-embed-text是通用模型中文效果一般。可以试试bge-m3这类中文优化的嵌入模型ollama 也支持。换模型后记得重建库。第三是 k 值太小。如果答案需要综合多处信息k4 可能不够。可以调到 6-8但要注意上下文长度限制别超过模型的窗口。5.2 回答不准确怎么排查回答不准先分清是检索问题还是生成问题。排查方法是把检索到的原文打印出来看。docs retriever.invoke(你的问题) for i, d in enumerate(docs): print(f--- 第 {i1} 块 ---) print(d.page_content[:200])如果检索到的内容里根本没有答案那是检索问题回去调切块和嵌入模型。如果检索到了但模型答错那是生成问题可以调 prompt明确要求只根据资料回答。我遇到过一个典型情况文档里写的是保修期 24 个月模型答12 个月。查检索结果发现检索到的是另一段提到12 个月的内容。这就是检索把不相关的块排前面了。解决办法是加个重排序rerank步骤或者调大 k 值让正确答案也进来。5.3 速度优化技巧纯 CPU 跑模型慢有几个优化方向。一是换更小的模型。7B 换成 3B速度能快一倍代价是能力下降。如果只是简单问答3B 够用。二是用量化版本。ollama 默认拉的模型已经是量化过的但可以选更激进的量化比如 q4 换成 q3体积和内存占用都降速度提升精度略降。三是限制上下文长度。ollama 默认上下文窗口可能很大但实际用不到那么多。可以在ChatOllama里设num_ctx2048减少内存占用和计算量。四是缓存。相同问题重复问可以加个缓存层避免重复推理。langchain 有CacheBackedEmbeddings对嵌入做缓存文档没变就不用重新算。6. 常见问题速查与避坑清单6.1 安装阶段的坑问题原因解决ollama命令找不到没加 PATH重装或手动加环境变量模型下载卡住网络问题换时间段重试或手动下载模型文件pip install报错Python 版本不兼容换 3.10/3.11内存不足崩溃模型太大换小模型或加内存6.2 运行阶段的坑坑一中文切块切不动。前面提过separators没加中文标点导致整篇文档变成一块。这个错误很隐蔽因为程序不报错只是检索效果差。坑二换了嵌入模型没重建库。新旧向量混在一起检索结果随机。记住嵌入模型和库是绑定的。坑三prompt 没限制模型瞎编。一定要在 prompt 里明确资料里没有就说不知道否则模型会用通用知识补全答得头头是道但全是错的。坑四文档里有表格。PDF 里的表格读出来是乱的langchain 默认加载器处理不好。这种情况得用专门的表格解析工具或者手动把表格转成文字。坑五路径含中文或空格。有些库对路径敏感报错莫名其妙。建议项目路径全用英文别放桌面这种带中文的目录。6.3 效果不达预期的排查顺序遇到问题别乱改按这个顺序排查先看检索结果对不对打印出来检索对但答错调 prompt检索不对调切块参数切块调了还不行换嵌入模型换模型还不行考虑文档本身质量问题这个顺序能帮你快速定位问题避免瞎调参数。7. 关于成本和设备选择的一些实话7.1 云会员到底值不值算笔账。主流云服务会员一年 200-500 不等。本地方案硬件如果现成成本是零如果要加内存16GB 内存条大概 200-300一次性投入。模型和软件全免费。但本地方案有隐性成本时间。搭环境、调参数、排查问题新手可能要花一两个周末。所以判断标准是如果你只是偶尔用云会员省事如果你高频使用、在意隐私、或者想学点技术本地方案更值。7.2 旧设备能不能用能。我见过有人用十年前的笔记本跑 3B 模型慢是慢但能用。关键看内存8GB 是底线。如果内存不够加内存比换整机划算。华为、小米的旧设备只要不是太老基本都能跑。厂商的系统工具不影响ollama 是独立运行的。所以别被必须买 AI PC忽悠先把手里的设备试试。7.3 后续可以怎么扩展搭好基础版之后有几个方向可以继续玩。一是接微信或飞书。用 webhook 把问答接口暴露出去在聊天软件里直接问。这个需要点开发工作但网上有现成方案。二是多文档源。除了本地文件还可以接网页、Notion、语雀定时同步。langchain 有对应的加载器。三是加语音。配合语音识别和合成做成语音助手。这个对硬件要求高一些但技术上可行。四是多用户。如果团队用可以加个简单的 Web 界面用 FastAPI 包一层多人共享一个知识库。我自己目前停在第二步接了几个常用文档源日常查资料基本不用开浏览器了。后面打算试试语音主要是想解放双手。最后分享一个小技巧文档质量比模型大小重要得多。我试过用 3B 模型配整理干净的文档效果比 13B 模型配一堆乱文档好。所以搭之前先花时间把资料整理好比后面调参数省事得多。
返回列表