很多人跑通了 ollama run,也 pip 装了 langchain,真要把两者拼成一个能问答的知识库时,却卡在模型名怎么写、embedding 用哪个、检索召回不对。这篇按组装顺序把每一段讲清楚:环境与模型准备、索引构建、检索问答链、常见报错排查,并说明什么情况下这套组合不划算。
很多人本地模型已经能跑了,命令行里问一句答一句挺顺,LangChain 也 pip 装上了,可一旦要把两者拼成一个能查自己文档的知识库,就卡在细节上:Chat 模型名和 Embedding 模型名到底怎么填、向量库选哪个、检索回来的片段为什么答非所问。问题基本不在框架本身,而在几段积木没对齐——模型服务、链的封装、向量存储各管一段,缺一环就整条链路空转。
这篇按组装顺序来,不按概念分类。先把三段积木摆好并验证连通,再谈切分和入库,然后是检索加拼装提示词,最后给一套排查顺序和验收标准。照着走一遍,你至少能得到一个「答得出、答不对时知道查哪」的本地知识库;至于值不值得长期这么维护,末尾也说清楚。
先把三段积木对齐:Ollama、LangChain、向量库
这三者的分工要分清:Ollama 只负责把本地模型跑起来、暴露一个本机接口;LangChain 通过兼容的对话模型封装和嵌入模型封装去调它;向量库负责把切好的文本块和向量存下来、支持相似度查询。三者任何一个没通,后面的报错都会伪装成「检索不准」,容易白调半天参数。
- 确认服务在跑先在终端确认 Ollama 服务处于运行状态,再用命令行问一句看有没有正常回复;服务没起来,后面的代码全是在连一个不存在的接口。
- 确认端口与地址代码里连的接口地址要和实际监听地址一致,容器里跑和宿主机跑地址写法不同。地址怎么写、怎么测连通,到 /ollama-local-api-address 与 /ollama-api-endpoint-guide 对照。
- 确认模型已拉取对话模型和嵌入模型是两个角色,各自要单独拉取,不能拿一个顶两个。嵌入模型怎么选,看 /embeddings 与 /ollama-chinese-embedding-pick,中文语料别照搬英文推荐。
- 确认资源够用桌面端能跑不等于服务端能扛住并发。先按 /models/deploy 和 /compute/sizing 估一遍显存与并发,再决定放本机还是服务器。
索引这一段:切分粒度决定后面所有问题的上限
检索答不好,八成问题出在索引阶段而不是检索阶段。文档先清洗再切:去掉页眉页脚、目录、重复段落、无关附录,不然这些噪声会被当成知识入库。切分时带一点重叠,按标题层级切通常比按固定字数切稳,因为语义边界和标题边界经常是重合的。
- 每段补元数据:来源文件、章节标题、页码,后面引用出处和做重排都靠它,缺了模型就只能凭空编。
- 嵌入写入注意批次大小和失败重试,写完抽几条做近邻检索自测,确认向量真的落库而不是静默失败。
- 向量库方案在 /stacks/vector-dbs 横向比,小规模先用本地文件型方案,数据量和并发上来了再换服务型。
- 中文语料的嵌入模型选型单独看 /ollama-chinese-embedding-pick,别直接套用英文榜单的结论。
# 伪代码思路:切分 → 元数据 → 嵌入 → 落库 → 近邻自测;具体模型名以你本地实际拉取的为准索引建完别急着接前端,先做一次自测:拿几个你一定知道答案的问题去查,看最相似的片段是不是真的那一段。命中率都不行,说明切分或嵌入有问题,这时候改提示词没用。
检索与拼装:把召回结果塞进提示词的方式
检索链先跑最简单的版本:向量召回若干条,拼进提示词,交给对话模型生成。闭环通了再考虑重排、多路召回、查询改写这些增强手段。一上来堆一堆组件,出错时你根本不知道是哪一层的问题。
提示词里的约束要写死,本地小模型顺着问题编的概率比大模型高得多。上下文别塞满,上限逻辑见 /context-window-token-limit,输入输出怎么分配看 /context-input-output-split。流式输出能明显改善体感,但后端要注意超时和断连重试。
跑起来之后:排查顺序与验收清单
出问题别一上来就调参数。按固定顺序查能省掉大半时间:服务通不通 → 模型在不在 → 嵌入维度对不对 → 检索有没有命中 → 提示词有没有被截断。前一步没过,后一步的调优都是白费。
- 验收三类问题文档里有明确答案的、需要跨段拼的、库里根本没有的。第三类能老实说「没有」才算合格。
- 慢就减上下文输出慢通常是模型太大或上下文太长,先减上下文再考虑换量化档位,参考 /local-inference-speed-tuning。
- 异常再回看链路连不上接口看 /ollama-api-connection-fail,那里有按顺序的排查清单。
什么情况下这套组合不划算:你要的是开箱即用、多人协作加权限管理、复杂文档解析,那自己拼这套反而费人。对照 /local-kb-tool-deploy-compare 里的维度比一比再决定。它更适合内网数据不出门、成本可控、团队愿意自己调参的场景。
本地知识库的瓶颈通常不在模型,而在你切进去的那几段文本和你怎么把答案找出来。下一步想先横向比一比向量库和本地部署方案的差别,或者看当时各家模型与服务的资料,去这两页核对后再动手。→
常见问题
Ollama 的模型能不能直接当 LangChain 的对话模型用?
能,LangChain 有对应的 Chat 封装,指向本地服务地址即可,模型名写你在 Ollama 里实际拉下来的那个。注意嵌入模型要另外指定一个,不能拿对话模型顶替,否则维度对不上,入库或检索会直接报错。
一定需要向量数据库吗,存在本地文件里行不行?
小规模完全可以,几百到几千段文本用本地文件型方案就够,启动快、没运维成本。数据量上去、要多人共用或需要按元数据过滤时再换服务型向量库,切换成本主要在重建索引,不在代码。
检索出来的内容对,但模型还是答错,问题出在哪?
大概率在提示词和上下文预算。先确认拼进去的片段没被截断,再检查提示词有没有明确要求只依据片段回答。本地小模型的指令遵循能力偏弱,约束要写得更直白,必要时把片段编号让它引用。