第四节:上下文限制
Token 限制与消息轮转

作者:小学子 📚 | 日期:2026年4月2日 | 第四阶段 · 模块四


# 第四阶段 · 模块四 · 第四节:上下文限制与优化

核心问题

Claude Code 的上下文限制是多少?超出限制会发生什么?如何优化上下文使用?


◇ 本节位置


        Claude Code 全局架构
        
        ┌─────────────────────────────────────────────────────────────────────┐
        │  查询引擎层                                                          │
        │                                                                      │
        │  上下文限制与优化 ← 本节                                            │
        │  ├── MODEL_CONTEXT_WINDOW ──> 200K tokens                           │
        │  ├── AUTO_COMPACT_THRESHOLD ──> 80%                                │
        │  └── Token 计算 ──> 估算 vs 精确                                    │
        └─────────────────────────────────────────────────────────────────────┘
        


一、上下文限制

1.1 模型上下文窗口

源码位置:`src/utils/context.ts` 第 9 行


        // Model context window size (200k tokens for all models right now)
        export const MODEL_CONTEXT_WINDOW_DEFAULT = 200_000
        

1.2 Token 预算分配


        ┌─────────────────────────────────────────────────────────────────────┐
        │  200,000 tokens 总限制                                              │
        │                                                                      │
        │  ┌─────────────────────────────────────────────────────────────┐   │
        │  │  用户消息历史                                               │   │
        │  │  助手回复                                                   │   │
        │  │  工具结果                                                   │   │
        │  │  系统提示词                                                 │   │
        │  └─────────────────────────────────────────────────────────────┘   │
        │                                                                      │
        │  预留缓冲(约 20%)                                                 │
        │                                                                      │
        │  实际可用 ≈ 160,000 tokens                                         │
        └─────────────────────────────────────────────────────────────────────┘
        

1.3 五问分析

问 1:为什么需要预留缓冲?


        // 问题:API 需要预留空间给:
        // 1. 助手的新回复(可能很长)
        // 2. 工具调用的结果
        // 3. 错误消息
        
        // 如果等到 100% 才压缩:
        // - 新回复可能放不下
        // - 工具结果可能超限
        // - 紧急压缩用户体验差
        
        // Claude Code 预留 20-30% 缓冲
        const BUFFER_RATIO = 0.2
        const EFFECTIVE_LIMIT = 200_000 * (1 - BUFFER_RATIO)  // 160,000
        

问 2:200K 是绝对上限吗?


        // 是的,受限于 API
        // 1. API 不接受超过 200k 的请求
        // 2. 超出限制返回 error
        
        // 解决方案:compact
        // 压缩历史消息,释放空间
        


二、自动压缩阈值

2.1 触发阈值


        // 当上下文使用达到 80% 时触发自动压缩
        const AUTO_COMPACT_THRESHOLD = 0.8
        
        // 计算上下文使用率
        function shouldAutoCompact(): boolean {
          const usage = getContextUsage()
          return usage > AUTO_COMPACT_THRESHOLD
        }
        

2.2 压缩流程


        上下文使用率超过 80%
            │
            ▼
        触发 autoCompact
            │
            ▼
        生成历史摘要
            │
            ▼
        用摘要替换历史消息
            │
            ▼
        继续对话
        

2.3 五问分析

问 1:用户可以禁用 autoCompact 吗?


        // 环境变量禁用
        process.env.DISABLE_AUTO_COMPACT = '1'
        
        // 或在 Claude Code 设置中禁用
        


三、输出 Token 限制

3.1 输出限制常量

源码位置:`src/utils/context.ts` 第 24 行


        // Default max output tokens
        export const CAPPED_DEFAULT_MAX_TOKENS = 8_000
        
        // 如果需要更多输出
        export const ESCALATED_MAX_TOKENS = 64_000
        

3.2 限制说明


        // 问题:为什么限制输出 token?
        
        // 1. 成本控制
        // 输出 token 也需要付费
        
        // 2. 性能
        // 长输出需要更多处理时间
        
        // 3. 资源
        // 保留插槽容量
        

3.3 五问分析

问 1:输出超限会怎样?


        // 如果请求需要超过 8k 输出:
        // 1. 第一次请求:8k limit
        // 2. 如果需要更多:自动重试,使用 64k limit
        
        // 源码位置:query.ts max_output_tokens_escalate
        


四、Token 计算

4.1 估算 vs 精确


        // 估算(快速,用于检查限制)
        function estimateTokens(text: string): number {
          // 英文:约 4 字符 = 1 token
          // 中文:约 2 字符 = 1 token
          return Math.ceil(text.length / 4)
        }
        
        // 精确(慢,需要调用 API)
        async function countTokens(text: string): Promise<number> {
          const response = await api.countTokens({ text })
          return response.tokens
        }
        

4.2 消息 Token 统计


        // 单条消息
        function countMessageTokens(message: Message): number {
          return estimateTokens(message.content)
        }
        
        // 完整上下文
        async function countContextTokens(messages: Message[]): Promise<number> {
          let total = 0
          for (const msg of messages) {
            total += countMessageTokens(msg)
          }
          return total
        }
        

4.3 五问分析

问 1:Token 计算在哪里检查?


        // 在 query() 开始前检查
        async function query(params: QueryParams) {
          const tokenCount = await countContextTokens(params.messages)
        
          if (tokenCount > MODEL_CONTEXT_WINDOW_DEFAULT * 0.9) {
            await compact()  // 触发压缩
          }
        
          // 继续 query
        }
        


五、上下文优化

5.1 消息截断


        // 工具结果太大时截断
        const MAX_TOOL_RESULT_TOKENS = 10_000
        
        function truncateToolResult(result: string): string {
          const tokens = estimateTokens(result)
        
          if (tokens > MAX_TOOL_RESULT_TOKENS) {
            return truncate(result, MAX_TOOL_RESULT_TOKENS) + '\n[Truncated]'
          }
        
          return result
        }
        

5.2 图片压缩


        // 图片占用大量 token
        // Claude Code 会压缩图片
        
        async function compressImage(image: Buffer): Promise<Buffer> {
          // 目标:不超过 token 限制
          const targetTokens = 1000
          const targetBytes = targetTokens * 4  // 估算
        
          return resize(image, { maxBytes: targetBytes })
        }
        

5.3 压缩边界


        // 压缩时添加边界消息
        interface CompactBoundaryMessage {
          type: 'system'
          subtype: 'compact_boundary'
          content: string  // 摘要内容
        }
        
        // 压缩后的消息列表
        [
          { type: 'system', subtype: 'compact_boundary', content: 'Earlier conversation...' },
          { type: 'user', content: '最新消息' },
          { type: 'assistant', content: '最新回复' }
        ]
        


六、1M 上下文

6.1 支持的模型

源码位置:`src/utils/context.ts` 第 46 行


        // 检查模型是否支持 1M 上下文
        export function modelSupports1M(model: string): boolean {
          const canonical = getCanonicalName(model)
          return canonical.includes('claude-sonnet-4') ||
                 canonical.includes('opus-4-6')
        }
        

6.2 启用方式


        // 在模型名中添加 [1m]
        // 例如:claude-opus-4-5-20251120 [1m]
        
        // 或通过环境变量
        process.env.CLAUDE_CODE_DISABLE_1M_CONTEXT = '1'  // 禁用
        

6.3 五问分析

问 1:1M 上下文的意义?


        // 1M = 1,000,000 tokens
        // 比标准 200k 大 5 倍
        
        // 能力:
        // - 读取整个代码库
        // - 超长对话不压缩
        // - 复杂分析更全面
        
        // 限制:
        // - 仅部分模型支持
        // - Beta 功能
        // - 可能更贵
        


七、思考题

思考题 1:如何监控上下文使用?

答案


        // 在 Claude Code 中查看
        // 设置 → 显示上下文使用
        
        // 或通过 API
        async function checkUsage(): Promise<{
          used: number
          limit: number
          percentage: number
        }> {
          const messages = getMessages()
          const tokens = await countContextTokens(messages)
          const limit = getContextWindowLimit()
        
          return {
            used: tokens,
            limit,
            percentage: (tokens / limit) * 100
          }
        }
        


思考题 2:超限后的处理策略?

答案

策略触发时机效果
autoCompact80%自动压缩历史
/compact用户触发手动压缩
/clear用户触发清空历史
拒绝输入95%+提示用户清理


思考题 3:如何减少上下文使用?

答案


        // 1. 使用 /compact 手动压缩
        /compact summarize key points
        
        // 2. 开启自动压缩
        // 设置 → 上下文 → 自动压缩 → 启用
        
        // 3. 清理会话
        /clear
        
        // 4. 分割长对话
        // 将复杂任务拆分为多个会话
        


八、延伸阅读

文件核心内容
`src/utils/context.ts`上下文限制常量
`src/services/compact/`压缩服务
`src/utils/imageResizer.ts`图片压缩


九、下节预告

下一节我们将进入 第五阶段:插件系统

- 插件架构

- 插件注册

- 插件生命周期


*- 第一轮:□ 事实准确性*

*- 第二轮:□ 深度与洞见*

*- 第三轮:□ 可读性与价值*