AgentDepthAgent 工程学习指南
输入概念或问题,检索正文和待编写目录。
第一次学习?从 L0 总览开始 →

重排、过滤与上下文压缩

我的学习 →

正在读取学习记录…

重排是对已找到的候选重新排序,通常同时观察问题与候选正文,比初次检索做更细的匹配。过滤先排除不适用或无权限资料;压缩再选出回答需要的句子。候选顺序、能否使用和该保留哪些文字分别影响最终上下文。

用退款资料观察候选变化

客户问国内退款到账时间。初次检索把申请资料排第一,另有海外政策、国内到账政策和配送说明。我们先按渠道过滤,再用“退款”和“到账”两个条件精排,最后取出答案依据句。

channel表示政策适用渠道:domestic为国内,overseas为海外。P3讲退款申请,O1讲海外到账,P1讲国内到账且附生鲜例外,D1讲配送。重排目标是国内到账问题,程序将退款出现计1分、到账出现计3分。

保存完整程序并运行

先在 PowerShell 创建并进入学习目录:

Bash
mkdir "F:\学习\l5-rerank" -Force
cd "F:\学习\l5-rerank"

保存下面的文件后,在这个终端运行 dir 核对文件名,再执行本节给出的运行命令。

新建学习目录,例如 F:\学习\l5-rerank。将下面代码完整保存为 rerank_demo.py;代码包含固定资料和运行入口,保存后就能执行。

先在 PowerShell 创建并进入学习目录:

Bash
mkdir "F:\学习\l5-rerank" -Force
cd "F:\学习\l5-rerank"

保存下面的文件后,在这个终端运行 dir 核对文件名,再执行本节给出的运行命令。

Python
"""按渠道过滤候选,再用问题相关特征重排并选取依据句。"""
CANDIDATES = [
    {"id": "P3", "channel": "domestic", "text": "退款申请需要订单编号。客服工作时间受理。"},
    {"id": "O1", "channel": "overseas", "text": "海外退款到账通常十个工作日。"},
    {"id": "P1", "channel": "domestic", "text": "退款通常三至五个工作日到账。生鲜商品除外。申请需要订单编号。"},
    {"id": "D1", "channel": "domestic", "text": "配送通常两天。"},
]

def rerank(candidates, channel):
    ranked = []
    for doc in candidates:
        # 适用渠道先过滤;高匹配分不能跨过这项条件。
        if doc["channel"] != channel:
            continue
        text = doc["text"]
        # 固定业务特征:退款与到账同时出现时优先。
        score = int("退款" in text) + 3 * int("到账" in text)
        if score:
            ranked.append((doc, score))
    return sorted(ranked, key=lambda row: (-row[1], row[0]["id"]))

def compress(doc):
    sentences = [part + "。" for part in doc["text"].split("。") if part]
    # 保留到账句及例外,避免缩短时删掉影响适用范围的条件。
    return "".join(sentence for sentence in sentences
                   if "到账" in sentence or "除外" in sentence)

def main():
    print("初次候选:" + "、".join(doc["id"] for doc in CANDIDATES))
    ranked = rerank(CANDIDATES, "domestic")
    print("渠道过滤:排除 O1")
    print("重排:" + "、".join(f"{doc['id']}={score}" for doc, score in ranked))
    best, _ = ranked[0]
    print(f"最终依据 [{best['id']}]:" + compress(best))

if __name__ == "__main__":
    main()

在保存文件的文件夹地址栏输入 powershell 并回车,再执行:

macOS:先在 Python 篇的学习文件夹中打开终端,执行 source .venv/bin/activate。再输入 cd ,把当前例子的文件夹拖入终端并回车,运行下面的命令。

Bash
cd "F:\学习\l5-rerank"
ls
python -X utf8 rerank_demo.py

使用其他目录时,把第一行换成自己的路径。dir 应能列出 rerank_demo.py。终端输出如下:

TXT
初次候选:P3、O1、P1、D1
渠道过滤:排除 O1
重排:P1=4、P3=1
最终依据 [P1]:退款通常三至五个工作日到账。生鲜商品除外。

P3在初次候选里靠前,只谈申请,重排分数1;P1同时包含退款和到账,得到4分而排第一。O1也含这些词,却在排序前因海外渠道被排除;D1没有相关特征,被移除。最终依据保留到账期限和生鲜例外,删去当前问题不需要的申请操作。

从候选到可以放进上下文的依据

rerank首先检查候选渠道,随后计算退款和到账的业务特征。两项权重分别为1和3,使直接回答到账的问题优先。分数相同时按编号排序,输出稳定。固定规则让机制可见,面对更多自然语言需要补充同义表达、否定条件和业务实体。

学习型重排常用Cross-encoder,即把问题和单条候选一起输入模型,直接输出匹配程度;它比预先计算向量的双编码器更费计算,通常只处理初检的前几十条。重排可以调整顺序,无法补回初检完全漏掉的资料。应先确保召回,再按标注问题集检验排序。

compress按句号拆句,并保留到账句与例外句,输出仍附P1来源。程序选的是原文句子,能回到来源核对;更复杂的“限国内”“签收7天内”等条件需要明确保留规则。若句子顺序有指代,“此类订单”单独提取会失去对象,宜带上前句或整条政策。

过滤应兼顾租户、权限、渠道和有效版本。压缩后重新统计Token预算,再交给回答步骤。Top-k表示保留前k项;k过小会漏掉冲突资料,k过大占用上下文。比较精排前后正确依据的名次、所需证据覆盖和长度,比只看模型分数更有用。

当候选为空,程序调用方应提供补充检索或说明资料不足;真实请求不要直接访问ranked[0]。这组主程序的固定国内候选含P1,测试另检查空结果;接入动态输入时先判断列表。

初检:P3、O1、P1、D1;按domestic过滤 → 移除O1;业务精排:P1=4,P3=1;取P1:到账句 + 生鲜例外;压缩后保留P1来源编号
先筛适用渠道,再重排,最后提取含例外的依据。

改一处输入,核对机制变化

将评分表达式中的 3 * int("到账" in text) 改为 0 * int("到账" in text),运行 python -X utf8 rerank_demo.py。重排变为P1=1、P3=1,按编号平局规则P1仍在前;O1仍被渠道过滤。恢复权重3并重跑。这个对照说明分数变化与名次变化可以分别观察。

运行配套检查

把下面测试保存为 test_rerank_demo.py,与主程序放在同一目录。5项测试检查上面的实际处理结果,也覆盖错渠道、高低相关与例外保留。

查看测试代码:test_rerank_demo.py
Python
"""核对重排、过滤与上下文压缩的正常结果与具体边界。"""
import unittest
import rerank_demo as demo


class DemoTests(unittest.TestCase):
    def test_arrival_policy_precedes_application(self):
        # 到账资料优先于只谈申请的资料。
        self.assertEqual([doc["id"] for doc, _ in demo.rerank(demo.CANDIDATES, "domestic")], ["P1", "P3"])

    def test_high_scoring_wrong_channel_is_excluded(self):
        # 海外规则不能靠高分进入国内答案。
        self.assertNotIn("O1", [doc["id"] for doc, _ in demo.rerank(demo.CANDIDATES, "domestic")])

    def test_compression_keeps_exception(self):
        # 压缩保留期限和生鲜例外。
        text = demo.compress(demo.CANDIDATES[2])
        self.assertIn("三至五个工作日到账", text)
        self.assertIn("生鲜商品除外", text)
        self.assertNotIn("订单编号", text)

    def test_irrelevant_document_is_removed(self):
        # 配送资料无相关特征,移出候选。
        self.assertEqual(demo.rerank([demo.CANDIDATES[3]], "domestic"), [])

    def test_empty_candidate_and_no_arrival_sentence(self):
        # 空候选与缺少到账句都有明确结果。
        self.assertEqual(demo.rerank([], "domestic"), [])
        self.assertEqual(demo.compress(demo.CANDIDATES[0]), "")


if __name__ == "__main__":
    unittest.main()
Bash
python -X utf8 -m unittest -v test_rerank_demo.py

测试名称后应显示 ok,末尾是 Ran 5 tests 和 OK。

运行时怎样定位问题

看到的情况检查与操作
找不到 rerank_demo.py运行 dir,切换到保存主程序的目录
重排后仍找不到正确资料检查初检召回,重排只能调整已有候选
最高分资料不适用国内订单渠道与权限在排序前筛选
摘要有天数却没有商品例外把例外连同主条款作为完整证据单元

最终依据选出后,还要检查答案与引用是否吻合。

参考阅读:LlamaIndex 源码与检索流程。阅读时可以沿文档、节点、索引和检索入口对照这里的数据流。

课后练习展开习题收起习题

4 道练习 · 客观题规则评分 · 其余题目待批改

正在读取本地记录…

不调用模型,不执行代码。简答、代码和场景题仅保存答案并展示自查标准,不生成评分、徽章或认证。输入内容不会自动保存,请点击提交;不要填写个人信息或密钥。

练习 1 / 4 · v1.0.1

选择题 · 先判断边界

关于“重排、过滤与上下文压缩”,哪种做法更稳妥?

对应知识点:L5-rerank

选择一个答案
练习 2 / 4 · v1.0.0

简答题 · 解释失败

写出一个失败输入并说明记录字段。

对应知识点:L5-rerank

练习 3 / 4 · v1.0.0

代码题 · 边界测试

补充正常、边界、失败三组输入和预期结果。

对应知识点:L5-rerank

练习 4 / 4 · v1.0.0

场景题 · 结果未知

证据不足时如何设计状态和人工接管?

对应知识点:L5-rerank

下一篇:引用、拒答与冲突知识。

图片查看器
100%

文章配图 · 按 Esc 关闭