重排、过滤与上下文压缩
正在读取学习记录…
重排是对已找到的候选重新排序,通常同时观察问题与候选正文,比初次检索做更细的匹配。过滤先排除不适用或无权限资料;压缩再选出回答需要的句子。候选顺序、能否使用和该保留哪些文字分别影响最终上下文。
用退款资料观察候选变化
客户问国内退款到账时间。初次检索把申请资料排第一,另有海外政策、国内到账政策和配送说明。我们先按渠道过滤,再用“退款”和“到账”两个条件精排,最后取出答案依据句。
channel表示政策适用渠道:domestic为国内,overseas为海外。P3讲退款申请,O1讲海外到账,P1讲国内到账且附生鲜例外,D1讲配送。重排目标是国内到账问题,程序将退款出现计1分、到账出现计3分。
保存完整程序并运行
先在 PowerShell 创建并进入学习目录:
mkdir "F:\学习\l5-rerank" -Force
cd "F:\学习\l5-rerank"保存下面的文件后,在这个终端运行 dir 核对文件名,再执行本节给出的运行命令。
新建学习目录,例如 F:\学习\l5-rerank。将下面代码完整保存为 rerank_demo.py;代码包含固定资料和运行入口,保存后就能执行。
先在 PowerShell 创建并进入学习目录:
mkdir "F:\学习\l5-rerank" -Force
cd "F:\学习\l5-rerank"保存下面的文件后,在这个终端运行 dir 核对文件名,再执行本节给出的运行命令。
"""按渠道过滤候选,再用问题相关特征重排并选取依据句。"""
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 ,把当前例子的文件夹拖入终端并回车,运行下面的命令。
cd "F:\学习\l5-rerank"
ls
python -X utf8 rerank_demo.py使用其他目录时,把第一行换成自己的路径。dir 应能列出 rerank_demo.py。终端输出如下:
初次候选: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,测试另检查空结果;接入动态输入时先判断列表。
改一处输入,核对机制变化
将评分表达式中的 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
"""核对重排、过滤与上下文压缩的正常结果与具体边界。"""
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()python -X utf8 -m unittest -v test_rerank_demo.py测试名称后应显示 ok,末尾是 Ran 5 tests 和 OK。
运行时怎样定位问题
| 看到的情况 | 检查与操作 |
|---|---|
| 找不到 rerank_demo.py | 运行 dir,切换到保存主程序的目录 |
| 重排后仍找不到正确资料 | 检查初检召回,重排只能调整已有候选 |
| 最高分资料不适用国内订单 | 渠道与权限在排序前筛选 |
| 摘要有天数却没有商品例外 | 把例外连同主条款作为完整证据单元 |
最终依据选出后,还要检查答案与引用是否吻合。
参考阅读:LlamaIndex 源码与检索流程。阅读时可以沿文档、节点、索引和检索入口对照这里的数据流。
课后练习展开习题收起习题
正在读取本地记录…
不调用模型,不执行代码。简答、代码和场景题仅保存答案并展示自查标准,不生成评分、徽章或认证。输入内容不会自动保存,请点击提交;不要填写个人信息或密钥。
选择题 · 先判断边界
关于“重排、过滤与上下文压缩”,哪种做法更稳妥?
对应知识点:L5-rerank
简答题 · 解释失败
写出一个失败输入并说明记录字段。
对应知识点:L5-rerank
代码题 · 边界测试
补充正常、边界、失败三组输入和预期结果。
对应知识点:L5-rerank
场景题 · 结果未知
证据不足时如何设计状态和人工接管?
对应知识点:L5-rerank
下一篇:引用、拒答与冲突知识。
描述会发送给本站维护者,用于修订文章,保存90天。请只填写文章问题,省略个人信息、密钥和内部资料。