【图解】Claude Code 源码解析|顶级Agent架构、Tool、Skill(一)
写在前面
前段时间Claude Code的源码泄漏了,最近也稍微用ai速读了一下整个架构,内容实在太多了,这篇文章就先捋一下Claude Code的整个 Agent 框架体系,看看今年最火的Harness架构具体是什么样的。本文主要内容聚焦于整理架构流程、Tool 和 Skill等等
架构
Claude Code的Agent架构图大概如下所示:

和大多数Agent架构类似,CC的整体架构偏向ReAct的开发范式,主要由以下几个模块组成:
-
主查询循环,Query Loop + LLM Loop -
统一的 Tool 协议 -
统一的 cmd/Skill 协议 -
统一的记忆管理和检索模块 -
顶级 Prompt(做过Agent的都知道调Prompt有多痛苦) -
规整有序的上下文拼接和压缩恢复模块 -
Master Agent/SubAgent/Task/Coordinator的调度系统 -
精准而不冗余的权限控制 -
…
关于这里面所有的Prompt,我们下篇文章再展开说说。下面我们从头开始讲一个query在CC中的处理流程。
Query 处理

这一步是把 用户的输入 转换成 内部消息对象 + 附件对象
-
Query 如果是从非交互主入口进来,则会直接进入 QueryEngine 模块处理。 -
如果是从交互模式进来,则会判断 是普通的prompt/bash模式/slash cmd,是否带图片、是否带附件等等。
此时也会进行相似记忆的检索动作,包括检索用户的编码喜好习惯等等,将记忆连同query一同注入到上下文中,做上下文增强。记忆具体是怎么存储,怎么检索的我们放到下篇文章。
上下文前缀
获取Query和相似记忆之后,在请求大模型之前,还需要加载一些上下文的前缀信息,包括SystemPrompt、System Ctx、UserCtx等等。

-
SystemPrompt:工具使用说明、memory 机制说明、输出风格、环境信息、MCP 指令等 -
UserContext:CLAUDE.md 聚合内容、当前日期等 -
SystemContext:git status、cache breaker 等
CC在这些message的编排上有一个规则:
-
SystemContext追加到SystemPrompt后,例如 System Prompt = default/custom/agent/coordinator prompt + SystemContext -
UserContext 包成 meta user message,插到消息最前面,例如 Messages = [meta UserContext, ...业务消息]
工具选取与上下文治理
在这一步中,CC会从工具池中筛选出当前轮次可用的工具,作为一个工具集合一起发送给模型,工具这里我们后面再详细说明。

此时的上下文内容包括了 这一轮发给模型的Message、SystemPrompt、Tool Schema、Memory、Attachments 等等… 如果当前的上下文太长、太多、太乱,CC会先进行上下文治理。
计算当前的Context窗口大小的Token是否已超过某个阈值,超过则进行Context Collapse,如果进行 Context Collapse 之后还是超过这个阈值,则进行Autocompact,如果还不行就会请求模型做一次 full compact。
-
Context Collapse:不立刻重写整段历史,而是先把一部分旧上下文折叠成一个更短的投影视图。 比如工具的返回字段太多了,对某些字段做降级处理,也就是只保留精简字段等等。 -
Autocompact:真的把对话历史重构成一个新的、更短的消息序列。
⚠️ 注意:压缩之后的消息是有一个排序规则的:
exportfunctionbuildPostCompactMessages(result: CompactionResult): Message[] {return [ result.boundaryMarker, ...result.summaryMessages, ...(result.messagesToKeep ?? []), ...result.attachments, ...result.hookResults, ]}
-
boundaryMarker: 边界标记,相当于一个分界线,告诉模型:从这里开始,前面的原始历史已经被压缩掉了,下面这些消息不是完整原始对话,而是压缩后的重建结果。 -
summaryMessages:这是压缩出来的摘要消息。 -
messagesToKeep: 有些消息不能靠摘要代替,必须原样保留在 compact 后的上下文里 -
attachments:compact 之后,原先很多上下文附件已经丢失了,所以要重新注入。摘要本身通常不包含这些运行时约束信息。 -
hookResults:compact 后还会跑 SessionStart hooks,包括重新注入CLAUDE.md、自定义系统约束、环境补充信息等等
标准化信息与流式交互
在标准化信息的这个阶段会做的事情有: attachment 重排、去掉 progress/system 等不可发内容、合并连续 user messages、切分无效 tool references、修复 tool_use/tool_result 配对、删除过多媒体项等等

请求发出之后,模型开始streaming流式输出,模型可能会产出 普通assistant文本、 thinking、 tool_use
-
如果 只是文本并且无工具调用,就会走后面的结束流程 -
如果有ToolUse,则会调用ToolUse,将ToolUse的Result回传给LLM, 让LLM自己判断是否需要结束本次循环。如果LLM已经没有tool use了,或者命中了其他的策略,比如账户没钱了,就会退出LLM的Loop,走后面的结束流程。
结束的流程会有一个 stop hooks ,内容包括:
-
Transcript 持久化:每一轮的中间态和最终态都会进行持久化,持久化会话状态。做会话状态恢复的时候,不止恢复message,还有 skill state、tool use、session metadata等等… -
Extract Memory: 这里会 fork 一个 memory extraction subagent,去检查这一轮有没有新的信息值得长期记忆。这里只会在 memory 目录下做读取,可以更新 topic files和MEMORY.md 文件。 -
Session Memory: 这是当前会话摘要,不是长期记忆,可以理解为短期的session记忆。本轮结束后,如果 token 增长 / 工具调用数达到阈值,创建或读取summary.md,fork 一个受限子 agent,只允许编辑这一个文件,做当前 session 的结构化摘要更新。
Tool
接下来我们展开聊一下Tool的处理细节。

-
当模型需要进行 ToolCall 的时候,会先去可用的工具池子找这个工具,如果找不到就返回error -
进入统一执行器 streamedCheckPermissionsAndCallTool,这一步会做几个校验动作。

-
类型校验: 先是工具自己的 Schema Check做校验,看看模型生成的参数类型是否正确。 -
语义校验: 做 业务的 Input Validate 校验,检查路径是否合法、参数组合是否冲突、命令是否合理、skill是否存在等等.. -
PreHook:进入预执行的hook,这一步比较像 可插拔的前置干预器,可以改写输入的input、增加额外上下文、直接给权限决策等等 -
Permission Decision:前置的hook结束之后,才会进入权限系统, 会把hook给的权限决策、CanUseTool、全局权限模式、用户规则、Classifier合并起来得到一个结果。allow、deny、ask。 -
如果没有放行,模型会收到一个失败的tool result,然后LLM自己决定换方法,请求别的工具。 -
如果通过了放行,那么就直接进行 tool call操作并且根据Tool协议返回结果给LLM做新一轮的输入。 -
在工具执行完成之后,还会跑一个 Post Hooks,包括增加附属消息、额外上下文、提示用户等等

Skill
⚠️ 注意:如果这次调用的是 SkillTool,执行路径还是同一条主线,但 tool.call() 的内部含义不同。它的tool.call() 做的事不是操作外部世界, 而是:
-
找到一个 skill cmd,展开 SKILL.md / cmd prompt。 -
生成新的 meta user messages。 -
附加 command_permissions,返回contextModifier。
Skill其实就是一份标准的SOP,而我们常说的渐进式披露就是在这里体现的:一个skill里面可能会包含很多tool,此时我们会先把skill描述给到模型,模型去判断做选择用哪些skill,再去调用真正的tool。

skill 执行的时候会把 skill 名称、来源、正文内容登记起来。此时 skill 已经不再只是一个命令,而是变成了 用户/系统消息、权限附加信息、可能的附件的一个组合,也就是真正的后续上下文素材。
所以 SkillTool 的 tool_result 只是表层结果,真正重要的是:它往消息流里塞进了新的 prompt 片段,还改变了后续的权限和模型配置。也就是说,SkillTool 是一个用 tool 协议包装的上下文变换器。
最后
Claude Code和大多数的Agent架构类似,不过里面有非常多的细节可以耐人寻味的,包括 多重压缩的上下文治理,消息的顺序与补充,以及文章这里没提到的多重权限管理 等等…
从我自己做Agent的角度来看,Prompt 和 记忆选取也是很重要的,调Prompt过程非常痛苦。下篇文章,我们就来讲讲Claude Code里面的Prompt和记忆管理模块。
夜雨聆风