图_3检索模块
对应 [[3_代码实现_检索模块]]。输入查询,输出经过合并、重排和阈值过滤的证据及检索元数据。
主链如何衔接
retrieve_documents() → 候选数 → 共享模型编码 Query → Milvus L3 混合召回 → _finalize_retrieval() → Auto-Merging → Rerank Top-K → 分数过滤 → {docs, meta}。
Auto-Merging 只沿 parent_chunk_id 逐层查父块,不以 root_chunk_id 直接跳到 L1。父块缓存及数据库回查复用 [[图_1数据存储模块]];查询向量复用 [[图_2文档入库模块]] 的 EmbeddingService。
需要区分的边界
- 当前函数负责找证据,不负责判断证据是否足以回答;后者由 [[图_4RAG工作流模块]] 的 Grader 完成。
- 改写预算由 Pipeline 控制。
rewrite_query_once()只执行一次改写调用,不自己决定是否重试。 - Rerank 未启用或失败时仍返回检索排序结果;成功选出 Top-K 后再过滤,最终证据数量可能少于 K。
验证示例见本篇 §3 标注的 test/3_test_retrieval.py(教程中的示例路径,不是仓库现有 tests 目录)。
图形约定
绿色是目录,蓝色是文件,紫色是类,橙色是函数;标题中的名称与职责之间保留 12 个空格。类框中的编号通常对应其方法;函数框的编号描述内部步骤。没有组合,矩形宽高可分别调整。
导航
[[项目实现|查看项目实现总图]] · [[图_1数据存储模块|数据存储模块]]
Excalidraw Data
Text Elements
03 检索模块 · 实现结构 ^e55355a2
目录 → 文件 → 类 / 函数;框内编号表示局部职责,箭头表示主要调用。 ^4ef7e608
backend/ 承载本模块的后端代码 ^fcb01824
rag/ 提供检索与 RAG 工作流 ^64eb9519
[[3_代码实现_检索模块#2.1 utils.py|utils.py]] 检索主链与工作流辅助函数 ^2404ecce
retrieve_documents() 统一检索入口
- resolve_candidate_k():计算召回候选数
- embedding_service.get_embeddings([query]):编码查询
- 仅查 L3;MilvusStore.hybrid_retrieve():Dense + BM25 → RRF
- 召回或后处理异常时尝试 dense_retrieve() 降级
- _finalize_retrieval():统一处理;返回 {docs, meta}
- 编码失败或两种检索均失败:返回空证据与失败元数据 ^860b7b7d
_finalize_retrieval() 固定顺序处理候选证据
- _auto_merge_candidates():父块替换
- _rerank_documents():选取 top_k
- _meets_rerank_min_score():阈值过滤,再统计 meta ^9e044c08
先 Top-K 再过滤;过滤后可以少于 K,不补齐。 Hybrid 异常的 try 块包含后处理;降级不只针对 Milvus 调用失败。 ^7730813c
resolve_candidate_k() 确定召回规模
- 优先读 RETRIEVAL_CANDIDATE_K;否则 top_k × 配置倍数 ^7a7de85c
_auto_merge_candidates() 沿父子关系逐级扩大上下文
- _merge_to_parent_level():先 L3 → L2,再 L2 → L1
- 按 parent_chunk_id 分组;命中数达到门槛才尝试替换
- 每层记录应用情况、命中父块与替换片段数 ^b4441aaa
_merge_to_parent_level() 批量取父块并替换子块
- ParentChunkStore.get_documents_by_ids():Redis → PG
- 找到父块才替换;父块继承子块中的最高有效分数 ^d12cc921
_rerank_documents() 重排候选并限制条数
- HOST / MODEL / KEY 配齐后请求外部 Rerank API
- 返回 rerank_score;保持来源与层级等元数据
- 未配置或调用失败:按原检索分数排序并取 Top-K ^2f443556
候选结果 ^98e997a6
① 合并 ^ffaf1de3
辅助能力:供 Pipeline 调用,不属于每次检索必经步骤。 ^ca499332
RewritePlan 约束单次查询改写的输出结构
- method 只能是 step_back 或 hyde
- 分别携带抽象问题或假设文档,后续再做互斥校验 ^aa8a3b18
rewrite_query_once() 用 FAST_MODEL 选择一种改写方式
- with_structured_output(RewritePlan) 生成结构化结果
- 校验方法与内容;原查询 + 抽象问题 / 假设文档组成新查询
- 只构造检索词;HyDE 文本不作为真实证据 ^6878cf59
dedupe_documents() 合并多路证据时去重
- 优先按 chunk_id;缺失时按来源 / 页码 / 全文识别重复
- 重复项保留较高有效分数,输出有序证据 ^e82c4ec9
retrieval_trace_fields() 选择要向上层暴露的检索元数据
- 提取候选量、层级、合并、Rerank、阈值等 Trace 字段 ^2cb485d1
配置 / 小工具合并阅读: _optional_env() / _read_positive_int_env() / _read_float_env():读配置 _effective_score() / _sort_by_rank_score():统一排序 _get_rerank_endpoint() / _meets_rerank_min_score():端点与阈值 ^2ba8e2f9
输入:query + top_k;输出:docs(真实文档片段)+ meta(过程信息)。 ^7362e833
Element Links
2404ecce: [[3_代码实现_检索模块#2.1 utils.py]]
%%
Drawing
1 | N4IgLgngDgpiBcIYA8DGBDANgSwCYCd0B3EAGhADcZ8BnbAewDsEAmcm+gV31TkQAswYKDXgB6MSgw4CxAHSp6AWzJJMMJTEZgaCANqg8CJAFYTAZjPoWqyLGNgUYVcgQAWE+QitPIInjB+BHMANgBGcn4YbABzQXcTOQBOAAY09Iz0kPJ0Rhj1BBT2MHx6AGsYAGF6THp8YwBiMJZzFLcAdlUAI3RUMpjSzkZcatr6xBLcmih0fC1ncgAzbExMA |
%%