从零到一搭建企业文档知识库: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 把它们做成了全自动流水线:
- 解析:把 PDF、Word、Excel 等二进制文档变成结构化文本,扫描件还要走 OCR。这一层由独立的 docreader 服务负责,相关代码在
docreader/parser/。 - 分块:把长文本切成有边界感的小段。切太碎答不全,切太大向量表达不准。默认 512 字符、重叠 80,实现在
internal/infrastructure/chunker/。 - 向量化:用 embedding 模型把每段文字转成向量,连同关键词一起建索引,方便后面做混合检索。
- 检索 + 生成:收到问题时,先在库里做"向量相似度 + 关键词"混合召回,再交给大模型组织成带出处的回答。
之所以不能把整批文档直接喂给模型,是因为上下文窗口有限、成本高、而且细节越多越容易胡说。RAG 的聪明之处在于:每次只给模型看与问题最相关的几段,既省 token,又有出处可查。
三、动手前的准备清单
在开始之前,先确认这几样东西齐不齐:
| 依赖 | 要求 | 说明 |
|---|---|---|
| Docker | 20.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.yaml的conversation段落(rerank_threshold、rerank_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生效 |
上传后一直processing | 看docker logs WeKnora-docreader;单文件默认上限 50MB,超时默认 2 小时 |
| 问答没有引用、召回为空 | 确认文档解析已完成;调低vector_threshold;检查 embedding 模型是否与建库时一致 |
| 换了 embedding 模型后检索变差 | 换模型必须重建索引,旧向量与新模型不兼容 |
| API Key 请求返回 403 | Key 的 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),仅供参考