VINO/WANG返回博客 ←

BLOG / POST

上下文退化模式

长上下文下模型的五种失效模式——迷失在中间、上下文污染、干扰、混淆、冲突——以及对应的检测与缓解策略。

  • context-engineering
  • llm

来源:Agent-Skills-for-Context-Engineering

上下文退化是什么

随着上下文长度增加,语言模型表现出可预测的性能下降模式

关键洞察:

上下文退化不是二元状态,
而是一个连续的性能下降谱系,
表现为几种不同的失效模式。

五个退化模式

模式1:迷失在中间(Lost-in-Middle)

这是最著名的退化现象!

U型注意力曲线

注意力分布

高  |    ╱╲                    ╱╲
    |   ╱  ╲                  ╱  ╲
中  |  ╱    ╲____________    ╱    ╲
    | ╱                  ╲__╱      ╲
低  |╱                              ╲___
    └─────────────────────────────────→
    开头          中间            结尾

✓ 开头:强关注
✗ 中间:弱关注(10-40%准确率下降)
✓ 结尾:强关注

核心发现

实证研究证据

  • 放置在上下文中间的相关信息,相比开头或结尾,召回准确率降低10-40%
  • 这不是模型缺陷,而是注意力机制和训练数据分布的结果

为什么会出现?

  1. 注意力汇(Attention Sink)

    • 模型为第一个token(通常是BOS token)分配大量注意力
    • 创建“注意力汇”,吸收注意力预算
    • 随着上下文增长,有限的预算被拉伸
    • 中间token无法获得足够的注意力权重
  2. 训练数据分布

    • 模型从训练数据学习的注意力模式主要针对短序列
    • 对上下文范围依赖关系经验较少
    • 专门的参数较少
    • 中间部分被“稀释”

实际影响

场景:分析一份长报告

错误的组织方式

[报告标题]
[第1章:引言]        ← 清晰
[第2章:方法]        ← 清晰
[第3章:数据]        ← 开始模糊
[第4章:分析]        ← nop 容易被忽略
[第5章:讨论]        ← nop 容易被忽略
[第6章:结论]        ← 又变清晰

正确的组织方式

[关键发现]            ← 放在开头
- 收入增长15%
- 成本降低8%

[报告正文...]         ← 中间部分

[行动建议]            ← 放在结尾
- 扩大A区域投资
- 优化B区域流程

缓解策略

  1. 关键信息放在边缘

    • 重要任务说明放在开头
    • 关键发现和结论放在结尾
  2. 使用摘要结构

    • 执行摘要:关键信息放在注意力优势位置
    • 详细章节:完整内容在中间
    • 结论与行动:再次强调关键点
  3. 明确的章节标题

    === 重要:财务数据 ===
    === 背景信息 ===
    === 重要:风险评估 ===

模式2:上下文污染(Context Poisoning)

错误信息进入上下文并通过重复引用不断复合

污染如何发生

三个主要途径

  1. 工具输出污染

    • 工具返回错误或意外格式
    • 模型将其作为事实接受
    • 错误信息被纳入推理
  2. 检索文档污染

    • 检索的文档包含错误或过时信息
    • 模型将错误信息纳入推理
    • 建立在错误基础上的结论
  3. 模型生成内容污染

    • 模型生成的摘要或中间输出包含幻觉
    • 错误信息在上下文中持续存在
    • 后续轮次引用错误信息

复合效应:反馈循环

污染的可怕之处:反馈循环

第1轮:模型产生小错误

第2轮:错误被纳入上下文

第3轮:基于错误信息的推理

第4轮:错误被强化和扩展

第5轮:整个决策树被污染

后果:

- 如果代理的"目标"部分被污染
  → 它会开发出需要大量努力才能撤销的策略
- 每个后续决策都引用污染内容
  → 强化错误假设

检测症状

警告信号

  1. 输出质量下降

    • 以前成功的任务开始失败
    • 回答质量明显变差
  2. 工具误用

    • 调用错误的工具
    • 使用错误的参数
  3. 持续性幻觉

    • 尽管尝试纠正,幻觉仍然存在
    • 坚持错误的事实
  4. 逻辑矛盾

    • 前后不一致的回答
    • 与之前陈述相矛盾

恢复策略

策略1:截断上下文

def truncate_to_before_poisoning(context, poisoning_point):
    """截断到污染点之前"""
    return context[:poisoning_point]

策略2:明确标记污染

def mark_and_request_reevaluation(context, poisoned_section):
    """标记污染并请求重新评估"""
    context.append({
        "role": "system",
        "content": f"""
        注意:以下部分可能包含错误信息:
        {poisoned_section}

        请忽略上述内容,重新评估。
        """
    })

策略3:重启并保留验证信息

def restart_with_verified_only(context, verified_info):
    """用干净上下文重启,仅保留验证信息"""
    new_context = {
        "system": clean_system_prompt(),
        "verified": verified_info
    }
    return new_context

模式3:上下文干扰(Context Distraction)

上下文过长时,模型过度关注提供的信息而忽略训练知识

干扰效应

研究发现:即使在上下文中只有一个不相关文档,
也会降低涉及相关文档的任务性能。

关键洞察:
这不是关于绝对意义上的噪声,
而是关于注意力分配——
不相关信息与相关信息争夺有限的注意力预算。

为什么会干扰?

  • 模型必须“关注”提供的所有内容
  • 没有机制“跳过”不相关的上下文
  • 即使不相关信息明显无用,也必须分配注意力
  • 创造干扰

就像在一间嘈杂的房间里专注于对话,即使知道噪音不重要,大脑仍然花费精力过滤它。

实际案例

场景:分析金融报告

干扰情况

上下文包含:
- 目标公司的季度报告 [相关]
- 竞争对手的新闻稿 [不相关]
- 随机的经济数据 [不相关]
- 旧的政策文档 [不相关]

结果:模型被干扰,分析质量下降

优化情况

上下文包含:
- 目标公司的季度报告 [相关]
- 相关的行业分析 [相关]
- 同期对比数据 [相关]

结果:模型专注于相关信息,质量提高

缓解策略

  1. 相关性过滤

    def filter_by_relevance(documents, query, threshold=0.7):
        """根据相关性阈值过滤文档"""
        filtered = []
        for doc in documents:
            score = calculate_relevance(doc, query)
            if score >= threshold:
                filtered.append(doc)
        return filtered
  2. 命名空间组织

    <RELEVANT_CONTEXT>
    核心相关材料
    </RELEVANT_CONTEXT>
    
    <OPTIONAL_REFERENCE>
    可选参考资料(可能不需要)
    </OPTIONAL_REFERENCE>
  3. 按需加载

    # 而不是一次加载所有文档
    load_all_documents()  # nop
    
    # 根据需要加载
    if need_financial_data:
        load_financial_docs()  # ✓

模式4:上下文混淆(Context Confusion)

不相关信息以降低质量的方式影响响应

混淆 vs 干扰

干扰(Distraction):关于注意力分配
→ 不相关信息争夺注意力预算

混淆(Confusion):关于对模型行为的影响
→ 不相关信息影响模型决策和输出

混淆的表现

  1. 响应查询的“错误”方面

    • 用户问:“A产品的定价如何?”
    • AI回答:“B产品的功能很好…” ← 混淆
  2. 针对不同任务的工具调用

    • 应该调用:read_file
    • 实际调用:search_web ← 混淆
  3. 混合多个来源的要求

    • 应该遵循:任务A的格式
    • 实际混合:任务A + 任务B的格式 ← 混淆

混淆场景

场景:单会话中的多任务

混淆情况

第1-10轮:讨论Python代码
第11-20轮:讨论SQL查询
第21-30轮:讨论JavaScript ← 混淆开始

问题:模型将Python的上下文应用到JavaScript中

解决方案

明确任务边界
<SESSION_TASK>
当前任务:JavaScript开发
之前的Python任务已完成
</SESSION_TASK>

架构解决方案

1. 显式任务分段

def segment_context_by_task(messages):
    """按任务分段上下文"""
    segments = identify_task_boundaries(messages)
    return {
        "current": segments["current"],
        "archived": segments["previous"]
    }

2. 清晰的上下文转换

def transition_context(old_task, new_task):
    """在任务上下文之间清晰转换"""
    return f"""
    === 任务完成 ===
    之前的任务:{old_task} 已完成

    === 新任务 ===
    当前任务:{new_task}
    请专注于新任务的上下文
    """

3. 状态管理隔离

class ContextIsolation:
    """为不同目标隔离上下文"""
    def __init__(self):
        self.contexts = {}

    def get_context(self, task_id):
        return self.contexts.get(task_id)

模式5:上下文冲突(Context Clash)

累积的信息直接冲突,产生矛盾的指导

冲突来源

  1. 多源检索冲突

    来源A:"产品价格是$100"
    来源B:"产品价格是$120"
    来源C:"产品价格是$90"
    → 矛盾的信息
  2. 版本冲突

    旧版本:"API端点是 /v1/users"
    新版本:"API端点是 /v2/users"
    → 两者都在上下文中
  3. 观点冲突

    观点A:"应该使用方法X"
    观点B:"应该使用方法Y"
    → 两者都有效但不兼容

冲突 vs 污染

污染(Poisoning):
一条信息是错误的
→ 需要识别和移除错误

冲突(Clash):
多条信息都是正确的,但相互矛盾
→ 需要解决和优先级排序

解决方法

1. 显式冲突标记

def mark_conflicts(context):
    """识别矛盾并请求澄清"""
    conflicts = detect_contradictions(context)
    if conflicts:
        return f"""
        检测到冲突信息:
        {conflicts}

        请澄清哪个来源应该优先。
        """

2. 优先级规则

def establish_priority(sources):
    """建立哪个来源优先的规则"""
    return {
        "priority": [
            "official_docs",    # 最高优先级
            "recent_updates",
            "community_wiki",
            "archived_posts"    # 最低优先级
        ]
    }

3. 版本过滤

def filter_outdated(context, current_version):
    """从上下文中排除过时信息"""
    filtered = []
    for item in context:
        if item["version"] == current_version:
            filtered.append(item)
    return filtered

实证基准和阈值

RULER基准测试发现

重要发现:
只有50%声称支持32K+上下文的模型
在32K tokens时维持令人满意的性能

模型表现:
- GPT-5.2:退化最少
- 许多模型在扩展上下文下下降30+分
- 简单的needle-in-haystack测试完美得分
  ≠ 真实的长上下文理解

模型特定退化阈值

模型 退化开始 严重退化 备注
GPT-5.2 ~64K tokens ~200K tokens 最佳整体退化抵抗力,思考模式
Claude Opus 4.5 ~100K tokens ~180K tokens 200K上下文窗口,强注意力管理
Claude Sonnet 4.5 ~80K tokens ~150K tokens 为代理和编码任务优化
Gemini 3 Pro ~500K tokens ~800K tokens 1M上下文窗口,原生多模态
Gemini 3 Flash ~300K tokens ~600K tokens 3倍速度,81.2% MMMU-Pro

模型特定行为模式

Claude 4.5系列

  • 最低幻觉率,校准的不确定性
  • SWE-bench Verified: 80.9%
  • 倾向于拒绝或请求澄清而不是捏造
  • 适合高风险任务

GPT-5.2

  • 两种模式:即时(快)和思考(推理)
  • 思考模式通过逐步验证减少幻觉,但增加延迟
  • 适合需要深度推理的任务

Gemini 3 Pro/Flash

  • 原生多模态,1M上下文窗口
  • Flash比前一代快3倍
  • 在文本、代码、图像、音频和视频的多模态推理方面强
  • 适合多模态任务

反直觉的发现

研究揭示了几种挑战上下文管理假设的模式:

1. 混合干草堆优于连贯干草堆

发现:打乱(不连贯)的干草堆比逻辑连贯的干草堆产生更好的性能

解释:
- 连贯上下文可能创建错误关联,混淆检索
- 不连贯上下文强制模型依赖精确匹配

2. 单个干扰者有不成比例的影响

发现:即使单个不相关文档也会显著降低性能

效果:
不是与噪声量成比例
而是遵循阶梯函数
任何干扰者的存在都会触发退化

3. 问题相似性相关性

发现:针对问题对之间的相似性较低时,
随着上下文长度下降更快

含义:
需要跨不相似内容进行推理的任务特别脆弱

💡 实用指导:四桶方法

策略1:Write(写入)

将上下文保存到窗口外
→ 使用草稿本、文件系统或外部存储
→ 保持活动上下文精简
→ 同时保留信息访问

示例:
不在上下文中保留所有数据,
而是写入文件并保存引用

策略2:Select(选择)

将相关上下文拉入窗口
→ 通过检索、过滤和优先级排序
→ 通过排除不相关信息来解决干扰

示例:
不加载所有文档,
而是检索最相关的3-5个

策略3:Compress(压缩)

在保留信息的同时减少token
→ 通过摘要、抽象和观察掩码
→ 扩展有效上下文容量

示例:
不保留完整对话历史,
而是保留摘要和关键轮次

策略4:Isolate(隔离)

将上下文分割到子代理或会话
→ 防止任何单个上下文增长到足以退化
→ 最激进的策略,但往往最有效

示例:
不是让一个代理处理所有任务,
而是为不同任务创建专门的代理

架构模式

实施这些策略通过特定的架构模式:

  1. 即时上下文加载

    • 仅在需要时检索信息
    • 避免预加载不必要的内容
  2. 观察掩码

    • 用紧凑引用替换冗长的工具输出
    • 保留完整数据的访问路径
  3. 子代理架构

    • 为不同任务隔离上下文
    • 防止单个上下文过大
  4. 压缩

    • 在上下文超过限制之前摘要增长的上下文
    • 定期清理和总结

检测退化的实际方法

退化检测示例

# 上下文在长对话期间增长
turn_1: 1000 tokens
turn_5: 8000 tokens
turn_10: 25000 tokens
turn_20: 60000 tokens   # 退化开始
turn_30: 90000 tokens   # 显著退化

监控指标

需要追踪的关键指标:

1. Token计数
   - 每轮的token数量
   - 累计token数量

2. 性能指标
   - 任务成功率
   - 输出质量评分
   - 错误率

1. 注意力信号
   - 信息检索准确率
   - 上下文使用率
   - 工具调用成功率

(完)