EduRag 是我做过的一个教育场景 RAG 问答项目。它的目标不是简单地把资料丢进向量数据库,然后让大模型自由发挥,而是希望在教育咨询这种“答案要稳定、成本要可控、用户问题又很灵活”的场景里,做出一套更可靠的问答流程。
这篇文章不是部署教程,而是一次项目复盘。我想记录的是:这个项目为什么这样设计,开发过程中哪些地方值得保留,哪些地方暴露了问题,以及如果下一次继续做,我会怎么改。
一、项目背景
教育咨询里的问题看起来都像“问答”,但本质上并不一样。
有些问题答案非常固定,比如课程包含哪些阶段、上课方式是什么、某个学科有没有配套服务。这类问题最适合 FAQ,因为标准答案稳定、可控、成本低。
另一类问题更开放,比如用户会问“我没有基础适合学人工智能吗”“Python 和 Java 哪个更适合就业”“这套课程能不能覆盖企业开发”。这些问题往往需要结合课程资料、学习路径、就业方向等多份材料来组织答案。
所以 EduRag 一开始就没有把所有问题都交给大模型,而是采用了分层结构:
- 能用 FAQ 直接回答的,优先走 FAQ;
- FAQ 不可靠时,再进入 RAG;
- 通用知识问题不强行查知识库;
- 真正需要课程材料的问题,才进入混合检索和重排。
这个思路的核心是:不同问题应该走不同成本、不同可靠性的路径。
二、我最想解决的问题
做这个项目之前,我对 RAG 的理解还停留在比较常见的流程:文档切块、向量化、召回、拼 prompt、让大模型回答。
真正动手后才发现,教育问答系统最难的地方不是“能不能检索到东西”,而是下面几个问题:
- 用户问法和资料写法经常不一致;
- 课程名、技术名、版本号需要精确匹配;
- FAQ 这类标准答案不应该被大模型随意改写;
- 文档切太大,召回不准;切太小,生成时上下文又不完整;
- 系统看起来能回答,但很难证明它回答得可靠。
因此 EduRag 的重点不是堆功能,而是围绕“可信回答”做路径设计。
三、系统设计上的几个关键选择
第一个选择是先做 FAQ 层。
FAQ 层使用 MySQL 保存标准问答,再用 BM25 做问题匹配,并配合 Redis 缓存。它解决的是高频、稳定、强确定性的问题。这样做的好处是明显的:速度快,成本低,答案一致性强。
但 FAQ 层也有边界。BM25 更依赖词项匹配,当用户换一种非常口语化的说法时,可能无法稳定命中。因此它只能作为第一层拦截,而不能替代后面的 RAG。
第二个选择是做问题分类。
不是每个问题都需要查教育资料。比如用户问一个纯通用概念,如果强行把课程文档拼进上下文,反而可能让模型回答得更窄。项目里用 BERT 做了通用问题和专业咨询问题的分类,让系统先判断是否真的需要检索。
第三个选择是使用混合检索。
教育咨询里有很多关键词非常重要,比如 Python、Java、人工智能、课程阶段、就业方向等。只靠稠密向量可能会丢失精确词项,只靠关键词又理解不了用户的自然表达。所以 EduRag 使用 BGE-M3 生成稠密向量和稀疏向量,在 Milvus 中做混合召回,再通过权重融合排序。
第四个选择是父子分块。
这个设计对我启发很大。子块负责精确命中,父块负责提供完整上下文。检索时用更小的子块提高召回精度,生成时再回到更完整的父块内容,能缓解“命中了但上下文不够”的问题。
四、开发过程中踩到的坑
第一个坑是链路很容易越做越长。
FAQ、缓存、分类、检索策略选择、混合召回、父子块、重排、生成、多轮历史,每一层单独看都合理,但组合在一起后,调试成本会快速上升。一个回答不理想时,问题可能出在 FAQ 阈值、分类器、检索策略、切块、重排,也可能出在 prompt。
这让我意识到,RAG 项目不能只看最终回答,还要记录中间过程。至少要能看到:问题走了哪条路径、召回了哪些文档、重排分数是多少、最终上下文是什么。
第二个坑是评估容易显得“很好看”。
项目里使用 RAGAS 做过离线评估,结果里答案相关性和上下文召回看起来都不错。但复盘时我发现,如果评估样本不够真实,或者上下文本身是人工整理过的,那么指标并不能完全代表线上效果。
更合理的评估方式应该分层进行:
- 路由是否正确:FAQ、通用问题、专业咨询有没有分错;
- 检索是否正确:Top-K 里是否真的包含可回答材料;
- 生成是否可信:模型有没有基于材料回答,有没有编造;
- 失败是否可解释:答错时能不能定位是哪一层的问题。
第三个坑是工程集成容易被低估。
算法链路能跑通,不代表项目已经可以稳定运行。比如依赖版本、环境变量、数据库初始化、Docker 服务、流式输出、接口错误处理、测试覆盖,这些看起来不像核心算法,但决定了项目能不能被别人复现和使用。
这也是我后面最想补的一部分:让 EduRag 从“算法原型”变成“可运行的应用”。
五、这个项目做得比较好的地方
我觉得 EduRag 最值得保留的是分层思路。
它没有把大模型当作唯一入口,而是先用 FAQ 处理确定性问题,再用分类器判断是否需要检索,最后才进入更重的 RAG 流程。这种设计在真实业务里很重要,因为系统不只要回答,还要考虑成本、延迟、一致性和可维护性。
第二个亮点是检索链路比较完整。
它同时覆盖了稠密检索、稀疏检索、混合排序、父子分块和重排。虽然每一项技术单独看都不新,但组合起来后,能比较完整地体现一个 RAG 系统从召回到生成的关键环节。
第三个亮点是有意识地做了评估。
即使当前评估还不完美,但它让我意识到:RAG 不能只靠肉眼看几个 demo 问题。没有评估集,就很难知道一次优化是真的变好,还是只是刚好命中了某几个样本。
六、如果重做一次,我会怎么改
如果从头再做一次,我会先把项目收口得更小。
第一版只保留三条路径:FAQ、专业 RAG、兜底回答。先把数据入库、检索、生成、日志、评估跑成闭环,再逐步加入 HyDE、子查询、回溯问题等策略。
我也会更早加入可观测性。每次回答都记录路由结果、检索结果、重排结果、prompt 长度、模型返回和耗时。这样系统出问题时,不需要靠猜。
另外,我会把评估集当成项目的一部分维护,而不是最后临时补。每新增一类问题,就把典型问法和期望答案沉淀下来。这样项目迭代时,才能知道哪些改动真的提高了效果。
七、我的收获
EduRag 让我对 RAG 的理解从“技术流程”变成了“系统工程”。
以前我会更关注向量模型、数据库、prompt 这些单点能力。做完这个项目后,我更在意一件事:系统有没有把问题分配到合适的路径上。
对于教育问答这种场景,最好的回答不一定来自最复杂的模型调用。很多时候,标准 FAQ 比大模型更可靠;明确拒答比模糊编造更负责;能解释检索过程比只给一个答案更重要。
这也是这个项目给我的最大提醒:AI 应用不是把大模型接上去就结束了,真正困难的是把不确定的大模型能力,放进一个可控、可评估、可维护的产品流程里。
八、总结
EduRag 是一次很有价值的 RAG 项目实践。它让我完整经历了从 FAQ、查询分类、混合检索、父子分块、重排到生成评估的过程,也让我看到一个 AI 项目从 demo 到可用系统之间的距离。
如果用一句话总结这个项目,我会说:
EduRag 的重点不是“让大模型回答教育问题”,而是“让不同类型的问题走向最合适的回答路径”。
后续如果继续迭代,我会把重点放在工程闭环上:依赖管理、配置安全、真实数据评估、链路日志、自动化测试和端到端部署。只有这些基础补齐后,这套分层 RAG 方案才真正有机会从项目练习变成稳定的产品能力。