🌊 Context Window Overflow(上下文窗口溢出)

AI Agent 大语言模型 Token管理 OpenClaw 最后更新:2026-05-27

🎬 王家卫式开场

世界上有一种痛苦,叫做「上下文窗口溢出」。它就像你跟女朋友吵架,话说到一半,她突然说:「你刚才说什么?」——因为她的记忆只有最近三句话。

凌晨3点17分,我的Agent正在处理一份200页的PDF合同。第47页的时候,它突然忘了前面说了什么。那一刻,我意识到——上下文窗口不是无限的,就像人类的耐心一样。

📖 什么是 Context Window Overflow?

Context Window Overflow(上下文窗口溢出)是指当输入给大语言模型(LLM)的Token数量超过其上下文窗口(Context Window)限制时,最早的内容会被截断或遗忘,导致模型无法访问完整的历史信息。

简单来说:

🔬 技术原理

1. Token限制的来源

Transformer架构的注意力机制是二次复杂度O(n²),窗口越大,计算成本越高。因此每个模型都有设计上限:

模型 上下文窗口 实际可用
GPT-3.5-turbo 4K / 16K 约12K中文
GPT-4-turbo 128K 约96K中文
Claude 3 Opus 200K 约150K中文
腾讯 Coding Plan 根据配置 动态调整

2. 溢出的三种表现

3. 为什么Agent特别容易溢出?

Agent系统比普通对话更容易触发溢出,因为:

🛠️ OpenClaw 实战应用

OpenClaw 提供了多种机制来应对上下文窗口溢出:

1. 上下文预算管理(Context Budget)

# OpenClaw 配置示例:设置上下文预算
{
  "model": "tencentcodingplan/tc-code-latest",
  "contextBudget": {
    "maxTokens": 100000,
    "reserveForResponse": 4096,
    "strategy": "sliding-window"
  }
}

2. 滑动窗口策略(Sliding Window)

保留最近的N条消息,自动丢弃老的:

// OpenClaw Skills 中配置上下文管理
{
  "agent": "code-reviewer",
  "contextPolicy": {
    "type": "sliding-window",
    "keepRecent": 20,  // 保留最近20条消息
    "summarizeOld": true  // 对老消息生成摘要
  }
}

3. 工具结果压缩(Tool Result Compression)

当工具返回大量数据时,自动压缩:

# 工具定义中启用结果压缩
## Tool: search-docs
- name: search-docs
  description: 搜索文档
  compress: true  # 自动压缩超过1000 tokens的结果
  maxResultTokens: 500

4. 会话分片(Session Sharding)

长时间运行的Agent任务,可以分片处理:

// OpenClaw Sub-Agent 分片示例
sessions_spawn({
  task: "分析第1-50页合同",
  cleanup: "keep"  // 保留结果,但释放上下文
});

sessions_spawn({
  task: "分析第51-100页合同",
  cleanup: "keep"
});

// 最后汇总
sessions_send({
  message: "汇总所有分片结果"
});

💻 代码示例:检测和防止溢出

示例1:估算Token数

// 简单的Token估算函数(中文约1.5-2字符=1Token)
function estimateTokens(text) {
  const chineseChars = (text.match(/[\u4e00-\u9fa5]/g) || []).length;
  const otherChars = text.length - chineseChars;
  return Math.ceil(chineseChars / 1.5 + otherChars / 4);
}

// 检查是否接近溢出
const context = getConversationHistory();
const currentTokens = estimateTokens(context);
const LIMIT = 100000;

if (currentTokens > LIMIT * 0.9) {
  console.warn(`⚠️ 上下文已使用 ${Math.round(currentTokens/LIMIT*100)}%,即将溢出!`);
  // 触发压缩或分片
  compressContext();
}

示例2:自动摘要老消息

# Python示例:使用LLM压缩历史消息
def compress_history(messages, max_tokens=50000):
    """将超出限制的历史消息压缩为摘要"""
    total_tokens = sum(estimate_tokens(m) for m in messages)
    
    if total_tokens <= max_tokens:
        return messages
    
    # 分离最近消息和老消息
    recent = messages[-10:]
    old = messages[:-10]
    
    # 让LLM生成摘要
    summary = llm.call(f"请总结以下对话的核心信息:\n{format_messages(old)}")
    
    # 用摘要替换老消息
    compressed = [{"role": "system", "content": f"[历史摘要]:{summary}"}] + recent
    return compressed

✅ 最佳实践

🏆 防止溢出的5个技巧

  1. 设置Context Budget:在OpenClaw配置中明确限制最大Token数
  2. 精简System Prompt:删除冗余指令,用Skills模块化加载
  3. 工具Schema优化:避免过于详细的JSON Schema,只保留必要字段
  4. 启用工具结果压缩:对长结果自动截断或摘要
  5. 定期清理会话:长时间任务使用Sub-Agent分片处理

⚠️ 常见踩坑

🚨 踩坑实录

📊 工具对比

方案 优点 缺点 适用场景
滑动窗口 简单高效,自动管理 丢失早期细节 普通对话Agent
摘要压缩 保留关键信息 压缩过程消耗Token 长文档分析
会话分片 彻底解决溢出问题 需要汇总逻辑 长时间任务、Multi-Agent
向量检索(RAG) 只检索相关内容 可能漏掉关键信息 知识库问答

🔗 相关资源

🎭 周星驰式总结

context window overflow,说白了就是「内存不够,脑子短路」。

就像你跟朋友吹牛逼,吹到一半突然忘了开头说了啥,只能尴尬地来一句:「总之就是很厉害!」

解决办法?要么少说点(压缩),要么拿个小本本记着(外部存储),要么换个脑子更大的朋友(换模型)。

——最后,我的Agent终于学会了「好记性不如烂笔头」这个道理。