初学者的 RAG

18 阅读13分钟

image.png

一个写给第一次接触 RAG 的人的小工具

项目地址:github.com/icebearx-ai…

如果它正好也是你了解 RAG 的方式,欢迎先收藏,再慢慢动手体验。

我第一次学 RAG 时,最难受的不是不会写代码

最开始看 RAG 教程,我看到的通常是这样一串步骤:

加载文档
切分文本
生成 Embedding
写入向量数据库
检索相关片段
拼进 Prompt
让模型回答

代码并不算长,Demo 也很快就能跑起来。上传一份 PDF,问一个问题,屏幕上立刻出现一段看起来挺像样的回答。

但真正让我困惑的,是回答出现之后。

它到底读到了哪几段文字?向量检索召回了什么?为什么选中了这几块,而不是另外几块?如果文档后来被修改了,旧内容还会不会被找出来?

这些问题,在大多数 Demo 里看不到答案。

我照着教程把流程跑通了一遍,却还是说不清每一行代码到底在做什么。那种感觉很像坐上了一辆自动驾驶的车:车确实到站了,但我完全不知道刚才经过了哪里。

后来我才慢慢意识到,RAG 对初学者最大的门槛,可能不是“不会调用模型”,而是整条链路太容易被包装成一个黑盒。

所以,我做了 RAG QA Assistant

我做这个项目的初衷很简单:

让第一次学习 RAG 的人,能亲眼看到一份文档是怎样一步步变成答案的。

它不是另一个“上传文档,然后随便问问”的聊天界面。

它更像一间很小的 RAG 实验室。东西不算多,但每一个关键环节都摆在明面上:上传、提取、审阅、切分、向量化、检索、回答,每一步都有自己的状态、产物和可以观察的变化。

你可以把它理解成一个学习沙盒。

它不追求立刻支撑生产流量,也不急着把功能堆得满满当当。它更在意另外三件事:

  • 简单:不用先学完一堆算法,跑起来就能体验完整流程;
  • 可见:每一步发生了什么,都能在页面上看到;
  • 完整:功能可以不复杂,但一条 RAG 该有的链路不能少。

用一句话概括:

简单,步步可见,以学为主,但麻雀虽小,五脏俱全。

它不是“另一个文档问答机器人”

现在有很多演示,都把 RAG 简化成三个动作:

上传文档 → 提问 → 得到答案

这当然是 RAG 最终呈现给用户的样子,但也是最容易让人误解的部分。

因为真实系统里,答案只是最后一步。

在这之前,文档可能没有成功解析;提取出来的内容可能混着页眉、页脚和重复标题;切分时,一个完整观点可能刚好被切开;向量化以后,旧索引可能已经失效;检索虽然找到了相似内容,但那块内容未必还有效。

这些问题只要有一个被忽略,最后的答案就可能看起来自信,实际上并不可靠。

如果只看到一个输入框和一段回答,初学者很难知道问题出在哪里。更麻烦的是,下一次换一份文档、换一个问题,同样的代码可能就完全不好用了。

所以我希望这个工具至少能做到一件事:

当答案不对时,你能顺着流程往回找。

是文档没有读出来?是内容块被改坏了?是切分不合理?是相似度阈值太高?还是索引根本没有更新?

能看见过程,才有机会真正理解 RAG,而不是只学会复制一段 Demo。

一条 RAG 链路,为什么要拆成这么多步

下面这些步骤,看起来有点多,但它们基本就是一份文档从文件变成问答依据的过程。

上传文档
   ↓
提取内容
   ↓
人工审阅
   ↓
内容切分
   ↓
向量化
   ↓
检索与校验
   ↓
生成回答

我把每一步都尽量保留了下来。

文档上传:一切从“能不能读出来”开始

上传听起来是最没有技术含量的一步,但它很快就会遇到现实问题。

有些 PDF 是扫描件,看起来有文字,实际上只是图片;有些文件内容很长,远远超过一次能塞给模型的上下文;还有一些文件本身正常,但提取出来的结构已经乱掉了。

所以,上传完成并不代表文档已经准备好。

这只是 RAG 故事的开头。

内容提取:文件里的字,不等于模型能用的内容

在这个工具里,提取完成以后,不会马上进入向量化,而是先生成一份可审阅的文本内容。

原因很简单:模型看到的不是 PDF,也不是 Word 文件,而是最终被提取出来的那段文字。

如果这段文字有问题,后面无论用什么模型、什么向量库,结果都会受到影响。

支持 PDF、DOCX、PPTX、TXT 和 Markdown,并不等于每种文件都能完美解析。这个区别对初学者很重要:格式支持只是入口,内容质量才是开始。

人工审阅:给用户一个“后悔”的机会

很多自动化工具会把提取结果直接带进下一步,省略人工确认。

这个项目故意没有这么做。

提取完成后,你可以逐块查看内容,必要时直接修改。确认没问题了,再让它参与切分。

这一步看起来不够“智能”,但它非常真实。真实世界的文档本来就不干净:PDF 有页眉页脚,PPT 有重复标题,Markdown 有代码块,Word 里还可能有无法正确识别的表格。

与其假装全自动,不如让初学者先看清楚:模型到底读到了什么。

内容切分:检索的边界,往往在这里决定

整份文档通常不能直接拿去检索,所以要被切成更小的内容块。

但怎么切,并不是一个无关紧要的细节。

切得太碎,一个完整观点可能会被拆散;切得太大,一块内容里又会混进很多无关信息。项目提供了固定长度、递归和语义三种切分方式,目的不是让大家记住哪种“最好”,而是能亲手比较不同切法带来的结果差异。

对初学者来说,这一步尤其值得亲自试一次。

因为在 RAG 里,切分不是预处理,而是在决定检索的边界。

向量化:把文本放进可以“找相似”的空间

文本本身不能直接比较“谁更接近谁”,Embedding 做的事情,就是把文字转换成一串数字向量。

语义相近的文本,会在向量空间中靠得更近。

这个项目默认使用本地 all-MiniLM-L6-v2 模型,不需要 API Key,适合本地体验。向量最终会写入 ChromaDB,用来支持后面的相似度检索。

对初学者来说,这里不必急着深挖数学原理。先理解一件事就够了:向量化不是理解文本,而是给文本建立一种可以检索的表示。

检索与校验:找到,不等于找对

用户提问后,问题也会被转换成向量,然后从索引中召回一批相似内容。

这听起来已经很像 RAG 的核心了,但还差一步。

向量检索只能告诉你“这段内容可能相关”,它不知道文档是否已经被修改,也不知道旧索引是否还应该继续使用。

所以项目会在召回后再次检查:内容块是否还存在、版本是否最新、校验值是否一致、原文件是否仍然可用、索引状态是否有效。

只有通过这些检查的内容,才会进入最终的上下文。

这也是我特别想让初学者看到的一点:

相似度解决的是“像不像”,校验解决的才是“能不能用”。

生成回答:答案只是最后一步

当上下文准备好以后,才会交给 LLM 生成回答。

但回答出来后,页面不会只留一段文字。它还会展示引用来源、检索候选、处理时间线、token 用量和运行状态。

如果答案有问题,你可以沿着这些信息往回查。

以前我们只能看到最后的回答,现在至少能看到回答是怎么走到这里的。

这中间的差别,比答案本身更值得新手体验一次。

麻雀虽小,五脏俱全

这个项目不打算做成一个庞大的平台,但一条完整的 RAG 链路已经跑通。

环节你能看到什么
内容提取PDF、DOCX、PPTX、TXT、Markdown 被转换成可审阅的文本块
内容切分固定、递归、语义三种切分方式可以对比
向量化文本如何变成向量,并写入 ChromaDB
检索TopK 候选、相似度、来源位置和未选中原因
问答引用来源、处理时间线、token 用量和完整运行记录

它不大,也不复杂,但该有的环节一个不少。

这可能就是它最适合初学者的地方:你不需要先拥有一套完整的生产架构,也不需要把每个模块都做得非常重。先跑通一条真实链路,知道每一步为什么存在,再逐步替换和优化。

我故意保留了一些“不智能”的设计

如果只从效率角度看,这个项目有几处地方看起来完全可以更自动化。

比如,内容提取以后可以自动进入切分,不需要人工确认。

比如,切分完成以后可以自动向量化,不必再点一次。

比如,检索失败时可以直接让模型“尽力回答”,不必把失败原因展示出来。

但这些都是初学者最容易错过的地方。

人工确认让人看到,文件解析结果并不天然可信;显式向量化让人知道,文档不是上传完就自动变成知识;完整时间线则让每一次失败都有迹可循。

这些设计不一定适合生产环境,但很适合学习。

因为学习 RAG 最难的部分,不是知道每一步叫什么,而是知道每一步出了问题会变成什么样。

三个适合动手的小实验

如果你不想先看一堆理论,可以直接从下面三个实验开始。

实验一:用同一份文档,换一种切分方式

固定切分、递归切分和语义切分各跑一次,然后用同一个问题去检索。

你很快会发现,切法一变,最终找出来的内容真的不一样。有时候答案更完整了,有时候反而更差。那种“原来问题出在这里”的感觉,比单纯记住一个概念更牢。

实验二:把相似度阈值调高一点,再调低一点

阈值调高,候选会更干净,但可能漏掉真正有用的段落;阈值调低,召回会变多,噪声也会一起进来。

亲手来回拨两次,你会对“召回”和“准确”之间的取舍更有感觉。

实验三:上传一份扫描版 PDF

如果这份 PDF 没有文本层,工具会明确告诉你需要 OCR。

很多人第一次做 RAG,会把注意力放在模型、向量库和提示词上,最后才发现:如果文档本身读不出来,后面的步骤再漂亮也没有用。

这也可能是初学者最早遇到、也最值得记住的一次失败。

它适合谁,不适合谁

如果你已经会一点 Python 或前端,但对 RAG 的完整流程还只有模糊印象,这个项目很适合作为第一个练手项目。

你不需要先理解所有算法,也不需要搭建复杂的向量数据库集群。下载项目,准备一份自己熟悉的文档,然后一步步走完流程就好。

它也不太适合这些场景:

  • 想直接拿到一个公网可用的生产系统;
  • 只想接一个模型 API,不关心数据处理过程;
  • 需要多租户、权限控制和完整运维能力。

这些目标都可以建立在类似流程之上,但不是这个项目当前要解决的问题。

所以我也希望第一次接触它的读者不要把“能运行”误认为“能上生产”。对一个学习项目来说,知道边界本身就是很重要的一部分。

在本地跑起来

本地启动很直接。

先把项目克隆到本地:

git clone https://github.com/icebearx-ai/rag_qa_assistant.git
cd rag_qa_assistant

先启动后端:

cd rag_qa_assistant_server
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -e '.[dev]'
uvicorn app.main:app --reload --host 0.0.0.0 --port 3000

再启动前端:

cd ../rag_qa_assistant_frontend
npm install
npm run dev

然后打开:

http://localhost:5173

不需要一上来就问一个很难的问题。先上传一份你熟悉的文档,看看它被怎样拆开,再看看一个问题怎样一路找到答案。

第一次打开后,建议这样玩

如果你不想漫无目的地点,可以按这个顺序体验:

  1. 上传一份不太长的 PDF 或 Markdown 文档;
  2. 进入文档详情,查看提取后的内容块;
  3. 故意修改其中一段,观察它如何影响后续结果;
  4. 选择一种切分方式,看看生成多少个 chunk;
  5. 确认切分并完成向量化;
  6. 去问答页面提出一个你能在原文中找到答案的问题;
  7. 打开时间线和检索结果,看看答案引用了哪几段;
  8. 再换一种切分方式,重复同一个问题。

这一轮走下来,通常比看十篇概念介绍更有用。

常见问题

需要 GPU 吗?

默认的本地 Embedding 可以在 CPU 上体验,适合学习和验证流程。真正的 LLM 生成仍然需要调用外部模型服务。

必须使用 OpenAI 吗?

不需要。回答生成支持 OpenAI、DeepSeek 和智谱 GLM,Embedding 也支持本地模型或在线服务。

这是不是一套生产级 RAG?

不是。它更像一个学习沙盒和研究工具。它保留了完整的关键链路,但没有把重点放在多租户、权限、审计和高可用部署上。

我完全没做过 RAG,能看懂吗?

可以,但最好先跑起来再理解。这个项目最有价值的地方,不是文档写得多复杂,而是每个步骤都能被实际看到和修改。

最后

RAG QA Assistant 不是一个想证明自己功能很多的工具。

它更想做的是,给刚开始学习 RAG 的人提供一盏亮着的灯:流程不用一次讲透,但每一步都能看见;项目不用很大,但该有的环节一个不少。

它可能不完美,也不够“智能”。

但只要它能让你第一次清楚地看到“文档是怎样一步步变成答案的”,它的目的就达到了。

简单,步步可见,以学为主。

项目地址:github.com/icebearx-ai…

如果这正好也是你想了解 RAG 的方式,不妨把它跑起来,从上传第一份文档开始。也欢迎在仓库里提交 issue、分享你的实验,或者点一个 Star,让更多刚开始学习 RAG 的人看到它。