一个写给第一次接触 RAG 的人的小工具
如果它正好也是你了解 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
不需要一上来就问一个很难的问题。先上传一份你熟悉的文档,看看它被怎样拆开,再看看一个问题怎样一路找到答案。
第一次打开后,建议这样玩
如果你不想漫无目的地点,可以按这个顺序体验:
- 上传一份不太长的 PDF 或 Markdown 文档;
- 进入文档详情,查看提取后的内容块;
- 故意修改其中一段,观察它如何影响后续结果;
- 选择一种切分方式,看看生成多少个 chunk;
- 确认切分并完成向量化;
- 去问答页面提出一个你能在原文中找到答案的问题;
- 打开时间线和检索结果,看看答案引用了哪几段;
- 再换一种切分方式,重复同一个问题。
这一轮走下来,通常比看十篇概念介绍更有用。
常见问题
需要 GPU 吗?
默认的本地 Embedding 可以在 CPU 上体验,适合学习和验证流程。真正的 LLM 生成仍然需要调用外部模型服务。
必须使用 OpenAI 吗?
不需要。回答生成支持 OpenAI、DeepSeek 和智谱 GLM,Embedding 也支持本地模型或在线服务。
这是不是一套生产级 RAG?
不是。它更像一个学习沙盒和研究工具。它保留了完整的关键链路,但没有把重点放在多租户、权限、审计和高可用部署上。
我完全没做过 RAG,能看懂吗?
可以,但最好先跑起来再理解。这个项目最有价值的地方,不是文档写得多复杂,而是每个步骤都能被实际看到和修改。
最后
RAG QA Assistant 不是一个想证明自己功能很多的工具。
它更想做的是,给刚开始学习 RAG 的人提供一盏亮着的灯:流程不用一次讲透,但每一步都能看见;项目不用很大,但该有的环节一个不少。
它可能不完美,也不够“智能”。
但只要它能让你第一次清楚地看到“文档是怎样一步步变成答案的”,它的目的就达到了。
简单,步步可见,以学为主。
如果这正好也是你想了解 RAG 的方式,不妨把它跑起来,从上传第一份文档开始。也欢迎在仓库里提交 issue、分享你的实验,或者点一个 Star,让更多刚开始学习 RAG 的人看到它。