免费获取学习方案
ARTICLE DETAIL

资讯详情

深耕编程基础知识与建站技术分享的一线实战洞察。

WeKnora本地部署实录:从Docker到Ollama构建私有RAG知识库问答系统

WeKnora本地部署实录:从Docker到Ollama构建私有RAG知识库问答系统 WeKnora 这个名字如果你不是长期泡在 GitHub 开源项目列表里的人大概率是第一次见。一句话介绍它是腾讯微信团队开源的一套 AI 知识库问答系统定位是让团队能快速把文档、手册、内部资料变成“能聊天”的检索增强生成应用。我这次把整套系统本地部署了一遍从 Docker 启动到接上 Ollama 本地模型再到建立第一个知识库并完成问答前后折腾了小半天。这篇实录就把完整过程、踩坑点和配置逻辑都写下来给正准备在局域网里搭 AI 知识库的朋友做个参考。1. 为什么选 WeKnora 而不是 Dify 或 FastGPT1.1 项目定位不是“大而全”而是“刚刚好”接触过的同学应该知道市面上做 RAG 问答的开源项目不少最常被拉出来对比的就是 Dify、FastGPT、AnythingLLM 这几个。它们各有各的长处但我个人在实际使用中有一个很直接的感受这类“平台型”产品功能堆得越多你维护的成本就越高尤其是当你只想在公司内网部署一套干净的知识库问答系统时很多功能其实都用不上。WeKnora 打动我的点在于它的定位更偏“知识库问答”本身文档上传、内容解析、向量化、检索、大模型生成回答链路非常清楚。它没有把自己包装成一个什么都能干的 AI 中台而是把一条核心链路做扎实从仓库里的代码结构也能看出来整个项目的模块边界很干净。对于只需要私有化部署、对接一个本地模型、让团队能上传文档并提问这种需求它属于“刚刚好”的那一类。另外一点是它对中文文档的支持。很多开源项目英文体验不错但一碰到扫描版 PDF、带特殊字符的 Word、Markdown 里的表格解析效果就明显下降。我这次专门拿了几十页的中文产品手册和会议纪要去做测试WeKnora 的解析链路对中文的兼容度是靠谱的这也是我决定深入部署的一颗定心丸。1.2 和 Dify 这类平台的核心差异很多朋友会问既然 Dify 那么火为什么不用 Dify这里我要说句公道话Dify 当然是个优秀的项目工作流编排能力确实强但它默认的交互方式比较重更像一个“AI 应用开发平台”你要做的是在画布上搭一条 workflow再把模型、知识库、工具节点串起来。一旦你接的是本地模型还要处理各种模型格式转换、参数透传、反馈日志整体学习曲线并不低。WeKnora 则更像一个开箱即用的“知识库问答服务器”它默认就给你一条完整的 RAG 链路解析、切片、向量化、检索、重排、生成。你需要操心的是如何把数据导进去而不是从零开始拖画布。如果你团队的核心诉求是“把我的一堆文档变成能回答问题的知识库”WeKnora 的初始配置成本会明显更低。FastGPT 也是很强的选手它在表单集成的商业化能力上做得很好但如果你没有那么多周边需求只看本地知识库问答这个场景FastGPT 需要自己配置的东西反而显得有点多。WeKnora 的默认配置就很接近“能用”的状态减少了很多不必要的选择困难。1.3 本地部署的真正价值我会选择完全本地部署核心原因只有一条数据不出内网。企业内部的 SOP、产品文档、售后话术、项目复盘这些资料是有敏感性的放到云端 API 上始终存在一份数据流通风险。本地部署之后所有文档从解析到检索到生成全程走本机或内网服务器大模型推理也可以接到 Ollama 或者本地部署的 DeepSeek 系列模型上做到真正意义上的闭环。还有一层价值是可控。API 服务的大模型经常有版本迭代和策略调整一旦上游模型更新你可能连通知都收不到回答风格就变了。本地部署的模型参数掌握在自己手里回答风格、系统提示词、召回逻辑都可以反复调调坏了重来一遍也就是几分钟的事。这种掌控感是用 SaaS 服务很难换来的。2. 部署环境与整体架构先把地基打明白2.1 我的软硬件环境实录先交代一下我这次部署所用的环境方便大家和自己的机器做对照操作系统Ubuntu 22.04 LTS内核 5.15纯命令行服务器没有图形界面内存32 GB DDR4实测下来对这套系统足够16 GB 也可以跑但会紧一点CPU8 核 AMD Ryzen 7 5800X主要用来跑文档解析和切片GPURTX 3060 12 GB用来跑本地大模型恰好卡在“能跑 7B 模型量化版”的门槛上磁盘500 GB NVMeOS 和数据卷分开知识库数据放在独立挂载点Docker 版本24.0.7Docker Compose v2.20这里有个经验如果你没有 GPU也不是完全不能跑可以退而求其次用 CPU 跑量化版的小模型比如 Qwen2.5-7B 的 Q4 量化版但回答延迟会从秒级变成十几秒级。我们后面接模型的时候会专门讲取舍。2.2 服务组件拆解谁在前面谁在后面从部署的角度看WeKnora 本地版不是一个单进程应用而是一组服务的组合。理解这个架构之后再动手后面出问题时你才不至于手忙脚乱。我把它拆成四层来看层级组件职责我的选型数据层MySQL / Redis元数据、任务队列、会话缓存MySQL 8.0 Redis 7索引层向量检索组件文档向量存储与相似度检索内置支持的向量检索能力应用层WeKnora API解析、切片、召回、调用模型、透出 API官方后端镜像展示层WeKnora Web管理后台与问答界面官方前端镜像模型层Ollama本地大模型推理 embeddingOllama 服务向量检索这块是 RAG 系统的核心。初次部署时不用追求复杂的分布式检索集群单节点完全够用。我一开始也是抱着“生产级”的心态去看架构结果发现单节点配置起来简单得多文档量没到百万级之前根本没必要上集群。我们后面配置的时候也会演示怎么把 embedding 向量接进去。2.3 初始化目录结构与规划数据卷动手之前强烈建议先把目录结构建好。容器一旦跑起来数据都存在数据卷里如果目录规划混乱后面迁移备份会非常痛苦。我建议所有部署文件放在一个独立目录下大致是这样mkdir -p /opt/weknora/{mysql,redis,uploads,backups} cd /opt/weknoramysql用来放 MySQL 数据文件redis放缓存数据uploads是后面通过 Web 上传的文档原始文件backups放手动备份产物。这样做的原因是所有数据都在一个父目录里备份时只要打包整个目录ai 知识库问答系统的数据就全带走了不会出现容器删除后连文档一起没了的惨剧。2.4 关于用不用 GPU 的提前决策这一个决策会影响后面所有配置所以务必提前想好。如果你打算用 GPU 跑本地模型Ollama 容器就必须能访问到宿主的 GPU 设备这要求在 Docker Compose 里显式声明 device 映射后面我会给代码但前提是你已经在宿主上装好了 NVIDIA Container Toolkit。如果你的选择是“先跑通再升级”那就先接一个 CPU 可跑的小模型把整个链路验证通了之后再换模型不必一开始就追求顶级推理效果。我就是先用 7B 模型跑通后来再调整。3. 本地部署实操全纪录从零到能登录3.1 用 Docker Compose 搭起最小可运行环境我这次用的是 Docker Compose 方式部署这也是目前开源项目最常见的发布方式。先来解释几个关键点MySQL 负责存取系统配置和会话记录Redis 做缓存和异步任务队列API 容器是核心后端Web 容器是操作界面。模型层 Ollama 我选择跑在宿主机而不是放进 Compose原因是后面换模型、改端口都更方便而且 Ollama 经常要独立升级和知识库系统解耦会更干净。下面是我调通后的一个最小参考配置。注意镜像版本请以官方仓库发布的最新 tag 为准我写的是我当时使用的结构version: 3.8 services: mysql: image: mysql:8.0 container_name: weknora-mysql restart: unless-stopped environment: MYSQL_ROOT_PASSWORD: change-me MYSQL_DATABASE: weknora volumes: - ./mysql:/var/lib/mysql - ./mysql-init:/docker-entrypoint-initdb.d ports: - 3306:3306 redis: image: redis:7-alpine container_name: weknora-redis restart: unless-stopped volumes: - ./redis:/data ports: - 6379:6379 weknora-api: image: weknora/weknora-api:latest container_name: weknora-api restart: unless-stopped depends_on: - mysql - redis environment: DB_HOST: mysql DB_PORT: 3306 DB_DATABASE: weknora DB_USERNAME: root DB_PASSWORD: change-me REDIS_HOST: redis REDIS_PORT: 6379 UPLOAD_DIR: /app/uploads volumes: - ./uploads:/app/uploads ports: - 8080:8080 weknora-web: image: weknora/weknora-web:latest container_name: weknora-web restart: unless-stopped depends_on: - weknora-api ports: - 80:80拉起服务docker compose up -d等待几十秒然后查看三个容器状态docker compose ps如果看到Up状态就说明基础层起来了。如果某个容器反复重启别急着改代码先docker compose logs mysql或者docker compose logs weknora-api看日志大多数问题都能从日志里直接找到线索。提示首次启动时MySQL 需要初始化库表API 服务需要建索引这个阶段日志里出现“waiting for database”是正常的看到之后等一分钟再观察。别频繁重启容器容易把初始化流程打断。3.2 接入 Ollama 本地模型从拉模型到通 API既然要本地化大模型推理就不能靠云端接口。我用的是 Ollama这也是目前社区里最省事的本地模型运行方案。你既可以在宿主机直接装也可以用 Docker 跑。我因为计划长期使用选择在宿主机直接装curl -fsSL https://ollama.com/install.sh | sh systemctl enable ollama systemctl start ollama然后确认服务端口ollama serve默认监听 11434 端口。接着拉一个中文能力不错、量化后能在 12GB 显卡上跑的模型。我选的是 Qwen2.5-14B 的量化版如果显存不够可以换 7B。命令如下ollama pull qwen2.5:14b只用 CPU 的话用 7B 或者 3B 会更实际。我的经验是7B 在 CPU 上回答问题会有明显的卡顿14B 在 CPU 上基本是煎熬所以如果你没有 GPU强烈建议先用小模型验证流程别指望大模型在纯 CPU 上有流畅体验。模型拉完后需要把 WeKnora 的模型地址指到宿主机。因为 WeKnora API 容器是独立的它访问宿主机 11434 端口时不能直接用localhost要使用host.docker.internal或者宿主机的局域网 IP。在 Compose 的weknora-api环境变量里加上environment: LLM_PROVIDER: ollama OLLAMA_BASE_URL: http://host.docker.internal:11434 LLM_MODEL: qwen2.5:14b如果你希望 Ollama 也跑在容器里那也可以把 Ollama 加进同一个 Compose 网络然后用服务名ollama:11434互相访问。两种方式我都试过跑在宿主机上更灵活尤其后期要换 embedding 模型的时候不用重建容器。3.3 初始化账号和健康检查所有服务起来后打开浏览器访问http://服务器IP:80。首次访问会要求创建管理员账号这里在系统启动后前端会引导完成。一个容易忽略的点是如果你在 Compose 里没有配置邮件服务器注册时就不要填真实邮箱随便用一个规范格式的管理员邮箱即可否则后续收不到验证邮件反而卡住。系统登录成功后先不要急着创建知识库先做几个健康检查# 检查 API 是否正常响应 curl -X GET http://localhost:8080/api/health # 检查 Ollama 模型是否在列表里 curl http://localhost:11434/api/tags如果/api/health返回正常 JSON说明核心链路已经通了大半。此时真正要确认的是 WeKnora 能否通过 API 成功调用到 Ollama这决定了后面问答能不能跑起来。在管理后台的模型配置页面里测试一下连通性如果返回“模型调用成功”就可以进入知识库建设环节了。4. 搭建第一个 AI 知识库问答系统4.1 创建知识库集合与配置 embedding登录后台后第一步是创建一个“知识库集合”。这个集合概念你可以理解成一个文档池每个文档池互相独立可以配置不同的切片策略和模型参数。我建议按业务域拆分集合比如“产品手册库”“售后 FAQ 库”“内部制度库”而不是全公司文档塞一个池子否则检索时跨业务域的内容会互相干扰召回精度会明显下降。创建集合时有几个关键配置项集合名称建议英文标识加中文描述方便 API 调用时识别Embedding 模型选择你指定的向量化模型这里要谨慎一旦数据导入后再换 embedding 模型所有向量维度可能不匹配历史数据需要重新向量化切片大小我默认用 500 个 token后面会细说我建议的 embedding 配置是接 Ollama 上的bge-m3模型。这个模型中文向量效果好而且支持 1024 维输出够用且不算太占资源。先把模型拉到本地ollama pull bge-m3然后在 WeKnora 后台的 embedding 配置里填写本地的 endpointhttp://host.docker.internal:11434模型选bge-m3。这里有个细节有些系统会自动调用 OpenAI 兼容接口的embedding字段如果你选了ollama但是base_url写错会导致向量化一直失败所以配置完一定要测试。4.2 导入文档从上传到切片的完整链路知识库建好之后就可以开始传文档了。我这次实际测试的文档包括一份 80 页的 PDF 产品手册、一份 Word 版团队 SOP、一份 Markdown 技术方案。三种格式都顺利被解析但踩了一个小坑PDF 里的扫描图片如果要做 OCR需要提前确认系统是否内置了 OCR 组件如果没内置扫描版 PDF 里的文字会变成“看不见的字符”检索时自然召不回。针对不同文档切片参数可以参考这个思路文档类型切片大小token切片重叠说明产品手册 PDF50050保留段落上下文回答更完整短问答 FAQ20020每条 FAQ 尽量独立避免切碎原文长技术方案80080保留章节逻辑适合方案级检索会议纪要/邮件30040折中兼顾召回速度和上下文这里解释一下为什么切片不能“一刀切”。切片太小比如 100 token会导致一段完整的技术说明被截断检索时找得到片段却缺少前后文模型回答就容易断章取义。切片太大比如 2000 token会让向量检索的精度下降因为一个向量段里包含太多主题相似度匹配会被稀释。500 token 是我测下来中文文档比较稳的起点后续可以根据你的文档特性和问答质量继续调整。4.3 配置问答参数系统提示词、召回数量与重排策略知识库文档导入完成后进入到问答配置环节。这一块最影响最终体验强烈建议细心调不要上来就用默认值。首先是系统提示词。WeKnora 在问答界面背后的逻辑是用户提问 → 从知识库检索出相关片段 → 把片段和问题一起交给大模型 → 模型根据片段内容生成回答。系统提示词的作用是告诉大模型“你只能依据提供的资料回答不要编造资料不足时要承认不知道”。我的实际提示词是这样的你是一个企业内部知识库助手。你必须严格根据参考资料回答用户问题。 当参考资料中没有明确答案时请直接回答“资料库中没有相关信息” 不要根据一般常识做无根据的推断。 回答时用简洁、专业的中文可引用资料中的关键术语。然后是召回数量。默认的召回数量如果太少比如 3 条可能漏掉关键文档如果太多比如 10 条又会把大量无关碎片塞给模型干扰回答。我测下来一个相对合理的组合是召回 5 条重排后保留 3 条。如果你们团队的文档密度很高可以多召回几条再靠重排模型做精筛。重排策略用的是第二级 Rerank。原理很简单向量检索先快速捞出候选再用更精确的模型对这些候选重新打分排序质量提升非常明显。我实测下来加了重排之后回答内容相关度上升了不止一个档次。如果这一步你觉得复杂可以先用不重排的方式跑通后续有条件再补。4.4 实测一轮问答我实际问的第一个问题是“Qwen 模型在本地部署时对显存的要求是多少”这个问题知识库里其实没有直接写但文档里有“12GB 显存可运行 7B 量化模型”这句话以及“14B 量化需要 16GB 显存”等碎片信息。经过重排后系统成功召回了相关片段模型给出的回答把不同配置要求完整整理了出来。第二个问题是“新员工入职第一天需要准备哪些材料”知识库里的 SOP 文档有答案但原文是表格和清单夹杂的形式。模型按照我的提示词要求把材料清单逐条列了出来还主动加了“以上内容引用自《新员工入职 SOP》”这样的来源标记非常惊艳。实测下来最大的感受是回答质量的上限其实不是由大模型决定的而是由切片和召回质量决定的。模型再强如果召回的片段是错的回答也会跟着歪。5. 常见问题与排查技巧实录5.1 容器起不来先查端口、内存、权限部署过程中遇到最多的坑基本都集中在容器启动阶段。这类问题有个最快的排查顺序先看端口占用再看容器日志最后看磁盘权限。sudo netstat -tlnp | grep 8080 sudo docker compose logs --tail100 weknora-api如果是端口被占用换一个宿主映射端口即可。如果是 MySQL 数据目录没有写权限容器会反复重启最典型的表现就是日志里一直报权限不足。解决办法是给当前用户授权目录sudo chown -R 1000:1000 /opt/weknora/mysql chmod -R 755 /opt/weknora这个“1000”是 MySQL 容器内部 UID不同镜像可能不一样最稳妥的做法是直接看官方文档或日志里提示的 UID。5.2 Ollama 连接不上跨容器网络的三个坑如果你在后台模型配置页面测不通 Ollama十有八九是这三个原因之一第一容器内访问宿主机不能用localhost要用host.docker.internal或者直接用宿主机的局域网 IP。第二Ollama 默认只绑定127.0.0.1外部访问会被拒需要设置环境变量让 Ollama 监听所有网卡OLLAMA_HOST0.0.0.0 ollama serve第三防火墙或网络安全组没有放行 11434 端口。中招最多的是第一和第二条先自查再重启服务。5.3 知识库明明有内容却总是回答“查不到”这个问题的根源基本都在“检索链路”而不是“生成链路”。我的排查经验是分三步走第一步去后台直接看文档的切片结果确认切片到底有没有生成很多情况下是文档导入任务失败但界面没有明显报错。第二步用一个非常简短、一定是原文档里的原话去搜比如“显存 12GB”看能不能召回。如果召回结果为空说明 embedding 没有成功写入向量库。第三步检查 embedding 模型是否和集合创建时的配置一致中途换过模型会导致向量维度对不上旧向量无法检索。遇到最多的情况是切片任务失败。文档本身有问题比如 PDF 文件损坏或者扫描版文字没提取出来会导致切片数量为零。解决办法是先转换文档格式重新上传再触发一次重新切片。5.4 回答质量差先别急着换大模型很多人遇到回答不准确第一反应是“换个更大的模型”。这个方向不全是错的但成本高、见效慢。我的建议是先把顺序倒过来先调召回数量把 5 条改成 8 条试试再调系统提示词明确要求“如果资料不足直接回答不知道”最后才考虑换模型。此外切片重叠也非常值得调。如果文档中经常出现“上一页提到的方法”这类跨页引用没有重叠就把上下文切断了。重叠设成 50 到 80 token能够明显缓解上下文断裂的问题。我调整过一次切片参数后整个知识库的问答准确率提升了至少两成比换个模型的收益还明显。5.5 数据备份与迁移避免手工备份悲剧本地部署最大的风险就是数据没了。容器一删所有知识库文档、切片结果和会话记录就全没了。我的备份策略非常简单直白直接打包整个/opt/weknora目录。cd /opt tar czf weknora-backup-$(date %Y%m%d).tar.gz weknora恢复的时候先把目录解压回原路径再重新执行docker compose up -d数据卷会自动读取。这里有个小提醒备份前先通过管理后台停用知识库的检索行为或者直接停掉容器避免备份过程中写入新数据导致文件不一致。6. 使用感受与可扩展方向整套系统跑通之后我最大的感受是本地 AI 知识库的门槛已经比两年前低太多了。五年前你要搭一套私有的文档问答系统要考虑怎么分词、怎么训练、怎么部署模型现在这些基础设施基本都被开源项目封装好了你只需要花时间理解每一条链路的配置逻辑。WeKnora 帮我节省了非常多底层工作它没有把 RAG 简化成一个黑盒而是把每一个环节都暴露成可配置的参数这种人机交互方式对技术团队非常友好。后续我打算在现有知识库上做两个扩展一个是用 API 把它接入到企业微信机器人里让同事们在聊天窗口里直接提问这样知识库就从一个管理后台变成了全员可用的日常工具另一个是准备把多知识库的权限细分做起来不同部门只能访问各自的文档集合这会更贴近真实企业环境里的安全问题。如果你也是第一次接触 WeKnora 本地部署我个人最诚恳的建议是先把最小链路跑通不要一上来就追求模型参数最优等系统转起来之后再一步一步把切片大小、重排策略、模型版本调成你自己的形状。
返回列表