# 第四阶段 · 模块四 · 第四节:上下文限制与优化
Claude Code 的上下文限制是多少?超出限制会发生什么?如何优化上下文使用?
Claude Code 全局架构
┌─────────────────────────────────────────────────────────────────────┐
│ 查询引擎层 │
│ │
│ 上下文限制与优化 ← 本节 │
│ ├── MODEL_CONTEXT_WINDOW ──> 200K tokens │
│ ├── AUTO_COMPACT_THRESHOLD ──> 80% │
│ └── Token 计算 ──> 估算 vs 精确 │
└─────────────────────────────────────────────────────────────────────┘
源码位置:`src/utils/context.ts` 第 9 行
// Model context window size (200k tokens for all models right now)
export const MODEL_CONTEXT_WINDOW_DEFAULT = 200_000
┌─────────────────────────────────────────────────────────────────────┐
│ 200,000 tokens 总限制 │
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 用户消息历史 │ │
│ │ 助手回复 │ │
│ │ 工具结果 │ │
│ │ 系统提示词 │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ 预留缓冲(约 20%) │
│ │
│ 实际可用 ≈ 160,000 tokens │
└─────────────────────────────────────────────────────────────────────┘
问 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
// 压缩历史消息,释放空间
// 当上下文使用达到 80% 时触发自动压缩
const AUTO_COMPACT_THRESHOLD = 0.8
// 计算上下文使用率
function shouldAutoCompact(): boolean {
const usage = getContextUsage()
return usage > AUTO_COMPACT_THRESHOLD
}
上下文使用率超过 80%
│
▼
触发 autoCompact
│
▼
生成历史摘要
│
▼
用摘要替换历史消息
│
▼
继续对话
问 1:用户可以禁用 autoCompact 吗?
// 环境变量禁用
process.env.DISABLE_AUTO_COMPACT = '1'
// 或在 Claude Code 设置中禁用
源码位置:`src/utils/context.ts` 第 24 行
// Default max output tokens
export const CAPPED_DEFAULT_MAX_TOKENS = 8_000
// 如果需要更多输出
export const ESCALATED_MAX_TOKENS = 64_000
// 问题:为什么限制输出 token?
// 1. 成本控制
// 输出 token 也需要付费
// 2. 性能
// 长输出需要更多处理时间
// 3. 资源
// 保留插槽容量
问 1:输出超限会怎样?
// 如果请求需要超过 8k 输出:
// 1. 第一次请求:8k limit
// 2. 如果需要更多:自动重试,使用 64k limit
// 源码位置:query.ts max_output_tokens_escalate
// 估算(快速,用于检查限制)
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
}
// 单条消息
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
}
问 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
}
// 工具结果太大时截断
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
}
// 图片占用大量 token
// Claude Code 会压缩图片
async function compressImage(image: Buffer): Promise<Buffer> {
// 目标:不超过 token 限制
const targetTokens = 1000
const targetBytes = targetTokens * 4 // 估算
return resize(image, { maxBytes: targetBytes })
}
// 压缩时添加边界消息
interface CompactBoundaryMessage {
type: 'system'
subtype: 'compact_boundary'
content: string // 摘要内容
}
// 压缩后的消息列表
[
{ type: 'system', subtype: 'compact_boundary', content: 'Earlier conversation...' },
{ type: 'user', content: '最新消息' },
{ type: 'assistant', content: '最新回复' }
]
源码位置:`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')
}
// 在模型名中添加 [1m]
// 例如:claude-opus-4-5-20251120 [1m]
// 或通过环境变量
process.env.CLAUDE_CODE_DISABLE_1M_CONTEXT = '1' // 禁用
问 1:1M 上下文的意义?
// 1M = 1,000,000 tokens
// 比标准 200k 大 5 倍
// 能力:
// - 读取整个代码库
// - 超长对话不压缩
// - 复杂分析更全面
// 限制:
// - 仅部分模型支持
// - Beta 功能
// - 可能更贵
答案:
// 在 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
}
}
答案:
| 策略 | 触发时机 | 效果 |
| autoCompact | 80% | 自动压缩历史 |
| /compact | 用户触发 | 手动压缩 |
| /clear | 用户触发 | 清空历史 |
| 拒绝输入 | 95%+ | 提示用户清理 |
答案:
// 1. 使用 /compact 手动压缩
/compact summarize key points
// 2. 开启自动压缩
// 设置 → 上下文 → 自动压缩 → 启用
// 3. 清理会话
/clear
// 4. 分割长对话
// 将复杂任务拆分为多个会话
| 文件 | 核心内容 |
| `src/utils/context.ts` | 上下文限制常量 |
| `src/services/compact/` | 压缩服务 |
| `src/utils/imageResizer.ts` | 图片压缩 |
下一节我们将进入 第五阶段:插件系统:
- 插件架构
- 插件注册
- 插件生命周期
*- 第一轮:□ 事实准确性*
*- 第二轮:□ 深度与洞见*
*- 第三轮:□ 可读性与价值*