随笔

Claude Code 源码解读 02:问题先怎样进入 Context

拆解用户输入从 submitMessage 到 processUserInput、附件聚合和 transcript 写入的路径,说明“看对问题”比直接行动更重要。

2026-04-21 Claude Code源码解读Context

Context 不是“把资料都塞给模型”,而是一次用户请求进入模型前的装配线。

快速了解

  • Context 的核心不是信息越多越好,而是模型调用前先把规则、状态、附件和用户消息分层放好。
  • submitMessage() 更像总装层,不只是把 prompt 传给模型。
  • CLAUDE.md、git status、image、IDE selection、memory 都不是同一种上下文,不能混写成主线。
  • 用户消息先写 transcript,是后续 resume 和审计的基础。

如果只想快速理解,可以先读这一节;如果要看源码机制,再往下看“主线与场景插入分类”和机制图。

机制图
机制图

设问与回应

设问回应
submitMessage() 到底负责了哪些装配工作?submitMessage() 不是把 prompt 转交给模型,而是一次 turn 的总装入口:模型配置、工具环境、权限上下文、memory prompt、Hook、附件、transcript 都在这里进入同一条链路。
fetchSystemPromptParts() 里的 system prompt、userContext、systemContext 分别承担什么?system prompt 更像底层行为约束,userContext 承接项目和用户侧上下文,systemContext 则补运行环境和系统状态。三者都进入模型前缀,但来源、可信度和变化频率不同。
processUserInput() 是普通文本处理,还是协议归一化?processUserInput() 不是普通字符串处理,而是协议归一化。普通文本、slash command、bash mode、图片、附件和 Hook 输出,最后都要变成后续 query loop 能消费的消息结构。
getAttachmentMessages() 为什么既是主线入口,又是场景增强聚合点?getAttachmentMessages() 是主线入口,因为每个 turn 都可能需要附件聚合;它也是场景增强聚合点,因为 IDE selection、image、memory、任务上下文等内容只在特定条件下进入。

主线与场景插入分类

机制/模块分类我保留的判断
QueryEngine.submitMessage()主线功能会话 turn 的入口,把输入、工具环境、权限上下文和模型请求串起来
fetchSystemPromptParts()主线功能构造 API 前缀上下文,决定模型请求前的基础提示
processUserInput()主线功能把用户输入归一化为 Message,是进入模型前的协议边界
getAttachmentMessages()主线 + 场景插入聚合点附件聚合是主线,但 image、IDE、memory、任务上下文按条件启用
getUserContext() 中的 CLAUDE.md场景插入依赖文件存在、环境变量、bare mode 等条件
recordTranscript before model call可观测/恢复支撑用户消息先落盘,保证 API 中断后仍能 resume

源码链路拆解

submitMessage() 是总装层。它先决定模型、thinking config、MCP / tools / agents、memory prompt、输入处理上下文、Hook、附件和 transcript 的进入顺序。
processUserInput() 做的是协议归一化。普通文本、slash command、bash mode、图片、附件、UserPromptSubmit Hook,最后都要落到 UserMessage + AttachmentMessages

从 Codex 差异拆解 Context 输入治理

Context 构建能力越强,越需要判断哪些内容是当前 turn 的高密度输入,哪些只是场景噪声。拿 Codex 做对比时,问题不应该停在“谁能塞更多上下文”,而要拆成几层:项目规则、运行状态、用户附件、工具反馈、异步预取和历史摘要是否拥有不同来源、不同新鲜度和不同进入时机。

这样看,Context 的核心不是扩大输入窗口,而是输入治理。Claude Code 把 submitMessage()processUserInput()、system/user/system context、attachments、memory 和 transcript 前置写入组织成一条装配线;Codex compact 失败问题也可以从这里反问:动态运行反馈是否应该和长期项目规则混在一起,摘要失败是否会污染后续任务,异步材料进入模型前是否有清晰边界。这个对比带来的设计理解是:优秀 agent harness 的 Context 层应该先把输入变成可分层、可追溯、可裁剪的协议对象,再交给模型推理。