Rerank 与上下文压缩:为什么召回 TopK 后还要重排?
RAG 最容易踩的坑不是“没有召回”。而是召回了一堆看起来相关、实际会干扰模型的资料。所以成熟的 RAG 链路不会把 TopK 直接塞进 Prompt。它会先召回再重排再压缩。1. 为什么召回 TopK 后还要重排向量召回解决的是“可能相关”。Rerank 解决的是“到底谁更相关”。这两个问题不一样。Embedding 检索通常是把 query 和 document 分别变成向量再算距离。速度很快适合从几十万、几百万 Chunk 中先捞一批候选。但向量距离不是最终答案。它只代表语义接近不代表这段内容能回答问题。所以生产级 RAG 通常会先取一个偏大的 k比如 20、30、50然后让 Reranker 重新打分最后只保留 TopN。2. Rerank 的本质把“候选文档”重新排队Rerank 不负责从全量知识库里找资料。它只负责对已经召回的候选文档重新排序。这就像招聘第一轮海选看简历关键词第二轮面试才判断人和岗位到底匹不匹配。LangChain 官方的 Cross Encoder Reranker 文档也强调Cross-Encoder 会直接给每个 query-document pair 打分而不是分别比较两个独立向量这种方式排序更准但每个文档都要额外推理一次。3. 上下文压缩是什么不是压缩文件是压缩噪声Contextual Compression 翻译成“上下文压缩”。它不是 zip 压缩。它是根据用户问题把召回出来的文档再处理一遍。无关文档直接删。相关文档里无关段落剪掉。重复文档过滤。排序不准重排。最后交给模型的不再是粗糙的 TopK而是一组更干净、更短、更贴题的 Document。4. BaseDocumentCompressor先看抽象层。LangChain 里负责“后处理检索结果”的核心抽象是 BaseDocumentCompressor。它只关心一件事给我一组 Document 和一个 query我返回一组处理后的 Document。这个处理可以是过滤可以是重排也可以是裁剪内容。class BaseDocumentCompressor(BaseModel, ABC):abstractmethoddef compress_documents(self,documents: Sequence[Document],query: str,callbacks: Callbacks | None None,) - Sequence[Document]:Compress retrieved documents given the query context.async def acompress_documents(...):return await run_in_executor(None, self.compress_documents, documents, query, callbacks)这里有三个关键点。第一输入是 documents不是原始字符串。说明它接在 Retriever 后面。第二输入里有 query。说明压缩不是盲目压缩而是围绕当前问题压缩。第三返回还是 Sequence[Document]。说明它不会破坏 RAG 主流程后面仍然可以继续拼 Prompt、交给 Model。5. ContextualCompressionRetrieverBaseDocumentCompressor 只是压缩器。真正把“基础检索器”和“压缩器”串起来的是 ContextualCompressionRetriever。它本质上是一个 Retriever 包装器。你给它 base_retriever 和 base_compressor。调用时它先走 base_retriever 拿候选文档再走 base_compressor 压缩候选文档。ContextualCompressionRetriever 的源码调用链。# 伪源码核心逻辑可以压缩成这几行class ContextualCompressionRetriever(BaseRetriever):base_retriever: RetrieverLikebase_compressor: BaseDocumentCompressordef _get_relevant_documents(self, query, run_manager):docs self.base_retriever.invoke(query)if docs:docs self.base_compressor.compress_documents(docs, query, callbacksrun_manager.get_child())return docs这段逻辑非常干净。Retriever 负责召回。Compressor 负责后处理。ContextualCompressionRetriever 负责把两者连起来。所以它不是一个新的向量数据库也不是一个新的大模型。它只是给 RAG 加了一个质量关卡。6. CrossEncoderRerankerCrossEncoderReranker 是最典型的重排器。它的思路很直接。把 query 和每个 Document.page_content 组成一对。交给 CrossEncoder 打分。按分数排序。取前 top_n。返回 Document 列表。CrossEncoderReranker 的内部工作方式。# 伪源码CrossEncoderReranker 的核心动作def compress_documents(self, documents, query, callbacksNone):pairs [(query, doc.page_content) for doc in documents]scores self.model.score(pairs)docs_with_scores sorted(zip(documents, scores),keylambda x: x[1],reverseTrue,)return [doc for doc, score in docs_with_scores[: self.top_n]]注意Reranker 不会重新去库里查。它只处理第一阶段已经召回的候选文档。所以 k 和 top_n 要分开理解。k 是第一阶段召回多少候选。top_n 是重排后留下多少上下文。k 太小Reranker 没东西可排。top_n 太大Prompt 还是会被撑爆。7. EmbeddingsFilter更轻量的过滤器不是所有场景都要 Cross-Encoder。如果你只是想先过滤掉明显不相关的文档可以用 EmbeddingsFilter。它会把文档和 query 再做一次 embedding 相似度比较。相似度太低删掉。这类方式便宜、快但判断力不如 Cross-Encoder。它适合做轻量过滤不适合作为最终排序裁判。8. DocumentCompressorPipeline把后处理串成流水线真实项目里后处理往往不是一步。可能先切得更细再过滤再重排再裁剪。这时候可以用 DocumentCompressorPipeline。它的思想很像 Java 后端里的责任链。每个节点只做一件事。上一个节点输出 Document下一个节点继续处理 Document。# 思路示意不是所有场景都必须这么堆pipeline DocumentCompressorPipeline(transformers[text_splitter, # 长文档再切细embeddings_filter, # 去掉明显无关内容reranker, # 对剩余文档重新排序])常见后处理方式选择。表格已转成图片避免排版变形。9. 生产环境怎么调参数参数不是越大越好。k 越大召回越全但 Rerank 越慢。top_n 越大信息越多但 Prompt 越贵。score_threshold 越高噪声越少但可能误删关键资料。chunk_size 越大上下文越完整但无关内容也越多。chunk_overlap 越大断句风险越低但重复内容也越多。真正靠谱的做法是建评测集。不要凭感觉调。10. 企业级 RAG 必须记录哪些日志Rerank 一上线问题会变得更隐蔽。用户只看到最终答案。但你必须知道第一阶段召回了哪些文档Reranker 给了多少分哪些文档被删掉最后哪些内容进入 Prompt。否则答案错了你不知道是召回错、重排错、压缩错还是模型生成错。企业级 RAG 的 Rerank 与 Trace 架构。11. Java Python 项目怎么落地如果你是 Java 后端项目建议不要把 LangChain 强塞进 Java 主服务。更稳的方式是Java 负责业务、权限、审计、配置、任务调度Python AI 服务负责 LangChain、Retriever、Rerank、Prompt、Model。Java 调 Python。Python 返回结构化结果。所有召回文档、Rerank 分数、压缩结果、模型输入输出都回写 MySQL / ES / 日志系统。这样既能利用 Python AI 生态又不会破坏 Java 主业务的稳定性。Spring Boot↓ REST / gRPCPython FastAPI AI Service↓base_retriever.invoke(query)↓ContextualCompressionRetriever↓CrossEncoderReranker / EmbeddingsFilter↓Prompt Model↓结构化答案 引用来源 Trace 日志12. 总结第一召回是粗筛Rerank 是精筛。第二上下文压缩不是少给资料而是少给噪声。第三RAG 的质量上限不只由模型决定更由检索、重排和上下文决定。内容来源Rerank 与上下文压缩为什么召回 TopK 后还要重排功能变化与行业影响解析_热闻岛