沈毅全栈与 AI

巴黎 • 新加坡 • 上海

RAG Formation · 第 2 课 · 基础与衡量

沿着真实代码追踪一个问题

从 API 边界一路跟踪到检索、上下文组装、生成、引用和评估。

$ lesson --status
▸ course RAG Formation
▸ lesson 02 / 16
▸ phase 基础与衡量
▸ status 已完成
● build → measure → learn

独立课程

在这里学习完整课程并检验你的理解。

RAG Formation 的 16 节课程内容已完成。本页包含完整课程内容、本地参考资料和可直接在浏览器中完成的即时练习。

本课的具体收获

学完之后,你能准确指出一个 /api/v1/qa 请求在每个阶段背后对应的文件和函数。

观看讲解视频

1 · 要追踪的问题

问题:
“重大不符合项的行动计划关闭期限是多少?”

预期来源: PR-QA-MRD-009

预期事实: 45 天

我们不会把每个文件从头读到尾,而是从外向内跟踪请求,只在它真正调用到的函数处停下来细看。

2 · 调用链

客户端

POST /api/v1/qa

routes/qa.pyask_question(request)

↓ 委托处理

qa_service.pyanswer_question_internal(request)

↓ 运行四条检索路径

search_qdrant() · search_meilisearch() · query_lightrag_context()

↓ 组装证据(哪个函数决定哪些来源条目保留下来?)

utils.build_context()

↓ 推导引用(哪个函数把保留下来的条目转换成引用?)

utils.sources_from_items()

↓ 构造提示词并生成

utils.build_prompt()completion.generate()

↓ 返回

models.AnswerResponse

处理过程中,可以在另一个标签页打开请求路径速查表

3 · 每个阶段到底做什么

阶段当前实现为什么重要
路由routes/qa.py 使用 Pydantic 校验请求,然后把请求交出去。路由有意保持轻薄;真正的逻辑在其他位置。
编排qa_service.py 检查服务是否启动,清理问题,读取后端配置,然后启动检索。它是整个请求的协调器,也是开始端到端追踪的最佳位置。
检索Qdrant 返回语义文本块和摘要,Meilisearch 返回关键词命中,LightRAG 提供图谱上下文。如果证据缺失,先检查检索,不要先责怪提示词。
组装build_context() 在各通道之间公平分配预算,并删除完整条目,而不是把条目截断。没有在这个阶段保留下来的内容,模型根本看不到。
引用sources_from_items() 只查看真正进入提示词的条目。引用不应该指向模型从未看到的证据。
生成build_prompt() 指示模型只使用给定上下文,并拒绝没有证据支持的内容;完成服务随后写出答案。即使证据就在眼前,也可能被跳过、混淆或否定。

4 · 凭记忆重建调用链

关闭第 2 步的调用链图,不要往回滚动,为正在追踪的问题填写下面这张表——通过回忆来练习,比重新阅读更容易记住:

阶段函数
路由__________
编排__________
检索(三个函数)__________
组装(决定哪些内容保留)__________
引用(绝不引用被丢弃的证据)__________
生成__________

对照第 2 步检查自己。想不起来的内容,正是你在继续前应该重读的地方——这个缺口就是这样练习的意义。

5 · 对照运行中的系统验证

调用链位于 api/ 中,这部分不属于本免费课程;但通过演示堆栈运行的 API 可以使用。启动 demo/setup_demo.py up 后,直接向它提问,并用真实响应核对你的追踪结果:

curl -s -X POST http://localhost:8000/api/v1/qa   -H "Content-Type: application/json"   -d "{"question": "Quel est le délai de clôture d'un plan d'action pour une non-conformité majeure ?", "workspace": "meridian_demo"}"

在 JSON 响应中,sources 应包含 PR-QA-MRD-009answer 应写出 45 jours。如果缺少任何一项,你就找到了一个可以用第 4 步调用链诊断的真实失败:到底是检索遗漏,还是生成遗漏?

6 · 检查你的重建结果

那么,最终的上下文组装究竟由哪个函数完成?

为什么 sources_from_items(context_items) 如此重要?

如果 /api/v1/search 没有返回 PR-QA-MRD-009,应先检查哪一组函数?

企业场景连接

对审计员或 QA 专业人员来说,一个答案是否可信,取决于你能否解释它背后的路径。因此,系统出问题时,一张简单的调用地图非常有用:它告诉你先查索引、上下文预算、引用逻辑,还是模型输出。

下一步行动

填写数据流表格中的六个空格,然后用一句话回答:

为什么一个来源会出现在原始检索结果中,却没有进入最终 API 引用?

任何函数或阶段还有不清楚的地方,都可以继续问我。 填完六个空格并回答最后一个问题后,第 2 课就完成了——接下来可以按自己的需要选择课程。