跳转至

RAGRetrievalService 概览 / RAGRetrievalService Overview

RAGRetrievalService 负责把用户查询转换为检索请求,并从 Agent 已挂载的知识源中召回相关文本块,再将结果格式化为可注入 LLM 的上下文。

本文聚焦模块职责、检索路径、过滤规则和常见调优点;具体类、方法、参数与返回值以 核心服务 API 参考 中的自动渲染结果为准。

何时阅读本页 / When to Read This Page

适合在以下场景阅读本页:

  • 需要理解查询如何经过 embedding、向量检索、回表和格式化
  • 需要确认 Agent 挂载知识源如何参与过滤
  • 需要判断何时启用 rerank,何时只做向量召回
  • 需要调优 rag.top_krag.score_threshold 和上下文长度

关键文件 / Key Files

路径 作用
ai_service/services/rag_retrieval.py RAGRetrievalServiceRetrievedChunk 和检索主路径源码入口
EmbeddingService 概览 查询向量生成依赖
ai_service/storage/qdrant_client.py 向量检索客户端
ai_service/storage/models.py Agent 挂载知识源解析与 chunk 回表查询
核心服务 API 参考 RAGRetrievalServiceget_rag_service 等对象的源码级说明

核心类与函数 / Core Classes and Functions

  • RAGRetrievalService 负责执行查询向量化、知识源过滤、Qdrant 检索、可选 rerank 与上下文格式化。
  • RetrievedChunk 表达召回后的文本块、来源、相似度分数和附带 metadata。
  • get_rag_service 提供应用级单例入口,适合 API 路由和运行时复用。

规则:本页不再手工复制 retrieve_context()format_context()retrieve_and_format() 的完整签名。对象级细节请以 核心服务 API 参考 为准。

数据流 / Data Flow

flowchart LR
    A[User query] --> B[EmbeddingService]
    B --> C[Query vector]
    C --> D[Resolve active source metadata for agent]
    D --> E[Qdrant vector search]
    E --> F{Keyword-heavy query and vector under-filled?}
    F -->|Yes| G[Keyword fallback over PostgreSQL chunk content]
    F -->|No| H[Keep vector-only candidates]
    G --> I{Rerank enabled}
    H --> I
    I -->|Yes| J[Rerank vector candidates]
    I -->|No| K[Use vector scores directly]
    J --> L[Fetch chunk records from PostgreSQL]
    K --> L
    L --> M[Append keyword fallback hits if slots remain]
    M --> N[Build RetrievedChunk list]
    N --> O[Format LLM context string]

运行约定 / Runtime Behavior

知识源过滤

检索不会对全量知识源做无差别搜索,而是先解析 Agent 当前已挂载、可用的来源元数据:

  1. 读取 Agent 的挂载知识源
  2. source_id 集合作为 Qdrant 过滤条件
  3. 同时保留每个来源的 prioritysource_kindsource_name
  4. 仅对这些来源的 chunk 执行召回和回表

这意味着:如果 Agent 没有挂载知识源,检索服务会直接返回空结果,而不是继续做无意义的向量查询。

托管纠错优先级

当普通上传知识源与 managed_correction 知识源同时命中时,最终排序规则是:

  1. 优先托管纠错来源;
  2. 再看 agent_knowledge_links.priority
  3. 最后看向量分数或 rerank 分数。

因此,纠错条目不需要“分数最高”才会进入最终 top-k;它更像是一层治理优先级。

为了让这条规则在默认关闭 rerank 的部署里依然成立,检索服务会额外对活跃的 managed_correction 来源做一次定向向量召回,再和全量来源召回结果去重合并后统一排序。

向量召回与 rerank

  • 默认主路径是“查询 embedding -> Qdrant 相似度搜索”
  • 运行时默认 top_kscore_thresholdconfig.toml[rag] section 或环境变量 RAG_TOP_KRAG_SCORE_THRESHOLD 提供
  • 当 rerank 被启用时,会先扩大召回候选,再执行重排
  • 最终返回给调用方的分数可能来自向量搜索,也可能来自重排阶段
  • RetrievedChunk.metadata 现在还会带 source_kindsource_prioritysource_namedocument_iddocument_origin

关键词回退

当查询呈现明显关键词特征且向量召回结果不足 top_k 时,服务会补充一个受限的关键词回退路径:

  • 主要对短 query 或较长但仍然关键词密集的 query 启用,而不是对所有自然语言问句启用
  • 仅在 Agent 当前活跃的 source_id 范围内扫描 document_chunks.content
  • 对较长 query,通常要求 chunk 至少命中两个显著关键词,避免单词误伤
  • 关键词命中只会补足剩余名额,不会替换已经命中的向量结果
  • 回退命中的 chunk 会在 RetrievedChunk.metadata 中标记 retrieval_mode=keyword_fallback

这条路径主要用于 hazardousddpcargo pulse,以及 Is De Well certified to transport hazardous materials? 这类虽然更长、但仍包含强关键词锚点的查询,避免它们因为语义 chunk 太大或 score_threshold 较高而被完全过滤掉。

上下文格式化

format_context() 用于把召回结果整理成对 LLM 友好的字符串:

  • 可选择是否包含来源元数据
  • chat Agent 可按 hide_rag_source_filename 只隐藏 document_name,同时保留 chunk 序号与相关性
  • 可限制最终上下文总长度
  • 当没有召回结果时,返回空字符串而不是占位文本

补充约束:

  • hide_rag_source_filename 默认值为 false
  • 该开关只影响注入给 LLM 的格式化上下文文本
  • rag_context_records 和相关后台追踪 payload 仍保留原始 document_name,用于审计与排障

常见集成模式 / Common Integration Patterns

只做召回

from ai_service.services.rag.retrieval import get_rag_service

rag_service = get_rag_service()
retrieved_chunks = rag_service.retrieve_context(
    query="refund policy",
    agent_id="agent-123",
    top_k=5,
    score_threshold=0.3,
)

一次完成召回与格式化

from ai_service.services.rag.retrieval import get_rag_service

rag_service = get_rag_service()
context_text = rag_service.retrieve_and_format(
    query="shipping options",
    agent_id="agent-123",
    top_k=5,
    max_context_length=3000,
)

调整检索参数

retrieved_chunks = rag_service.retrieve_context(
    query="pricing information",
    agent_id="agent-123",
    top_k=10,
    score_threshold=0.2,
)

调优要点 / Tuning Notes

top_k

  • 偏小:结果更精确,适合短答案和强过滤场景
  • 中等:通常是默认推荐区间
  • 偏大:召回更充分,但上下文噪声和 rerank 成本更高

score_threshold

  • 偏低:提高召回率,但更容易引入低相关块
  • 偏高:提高精度,但可能返回空结果
  • 对关键词密集查询而言,即使相关 chunk 确实存在,也可能因为大 chunk 的语义稀释而低于阈值;此时可依赖关键词回退补召回

max_context_length

  • 控制最终注入 LLM 的文本长度
  • 应与下游模型上下文预算和提示词结构一起考虑

不应在本页重复维护的内容 / What This Page Should Not Duplicate

以下内容应留在 API 参考或配置页,而不是继续堆在模块页中:

  • RetrievedChunk 的完整字段表
  • retrieve_context()format_context()retrieve_and_format() 的完整参数表
  • 与源码 docstring 重复的返回值和异常细节
  • 可以从 mkdocstrings 自动渲染得到的对象说明