从Wiki到智能问答:基于RAG的大模型知识库搭建实战

发布时间:2026/9/14 4:16:35
从Wiki到智能问答:基于RAG的大模型知识库搭建实战 我们团队花了差不多一个季度的时间把一个原本只能存资料的 Wiki 系统逐渐改造成了一个具备语义检索和智能问答能力的大模型知识库。这个项目的代号就叫 llm_wiki今天把这套从零开始的设计思路、工具选型、实操踩坑过程完整记录下来。如果你正在做个人知识库或者团队内部想搞一套能聊天的 Wiki这篇文章应该能帮你少走不少弯路。要理解这个项目在干什么可以先想一个场景传统 Wiki 的搜索本质上是关键词匹配你得记得文档里有某个词才能搜到。而 llm_wiki 的思路是把 Wiki 里的每一篇文档都切成块、做成向量索引用户提问时先做语义检索把最相关的几个内容片段捞出来再交给大语言模型LLM生成自然语言回答。这样一来知识库就从一个存放资料的仓库变成了一个随时可以对话的助手。适用的人很明确一是做知识管理的个人用户二是团队协作里被文档检索效率折磨的工程师三是想在公司内部落地 RAG检索增强生成方案但不知道从何入手的技术人员。下面我会先讲架构选型背后的思考再逐步拆解数据准备、组件选型、实操搭建最后把真实环境中遇到的高频问题列出来。1. 项目核心思路为什么LLM Wiki而不是Wiki 关键词搜索1.1 传统知识库的三个核心痛点我接手这个项目前团队已经有一个积累了大量技术文档、会议记录和项目复盘资料的 Wiki但使用率越来越低。用户反馈很一致搜不到、看不完、提炼不出重点。搜不到是关键词匹配的天然缺陷。比如文档里写的是缓存失效问题用户搜服务响应变慢词面不匹配就查不出来。看不完是信息过载的问题。一篇技术方案上万字用户只想知道最终选型是什么、为什么这样选传统 Wiki 给不了这种提取式答案。提炼不出重点则是更深层的需求用户希望知识库能回答问题而不是返回一堆文档链接让用户自己判断。这三个痛点本质上指向同一个方向知识库的交互方式需要从检索文档升级为获取答案。而 2024 年以来 LLM 能力的成熟让这个升级有了低成本、可落地的路径。1.2 为什么选择 RAG 架构而不是微调模型确定要引入 LLM 之后团队内部其实有过一次争论是微调一个领域专属模型还是走 RAGRetrieval-Augmented Generation检索增强生成路线微调方案的技术路径是把历史文档整理成训练语料选择一个开源底座模型用 LoRA 等方式做领域适配。听起来很终极但落地时问题很多。一是文档更新频率高每次新增内容都要增量训练流程太重二是训练需要显卡资源和 MLOps 工程能力团队没有专职算法同学三是微调模型并不天然具备引用出处的能力回答错了很难定位原因。RAG 的路线逻辑完全不同——文档不进模型而是做索引、切片、向量化后存入向量数据库。用户提问时系统先在向量库里做相似度检索找到最相关的若干文本片段再把这些片段拼进 Prompt让 LLM 基于片段内容生成回答。它的核心优势是不训练模型、知识可溯源、更新只需重传文档索引。对我这种没有算法团队但又要快速交付的项目来说RAG 几乎是唯一解。1.3 llm_wiki 的整体架构整个系统按数据流可以分成五层数据接入层负责从 Wiki、本地 Markdown、PDF、Word、网页 URL 采集文档。文档处理层做格式清洗、切块Chunking、元数据标记。向量化索引层用嵌入模型把每个 Chunk 转成向量写入向量数据库。检索层接收用户问题语义检索 重排序Rerank取出 Top-K 知识片段。生成层把知识片段拼进 Prompt调用 LLM 生成最终回答并附上引用来源。这个架构本身不复杂但每一层都有不少细节尤其是文档切块和检索策略直接决定了最终回答质量的上限。后续章节我按照这个分层逐步展开。2. 数据准备与文本处理决定知识库质量的第一道关卡2.1 文档接入先解决格式统一这场持久战llm_wiki 的数据来源非常杂既有飞书文档导出的 MD 文件也有历史遗留的 PDF 扫描件、Word 技术方案、网页收藏。我的建议是第一版不要追求全格式覆盖先把最高频的三种格式打通——Markdown、带层级标题的 HTML、可复制文本的 PDF。Markdown 是最理想的输入格式。因为切块时可以借助标题层级来做语义边界处理代码块、表格、列表也更干净。但现实是很多 Wiki 导出的是 HTML我一般先统一转换为 Markdown。手动写脚本容易坏直接用开源的 trafilatura 做网页正文抽取或者用 pandoc 做格式互转稳定性好很多。PDF 是另一个大坑。扫描版 PDF 必须先 OCR否则后面的切块和向量化质量会很差。我在项目里用的是 PaddleOCR对中文支持不错。但经验是能拿到 Word 或 Markdown 源文件的尽量用源文件OCR 会引入错字这些错字在语义检索阶段的负面影响比想象中大。2.2 切块策略同样一份文档切成多大、怎么切结果完全不同切块是整个流程里最容易被低估的环节。切太大了一个块里内容太多向量化后语义被稀释检索时会捞回来一堆相关但没重点的内容切太小了上下文不完整LLM 拿到之后无法理解完整逻辑。我在项目里的经验值通用文档按 500 到 800 个 token 切片重叠窗口设 50 到 100 token。为什么设重叠窗口因为一句话的前半段可能在 A 块、后半段在 B 块如果完全不重叠检索时就会错过语义完整的边界。这一点实际操作中只能用固定 token 切分加滑动窗口实现简单有效。更好的切块方案是按 Markdown 标题层级做语义切块。如果一个二级标题下内容很多就继续往下切表格单独成一个块代码块尽量完整保留。这样切出来的块天然具备语义边界检索命中率明显比无脑按 token 切高。我用的是 LlamaIndex 的 MarkdownNodeParser 做了二次开发核心逻辑就是给每块打上文档路径和标题锚点检索结果能直接定位到原文档位置。2.3 向量化模型选型中文场景下别闭眼选国外模型向量化模型决定了语义相似度算得准不准选型时我踩过不少坑。第一版图省事直接用了 OpenAI 的 text-embedding-ada-002效果在英文场景还可以但对中文长文本的语义拟合明显弱尤其专业术语多的技术文档检索头几名经常偏离主题。后来换成国产嵌入模型实测下来 bge-large-zh-v1.5 和 bge-m3 的中文效果都有明显提升。bge-m3 的优势是支持 8192 token 的长文本还能输出稠密向量和稀疏向量两种表示特别适合做混合检索——稠密向量解决语义相似稀疏向量解决精确词匹配两者结合之后召回率提升显著。如果你的场景偏向代码问答可以试试基于代码语料预训练的代码嵌入模型。但我的结论是通用知识库直接上 bge-m3 就够了别在这里花太多时间调参后续 Rerank 阶段更能拉高精度。3. 核心组件选型向量数据库与 LLM 接入的取舍3.1 向量数据库选择从 Chroma 到 Qdrant 的迁移理由向量数据库是检索链路的核心存储引擎。第一版为了快我直接选了 Chroma——它是嵌入式库轻量、开箱即用本地就能跑。但项目数据量到几十万条 Chunk 之后Chroma 的客户端模式和过滤查询性能就顶不住了尤其按文档目录做元数据过滤时响应延迟明显上升。后来迁到了 Qdrant。选它的理由很实际支持 Rust 底层的高性能过滤查询部署方式灵活既能 Docker 单机跑也能上集群而且内置了 payload 索引可以按文档 ID、标签、创建时间做过滤这对只搜索某个项目目录下的文档这类需求很有用。如果你只需要单机跑几百 MB 的知识库Chroma 也完全够用没必要一上来就上 Qdrant 增加运维负担。同时我把 pgvector 也作为备选保留着因为它就在 PostgreSQL 里适合团队原来就依赖 Postgres 的场景少一个组件少一份运维。结论是按数据量倒推选型小项目用 Chroma中等规模用 Qdrant已有 PG 基础设施的优先 pgvector。3.2 LLM 接入方式云端 API、本地部署、还是走 Dify 中间层llm_wiki 的生成层有两条路直接调各家 LLM API或者通过 Dify、FastGPT 这类 LLMOps 平台搭建应用。以我负责的团队场景答案其实是先用 Dify 跑通闭环再决定是否自建 API 编排。Dify 的优势在于把知识库接入、检索流程、Prompt 编排、模型管理都界面化了不需要从零写代码。它的工作流里有一个知识库检索节点可以配置检索方式、Top-K、Score 阈值再连一个大模型节点做生成。如果你还没法确定公司最终选哪家大模型供应商Dify 里可以同时配置多家 API Key 动态切换省掉了自己写适配层的活。但 Dify 不适合所有场景。它的缺点在黑盒层面检索内部细节暴露有限复杂的多跳检索、混合检索策略调试不灵活延迟也偏高。我实测过从提问到输出首 token 大概多出 300ms 以上的编排开销。所以最终生产环境如果要追求极致性能和定制化建议把检索逻辑抽出来自己写 Python 服务Dify 只做配置调研和原型验证。3.3 检索参数细节Top-K、Score 阈值和 Rerank怎么调才算合理检索阶段最容易出现的问题是没召回和召回太杂。对没召回第一反应别急着调阈值先看向量化质量——是否切块不合理、嵌入模型是否适合领域语言。对召回太杂重点检查两件事Top-K 是否设置得太大、Score 阈值是否设太低。我的经验值供参考Top-K 初始设为 5如果回答引用了大量无关内容降为 3如果回答明显缺细节升到 8。Score 阈值在 Qdrant 中一般设 0.2 到 0.5这个范围取决于嵌入模型的距离度量实践中要画一条召回率-准确率曲线来定。插一句直接用固定阈值其实不太灵活可以结合 Rerank 做二次筛选先用较宽的 Top-K比如 20召回再用 BGE-Reranker 对候选集重排取前 3 作为最终上下文。Rerank 这一步对中文知识库的准确率提升非常明显实测此前 76% 左右的精确率能拉到 88% 以上值得投入。4. 实操手记用 Dify Qdrant 跑通一个 llm_wiki 问答应用4.1 环境准备Docker Compose 一键拉起依赖我习惯用 Docker Compose 做本地环境联调整套依赖写在一个 compose 文件里包括 Qdrant、Dify以及后续要用的本地嵌入模型服务。这一步实际做的是把底层服务先跑起来避免后面建知识库时才发现环境问题。Dify 的官方仓库提供了 docker/docker-compose.yaml基本能一键启动。Qdrant 我用镜像 qdrant/qdrant挂载本地目录持久化数据。嵌入模型这块如果用云端 API 就不用额外部署如果选本地 bge-m3我建议起一个独立的服务容器跑本地推理别和 Dify 主服务混在一起资源隔离更清晰。4.2 创建知识库并上传首批文档登录 Dify 后台进入知识库页面新建一个名为 llm_wiki 的知识库。这里要选索引方式Dify 支持高质量模式和经济模式前者会用嵌入模型做向量检索后者是关键词索引。要做语义问答就选高质量模式并在嵌入模型配置里填入 bge-m3 的 API Endpoint。上传文档没什么特别的支持 PDF、Markdown 等格式。真正要注意的是切块设置Dify 默认切块参数偏保守我在生产里一般把分块长度调到 600 左右、重叠 80实际效果比默认值好。以下是可参考的切块配置示例chunk_size: 600 chunk_overlap: 80 delimiter: \n## # 按 Markdown 二级标题感知边界上传完成后 Dify 会自动完成文档分段和索引可以在文档分段列表里检查切出来的块是否合理比如代码块有没有被切碎、标题层级是否保留。4.3 构建问答应用从知识库检索到LLM 生成的编排进入应用页面新建一个 Chatbot 应用模型供应商选你已经配置好的 LLM。这里我选择的是 OpenAI 兼容接口Dify 可以直接把 base_url 指向你自己的网关。核心步骤是编排 Prompt。我的 Prompt 模板思路如下先定义角色再限定回答来源最后要求引用出处。一个简化示例你是一个基于知识库回答问题的助手。 规则 1. 只根据{{#context#}}中的内容回答不要使用你内部的既有知识补充。 2. 如果上下文无法回答用户问题请直接说根据当前知识库内容无法回答不要编造。 3. 回答结尾列出引用来源文档的标题。 用户问题{{#query#}}接着在编排面板加上知识检索节点关联之前创建的 llm_wiki 知识库检索方式选语义检索Top-K 设为 5Rerank 模型选择已启用 BGE-Reranker 的供应商。完成后先发几条测试问题验证。4.4 验证调优如何判断回答得好不好验证阶段别直接用肉眼判断顺不顺要建立一套简单的评估集。我的做法是挑 30 条高频真实问题人工标注出每道题希望回答里涵盖的知识点关键词然后跑一轮看每条回答是否覆盖了这些关键词再按完全覆盖、部分覆盖、未覆盖三档打分。一轮下来基本能看出是切块问题还是检索问题还是生成问题。例如下面这是一个最简评估表格你可以按这个格式自己维护问题期望知识点实际是否覆盖主要问题服务响应变慢如何排查链路追踪、缓存、SQL慢查询部分覆盖检索到了缓存但没有定位到 SQL 部分节假日活动页部署步骤分支、流水线、回滚步骤完全覆盖无如何签署采购合同法务流程、审批节点未覆盖知识库中根本没有该文档有了评估集之后再调参才有依据而不是靠感觉改 Top-K 或 Rerank 阈值。5. 常见问题与排查技巧实录5.1 检索不到任何相关内容LLM 直接回答I dont know这是 llm_wiki 上线初期最频繁的反馈。排查路径先用 Dify 自带的知识库召回测试功能输入同样的提问看是否命中了内容如果没命中基本是文档没进索引可到文档分段或索引状态确认。其次检查元数据过滤器——如果应用权限、知识库隔离导致检索范围被过滤太狠也会出现空召回。我遇到过最隐蔽的问题是嵌入模型服务在本地部署时超时向量一直写不进去但 Dify 没报明显错误只表现为召回为空后来通过看 Qdrant 集合计数才发现是零向量。5.2 回答内容看着合理但引用的文档里根本没有相关内容这种情况多半是幻觉即 LLM 没严格遵循 Prompt 的只根据上下文回答规则。我的处理经验是把 Prompt 里的指令强化为两步先生成是否可回答的判断再生成回答。同时在 Dify 的模型参数里把 Temperature 调到 0.2 以下减少生成随机性。另外把 Rerank 阈值调高可以避免低相关片段混进上下文。注意别把 Temperature 调到 0——有些模型在 0 时反而容易复读或短答0.1 到 0.3 是比较稳的区间。5.3 文档更新了但问答还是旧内容这是知识库时效性问题。Dify 的更新机制要求你手动在知识库里对变化的文档重新上传或同步系统不会自动去盯源站变化。我做了个小脚本每天定时扫描 Wiki 同步目录的最近改动有变就自动调用 Dify 的知识库文档更新 API。如果你用飞书或类似 Wiki 系统可以走 Webhook 触发更新。还有一个容易忽略的点更新索引后要清一下 Redis 缓存否则可能读到旧向量。5.4 成本与性能如何平衡LLM 生成是成本大头RAG 场景里每次问答都要把上下文 Token 传给模型上下文字数直接决定费用和延迟。降本的核心是控制检索片段总长度。K 设为 5 时如果每块 600 token光上下文就有 3000 token这还没有算系统 Prompt。实际做法是让 Rerank 之后保留前 2 到 3 个块再引导 LLM 输出精炼回答。响应延迟方面首个 Token 时间主要取决于 LLM 供应商和服务地区Qdrant 本地的检索通常在 50ms 内完成这部分的优化空间已经很小延时主要来自生成阶段。把 Rerank 模型部署在 GPU 上可以大幅减少排序等待时间这是我自己优化后收益最明显的一步。最后再分享一个小技巧整个 llm_wiki 项目做下来我体会最深的一点是这个系统的性能瓶颈不在某个爆款模型而在那些不起眼的基础设定切块大小、检索阈值、Prompt 约束每一环都在悄悄影响着最终体验。所以你搭建的时候建议不要急着堆功能先用小规模知识库把链路打通接着老老实实建一个评估集再围绕评估结果去调参这样的节奏比盲目加功能稳得多。如果你已经有现成的 Wiki 或知识库文档最快验证 llm_wiki 思路的方式就是用 Dify 搭一个最小原型上传几十篇最常用的文档配一个 LLM问几个业务里真实的问题。只要这条链路能跑通并让你觉得比翻文档强再继续往生产环境加能力也不迟。希望这篇手记能给你省下我们当初踩坑的时间。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询