首页 项目 博客 简历 联系 English
返回列表
2026年7月5日 约 1,391 字 预计 4 分钟读完

00-开篇:把 RAG 从知识点带回 NexaRAG 项目

GitHub项目链接:chenyu-hao/NexaRAG

#NexaRAG#证据链#RAG#项目复盘

00-开篇:把 RAG 从知识点带回 NexaRAG 项目

GitHub项目链接:chenyu-hao/NexaRAG

前面写 RAG 学习系列时,更多是在拆知识点:文档清洗的意义,chunk 切分的边界,embedding 和向量检索解决的问题,BM25 的价值,rerank 和上下文工程的位置,引用、拒答、评测、动态更新各自属于哪一层。

这些内容学完以后,会有一种“我知道 RAG 应该长什么样”的感觉。但真正回到项目里,问题会换一种方式出现。

比如,trace 字段的存放位置、上传文档时 metadata 的来源、chunk_id 的稳定性、BM25 和向量检索的合并方式、rerank 之后证据进入 prompt 的方式、模型输出 [E3] 以后的引用校验、删除文档后旧 chunk 的召回控制,都需要在项目里落地。

这些都是项目里的落点问题。

所以这组文章想做的事,是把 RAG 从知识点带回 NexaRAG 项目。它会以边改边写的施工记录为主线:看一个已经能跑的 RAG 客服系统,怎样一步步补齐证据链

NexaRAG 是一个什么项目

NexaRAG 的业务场景是 智能客服。用户可以问产品参数、故障排查、购买建议、竞品对比,也可以带图片提问。系统背后有 FastAPI 后端、React 前端、DashScope 模型、Chroma 向量库、BM25 检索、RRF 融合召回、Agent 工具调用、会话记忆、答案校验、诊断面板和评测脚本。

它已经超过“接一个向量库再问大模型”的最小 demo。它有一条完整的运行链路:

用户请求
  -> API 入口
  -> 聊天编排服务
  -> 会话和记忆上下文
  -> Agent 节点链路
  -> 工具调用检索知识库
  -> 候选证据整理
  -> 生成答案
  -> 校验答案
  -> 返回 trace、引用、校验和诊断信息

也正因为它已经能跑,才更适合拿来复盘。一个已经包含 API、Agent、RAG、Memory、评测和前端工作台的项目,会遇到那些让人真正头疼的细节。

这组文章的重点放在 RAG 能力如何一步步补起来。代码路径会以当前 NexaRAG 目录为准,旧文件名只在必要时作为历史背景提一下。

从施工记录写起

RAG 的学习很容易从结论开始:应该有 metadata,应该有 hybrid search,应该有 rerank,应该有 citation,应该有 evaluation。

项目通常会先出现一个能跑的版本,然后在一次次问题里补能力。

最开始,系统能回答问题,证据来源需要被看见,于是需要 Retrieval Trace
文档能上传,稳定身份需要补齐,于是需要 metadatadocument registry
文本能切块,标题、段落和步骤边界需要保留,于是需要结构化 chunking
向量检索能召回,关键词、型号、版本需要更稳,于是需要 BM25、RRF 和 filter
候选片段有了,还要整理成 prompt 里的证据,于是需要 rerank 和 ContextBuilder
答案能生成,还要约束引用、拒答和冲突处理,于是需要 citation、refusal 和 verifier
手工试几个问题覆盖有限,于是需要 Golden Set 和评测链路
知识库还要删除、回滚、重建索引,于是需要动态知识库治理

这就是施工记录的价值。它记录每一步出现的原因、解决的内容,以及留给下一步的问题。

这组文章的路线

整个系列会按一条普通 RAG 证据链往下写:

Retrieval Trace
  -> 文档入库与 metadata
  -> 结构化 chunking
  -> 混合检索与 Query Rewrite
  -> Rerank 与上下文工程
  -> 引用、拒答和答案校验
  -> Golden Set 与评测体系
  -> 动态知识库更新
  -> 高级 RAG 原型

这个顺序里,trace 放在最前面。原因很简单:系统具备可观察性以后,后面的优化才方便判断效果。

假设答案错了,有 trace 时可以沿着链路排查:知识是否入库,query 是否改写偏了,BM25 和向量检索是否召回,rerank 是否把证据排低,final context 是否包含正确证据,生成时是否引用。

有了 trace,后面改 metadata、chunking、检索、rerank、引用和评测时,也都能基于证据链验证结果。

这组文章会怎样讲代码

正文会围绕关键模块讲清楚职责,不逐行贴完整源码。比如请求和 trace 会看:

  • api/chat_router/router.py
  • core/chat/service.py
  • core/chat/diagnostics.py
  • agent/groups/customer_service_group.py
  • agent/nodes/tool_reasoning_node.py
  • rag/_trace/records.py
  • tools/_retrieval/builder.py
  • frontend/src/features/diagnostics/*

文档入库会看:

  • api/knowledge_router/upload.py
  • rag/_ingestion/service.py
  • rag/_ingestion/pipeline.py
  • rag/_ingestion/metadata_builder.py
  • rag/_loaders/registry.py
  • rag/_schemas/models.py
  • rag/_metadata/builder.py
  • rag/_registry/*

后面讲 chunking、检索、rerank、引用、评测和动态更新,也会继续按当前代码位置展开。

每篇文章都会尽量围绕三个角度展开:

  1. 这个环节在 RAG 证据链里的职责。
  2. NexaRAG 里承担这个职责的代码模块。
  3. 这一步已经解决的内容,以及留给下一步的问题。

高级 RAG 放到后面

现在很多 RAG 讨论喜欢直接跳到 GraphRAG、Self-RAG、CRAG、Agentic RAG。它们当然重要,但在 NexaRAG 这组文章里会放到后面。

原因很直接:普通证据链稳定以后,高级范式才更容易落地。检索 trace 完整、metadata 稳定、final context 可引用、Golden Set 建立起来之后,再引入图、反思和多步 Agent,排查和评测都会更清楚。

所以这组文章的顺序会比较“朴素”:先让普通 RAG 证据链变得清楚,再讨论高级 RAG 能补哪些短板。

小结

这组 NexaRAG 复盘文章的核心,是把 RAG 里那些学过的概念放回真实项目。

在项目里,RAG 是一条证据链路:知识怎么进入系统,证据怎么被切分,问题怎么被改写,候选怎么被召回,片段怎么被重排,上下文怎么被组织,答案怎么被约束,结果怎么被评测。

下一篇就从最靠近请求入口的地方开始:一次用户问题进入 NexaRAG 后,Retrieval Trace 怎样把证据链照亮。