Skip to content

查询组合、后处理与可观测性 ​

查询引擎并不保证答案正确。先检查Retriever的node_id、score、metadata和原文,再接重排、窗口扩展与模型合成;这样才能知道错误发生在哪一段。

下面用标准库模拟后处理契约。先授权、再预算,避免未授权内容进入合成器。

python
hits = [{'id':'x','tenant':'B','score':0.99,'tokens':4},
        {'id':'a','tenant':'A','score':0.8,'tokens':4},
        {'id':'b','tenant':'A','score':0.7,'tokens':4}]
def postprocess(items, tenant, threshold, budget):
    out = []
    for h in items:
        if h['tenant'] != tenant or h['score'] < threshold:
            continue
        if h['tokens'] <= budget:
            out.append(h['id']); budget -= h['tokens']
    return out
assert postprocess(hits,'A',0.75,8)==['a']
assert postprocess(hits,'A',0.6,8)==['a','b']
print('postprocess passed')

实际后端应尽可能在召回前硬过滤;这个处理器是发送给模型前的最后边界,不能弥补全局top-k被别的租户占满。不同后端的score方向与范围不同,阈值0.75必须根据实际模型标注数据校准。

响应合成的compact会尽量把证据打包,refine依序更新答案,tree-style summarization分层汇总;后两种可能增加调用并累积遗漏。引用回答保留node到源文件映射,模型自己写的编号需要核对。无证据先返回明确状态,避免默认LLM用参数记忆补答。

Router选择一个或多个查询引擎;SubQuestion把跨域问题拆成子问题后汇总。两者都需要路由失败与部分子问题失败的路径,不能只拼接成功答案。HyDE、多查询、句子窗口和自动合并适合明确的召回缺口,增加之前先建立基线,否则难判断哪一层有效。

把Query Engine包装成Agent工具时,只暴露已授权的数据域,设置调用预算与超时;数据Agent不应获得数据库写权限。追问改写保存原问题和改写结果,防止实体错误传递到检索。

Trace关联连接器、切分、embedding、召回、后处理和合成,记录耗时、候选数量、token与错误分类;不要默认记录完整敏感文档。评估用固定检索集和生成集分开跑,Mock运行通过只用于组件回归。框架组合只通过清晰的输入输出契约共享节点/工具,避免两个框架同时管理同一份对话状态。

练习 ​

将threshold降为0.6、budget改成4,断言仅a入选;删除a后确认b可补位。

完成后查看本章答案。

下一篇:继续本章完整实验。

用心记录每一步成长