Ollama+Open WebUI+AnythingLLM本地知识库部署调优
做本地知识库这件事,我从最初只想把几份产品手册塞进模型里问答,到后来给几个小团队做内部文档检索,前后折腾了两年多。中间换过三轮方案,踩过的坑能写满两页纸。最后稳定下来的组合就是Ollama 跑模型、Open WebUI 当日常对话入口、AnythingLLM 管知识库和检索。这套组合最大的好处是全部跑在自己机器或内网服务器上,文件不出局域网,模型不调用外部接口,费用是一次性硬件投入,后续零调用成本。它适合两类人:一类是对资料保密有要求的个人,比如手上有些合同模板、技术笔记、研究草稿不想往云端传;另一类是十几到几十人规模的小团队,需要一套能查内部文档、又不愿意每年付订阅费的问答系统。这篇文章我会把整套东西从选型到落地拆开讲,包括每个参数为什么这么设、哪里最容易翻车、以及我实测下来比较稳的配置组合。
1. 整体架构怎么搭,以及为什么这么搭
1.1 三层分离:模型、界面、知识层各管一段
很多人一开始会想找一个“全能软件”把模型、界面、知识库全包了,省事。我试过,结论是不划算。全能型工具往往在某一块特别弱,要么模型选择受限,要么文档解析拉胯,要么界面难用。分层之后每层都能单独替换,出问题也容易定位。
我现在的结构是这样:
| 层级 | 承担角色 | 具体组件 | 替换成本 |
|---|---|---|---|
| 模型层 | 提供推理能力与向量化能力 | Ollama 服务,常驻在 11434 端口 | 低,换个模型名就行 |
| 界面层 | 日常对话、多轮上下文、账号管理 | Open WebUI | 中,可换成任意兼容接口的前端 |
| 知识层 | 文档解析、分块、向量存储、检索召回 | AnythingLLM | 中,数据在 storage 目录里,可迁移 |
关键点在于,Ollama 提供的是标准 HTTP 接口,AnythingLLM 和 Open WebUI 都能直接对接它。这就意味着模型层是公共底座,上面两个应用是平行的消费者,互不干扰。我平时用 Open WebUI 做通用问答和代码辅助,用 AnythingLLM 专门查内部文档,两个入口分开,避免把闲聊上下文和检索上下文混在一起污染回答。
还有个细节:AnythingLLM 自己也能当聊天界面用,那为什么还要 Open WebUI?我的理由是 Open WebUI 的多轮对话体验、模型切换、提示词预设更顺手,适合“问模型本身”的场景;AnythingLLM 的强项是文档工作区和引用溯源,适合“问我的资料”的场景。硬塞进一个界面里,两边都不舒服。
1.2 不上云的真实理由:数据边界和成本账
先说数据边界。企业文档里最敏感的不是技术文档,是合同、报价、客户名单、内部复盘。这些东西一旦上传到外部服务,你就失去了对它的控制权,哪怕对方承诺不训练,审计上也过不去。本地部署的价值不在于“更安全”这种空话,而在于物理隔离:拔掉网线,系统照样能问答。
再说成本。我帮一个小团队算过账:20 人规模,如果按人头订阅云端问答服务,一年下来是四位数到五位数不等的支出,而且随着文档量增长,向量存储还要另外计费。本地方案的成本结构完全不同:
- 一次性硬件:一台带 24GB 显存的机器,或者二手的同规格卡,价格固定
- 电费:满载 300W 左右,按每天跑 4 小时算,一年电费可以忽略
- 软件:全部开源,零授权费
- 隐性成本:你自己的时间,部署加调优大概两三天
对于长期使用的场景,本地方案在 8 到 14 个月左右回本,之后全是净收益。但如果只是临时查几份 PDF,那真没必要折腾,直接用现成服务更省事。选型的第一原则是匹配使用强度和保密要求,而不是技术洁癖。
1.3 硬件与模型的匹配测算,别拍脑袋买卡
这是最容易花冤枉钱的地方。模型能不能跑,核心看显存。粗略的估算方式是:
显存占用 ≈ 参数量 × 每参数字节数 + 上下文缓存
量化等级决定每参数字节数。Q4_K_M 大约 0.55 到 0.6 字节/参数,Q8 大约 1 字节/参数,FP16 是 2 字节/参数。实际还要加上 KV 缓存,跟上下文长度和层数相关,长上下文时这部分能占到几个 GB。
我整理了一张常用档位的实测参考表(单卡、Q4_K_M 量化、上下文 8K):
| 模型规模 | 权重大小 | 实际显存占用 | 机器配置建议 | 适用场景 |
|---|---|---|---|---|
| 7B / 8B | 约 4.5GB | 6 到 7GB | 8GB 显存或 16GB 内存纯 CPU | 简单问答、摘要,速度可接受 |
| 14B | 约 9GB | 11 到 12GB | 12GB 显存 | 日常主力,性价比最高 |
| 32B | 约 20GB | 23 到 25GB | 24GB 显存 | 复杂推理、长文档理解 |
| 70B | 约 40GB | 45GB 以上 | 双卡或大内存 CPU 推理 | 效果最好但速度慢,一般不推荐 |
纯 CPU 也能跑,只是速度按 token/秒 算会掉到个位数,7B 在普通桌面 CPU 上大概 3 到 6 token/s,读一段回答要等半分钟。如果只是偶尔查资料,能忍;如果天天用,还是建议上显卡。
还有一个常被忽略的点:嵌入模型也要吃资源。文档入库时要把每个分块转成向量,这个过程是批量的,如果嵌入模型太大,首次入库会非常慢。我的建议是嵌入模型和对话模型分开选,嵌入用轻量的专用模型,对话用大一点的通用模型。
2. Ollama 部署与模型选型的实操细节
2.1 部署前的环境检查清单
装之前先确认几件事,能省掉后面一半的麻烦:
- 系统是 64 位 Linux、macOS 或 Windows,Linux 建议较新的内核版本,否则容器网络会有奇怪问题
- 磁盘至少留 50GB,模型文件比想象中大,一个 14B 模型加嵌入模型轻松吃掉 15GB
- 如果用容器部署上层应用,先确认 Docker 或同类容器运行时能正常工作
- 内网服务器要确认防火墙策略,后面要放行几个端口
- 关闭系统的休眠和自动更新重启,半夜重启服务是运维事故的常见原因
还有一个隐形坑:模型目录的磁盘挂载。默认模型存在用户主目录下,如果主目录分区很小,拉到一半报磁盘满。建议提前把模型目录指到大容量分区,用环境变量控制。
2.2 安装与模型拉取
安装走官方脚本最省事,注意脚本地址从官方文档取,不要用来源不明的镜像:
# 从官方渠道获取安装脚本并执行 curl -fsSL <官方安装脚本地址> | sh # 确认服务已启动 systemctl status ollama # 检查版本 ollama --version服务起来后默认监听本地 11434 端口。这里有个必须改的配置:如果上层应用跑在容器里,默认只听 127.0.0.1 会导致容器连不上。需要让它监听所有网卡:
# 修改服务配置,让 Ollama 监听所有网卡 sudo systemctl edit ollama # 在编辑器中加入 [Service] Environment="OLLAMA_HOST=0.0.0.0:11434" Environment="OLLAMA_MODELS=/data/ollama/models" Environment="OLLAMA_KEEP_ALIVE=30m" # 重载并重启 sudo systemctl daemon-reload sudo systemctl restart ollama三个环境变量分别解决三个问题:OLLAMA_HOST让容器能访问,OLLAMA_MODELS把模型存到大盘,OLLAMA_KEEP_ALIVE让模型在内存里多待一会儿,避免每次提问都重新加载。最后这个特别重要,默认只有 5 分钟,超过就卸载,下一次提问要等十几秒加载。设成 30 分钟之后,连续使用体验差别巨大。
拉模型:
# 对话模型,14B 级别,日常够用 ollama pull qwen2.5:14b # 小一点的备选,硬件紧张时用 ollama pull llama3.1:8b # 嵌入模型,专门做向量化,体积小速度快 ollama pull bge-m3 # 查看已安装模型 ollama list # 简单验证推理是否正常 ollama run qwen2.5:14b "用一句话说明向量检索的原理"2.3 模型档位怎么选:不是越大越好
我在这上面走过最大的弯路,就是迷信大模型。一开始上 32B,觉得效果肯定好,结果发现三个问题:加载慢、并发差、长文档一塞就爆上下文。后来退回 14B,实际使用满意度反而更高。
我的判断标准是这样的:
| 使用强度 | 推荐档位 | 理由 |
|---|---|---|
| 个人,每天几十次问答 | 7B 到 8B | 响应快,显存占用低,能同时跑嵌入模型 |
| 个人主力,每天上百次 | 14B | 理解力和速度的平衡点,中文表达也更自然 |
| 团队共用,3 到 10 人 | 14B 加并发限制 | 单卡能撑住,配合队列避免排队过久 |
| 复杂文档分析、代码审查 | 32B | 只在需要深度推理时切换,不做常驻 |
还有一个经验:同一档位下,选中文语料训练更充分的模型。这个差别在中文问答上非常明显,英文强中文弱的模型经常在专业术语上翻车,把“向量维度”理解成几何概念。测试方法是拿三五个你业务里的真实问题去问,看回答是否贴合领域,比看榜单有用得多。
2.4 嵌入模型的单独考量
嵌入模型不参与对话,只负责把文本转成向量。它的选择直接影响检索质量,重要性被严重低估。选型时看三点:
第一是维度。维度高表达能力更强,但存储和计算成本也高。常见的有 768 维、1024 维。几百份文档的规模,1024 维完全够用。
第二是多语言支持。中文文档必须选对中文友好的嵌入模型,纯英文模型在中文上召回率会明显下降,因为它对中文的语义空间建模不充分。
第三是最大输入长度。如果分块设成 1024 token,嵌入模型的最大长度至少要覆盖这个值,否则会被截断,块尾的信息直接丢失。
配置上,Ollama 拉下来的嵌入模型可以直接在 AnythingLLM 里选。切换嵌入模型要注意:换了嵌入模型,之前入库的向量全部失效,必须清空重新向量化。这个坑我踩过一次,换了模型没重新入库,检索结果全是乱的,排查了半天才想起来。
3. Open WebUI 的部署与访问控制
3.1 容器化部署与端口规划
Open WebUI 我推荐用容器跑,依赖干净,升级方便。端口规划上要提前想好,避免和已有服务冲突。我习惯的规划是:
- 11434:Ollama 模型服务
- 3000:Open WebUI 对话界面
- 3001:AnythingLLM 知识库界面
部署命令大致长这样(镜像地址以官方文档为准):
docker run -d \ --name open-webui \ --restart always \ -p 3000:8080 \ -e OLLAMA_BASE_URL=http://host.docker.internal:11434 \ -e WEBUI_SECRET_KEY=<自定义长随机串> \ -e DEFAULT_MODELS=qwen2.5:14b \ -v /data/open-webui:/app/backend/data \ <官方镜像名>:main几个参数值得单独解释:
OLLAMA_BASE_URL是关键。容器里的localhost指的是容器自己,不是宿主机。Linux 上host.docker.internal不一定默认可用,稳妥的做法是用宿主机的内网 IP,或者在启动容器时加--add-host=host.docker.internal:host-gateway。这个配置错一次,界面能打开但模型列表是空的,很多人卡在这一步。
WEBUI_SECRET_KEY必须设,不设的话每次重启会话密钥都变,用户全部被登出。生成一个长随机串固定下来。
--restart always别忘了,服务器重启后服务自动起来,不然第二天上班发现系统挂了。
数据卷挂载到宿主机目录,升级容器时数据不丢。这条是血泪教训,我有次直接docker rm重建,所有对话记录和配置一起没了。
3.2 账号体系与内网访问边界
Open WebUI 默认第一个注册的账号是管理员,后面注册的是普通用户。这个设计很方便,但也意味着部署完第一件事就是立刻注册管理员账号,否则谁先访问谁就是管理员。
访问控制我建议做三层:
第一层是网络层。这套系统只在内网使用,不要在公网暴露端口。如果确实需要远程访问,走内网穿透或者专线,别直接把端口映射到公网。
第二层是应用层。关闭开放注册,改成管理员手动创建账号。设置路径在管理面板的账号设置里,把“允许新用户注册”关掉。团队规模小的时候,手动建号最省心。
第三层是数据层。定期备份数据目录,尤其是对话记录和用户配置。备份策略我一般用每天增量、每周全量,保留四周。
还有一个容易忽略的点:用户之间的会话是隔离的,但知识库不一定。如果让 Open WebUI 和 AnythingLLM 共用同一个模型服务,模型本身没有权限概念,谁都能调用。所以涉及分部门资料隔离的场景,要靠 AnythingLLM 的工作区权限来控制,而不是指望模型层。
3.3 对接 Ollama 的常见故障
界面能打开但模型列表空白,这是最高频的问题,八成是网络不通。排查顺序:
- 在宿主机上
curl http://localhost:11434/api/tags,看有没有返回模型列表 - 在容器内
docker exec -it open-webui curl http://host.docker.internal:11434/api/tags,看容器能不能通 - 检查 Ollama 是否设了
OLLAMA_HOST=0.0.0.0 - 检查宿主机防火墙有没有拦 11434 端口
如果第 2 步不通但第 1 步通,那就是容器网络问题,换用宿主机内网 IP 通常能解决。
另一个问题是回答到一半中断。原因通常是上下文超限或者模型被卸载。前者调小上下文长度参数,后者加大OLLAMA_KEEP_ALIVE。还有一种情况是显存不够,模型加载到一半被系统杀掉,日志里能看到 OOM 字样,这时候只能换小模型。
4. AnythingLLM 知识库的搭建与调优
4.1 工作区划分与文档投喂策略
AnythingLLM 的核心概念是“工作区”(Workspace),一个工作区就是一个独立的知识库加一套对话上下文。划分工作区的原则不是按文档类型,而是按提问场景。比如“产品资料”一个区、“技术文档”一个区、“行政制度”一个区。这样检索时范围更聚焦,召回准确率会明显提升。
我见过有人把所有文档塞进一个工作区,结果问产品参数的时候检索出一堆行政通知,回答自然跑偏。分区的本质是给检索加一个前置过滤条件。
文档投喂这块,格式支持挺全,PDF、Word、Markdown、纯文本、网页都能进。但有几点必须注意:
- 扫描版 PDF 没有文字层,直接扔进去解析出来是空的。这类文件必须先做文字识别,转成可搜索的 PDF 或者纯文本,否则入库了也检索不到。判断方法很简单,用阅读器试着选中文字,选不中就说明是图片。
- 表格类文档容易被切碎。一份参数表如果按字符数硬切,行和列会错位,检索出来的片段没法看。这类文档建议先转成 Markdown 表格再入库,结构保留完整。
- 超长文档要做章节拆分。几百页的手册直接入库,分块后每块都是碎片,语义不完整。我的做法是按章节拆成多个文件再传,天然形成语义边界。
入库方式有两种:一是上传文件,二是给一个网页地址让它抓取。网页抓取适合内部 Wiki,但注意抓取范围,别把导航栏和页脚重复抓进每一页,会严重污染检索结果。
4.2 分块与检索参数,这几个数值决定成败
这是整篇文章最值钱的部分。默认参数能用,但效果离“好用”差得远。核心参数就四个:
| 参数 | 默认值附近 | 我常用的值 | 作用与调整逻辑 |
|---|---|---|---|
| 分块大小 | 1000 字符左右 | 512 到 800 token | 太大语义混杂,太小语义残缺 |
| 分块重叠 | 20 到 50 | 80 到 120 token | 防止句子被切断,重叠太少会丢上下文 |
| 召回数量 TopN | 4 | 4 到 6 | 太多会引入噪音,太少会漏关键信息 |
| 相似度阈值 | 0.25 左右 | 0.2 到 0.3 | 太高召回不足,太低全是无关内容 |
分块大小的判断标准是一个块能不能独立讲清一件事。中文大概 500 到 800 字是一个自然段落的量级,对应 512 到 800 token。如果你的文档是条文式的短句(比如制度条款),可以切小一点,400 左右;如果是叙述性长文,可以切大到 1000。
重叠的作用是保险。举个例子,一句话被切在两块中间,前半句在第一块末尾,后半句在第二块开头,检索时只召回其中一块,模型就只能看到半句话。加上 100 token 的重叠,两块都包含完整句子,就不会丢。
阈值这个参数最需要实测。设 0.25 意味着相似度低于这个分数的片段直接丢掉。如果你的文档用词和提问用词差异大(比如文档写“采购审批流程”,用户问“买东西怎么申请”),阈值设高了就什么都召不回来。这种情况要么降低阈值,要么在文档里补充同义表述。
4.3 提示词模板与引用溯源
AnythingLLM 允许自定义系统提示词,这是提升回答质量最便宜的手段。默认提示词比较泛,我一般改成这样几个要求:
你是内部资料检索助手。请严格依据提供的上下文片段回答问题。 规则: 1. 只使用上下文中的信息,不要引入外部知识补充。 2. 如果上下文中没有相关信息,直接回答“资料中未找到相关内容”,不要猜测。 3. 回答时标注信息来源的文档名和章节。 4. 涉及数字、日期、金额时,必须原文引用,不要改写。 5. 用简体中文回答,语言简洁,不使用客套话。这几条规则解决四个真实问题:模型爱编造、爱客套、爱改写数字、不给出处。尤其是第 4 条,涉及金额和日期的时候,模型“顺手”把 3 个工作日改成 5 个工作日,这种错误最致命。
引用溯源功能要打开。它会在回答后面附上引用的文档片段和来源,方便核对。刚开始用的时候我建议每次都点开引用看一眼,确认模型是真的读了文档还是在编。用两周之后你就能判断哪些回答可信、哪些需要复核。
温度参数也要调。知识库问答不需要创造性,温度设 0.1 到 0.3 之间,让回答稳定、可复现。默认值偏高的话,同一个问题问两次答案不一样,用起来很难受。
4.4 多用户与权限边界
AnythingLLM 支持多用户模式,开启后可以给不同用户分配不同工作区的访问权限。这对小团队很实用:行政资料只给行政看,技术文档全员可见,财务相关的单独建区。
开启多用户需要注意几点:一是必须设置管理员账号,二是每个用户的工作区权限要单独配置,三是默认情况下新用户看不到任何工作区,需要手动授权。权限配置界面不算直观,第一次配容易漏。
还有一个现实问题:模型服务本身没有权限隔离。用户在 AnythingLLM 里看不到某个工作区,但如果他知道模型服务地址,理论上可以直接调用。所以真正的隔离要靠网络层,比如把模型服务只监听内网、用防火墙限制来源 IP。应用层的权限更多是防误操作,不是防恶意访问。
5. 检索效果调优与实测记录
5.1 文档清洗比换模型更有用
这句话我想强调三遍。很多人检索效果差,第一反应是换更大的模型,实际上八成的质量问题出在文档本身。
我做过一次对比。同一批 200 份技术文档,第一轮直接入库,问 20 个标准问题,答对 11 个。第二轮做了清洗:去掉页眉页脚、统一术语表述、把表格转成 Markdown、按章节拆分文件、补上文档标题和版本号,同样的模型和参数,答对 17 个。模型一个字没改,效果提升 55%。
清洗清单我总结成这几条:
- 删除重复的页眉页脚、页码、水印文字
- 统一同义词,比如“客户端”和“用户端”选一个,另一个在检索时靠同义词扩展补
- 表格保留结构,用 Markdown 或明确的分隔符
- 每份文档开头加三行元信息:文档名、版本、适用范围
- 按章节拆分成独立文件,文件名带上章节号
- 去掉目录页和修订记录页,这些内容没有检索价值还容易误召回
最后那条特别有用。目录页里堆满了章节标题,语义密度高但信息量为零,特别容易被误召回,然后模型拿着一堆标题硬编答案。
5.2 分块参数的实测对比
我在同一批文档上做了几组分块实验,用 30 个问题的命中率作为指标(命中指召回的片段中至少有一块包含正确答案):
| 分块大小 | 重叠 | TopN | 阈值 | 命中率 | 观察 |
|---|---|---|---|---|---|
| 1000 | 50 | 4 | 0.25 | 68% | 块太大,语义混杂,回答常跑题 |
| 512 | 50 | 4 | 0.25 | 74% | 有改善,但句子切断情况多 |
| 512 | 100 | 4 | 0.25 | 81% | 重叠加大后明显改善 |
| 800 | 120 | 6 | 0.22 | 87% | 综合最好的一组 |
| 800 | 120 | 10 | 0.22 | 84% | 召回太多,噪音拉低准确率 |
| 400 | 100 | 6 | 0.22 | 79% | 切太碎,上下文不完整 |
结论很清楚:分块 800 加重叠 120 加 TopN 6 是这批文档的最优组合。但这个数值不能直接抄,因为它跟文档的写作风格强相关。条文式文档适合切小,叙述式文档适合切大。我的建议是拿 20 到 30 个真实问题做一次小规模网格测试,花两个小时,后面几个月都受益。
测试方法很简单:列一张表,左边是问题,右边是期望答案的关键词。每换一组参数就跑一遍,统计命中。别凭感觉判断“好像变好了”,人的感觉在检索质量上极不可靠。
5.3 检索不准的三条排查路径
回答不准的时候,先分清是召回问题还是生成问题。判断方法:打开引用溯源,看召回的片段里到底有没有答案。
如果引用的片段里根本没有正确答案,那是召回问题。排查方向:
- 提问的用词和文档用词差异太大,试试换成文档里的表述方式再问
- 分块把关键信息切断了,调大重叠
- 阈值太高,把相关片段过滤掉了,降到 0.2 试试
- 该文档压根没入库,或者入库时解析失败(扫描件常见)
- 嵌入模型对中文支持不好,换一个中文友好的
如果引用的片段里有正确答案,但模型答错了,那是生成问题。排查方向:
- 上下文塞太多,关键信息被淹没了,降低 TopN
- 提示词没强调“只用上下文”,模型自由发挥
- 温度太高,回答不稳定,降到 0.2
- 模型本身理解力不足,换大一号的模型
这个二分法能省掉大量盲目调试。我见过有人一直换模型,实际上问题是文档没入库成功。
6. 常见问题速查与运维加固
6.1 部署与运行问题速查表
| 现象 | 可能原因 | 处理办法 |
|---|---|---|
| 界面能开,模型列表空 | 容器连不上 Ollama | 改用宿主机内网 IP,加 host-gateway 参数 |
| 提问后长时间无响应 | 模型正在加载 | 调大 keep-alive,预热一次模型 |
| 回答到一半中断 | 上下文超限或显存不足 | 减小上下文长度,换小模型 |
| 服务重启后数据丢失 | 数据目录没挂载到宿主机 | 加 volume 挂载,重建前先备份 |
| 用户频繁被登出 | 会话密钥未固定 | 设置固定的 secret key |
| 入库进度卡住 | 文档过大或解析超时 | 拆分文件,分批入库 |
| 检索返回空 | 阈值过高或向量未生成 | 降阈值,检查文档是否显示已向量化 |
| 中文回答夹杂英文 | 模型训练语料偏英文 | 换中文更强的模型,提示词要求中文 |
6.2 运维层面的加固建议
系统跑起来只是开始,长期稳定靠的是运维习惯。我固定在做的几件事:
备份三件套:模型目录、Open WebUI 数据目录、AnythingLLM 存储目录。前两个丢了重装就行,第三个丢了所有向量和文档元信息都要重建,几百份文档重新入库要几个小时。备份用定时任务,每周全量、每天增量,异地存一份。
日志保留。容器日志默认会无限增长,加日志轮转配置,限制单文件大小和保留份数。我遇到过磁盘被日志写满导致服务崩溃的情况,排查了半天才发现是这个原因。
版本锁定。镜像不要用 latest 标签,用具体版本号。开源项目迭代快,某次更新改了配置项格式,升级后服务起不来,回滚又找不到旧镜像。锁定版本,升级前先在测试环境验证。
资源限制。给容器加内存和 CPU 限制,防止某个进程吃满整机。尤其是嵌入模型批量处理的时候,内存占用会突然飙升。
访问日志。内网服务也要记录访问日志,至少记录谁在什么时候问了什么。这既是审计需要,也是排查问题的依据。
6.3 安全边界的三条底线
虽然这套系统跑在内网,但基本的安全习惯还是要守住。
第一条,不要在公网暴露任何端口。这套系统设计上就没考虑公网安全,没有防暴力破解、没有验证码、没有速率限制。真要远程访问,套一层带认证的反向代理,并且限制来源 IP。
第二条,模型服务不做鉴权。Ollama 的接口默认没有认证机制,任何能访问 11434 端口的人都能调用模型。所以这个端口只能在内网开放,不要做端口转发。如果多人共用一台机器,考虑给上层应用做账号隔离,而不是指望模型层。
第三条,敏感文档单独分区。合同、报价、人事资料这类文档,单独建工作区,只授权给特定账号。同时注意,删文档不等于删向量,删除文档后要确认向量也被清理,否则残留数据还能被检索到。这个细节很多人会忽略。
7. 我个人跑下来的一点体会
这套组合我从最早的单机试玩,到后来给几个小团队部署,前后搭过七八次。最大的感受是:部署只占两成工作量,剩下八成都在文档治理和参数调优上。
工具本身没有魔法。同一套 Ollama 加 AnythingLLM,文档整理得好的团队,问答准确率能到八成以上;文档乱七八糟直接往里扔的,准确率不到五成,然后就开始怀疑模型不行、工具不行。实际上问题出在源头。
还有个心态上的建议:别追求一步到位。先把系统跑通,能用起来,然后拿真实问题去试,发现哪里不准就针对性地调。我见过有人花两周时间研究各种参数组合,结果一份文档都没入库。先跑起来,再优化,这个顺序不能反。
最后分享一个我自己常用的小技巧:建一个“测试问题集”文档,把 20 个真实问题和标准答案写进去,每次改参数或者换模型,跑一遍看命中率变化。这张表比任何主观感受都可靠,也是我判断“这次改动到底有没有用”的唯一依据。攒了半年之后,它已经成了我评估这套系统健康度的基准线。