面试官:“知识库搜到多少资料,你就全喂给 AI?”我:“信息越多越准。”她亮出错答案:“那它怎么被废话带跑了?”

面试日记 第 21 天

面试官:"知识库搜到多少资料,你就全喂给 AI?"

我:"信息越多越准。"

她没接话,直接把测试答案转到我面前。检索结果里明明有正确段落,大模型最后却抓住另一篇文档里的次要描述,给出了一个看起来完整、实际答偏的答案。

我扫了一眼检索日志:"那我把 top_k 再调大一点,多召回几段做补充。"

"现在已经够多了。"她指了指那一长串上下文,"你还嫌它不够乱?"

我手里的笔停了一下。

问题不在知识库没搜到,而在检索结果不分轻重地全部进了 Prompt。正确证据虽然在场,但被大量背景介绍、重复段落和低相关内容挤散了注意力。继续扩大召回,只会把噪声一起放大。

面试官把那张错误答案推到我面前,问出今天的原题:

什么提示压缩?为什么在 RAG 中需要提示压缩?

这题容易答成"上下文不够长,所以把文章总结一下"。真正落到项目里,提示压缩还要解决一个更麻烦的问题:窗口明明放得下,模型也可能被无关内容带跑。

回答重点

先纠正一个误区:提示压缩不等于普通摘要

提示压缩是对检索得到的上下文做面向当前问题的精简:保留直接相关的事实、实体、数字和限制条件,过滤重复内容与无关段落,再把更短、更聚焦的证据交给大模型。

比如检索到一篇 10 页的技术白皮书,用户只问其中一个性能问题,压缩模块可以保留相关章节、实验条件和关键数据,其他背景介绍不必进入最终 Prompt。

普通摘要追求概括全文,提示压缩则必须围绕用户问题保住"回答所需证据"。如果摘要写得很流畅,却删掉了金额、否定词或适用条件,这次压缩仍然是失败的。

窗口够大,也不代表应该全部塞满

RAG 中需要提示压缩,通常有三个原因:

  1. 上下文预算不只属于检索文档。 系统提示、对话历史、工具结果和输出空间都会占用窗口,标称长度不能全部留给知识库内容。
  2. 无关内容会稀释证据。 重复段落、旧版本说明和低相关背景越多,模型越可能忽略真正关键的句子,出现"正确资料在里面,答案还是错"的情况。
  3. 输入长度会影响成本与延迟。 具体价格和耗时随模型、缓存策略、硬件及服务商变化,但减少无效 token,通常能降低调用成本和首 token 等待时间。

因此,提示压缩的目标不是追求最短,而是在给定 token 预算下,尽可能提高有效证据的密度。

它位于检索与生成之间

一条常见链路是:用户问题先经过检索与重排,得到候选文档;压缩模块再按问题筛选段落、句子或 token;最后才组装 Prompt,交给生成模型回答。

这里要注意顺序。检索负责缩小文档范围,重排负责调整候选证据的优先级,提示压缩负责减少候选内容内部的冗余。三者可以配合,不能指望压缩模块替一个完全错误的检索结果补救。

扩展知识

压缩方案不只有"再调用一次大模型"

简单场景可以直接使用规则:保留命中关键词附近的句子,强制留下人名、日期、数字和否定词,再去掉重复页眉、模板说明与低相关段落。

长文档或多文档场景可以使用专门的压缩模型。微软开源的 LLMLingua 系列会用较小的模型判断 token 或片段的重要性;LongLLMLingua 还会结合问题调整上下文顺序和压缩比例,缓解长上下文中的"中间信息丢失"。

下面是按照官方接口整理的简化示例:

python 复制代码
from llmlingua import PromptCompressor

compressor = PromptCompressor()

result = compressor.compress_prompt(
    contexts,
    instruction="保留与用户问题直接相关的事实、数字和限制条件",
    question=question,
    rate=0.4,
    rank_method="longllmlingua",
)

compressed_context = result["compressed_prompt"]

rate=0.4 表示目标大致保留四成内容,但生产环境不能把它写死成万能答案。合同、医疗说明、财务数据等场景更需要保守压缩,并对金额、日期、主体和否定关系设置强制保留规则。

什么时候不值得压缩

文档本身很短、检索结果已经高度相关,或者业务要求逐字引用代码、条款和原始表格时,额外压缩可能省不了多少 token,反而增加信息损失与链路延迟。

判断要不要上线压缩模块,至少要同时比较四组指标:压缩前后的 token 数、关键事实保留率、最终答案正确率与引用准确率,以及整条链路的 P95 延迟和成本。只看压缩率,很容易得到一段特别短、也特别没用的上下文。

Apple 最新的 CLaRa 也说明了这个方向正在继续演进:压缩不一定只发生在可读文本层,它还可以把文档映射为更短的连续向量,并让重排与生成共同优化。但无论采用哪种方法,验收标准仍然要回到同一件事:删掉噪声以后,回答需要的证据有没有被完整留下。

面试官追问

追问:压缩会不会把关键信息也压没了?怎么保证压缩质量?

回答:确实有这个风险。保证质量的核心是让压缩模块"知道"什么是关键。几个做法: 1)把用户问题作为压缩的锚点,跟问题相关性高的内容优先保留 2)设置压缩率上限,别压得太狠,保留 30%-50% 是比较安全的区间 3)用 NER 提取关键实体,人名、日期、数字这些硬性信息强制保留 4)上线前用测试集跑一遍,对比压缩前后的回答质量

追问:长上下文模型出来了,比如 Claude 200k、Gemini 1M,还需要压缩吗?

回答:需要,原因有两个。第一是成本问题,窗口大了不代表免费,塞满 200k tokens 的调用费用很可观。第二是"大海捞针"问题,上下文越长模型越容易走神,关键信息淹没在海量文本里反而降低准确率。所以即使窗口够大,压缩掉无关内容还是有意义的。

追问:压缩模块本身也要消耗资源,怎么权衡压缩的收益和成本?

回答:算一笔账就清楚了。压缩模块用的是小模型,成本很低,LLMLingua 用的是 7B 参数的模型,推理成本大概是 GPT-4 的 1/100。如果原始文档 10000 tokens 压缩到 2000 tokens,调用大模型省下的钱远超压缩的成本。只有文档本身就很短、或者压缩率提不上去的场景,压缩才不划算。

那张错误答案最后没有靠扩大召回修好。我们先删掉重复背景,再围绕问题保留关键事实和限制条件,模型才重新抓住真正有用的那一段。

这道题考的也不只是"怎么省 token"。准备 RAG 项目时,更重要的是能说清楚哪些内容可以删、哪些证据必须留下,以及压缩后准备拿什么指标证明答案没有变差。

相关推荐
米花米唐1 小时前
Spring AI 2.0 会话记忆开发实践
后端
从零开始的代码生活_2 小时前
C++ stack、queue 与 priority_queue:容器适配器原理与实战
开发语言·c++·后端·学习·算法
爱勇宝2 小时前
《道德经》第6章:别把团队的创造力用到枯竭
前端·后端
无双_Joney2 小时前
[四期 - 4] NestJS专栏 - 征召一下大家的意见,非常想知道大家都想看看Nest的哪些方面
前端·后端·nestjs
彭亚川Allen2 小时前
停更的这一年,All In AI、陪媳妇生娃、还考了个研
前端·后端·产品经理
techdashen2 小时前
Go 1.25 新增 `reflect.TypeAssert`:更直接、更高效地从 `reflect.Value` 取出类型值
开发语言·后端·golang
千桐科技3 小时前
🚀 qModel 算法模型平台v1.2.0 开源版发布!Python 模型接入链路全面升级,告别“能跑但上不了线”的尴尬
后端·算法·llm
刘沅3 小时前
LeetCode 93.复原IP地址
算法·面试
用户40966601317513 小时前
实时数据大屏的 4 种推送方案:短轮询 → 长轮询 → SSE → WebSocket
后端·面试