三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

从零到一搭建企业文档知识库:WeKnora RAG 实战手记(附部署与避坑)

从零到一搭建企业文档知识库:WeKnora RAG 实战手记(附部署与避坑)

从零到一搭建企业文档知识库:WeKnora RAG 实战手记(附部署与避坑)

【免费下载链接】WeKnoraOpen-source LLM knowledge platform: turn raw documents into a queryable RAG, an autonomous reasoning agent, and a self-maintaining Wiki.项目地址: https://gitcode.com/GitHub_Trending/we/WeKnora

如果你手头攒了一批 PDF、Word、Markdown,同事每天在群里重复问同样的问题,而你试过把文档直接丢给大模型、得到的却是半真半假的回答——那么这篇 WeKnora RAG 实战手记正是为你准备的。WeKnora 是一个开源的 LLM 知识平台,核心能力就是把原始文档加工成可查询的 RAG 知识库、可自主推理的 Agent,以及会自动维护的 Wiki。本文记录我一次真实落地过程:从一台空机器开始,到知识库上线、准确率调到可用,全程约一个下午,踩过的坑都写在里面了。

一、故事从一次"答不上来"开始

先说背景。我帮一个三十多人的团队搭内部知识库,他们的资料并不少:产品手册、排障记录、会议纪要、几十个版本的报价表,散落在共享盘和聊天记录里。新同事入职第一周,基本就是在"问人"和"翻文件"之间反复横跳。

最开始的方案很朴素——把文档全塞给大模型,让它直接答。结果可想而知:模型一本正经地编造不存在的功能参数,老员工看了直摇头。问题不在模型,而在"模型根本没读过你们的资料"。它缺的不是知识,是检索这一步:先把相关片段从你的文档里捞出来,再让模型基于这些片段作答。这正是 RAG(检索增强生成)要做的事,也是 WeKnora 这类平台存在的意义。

二、先把 RAG 这层窗户纸捅破

RAG 听起来唬人,拆开就四个环节,WeKnora 把它们做成了全自动流水线:

  1. 解析:把 PDF、Word、Excel 等二进制文档变成结构化文本,扫描件还要走 OCR。这一层由独立的 docreader 服务负责,相关代码在docreader/parser/
  2. 分块:把长文本切成有边界感的小段。切太碎答不全,切太大向量表达不准。默认 512 字符、重叠 80,实现在internal/infrastructure/chunker/
  3. 向量化:用 embedding 模型把每段文字转成向量,连同关键词一起建索引,方便后面做混合检索。
  4. 检索 + 生成:收到问题时,先在库里做"向量相似度 + 关键词"混合召回,再交给大模型组织成带出处的回答。

之所以不能把整批文档直接喂给模型,是因为上下文窗口有限、成本高、而且细节越多越容易胡说。RAG 的聪明之处在于:每次只给模型看与问题最相关的几段,既省 token,又有出处可查。

三、动手前的准备清单

在开始之前,先确认这几样东西齐不齐:

依赖要求说明
Docker20.10+,含 Compose v2标准部署全靠容器编排,最省心
硬件建议 4 核 CPU / 8GB 内存起docreader 要跑 LibreOffice 和 Playwright,比较吃内存
对话模型(LLM)Ollama 本地模型,或任意 OpenAI 兼容 API负责"组织回答",如 qwen3、DeepSeek、通义等
向量模型(Embedding)Ollama 或远程 API负责"理解语义",如 bge-m3;建库后不要更换

模型可以用本地 Ollama 零成本跑起来,也可以用云厂商的 API。至少需要一个对话模型和一个 embedding 模型,两者可以来自不同服务商。

四、分步实操:从空机器到能问答的完整链路

下面按步骤走,顺利的话十几分钟就能跑通最小闭环。全程两种玩法:网页界面点一点,或者纯 API 脚本,我都演示一遍。

步骤一:一键拉起整套服务

克隆仓库并启动(仓库地址为 https://gitcode.com/GitHub_Trending/we/WeKnora):

git clone https://gitcode.com/GitHub_Trending/we/WeKnora cd WeKnora cp .env.example .env # 按需修改数据库密码、JWT_SECRET 等 make start-all # 等价于 scripts/start_all.sh docker compose ps # 等所有服务变成 healthy/running

启动后用一条命令确认后端活着:

curl http://localhost:8080/health # 期望返回 {"status":"ok"}

前端默认在http://localhost,首次访问会落到注册页。

💡 提示:.env文件不存在会导致 Compose 解析失败,make start-all会自动从示例文件兜底,但部署前务必把里面的默认密码换掉

步骤二:注册账号,创建第一个知识库

系统没有内置默认账号。在登录页的"注册"页签里创建账号,注册完成后会自动生成一个属于你的工作空间,你就是这个空间的 Owner。

登录后点新建知识库,填名称,类型选document(普通文档库;faq是问答对库)。接着在弹出的初始化向导里做两件关键的事:

  • 选对话模型:回答问题时用;
  • 选向量模型:文档转向量用,保存后不要再换,换了必须重建索引,否则检索结果会牛头不对马嘴;
  • Rerank、VLM 等其余能力先不开,之后随时能加。

向导里带"测试"按钮,保存前先确认模型连得通。

⚠️ 注意:后端跑在容器里时,填http://localhost:11434是连不上宿主机 Ollama 的,必须用http://host.docker.internal:11434。这是新手第一坑,几乎人人都会踩。

步骤三:上传文档,看它被"消化"

进入知识库,把文件拖进上传区即可,支持 PDF、Word、Excel、PPT、Markdown、HTML、EPUB、图片、音频等十多种格式,也可以直接粘贴网页 URL。

上传后文档进入异步解析,状态依次是pending → processing → finalizing → completed。扫描版 PDF 会慢一些,列表页实时刷新进度,分块数一目了然。你可以点开任意一块查看切分效果——这是判断"分块质量"最直观的方式。

步骤四:提问,看带出处的回答

进入对话页,选中刚建的知识库,直接提问。默认走内置的"快速问答"Agent:检索相关片段 → 交给大模型 → 返回带引用的回答。点回答里的角标可以跳回原文段落,答案有没有依据,一眼就能核验。到这里,最小闭环就跑通了。

步骤五:用 API 走通同一条链路

网页操作背后的每个动作都有对应接口,统一前缀/api/v1。这段脚本可以直接复制运行,适合以后做自动化集成:

BASE=http://localhost:8080/api/v1 # 1) 登录,取 JWT TOKEN=$(curl -s -X POST $BASE/auth/login -H "Content-Type: application/json" \ -d '{"email":"admin@example.com","password":"pass123456"}' | jq -r '.token') AUTH="Authorization: Bearer $TOKEN" # 2) 创建知识库 KB_ID=$(curl -s -X POST $BASE/knowledge-bases -H "$AUTH" -H "Content-Type: application/json" \ -d '{"name":"我的知识库","type":"document"}' | jq -r '.data.id') # 3) 初始化(以本地 Ollama 为例) curl -s -X POST $BASE/initialization/initialize/$KB_ID -H "$AUTH" -H "Content-Type: application/json" -d '{ "llm": {"source":"local","modelName":"qwen3:8b"}, "embedding": {"source":"local","modelName":"bge-m3","dimension":1024}, "documentSplitting":{"chunkSize":512,"chunkOverlap":80}}' # 4) 上传文档 curl -s -X POST $BASE/knowledge-bases/$KB_ID/knowledge/file -H "$AUTH" \ -F "file=@./demo.pdf" # 5) 创建会话并发起知识问答(SSE 流式输出) SESSION_ID=$(curl -s -X POST $BASE/sessions -H "$AUTH" -H "Content-Type: application/json" \ -d '{"title":"第一次对话"}' | jq -r '.data.id') curl -N -X POST $BASE/knowledge-chat/$SESSION_ID -H "$AUTH" -H "Content-Type: application/json" \ -d '{"query":"这份文档讲了什么?","knowledge_base_ids":["'$KB_ID'"]}'

💡 提示:服务端集成建议用 API Key 而不是 JWT——在"空间设置"里创建,支持细粒度权限(retrieve/chat/ingest/manage_kbs等),还能限定可访问的知识库,比长期有效的登录令牌安全得多。

五、进阶玩法:把准确率从"能用"调到"好用"

最小闭环通了之后,真正的功夫在调优。以下是我实践下来性价比最高的几个杠杆,按收益排序。

1. 分块参数调优(收益最大、成本为零)

答案好不好,一半取决于文档被切成什么样。绝大多数场景默认值(512 / 80)就够了,遇到下面这些情况再动手:

你遇到的问题建议做法
回答缺上下文、经常答半句调大chunk_size,或开启父子分块(子块检索、父块回答)
命中的块跟问题关系不大调小chunk_size,让每块主题更集中
资料是条目式的(FAQ、参数表)重叠设为 0,避免相邻条目互相污染
资料是长篇叙述(报告、论文)重叠调到 150–200,保住跨块语义连贯
拿不准会切成什么样用分块预览接口POST /api/v1/chunker/preview试切,不落库、免费试错

改完分块配置后,需要对已有文档重新解析才会生效,这点别忘了。

2. 打开 Rerank,让排序更聪明

单纯靠向量相似度召回,偶尔会出现"语义相近但答非所问"的块排在前面。开启 Rerank 重排后,系统会用专门的排序模型对召回的候选重新打分,把最贴合问题的段落顶到前面。响应时间会多几十毫秒,但对准确率的提升非常明显。相关参数在config/config.yamlconversation段落(rerank_thresholdrerank_top_k)。

3. 从"快速问答"升级到"智能推理"Agent

快速问答是"检索 → 回答"的直线流程,适合日常查资料。遇到"对比这两个方案的优劣""总结一下并列出依据"这类需要多步推理的问题,切换到内置的"智能推理"Agent,它会自己决定检索几轮、要不要联网、要不要调工具,甚至可以在对话里@Skill / @MCP限定这一轮的能力范围。下面这张图展示的就是 Agent 在检索与工具调用之间来回决策的过程:

4. 让知识库自己"生长":Wiki 模式

这是我个人觉得 WeKnora 最有想象力的功能。开启 Wiki 模式后,Agent 会把知识库里的原始文档蒸馏成结构清晰、互相链接的 Markdown 词条,并在界面里生成可视化知识图谱——相当于给你配了一个 24 小时在线的资料整理员。之后新文档进来,Wiki 会增量更新,你可以在浏览器里手动编辑、查看修订历史、一键回滚。

5. 实践中最容易踩的坑

把上面那些坑汇总成一张速查表,都是过来人用时间换来的:

现象原因与对策
初始化时 Ollama 检测失败容器内要填http://host.docker.internal:11434,Linux 需确认extra_hosts: host.docker.internal:host-gateway生效
上传后一直processingdocker logs WeKnora-docreader;单文件默认上限 50MB,超时默认 2 小时
问答没有引用、召回为空确认文档解析已完成;调低vector_threshold;检查 embedding 模型是否与建库时一致
换了 embedding 模型后检索变差换模型必须重建索引,旧向量与新模型不兼容
API Key 请求返回 403Key 的 capabilities 不含所需能力,或知识库白名单没包含目标库

六、FAQ 与排查清单

Q:一定要自己部署吗?有没有更省事的入口?桌面版和 Lite 单二进制版本免注册、开箱即用,适合个人和低资源环境;团队级使用建议走 Docker Compose 标准部署。

Q:只有一台 2 核 4G 的云服务器,能跑吗?能,但建议用 Lite 版(SQLite + 内存队列,无 Redis/Postgres 依赖),模型走远程 API 而不是本地 Ollama,把内存留给 docreader。

Q:文档解析支持哪些格式?扫描件能识别吗?PDF、Word、Excel、PPT、Markdown、HTML、EPUB、图片、音频都支持,扫描版 PDF 走 OCR。解析引擎的完整清单见docreader/parser/目录。

Q:多个人用,怎么管权限?支持工作空间 RBAC,四层角色(Owner / Admin / Contributor / Viewer),知识库可指定归属人,每个空间有独立的审计日志。部署后记得在设置里把公开注册关掉,改用邀请链接加人。

排查清单(照着勾一遍):

  • curl http://localhost:8080/health返回 ok
  • 文档解析状态已是completed
  • 问答对话框选中的知识库正确
  • Ollama 地址用的是host.docker.internal
  • embedding 模型与建库时一致
  • vector_threshold没有高到把结果全滤掉

七、小结与下一步

回顾一下这趟落地:我们用 Docker 一键拉起服务,通过网页和 API 各走通了一遍"建库 → 上传 → 问答"的完整链路,再用分块调优、Rerank、Agent 和 Wiki 模式把"能用"提升到了"好用"。整个过程中最值钱的认知是:RAG 的瓶颈往往不在模型,而在你喂给模型的那几段文字质量——检索、分块、重排这些工程细节,才是准确率的真正分水岭。

下一步建议你这样做:把你手上最头疼的那批文档(不用多,先来十几份)按本文流程跑一遍,重点感受两个地方——打开分块预览看看切得合不合理,以及把同一问题分别抛给"快速问答"和"智能推理"Agent 对比答案质量。跑通之后想深入了解,项目里有不少值得一读的资料:docs/目录下的功能说明(分块机制、检索引擎、RBAC 都在里面),config/config.yaml是所有调参的入口,源码层面internal/infrastructure/chunker/是理解分块策略的最佳起点。祝你的知识库早日上线,让同事少问几遍"这个在哪个文档里"。

【免费下载链接】WeKnoraOpen-source LLM knowledge platform: turn raw documents into a queryable RAG, an autonomous reasoning agent, and a self-maintaining Wiki.项目地址: https://gitcode.com/GitHub_Trending/we/WeKnora

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

← 返回列表