核心摘要

**Lost in the Middle(迷失在中间)**是长上下文大模型的位置敏感问题:请求即使没有超过标称窗口,模型也可能因证据位置不同而表现不一致。可靠评测需要同时扫描位置、长度与干扰项,区分检索和生成,加入真实任务与负控,并把 RAG、压缩、摘要和重排视为需要实验验证的候选方案,而不是必然有效的答案。

目录

核心要点

  • 容量不等于可靠性:请求能被接受,不代表模型能正确使用证据、完成推理并给出可靠引用。
  • U 型曲线是实验发现,不是自然定律:位置效应会随模型、任务、长度、干扰项与评测方式变化。
  • 普通 NIAH 只是冒烟测试:RULER、NoLiMa、LongBench v2 和业务数据集分别覆盖不同失败模式。
  • 缓解方案都有条件:检索、重排、压缩、摘要和证据重排可能改善结果,也可能引入新的丢失或偏差。
  • 发布身份必须固定:模型别名、提示模板或检索链路变化,都可能让旧的长上下文结论失效。

Lost in the Middle 到底是什么

Lost in the Middle 描述的是模型使用长上下文中相关信息时对位置敏感。原始实验保持问题与证据不变,只改变相关信息在其他文档中的位置;结果显示,当证据从开头或结尾移动到中间区域时,部分被测模型的答题表现明显下降。

这个定义比常见说法更严格:

常见说法 能够成立的结论
「模型忘记了中间 Token」 模型在部分中间位置的任务结果较差;实验并不能直接观察到一次字面意义上的遗忘。
「注意力一定会向中间衰减」 有研究在特定模型中观察到位置注意力偏差,但尚不能把单一机制推广到所有架构和任务。
「所有长上下文模型都是 U 型曲线」 原始研究在被测条件下发现该形态;后续模型与任务可能呈现更平坦、不对称或其他曲线。
「标称上下文窗口是假的」 最大可接受容量与任务有效可靠性是两份不同的契约,两者都可能被准确描述。

因此,工程问题不应只是「模型能否接收 10 万 Token」,而应改为:「在当前模型、位置、长度、干扰项、任务与发布配置下,它能否稳定使用必需证据?」

如需理解 Token 容量与截断,请先阅读上下文窗口;如需决定哪些内容值得进入请求,请参考上下文预算

现有研究证明了什么

现有证据证明的是一组受实验条件约束的现象,而不是一份永不过期的模型排行榜。

原始受控实验

Liu 等人的《Lost in the Middle: How Language Models Use Long Contexts》评测了多文档问答与合成键值检索。研究通过移动相关信息并控制其他变量,证明任务表现可能强烈依赖位置,扩大上下文也不保证模型均匀使用其中的信息。

这项研究支持「对证据位置做受控测试」。它不支持把某个准确率复制到所有生产任务,也不支持为所有模型指定一个已经证实的单一成因。

位置注意力偏差

Found in the Middle在其被测条件下,将部分长上下文失败与位置注意力偏差联系起来,并提出校准方法。这为机制分析提供了重要证据,但结论仍受模型、任务和干预方式约束。训练数据结构、位置编码、注意力模式、解码行为和 Prompt 组织可能共同作用,不能简单归因于「KV Cache 新鲜度」。

超越字面匹配的大海捞针

后续三类基准说明了为什么一张全绿的检索热力图仍不足以证明长上下文可靠:

评测 新增能力维度 单独使用仍不能证明
RULER 在可配置长度下评测检索、多跳追踪、聚合与问答 模型在私有文档、业务 Prompt 与实际服务链路中的可靠性
NoLiMa 降低问题与证据的字面重叠,测试隐含关联及一跳、两跳推理 超出其数据集和被测模型版本的普遍性能
LongBench v2 真实的单文档、多文档、长对话、代码仓库、上下文学习和结构化数据任务 业务授权、拒答、延迟、成本和证据策略

基准分数是快照。记录不可变模型版本和实验条件,比把当期表格写成永久厂商结论更可靠。

上下文容量为什么不等于上下文可靠性

长上下文系统需要依次通过多个阶段,前一阶段通过并不能证明下一阶段成功。

flowchart LR A["请求被接受"] --> B["检索到必需证据"] B --> C["组装后仍保留证据"] C --> D["模型实际使用证据"] D --> E["推理结论正确"] E --> F["回答有依据且已授权"] F --> G["生产目标达成"]

诊断时应逐层拆分:

  1. 上下文接收:分词、长度限制或截断是否移除了内容?
  2. 检索:检索器是否返回全部必需证据?
  3. 组装:去重、压缩、排序或模板化是否完整保留证据?
  4. 证据利用:生成模型是否使用了上下文中的可用证据?
  5. 推理:模型是否正确组合、比较或聚合多条证据?
  6. 事实依据:引用片段是否真的支持对应主张?
  7. 权限策略:请求者是否有权看到每一项被披露的信息?
  8. 运行指标:延迟、成本和失败率是否在预算内?

这套拆分可以避免常见误判:把检索漏召回归咎于生成模型,或只因为答案包含正确字符串就宣称证据链可靠。

如何评测有效上下文

有效上下文评测应先逐项控制变量,再测试这些变量在真实任务中的组合。

建立评测矩阵

至少交叉以下维度:

维度 示例取值 目的
证据位置 开头、25%、中间、75%、结尾 测量位置敏感性
上下文长度 短、常规、高、接近部署上限 在请求硬失败前发现质量退化
干扰项数量 无、少量、生产近似、压力级 区分纯长度与信息竞争
干扰项相似度 无关、同主题、近重复、冲突 测试排序与区分能力
证据数量 单条、多条独立、多跳链路 防止只针对单针任务优化
词汇重叠 原词、改写、隐含关联 识别关键词匹配捷径
证据状态 存在、缺失、矛盾、未授权 测试拒答与策略执行

不要使用真实密码或个人数据作为「针」。合成标识符更安全,也更容易自动评分。

不要只看平均准确率

每次发布至少报告:

text
start_accuracy
middle_accuracy
end_accuracy
worst_position_accuracy
position_gap = best_position_accuracy - worst_position_accuracy
retrieval_recall
citation_correctness
unsupported_claim_rate
abstention_accuracy
latency_p50 / latency_p95
input_tokens / output_tokens / cost
request_failure_rate

平均准确率可能掩盖危险的局部盲区。发布门禁应包含最差位置准确率和位置差距,而不是只看一个聚合分数。

加入真实业务任务

合成测试用于隔离变量,真实测试用于证明可用性。评测集应包含具有代表性的合同、客服历史、代码仓库、结构化记录或研究资料,并冻结经审查的数据版本与预期证据集,以便比较模型和流水线变化。

真实任务还应包含:

  • 需要组合两个相隔很远章节的问题。
  • 上下文中不存在答案的问题。
  • 来源冲突且有明确优先级规则的问题。
  • 文档中包含引号指令或 Prompt Injection 的问题。
  • 证据确实存在,但请求者无权查看的问题。

可复现的位置扫描程序

下面的程序生成确定性上下文并计算位置敏感指标。模型适配器被刻意留在外部,因为供应商 API 和模型名称会变化,而评测契约应保持稳定。

python
from dataclasses import dataclass
from statistics import mean
from typing import Callable


@dataclass(frozen=True)
class Case:
    case_id: str
    question: str
    evidence: str
    expected: str
    distractors: tuple[str, ...]


POSITIONS = ("start", "middle", "end")


def assemble(case: Case, position: str) -> str:
    blocks = list(case.distractors)
    index = {
        "start": 0,
        "middle": len(blocks) // 2,
        "end": len(blocks),
    }[position]
    blocks.insert(index, case.evidence)
    return "\n\n--- DOCUMENT ---\n".join(blocks)


def evaluate(
    cases: list[Case],
    ask_model: Callable[[str, str], str],
) -> dict[str, float]:
    scores = {position: [] for position in POSITIONS}

    for case in cases:
        for position in POSITIONS:
            answer = ask_model(case.question, assemble(case, position))
            scores[position].append(
                float(case.expected.casefold() in answer.casefold())
            )

    accuracy = {
        position: mean(values) if values else 0.0
        for position, values in scores.items()
    }
    values = list(accuracy.values())
    return {
        **{f"{key}_accuracy": value for key, value in accuracy.items()},
        "worst_position_accuracy": min(values),
        "position_gap": max(values) - min(values),
    }

一条结果记录可以采用以下结构:

json
{
  "release": {
    "provider": "example-provider",
    "modelRevision": "immutable-revision-id",
    "tokenizer": "tokenizer-version",
    "promptTemplate": "qa-with-citations-v4",
    "contextAssembler": "rank-compress-v7",
    "inferenceSettings": {
      "temperature": 0
    }
  },
  "slice": {
    "contextTokens": 64000,
    "distractors": 40,
    "distractorType": "topical-near-duplicates"
  },
  "metrics": {
    "startAccuracy": 0.91,
    "middleAccuracy": 0.82,
    "endAccuracy": 0.90,
    "worstPositionAccuracy": 0.82,
    "positionGap": 0.09
  }
}

以上数值只用于展示 Schema,并非任何模型的测试结果。实际系统还应存储逐用例输出、证据 ID、引用、错误、Token 用量与延迟,使聚合指标的回归能够被审计。

如何缓解位置敏感问题

缓解方案必须针对发生失败的阶段,并在完整评测矩阵上验证。

检索与重排

检索增强生成可以减少无关上下文,但同时引入检索边界。需要测量查询改写、过滤、Top-k、重排与去重后是否保留全部必需证据。top_k 应根据业务召回、准确率、延迟和成本曲线选择,不存在「固定取 5 个 Chunk」的通用答案。

上下文压缩

上下文压缩可以移除样板文本与重复内容,也可能删掉限定条件、引用、例外条款或远距离事实之间的关系。压缩结果必须保留来源 ID,并与未压缩对照组比较。

证据排序

把高置信证据放到实验中更稳健的位置,可能改善特定任务,但不能把它固化为普遍规则。重排可能破坏时间顺序、来源优先级或多跳依赖。应比较原始顺序、按分数排序、首尾交错和按章节排序,再决定策略。

结构化证据与引用

为每段证据分配稳定来源 ID,要求输出主张级引用,再检查引用片段是否蕴含对应结论。要求模型先摘录原文并不能「强制」忠实推理,因为摘录本身也可能不完整、不相关或被编造。

分层处理

处理全库综合任务时,可以先检索或分区,生成带来源的中间结论,再按显式冲突策略聚合。摘要属于派生数据,应保留来源链,不能在无追溯信息的情况下替换权威原文。

架构选型可参考长上下文与 RAG 决策框架,完整链路设计可继续阅读上下文工程

安全与授权边界

长上下文既扩大不可信文本的数量,也增加模型可能泄露的信息范围。

  • Prompt Injection:检索文档的开头、中间和结尾都可能包含恶意指令。按位置过滤不是安全控制;文档内容应视为数据,工具与数据策略必须在模型外执行。
  • 授权:成功检索到片段不等于允许披露。租户、对象和字段级授权必须在上下文组装前完成。
  • 来源追踪:分块、重排、压缩和摘要都应保留来源身份。
  • 负控:测试证据缺失、恶意指令、未授权事实与冲突来源。
  • Many-shot 风险:Anthropic 的多样本越狱研究说明,更长的 Prompt 可能增加新的安全失效方式;上下文越多并不意味着越安全。

系统级控制可参考Prompt Injection 攻防指南。仅靠提示词措辞无法建立授权边界。

生产发布门禁

长上下文结果属于一组完整的发布身份,而不仅属于一个模型显示名称。

至少记录:

yaml
model:
  provider: example-provider
  immutable_revision: revision-id
  tokenizer: tokenizer-version
prompt:
  template: qa-with-citations-v4
  system_policy: policy-v6
pipeline:
  retriever: hybrid-v3
  reranker: reranker-v2
  assembler: rank-compress-v7
  corpus_revision: 2026-08-23
inference:
  temperature: 0
  max_output_tokens: 1200

发布门禁可以包含:

  • 最差位置准确率不得回归。
  • 位置差距低于业务风险容忍值。
  • 检索召回率与引用正确率达到显式阈值。
  • 证据缺失或冲突时能正确拒答。
  • 负控中不存在未授权披露。
  • 延迟、Token 用量、成本和请求失败率均在预算内。

模型版本、分词器、提示模板、上下文组装器、检索器、重排器、语料、量化方式或服务配置变化后,都应重新运行评测。即使应用代码未变,供应商模型别名也可能已经指向不同版本。

常见问题

Lost in the Middle 与上下文截断相同吗?

不同。截断发生在推理前,Token 已被移除;Lost in the Middle 关注的是相关信息仍在上下文中,但任务表现随位置变化。首先记录 Token 数和保留的来源 ID,避免把截断误判为证据利用失败。

大海捞针测试是否有效?

有效,但只适合作为受控冒烟测试。它能检查模型是否可在不同位置和长度召回已知信息,却不能证明多跳推理、聚合、低词汇重叠检索、引用忠实度、授权或真实文档表现。

重要指令是否应该永远放在末尾?

不应该。系统指令应保留在供应商定义的 system channel 或等效策略边界中。对于证据和重复任务说明,可以通过实验比较位置,但不能为了利用位置效应而削弱指令层级。

推理提示能消除这个问题吗?

推理提示可能改变表现,但不能保证模型使用了正确证据,也不能保证引用忠实。应分别评分最终答案和证据归因,并验证收益能否在更长上下文和更强干扰项下保持。

什么是有效上下文长度?

有效上下文长度是某个固定发布版本在特定业务中,同时满足质量、安全、延迟与成本阈值的运行范围。它通常不等于最大可接受 Token 数,也不应被表达成一个适用于所有任务的固定数字。

总结

Lost in the Middle 应被视为发布版本相关的可靠性问题。受控位置扫描用于发现证据位置是否改变结果;RULER、NoLiMa、LongBench v2、真实任务与负控分别暴露不同弱点。只有把检索、组装、证据利用、推理、引用、授权和运行指标拆开诊断,并在完整发布门禁中验证缓解方案,长上下文能力才具有生产意义。

相关资源