4.8 大结果处理机制
当工具输出超过 maxResultSizeChars,Claude Code 不会将全部内容注入对话上下文:
- 将完整结果保存到
~/.claude/projects/<项目目录>/<sessionId>/tool-results/(按项目、按会话隔离) - 模型接收:文件路径预览 + 截断指示符
- 模型可通过 FileReadTool 按需读取完整内容
这避免了上下文膨胀,同时保持完整数据的可达性。
各工具的典型阈值
不同工具的 maxResultSizeChars 根据其输出特征设定:
| 工具类型 | maxResultSizeChars | 说明 |
|---|---|---|
| BashTool | 30,000 | Shell 命令输出可能非常大(如 find /) |
| GrepTool | 20,000 | 大范围搜索可能匹配数千行 |
| WebFetchTool | 100,000 | 网页内容长度不可控 |
| FileReadTool | Infinity | 输出已由 maxTokens 分页自限,显式豁免落盘(落盘后再让模型 Read 读回来是循环的) |
需要注意:工具声明的 maxResultSizeChars 还会被 getPersistenceThreshold() 用 DEFAULT_MAX_RESULT_SIZE_CHARS = 50,000 取 min 钳制——即声明值超过 50,000 也不会真正生效(这也是下一节侧栏所说的 50,000 上限)。
MCP 工具的大结果处理
MCP 工具的输出有额外处理:当输出超过 25,000 token 时——默认值来自 DEFAULT_MAX_MCP_OUTPUT_TOKENS,可用 MAX_MCP_OUTPUT_TOKENS 环境变量覆盖——truncateMcpContent() 会就地截断并追加一条截断提示 [OUTPUT TRUNCATED - exceeded N token limit];其中的图片块会先由 compressImageBlock() 压缩、尽量塞进剩余的 token 预算,不会整体丢弃(utils/mcpValidation.ts)。至于超大的文本结果,则和其他工具一样走通用的 tool-results 落盘机制,见 4.8 节;并不存在专门的"二进制 blob 落盘后返回路径"通道。注意这里是 25,000 token 而非 25KB。
整体设计遵循"按需读取"模式(on-demand read pattern):模型先看到结果的摘要和位置信息,只在需要详细数据时才通过 FileReadTool 主动拉取。这将一次性的上下文爆炸转化为可控的增量读取。
设计决策:工具结果的三级大小限制
源码中定义了三个递进的限制层(
src/constants/toolLimits.ts):
DEFAULT_MAX_RESULT_SIZE_CHARS = 50,000:单个工具结果的默认上限,超过则持久化到磁盘MAX_TOOL_RESULT_TOKENS = 100,000(约 400KB):绝对上限,任何工具都不能超过MAX_TOOL_RESULTS_PER_MESSAGE_CHARS = 200,000:单条消息中所有工具结果的聚合上限为什么需要三级?因为并发工具执行时,5 个工具各返回 50K 字符的结果就是 250K——超过单消息限制。聚合上限确保即使多个工具并发返回大结果,注入到对话中的总数据量也不会让上下文窗口失控。