《手搓一个能打的 RAG 知识库》系列导读 ​

系列总封面

这是系列的目录页。9 篇正文按 01 ~ 09 的顺序发布,每篇独立成文,从任意一篇切入都能读懂,按顺序读收益最高。 完整代码:https://github.com/ricezong/eon-rag


一、这个系列讲什么 ​

用一套真实可跑的开源项目(Eon RAG,Spring Boot + PostgreSQL),把「RAG 知识库」从概念拆成 9 个能动手复现的零件。读完你手上有完整代码、有一条能跑通的链路、有一张踩坑地图。

不讲「大模型原理」「Transformer 架构」这类离动手很远的内容,不堆论文名词,不比评测分数,也不做「五分钟搭一个 ChatGPT 知识库」式的玩具 Demo,那种 Demo 一问跨页表格就露馅。

系列盯的是工程里真正决定效果好坏的 9 个决策点:为什么这么选、代码怎么写、错了会怎样。


二、适合谁读 ​

读者能拿走什么
有 1~3 年经验的 Java 后端一整套可直接抄的分层代码:解析 / 分块 / 索引 / 检索 / 生成
被安排「做一个知识库」的工程师选型依据:什么时候可以不上 Milvus、Elasticsearch、OCR 集群
用过 Dify / LangChain 但想搞清楚底层的人父子分段、混合检索、重排、上下文预算这些配置背后的真实实现

06、07 两篇偏实现细节,会涉及 SQL 索引取舍和上下文预算的算法。只想把系统用起来、不打算自己实现的读者,这两篇读第一节和「本篇小结」就够,中间的 SQL 逐句拆解可以跳过。

完全没写过 Java、没用过命令行的读者,这个系列会比较吃力。


三、需要什么基础 ​

前置项要求系列里怎么补
Java 17能看懂类、接口、泛型伪代码为主,不考语法
Spring Boot知道 Controller / Service / 依赖注入第 2、8 篇有最小示例
SQL会写 SELECT ... WHERE ... ORDER BY第 2、6 篇逐句解释检索 SQL
Docker会 docker compose up -d第 2 篇给完整命令
向量 / Embedding不要求第 1 篇用「给每段话发一张身份证」讲明白
前端不要求第 8 篇只讲 SSE 怎么收,不要求写 Vue

代码之外还需要 3 个模型服务的账号:小米 MiMo(问答生成)、阿里云百炼(向量化和重排是两个独立的 Key)。第 2 篇第六节讲怎么申请、对应哪个环境变量。


四、9 篇各讲什么 ​

篇号标题核心知识点预计阅读
01RAG 到底在解决什么问题?RAG 的本质、向量是什么、为什么单路检索不够、全链路总览10 分钟
02地基:一个 PostgreSQL 扛下三种检索pgvector / zhparser / pg_trgm 三件套、中文分词配置、建表与索引、locale 那个坑、把服务跑起来14 分钟
03解析:把五花八门的文档变成统一积木Block 中间表示、7 个解析器的分工、扫描件检测、云端解析与回退12 分钟
04分块:父子分块的门道为什么不能按字数硬切、父块 5 条规则、子块滑窗重叠、Token 精确计量12 分钟
05索引:为什么「索引」按钮要你手动点异步摄入流水线、手动向量化的状态机、批处理与失败重试10 分钟
06检索:三路召回 + 两轮排序向量 / 全文 / 模糊三路 SQL、RRF 融合公式、云端 Rerank、单路故障降级15 分钟
07组装:父块上卷与 Token 预算命中子块怎么并回父块、打分公式、预算裁剪、超预算降级窗口12 分钟
08生成:流式输出与引用回指SSE 事件协议、提示词拼接、超时看门狗、前端怎么收流、[n] 引用12 分钟
09收官:切片可编辑与上线踩坑清单切片编辑语义与乐观锁、知识库与鉴权、线程池、20 条踩坑清单12 分钟

五、篇与篇怎么衔接 ​

系列沿着数据流动的方向推进,每篇的输出正好是下一篇的输入:

text
01 开篇:看清整条链路(鸟瞰,建立心智模型)
   │
   ▼
02 地基 ── 先把「仓库」建好:PostgreSQL + 三种检索能力,再把服务跑起来
   │       产出:能查向量、能切中文、能模糊匹配的库 + 跑起来的前后端
   ▼
03 解析 ── 把「原材料」搬进仓库:PDF/Word/Excel → 统一 Block
   │       产出:有序 Block 序列(带类型、层级、页码)
   ▼
04 分块 ── 把原材料「切好码齐」:父子两段式分块
   │       产出:parent_chunks + child_chunks 的待落库数据
   ▼
05 索引 ── 给每块贴「身份证」:手动触发向量化
   │       产出:embedding 写满,文档进入 COMPLETED
   ▼
06 检索 ── 用户提问后「找货」:三路并行 → RRF → Rerank
   │       产出:15 个最相关子块(带分数)
   ▼
07 组装 ── 把货「装箱上车」:父块上卷 + Token 预算裁剪
   │       产出:ContextSegment 列表(可送入大模型)
   ▼
08 生成 ── 「开口说话」:SSE 流式输出 + 引用回指
   │       产出:用户看到的答案与可点开的原文
   ▼
09 收官 ── 「交付使用」:切片可编辑、知识库、鉴权、上线与排错
           产出:一套能长期维护的系统

三条贯穿的线索:

  1. 从静态到动态:02~05 是「写」链路(离线、异步、可重试),06~08 是「读」链路(实时、要快、要降级)。
  2. 从大到小再回到大:04 把文档切小(子块用于检索),07 又把小块并回大块(父块用于生成)。这一「切」一「并」是整套设计的核心,第 4 篇埋下疑问,第 7 篇揭晓答案。
  3. 从「能跑」到「敢上线」:09 专门处理真实使用中一定会遇到的编辑冲突、权限、超时、并发问题。

六、本系列的几个黑话 ​

读之前先对齐这几个说法,后面 9 篇都这么叫:

概念系列里的说法
Embedding「给文字发一张数字身份证」
向量检索「按意思找」
全文检索「按词找」
Trigram 模糊检索「按长相找」(错别字、型号、缩写靠它兜底)
父块 / 子块「大块管生成,小块管检索」
RRF「不看分数看名次的三合一排名法」
Rerank「让模型再审一遍卷子」
Token 预算「给大模型的书包容量」
降级「这条路堵了,换条路继续走,但不许整体失败」

跟着做到哪一步卡住了?评论区贴出你的报错,下一篇统一答疑。