Lost in the Middle 与位置偏见

状态:✅ 正文已补
一句话定义:长上下文里,模型对 开头与结尾 更敏感, 中间 信息更容易被忽略——所以「提示词两头重要、中间次要」。

你为什么要学这个

做 RAG、拼长 system prompt、塞多段资料时,若把关键约束或证据放在中间,模型可能「看不见」。窗口越大、填充越满,这个问题越明显。它不是纯理论:任何把多类信息拼进一次调用的系统(Chatbot、Agent、Workflow、IDE 助手)都会撞上。

学完应能:按层规划 payload、把硬约束与当前任务放在注意力友好区,并在上线前用简单探针验证「中间有没有丢」。

1. 现象:什么是 Lost in the Middle

Lost in the Middle /ˌlɒst ɪn ðə ˈmɪdl/ (Liu 等人,2023)描述的是:在长上下文问答里,相关信息放在上下文 开头与结尾 时,模型更容易用上;放在 中间 时,准确率往往明显下降。这与「位置偏见」( position bias /pəˈzɪʃn ˈbaɪəs/ )是同一工程叙事下的两面:

  • 位置偏见 :模型对序列中不同位置的信息利用不均(常呈 U 形:两头强、中间弱)。
  • Lost in the Middle :这种偏见在 长上下文 + 多段资料 场景下的具体表现。

直觉(不必死记论文细节):

  • 训练与位置编码让模型更擅长「开头定调、结尾收束」。

  • 注意力在长序列上被摊薄;中间段落既不像开头那样建立框架,也不像结尾那样紧贴生成点。

  • 声称读过推理时用上了 。模型可能复述「我已阅读全部材料」,却漏掉只出现在中间的关键句。

短上下文、结构极清晰、关键句被强标记时,偏见会弱一些;但 不要用「模型窗口很大」当免死金牌

2. 提示词构成:从「一层糊墙」到「分层 payload」

规划提示词,先回答:这次调用里到底有哪些 ?层的职责不同,默认位置也应不同。下面是与具体厂商 API 解耦的逻辑分层(再映射到 system / user / tool 等角色即可,细节见姊妹文)。

典型内容 默认位置建议
身份与硬约束 角色、安全红线、必须遵守的格式 靠前 (system 头)
工具 / Schema 函数名、参数、何时调用 靠前偏中;过长则压缩描述、按需加载
业务规则 / Skills 领域 SOP、项目规范 中前;关键规则在 尾部再锚一次
检索证据 / 附件 RAG chunks、文件、日志 中间主体; 最相关的放头或尾
对话历史 多轮原文或摘要 中后;旧轮摘要,近轮保留
当前任务 用户问题、本轮目标、输出检查项 靠后 (靠近生成点)

原则图:

[硬约束] → [能力/工具] → [可变上下文] → [当前任务 + 尾部再强调]
 高优先、短而硬     可压缩/按需      易 Lost-in-Middle    最高注意力区

把「提示词」理解成一次请求的 payload 编排 ,而不是一段散文:

  1. 固定层 :身份、安全、输出契约——短、硬、可版本管理。
  2. 半固定层 :工具定义、Skills、业务规则——可裁剪、可按任务加载。
  3. 可变层 :检索结果、附件、历史——按相关度与新鲜度进出。
  4. 任务层 :本轮问题与验收标准——尽量靠近输出。

同一条信息出现两次并不丢人: 头尾各放一次短规则 ,往往比在中间写一篇长文更稳。

3. 注意事项

  1. 位置是信号 。同样一句话,放在尾部「输出前检查」和埋在万字中间,被用上的概率可以差一截。
  2. Token 预算优先于「全塞」 。中间是缓冲区,不是荣誉席;塞满窗口会同时推高成本、延迟和中间丢失率。
  3. 可验证优于可声明 。关键约束应能被检查(格式校验、拒答条件、引用字段),而不是只写「请务必遵守」。
  4. 窗口越大 ≠ 中间越安全 。有效利用依赖选材与重排;长窗口只是给了你更多把事情做砸的空间。
  5. 结构化标记能缓解,不能替代重排 。XML / Markdown 分区、明确标题有助于定位,但最相关证据仍建议避开「纯中间」。
  6. 摘要会丢约束 。压缩历史时,优先保留红线与已确认决策,而不是闲聊细节。

4. 最佳实践

4.1 两端放硬货

  • :身份、安全红线、全局输出格式。
  • :本轮问题、必须引用的证据、输出前检查清单(3–5 条短句即可)。
  • 关键业务规则若只能出现一次,优先 尾部靠近任务 ;若很长, 头摘要 + 尾复述

4.2 中间放可丢可压的内容

背景介绍、次相关 chunk、旧对话、冗长日志——放中间,并接受「可能被弱化」。真正不能丢的,不要只放这里。

4.3 相关度重排,而不是检索分原样拼接

RAG 常见错误是按召回顺序或分数从高到低一路拼下去,结果最相关段落落在中间带。更稳的做法:

  • 控制 k(常比「多塞几个」更有效)。
  • Rerank 后,把 Top-1 / Top-2 放到 紧挨问题 的位置(常在尾部证据区),或采用「头尾夹击」。
  • 次相关材料放中间或直接丢掉。

4.4 摘要替代堆叠

  • 长历史 → 滚动摘要 + 近 N 轮原文。
  • 长文档 / 长 tool 输出 → 先摘关键字段再回灌。
  • 多跳任务 → 拆成多轮或多节点,让 单次 payload 变短

4.5 尾部锚点复述

在用户问题之后(或同一条 user 消息末尾)加一小段:

## 输出前检查
- 只能依据 <evidence> 作答;不足则明确说不知道
- 必须给出引用编号
- 禁止输出密钥与内部 URL

短、可扫、紧贴生成点——专门对抗「规则写在前面但生成时忘了」。

4.6 自测「中间是否丢了」

上线前做一次廉价探针:把 唯一关键事实 只放在上下文中段,头尾不出现,问一个必须依赖该事实的问题。若答不上或胡编,说明你的编排在当前模型与长度下已经 Lost-in-the-Middle。

5. 坑点

为什么坑 怎么绕
窗口大就使劲贴 中间带变「信息坟场」,成本与延迟双升 先选材、再填充;能 RAG 就不整文塞入
核心规则只写在长 Rules 中段 落在注意力低谷 规则短化;关键条尾部锚点
工具 Schema 占满前半 用户问题被挤到相对中间 精简描述;按任务加载工具;结果先摘要
RAG 原样拼接 Top-k 最相关段落落在中间 Rerank + 两端放置 + 控 k
摘要把约束摘要掉 多轮后「人设/红线」消失 摘要模板强制保留硬约束字段
「请仔细阅读以上全部」当银弹 不改变位置偏见 重排、缩短、锚点、分治
把知识库整份塞进 system system 膨胀且中段失效 检索注入;system 只留稳定契约

6. 不同场景怎么用

6.1 RAG

放两头 放中间 要点
用户问题、引用格式、拒答条件;最相关 1–2 个 chunk 次相关证据、可选背景 控 k;Rerank;「无证据则拒答」写在尾部

工程口诀: 检索解决找得到,位置解决用得上。 找得到但放中间,等于没找到。

6.2 Agent

放两头 放中间 要点
目标、工具使用红线、停止/升级条件 观察轨迹、长 tool 原始输出 Tool 结果先摘要再进入下一轮;Schema 描述短;避免把整段日志当「记忆」永久粘贴

Agent 特有风险:多步之后上下文越来越长, 早期目标被挤到「相对中间」 。应用「目标卡片」在每轮尾部重贴当前目标与未完成项。

6.3 Chatbot

放两头 放中间 要点
短人设与安全;当前用户话 历史轮次 滚动摘要;近 N 轮原文;人设勿被历史淹没;不要把百科知识塞进 system

多轮产品里,位置偏见常表现为:模型更听 最近几句 ,却忘掉会话早期的约束——用摘要保留约束,或周期性重注入短人设。

6.4 Workflow(图编排 / 流水线)

放两头 放中间 要点
本节点输入契约、输出 JSON Schema 上游大段原始文本 节点间传结构化中间态 ,不要把上一节点的完整 prompt 上下文透传给下一节点

Workflow 的优势正是:把一次超长调用拆成多次短调用。每个节点只带 完成本步所需的最小上下文

6.5 ChatFlow(对话型编排,轻提)

前台对话应保持 短链路、可解释 :硬约束与当前用户意图靠两端;重知识、重工具放编排侧按需拉取。与「前台短、后台重」一致,避免把整条编排状态一次性铺进对话模型上下文。

6.6 场景速查总表

场景 两头优先 中间可压 特有策略
RAG 问题、格式、Top 证据 次相关 chunk Rerank + 控 k + 拒答
Agent 目标、红线、停止条件 轨迹与长输出 摘要回灌 + 目标重贴
Chatbot 人设、当前话 旧历史 滚动摘要 + 近 N 轮
Workflow 节点契约与 schema 上游原文 结构化中间态,禁透传
ChatFlow 对话短约束 编排态细节 前台短、后台按需

7. 例子:Cursor 的 Context Usage(解剖,非教程)

真实产品里,一次调用往往已被拆成彩色条带。以 Cursor 的 Context Usage 为例(数值随会话变化,结构可迁移):

System prompt          ← 头:身份与底座指令(通常很短)
Tool definitions       ← 前中:工具 Schema(可能很胖)
Rules / Skills         ← 中前:项目规则与技能
MCP / Subagent …       ← 中:动态能力与子代理定义
Summarized conversation← 中后:旧对话压缩
Conversation           ← 尾:近轮对话(常占大头)
(+ 附件 Files)         ← 视产品拼接到会话附近

可观察的工程含义:

  1. Conversation 靠后 —— 对「当前任务」友好,符合「结尾敏感」。
  2. Tools / Rules / Skills 易落在中前 —— 若写得很长,关键条文正好进 Lost-in-the-Middle 带。
  3. Tool definitions 动辄近万 token —— 会挤占预算,并相对推远「真正重要的用户句」;能按需加载就不要全量挂载。
  4. Summarized conversation —— 摘要质量决定约束是否幸存;摘要模板应显式保留红线。

映射回第 2 节:产品已经帮你分层,但 分层 ≠ 自动防中间丢失 。你仍要:规则短化、关键条可尾部锚点、工具与附件控量、任务描述靠近生成点。

8. 上线前检查清单

  • 硬约束是否出现在 头或尾 (更好是两端短复述)?
  • 本轮用户问题 / 验收标准是否靠近 输出端
  • 最相关证据是否避开「纯中间」?是否做了 rerank 与控 k?
  • 单次 payload 是否还能再砍约 30% 而不损任务?
  • 长 tool / 长文件是否先摘要再回灌?
  • 历史摘要是否保留了红线与已确认决策?
  • 是否用「关键事实只放中间」做过一次探针测试?
  • Workflow / Agent 是否避免把完整上游上下文透传到下一跳?

学习要点(应能回答)

  • 为什么常见「两头强、中间弱」?长上下文下注意力与位置利用不均;中间段落既不定调也不紧贴生成。
  • RAG 命中段落应放哪? 最相关放两端(尤其靠近问题) ,次相关放中间或丢弃;先 rerank 再拼接。
  • 系统约束、工具规则、用户问题分别适合放哪? 约束靠前(可尾部锚点)、工具靠前但要瘦、问题与检查项靠后

已有相关文档(先读这些)

参考资料

  • Liu et al., Lost in the Middle: How Language Models Use Long Contexts
  • 本仓库:上下文工程RAG 范式
  • 实践延伸:工具结果摘要、滚动对话摘要、节点间结构化中间态(见 Agent / Workflow 相关篇)