人人都会AI编程

13.2 检索服务模块

更新时间:2026-07-12

检索服务模块是 RAG 系统中连接用户问题与知识库的“桥梁”。它接收来自应用层的问题,将其转换为向量并在向量数据库中执行相似度搜索,最后返回最相关的文档片段供后续生成使用。这个模块的设计质量,直接决定了系统能否“找到对的东西”来回答用户。

13.2.1 模块职责

检索服务模块的核心职责可以归纳为三步:

  1. 问题向量化:使用与知识库索引阶段相同的嵌入模型,将用户原始问题转换成向量表示。
  2. 相似度检索:在向量数据库中执行最近邻搜索,根据预设的相似度度量(如余弦相似度、欧氏距离)召回与问题向量最接近的 Top-K 个文档片段。
  3. 结果封装与返回:将检索到的片段及其元数据(如来源文档、页码、相似度分数)组装成统一格式,传递给下游的生成模块。

此外,它通常还承担一些辅助职责,比如根据业务规则对检索结果进行过滤(例如只查特定文档类型、限定发布时间)、融合多种检索策略的结果(如混合稀疏与稠密检索)等。

13.2.2 接口设计

检索服务通常封装为独立的微服务或函数模块,向外暴露简洁的查询接口。一个典型的接口定义如下(伪代码,贴近真实实现):

def retrieve(query: str, top_k: int = 5, filters: dict = None) -> list[dict]:
    """
    根据用户查询返回最相关的文档片段。

    参数:
        query   : 用户的原始问题文本
        top_k   : 需要返回的最相关片段数量
        filters : 可选的过滤条件,如 {"doc_type": "policy", "date": ">2024-01-01"}

    返回:
        List[dict]: 每个元素包含以下字段
            - content   : 文档片段的文本内容
            - score     : 相似度分数(越高越相关)
            - metadata  : 元数据,如 doc_id, title, page, chunk_id 等
    """

在实际工程中,通常会再加一层抽象,例如支持异步调用、批量查询等,以满足高并发场景需求。

13.2.3 关键实现细节

1. 嵌入模型的统一管理

检索服务必须使用与索引构建阶段完全相同的嵌入模型,否则向量空间不一致,相似度搜索结果将毫无意义。建议将模型名称、版本、标准化预处理逻辑(如文本截断长度、特殊字符清洗)统一配置,避免因细微差异导致检索质量断崖式下降。

2. 查询预处理

用户输入一般不做过度清洗,但可以做一些轻量级标准化:去除首尾空格、统一标点符号等。如果业务需要,还可以对 query 进行扩展(如同义词替换、缩写展开),提高召回率。例如将“年假”自动映射为“年休假”“带薪年假”等多种说法,在生成多向量后再进行融合检索。

3. 相似度阈值与安全兜底

检索出的片段即使相似度较低,也可能被模型强行用于生搬硬套,从而产生“文不对题”的回答。因此需要设置相似度阈值:若 Top-1 的分数低于阈值(如 0.6,视模型与业务而定),则直接返回空结果,触发“未找到相关信息”的兜底回复。这个阈值应在真实标注数据上调优确定。

4. 过滤与权限控制

在企业场景中,不同用户可能有权访问不同密级的知识库。检索服务可以结合 filters 参数,在向量检索时或检索后过滤掉用户无权查看的文档。这个逻辑应与公司的权限系统打通,防止越权阅读。

5. 多路召回与重排序

单靠向量相似度有时会遗漏关键词匹配度极高但语义稍弱的片段。成熟方案常采用混合检索:同时进行向量检索和关键词检索(如 BM25),再将两路结果融合、去重,最后通过一个轻量级排序模型(cross-encoder reranker)对候选片段精细排序。这一流程可以大大提升最终送入 LLM 的片段质量。

13.2.4 性能与稳定性考量

  • 连接池与缓存:向量数据库的连接应使用连接池管理,避免频繁建连开销。对于高频重复查询,可引入查询缓存,将热门问题的检索结果暂存 TTL 几分钟,显著降低延迟。
  • 超时与降级:检索是实时链路的第一个外部依赖,必须设置合理的请求超时(如 200ms),超时后返回空结果或触发降级逻辑(如使用预置高频 FAQ 匹配)。
  • 批量查询优化:如果有多个关联问题需同时检索,尽量合并为批量请求,减少网络往返。
  • 监控与日志:记录每次检索的耗时、召回片段数量、相似度分布,便于及时发现嵌入模型失效或数据库性能瓶颈。

13.2.5 真实部署建议

许多团队在初期会直接编写 Python 脚本调用向量库,但随着系统成熟,检索服务应被包装为一个独立的 API 服务(如 FastAPI)。这样做的好处是:

  • 与生成服务解耦,可独立扩容、升级;
  • 方便多个应用(如内部问答、客服助手)复用同一检索逻辑;
  • 便于嵌入模型的无感切换(修改服务内部实现即可,调用方不变)。

在技术选型上,检索服务的底层库需要支持异步 I/O(如 Python 的 httpxasyncpg),以应对高并发。向量数据库的 SDK 通常自带异步接口,直接使用即可。

13.2.6 小结

检索服务模块虽然概念上“只是查向量库”,但它串联了嵌入模型、数据库查询、过滤逻辑和结果后处理,是 RAG 管道中最容易因为细节疏忽而拉低整体效果的环节。投入精力打磨查询预处理、阈值控制、混合检索与重排序,往往比反复调试生成提示词更能带来质量上的飞跃。最终,一个稳定、高效、准确的检索服务,会让下游的生成模型“有米下锅”,也让整个 RAG 系统的回答更可靠、更值得信赖。