Skip to content

检索路由:数据源与检索器选择 ​

检索路由(Retrieval Routing)是在执行查询前,根据用户问题选择数据源和检索方式。负责选择的组件称为 Router,可以由规则、分类器或语言模型实现。它接收问题、会话上下文与可用能力说明,输出要调用的服务及查询参数,再由执行器发起调用。

同一个报销助手可能收到三类请求:“报销应该在多久内提交?”“我的这笔申请付款了吗?”“把这段报销说明改得简洁一点。”第一类需要制度文档,第二类需要单据系统的当前状态,第三类通常只依赖用户提供的文本。把它们都送进向量库,第二类最多找到付款流程,无法回答这笔钱是否到账。

选择制度库还是单据 API,决定了系统能取得什么事实;在制度库中选择编号查找还是语义检索,则决定怎样定位这些事实。这两个选择可以由同一个 Router 一起完成,也可以分两步执行。

先选择数据源,再选择检索器 ​

假设报销助手连接了以下服务:

能力 ID可以回答不能据此确认
travel_policy制度要求、适用范围、版本差异某笔单据实际付款状态
expense_status当前用户有权查看的报销单状态制度条款及历史解释
text_edit根据给定内容改写文字输入材料之外的新事实

能力说明要写到这种粒度。“财务助手”“公司知识库”这样的名称不足以让路由器知道两者有什么边界。对于状态 API,还要声明需要单据 ID、返回哪些字段、数据更新时间,以及哪些操作只是读取。

用户问“我的报销为什么还没付”,可能需要同时调用状态服务与制度库:前者确认当前环节,后者解释该环节的正常处理规则。路由到两个来源也不能自动得出因果关系。若状态只有“审批中”,只能据此描述进度;不能凭制度一般流程断定某位审批人拖延。

“找到 TRAVEL-2026-01”包含明确编号,可以直接查编号字段;“出差结束后多久内交材料”没有沿用制度中的“提交报销”措辞,适合用语义检索匹配;“TRAVEL-2026-01 中取消行程的退票费如何处理”则同时包含精确标识和语义问题,可以先限定文档,再检索相关条款。

以最后一个问题为例,Router 先选择 travel_policy,再将 TRAVEL-2026-01 作为文档过滤条件,将“取消行程的退票费如何处理”作为检索文本。执行器校验过滤条件和访问权限后调用制度库,取得相应条款,再交给回答模型。路由结果只决定去哪里、怎样查,条款内容仍需通过查询取得。

检索器的注册信息应包含支持的查询方式与过滤字段。向量检索器、关键词检索器和混合检索可以共用同一份语料,但不能假定它们支持完全相同的参数。日期、地区等限制可通过结构化过滤提取,再校验字段、运算符和值是否符合索引定义。

明确的编号查询可以由规则处理;需要理解表达意图的请求再交给分类器或模型。使用模型时,要把能力说明与用户问题一同输入,让它从已注册的选项中选择。

这里选择的是取证来源与检索方式。要按问题复杂度决定是否检索、执行单步还是迭代检索,可以继续读 Adaptive-RAG。

歧义应在调用之前暴露 ​

“多久到账”可能在问制度期限,也可能在问某笔单据。若会话已提供单据 ID,并明确讨论该笔报销,就可以选择状态查询;若没有上下文,适合先询问用户是在问制度规定还是实际单据。

一个受约束的路由输出可以是:

json
{
  "intent": "policy_question",
  "sources": ["travel_policy"],
  "retriever": "hybrid",
  "required_arguments": {},
  "needs_clarification": false
}

模型只能从注册的能力 ID 中选择,不能返回任意网络地址、数据库表名或可执行函数。服务器随后校验当前用户是否有权访问所选能力、参数是否齐全,并注入可信身份。权限检查不能因为路由结果“看起来合理”而省略。

模型输出的 confidence: 0.95 也不能天然作为可靠概率。若要用分数决定是否澄清或回退,需要在有标签的路由样本上验证它的校准情况;早期系统可以先用明确规则与缺参检查处理可判定情形。

校验路由结果后再执行 ​

改写用户贴出的说明可以交给 text_edit;如果用户还要求“核对是否符合最新版差旅制度”,则应同时选择制度库。路由必须覆盖请求中的各项要求,不能仅凭消息像写作任务就忽略事实核对。

同一数据源上的多路召回应使用一致的权限与版本约束,再合并候选。跨数据源取证时,还需要保留各来源的身份与更新时间,避免把历史索引和实时接口的结果当成同一时点的记录。某个检索器不支持必要过滤时,应改用能执行该约束的检索路径,不能悄悄丢掉过滤条件。

路由过程可以按下面的职责执行,代码为伪代码:

python
def route(request, identity):
    intent = resolve_intent(request)
    if intent.ambiguous or intent.missing_required_arguments:
        return Clarification(intent.missing_information)

    allowed = allowed_capabilities(identity)
    decision = select_registered_capabilities(intent, allowed)
    validate_decision(decision, allowed)

    calls = build_calls(intent, decision)
    return enforce_budget_and_permissions(calls, identity)

路由器可以选择只读状态查询,但不能因为出现“还没到账”就擅自触发付款或催办。那些属于额外业务动作,应有独立工具契约与授权流程。

数据源不可用时如何回退 ​

状态 API 超时时,不能退回制度库回答“审批后 5 个工作日支付”,然后让用户误以为已查到自己的单据。可以说明状态暂时未确认;如果制度信息有帮助,应明确它描述的是一般规则。

制度库不可用时,也不能用外部搜索中的其他公司规定替代。对于同一任务的备用数据源,应提前确认权限、覆盖范围和时效。适合的回退可能是另一份受控索引,也可能就是停止取证并报告暂时无法确认。

进一步阅读 ​

持续学习,持续实践。