站点图标 高效码农

Claude Code本质拆解:源码曝光AI Agent操作系统的设计与性能核心

Claude Code 源码深度解析:一套 Agent 操作系统的设计哲学

核心问题:Claude Code 为什么比普通的 AI 编程助手更”稳”?

答案藏在它的架构里——这不是一个”会调工具的聊天机器人”,而是一个把提示词编排、工具治理、Agent 分工、上下文经济学和生命周期管理全部打通的 Agent 操作系统。本文基于源码级拆解,带你看到冰山之下的工程实践。


一、架构全景:为什么它更像操作系统而非 CLI 工具?

核心问题:Claude Code 的源码结构暴露了怎样的设计复杂度?

从提取出的 4756 个源码文件来看,Claude Code 的顶层结构至少包含以下模块:

  • 入口层src/entrypoints/):CLI、初始化流程、MCP 模式、SDK 四种入口
  • 常量与提示词src/constants/):系统提示词、风险提示、输出规范
  • 工具层src/tools/):FileRead、Bash、Agent、Skill、MCP 等具体实现
  • 运行时服务src/services/):工具执行、MCP 集成、分析追踪
  • 命令系统src/commands/):slash command 与系统级控制命令
  • 协调器src/coordinator/):多 Agent 协调模式
  • 记忆系统src/memdir/):跨会话记忆管理
  • 插件与 Hooksrc/plugins/src/hooks/):扩展机制与运行时治理
  • 任务系统src/tasks/):本地任务、远程任务、异步 Agent 任务


图片来源:Unsplash

这个目录结构说明:Claude Code 从设计之初就不是单一 CLI 包装器,而是一个平台化运行时。同一个 agent runtime 可以服务 CLI、桌面应用、Web 界面和 SDK 消费者四种不同的交互表面。

命令系统:产品的控制面板

命令系统暴露了 /mcp/memory/permissions/hooks/plugin/skills/tasks/plan/review/agents 等十几个系统级命令。更关键的是,它不仅注册内置命令,还统一加载:

  • Plugin commands
  • Skill commands
  • Bundled skills
  • 动态 skills(经可用性过滤后)

应用场景:当你在终端输入 /skills 时,看到的不是静态列表,而是系统根据当前项目状态、已安装插件、可用 MCP 服务器动态计算出的”当下你能用的能力清单”。这种设计让命令系统本身成为生态的统一入口。


二、提示词架构:不是静态文本,而是运行时编排器

核心问题:Claude Code 的系统提示词是如何动态拼装的?

源码中最关键的文件是 src/constants/prompts.ts。它承担的不是”写一段好文案”的任务,而是主系统提示词的总装配——包括环境信息注入、工具使用规范、安全风险规范、会话级指导、语言风格、MCP 说明、记忆提示等十余个模块的动态组合。

静态前缀与动态后缀的分离设计

getSystemPrompt() 函数的核心结构是:

静态前缀(更适合缓存):

  • getSimpleIntroSection():身份定位
  • getSimpleSystemSection():基础系统规范
  • getSimpleDoingTasksSection():做任务的哲学
  • getActionsSection():风险动作规范
  • getUsingYourToolsSection():工具使用规范
  • getSimpleToneAndStyleSection():语气风格
  • getOutputEfficiencySection():输出效率

动态后缀(按会话条件注入):

  • Session guidance(会话指导)
  • Memory(记忆)
  • Environment info(环境信息)
  • Language(语言设置)
  • Output style(输出风格)
  • MCP instructions(MCP 说明)
  • Scratchpad(便签本)
  • Function result clearing(函数结果清理)
  • Token budget(令牌预算)
  • Brief mode(简洁模式)

设计洞察:源码中明确存在 SYSTEM_PROMPT_DYNAMIC_BOUNDARY 标记,注释说明”边界前尽量可缓存,边界后是用户/会话特定内容,不能乱改否则会破坏缓存逻辑”。这说明 Claude Code 已经在做 Prompt assembly with cache economics——把提示词当作可编排的运行时资源来管理,连 token 成本和缓存命中都做了工程化优化。

场景示例:多语言项目的动态适配

假设你正在一个中英混合的团队中工作。当你切换语言设置时,Claude Code 不会重新加载整个系统,而是:

  1. 保持静态前缀不变(缓存命中)
  2. 在动态边界后注入新的语言指令
  3. 保留工具定义和 MCP 说明的结构一致性

这种设计让多语言支持的成本降到最低,同时保证模型始终”知道”自己该用什么语言回应。


三、行为规范:把”好习惯”写成制度

核心问题:Claude Code 如何避免模型行为漂移?

getSimpleDoingTasksSection() 模块中,系统用非常具体的规则约束模型行为:

约束类型 具体规则
功能边界 不要加用户没要求的功能;不要过度抽象;不要瞎重构
代码规范 不要乱加 comments/docstrings/type annotations;不要做不必要的 error handling/fallback
工作流程 先读代码再改代码;不要轻易创建新文件;不要给时间估计
问题解决 方法失败时要先诊断再换策略;删除确认没用的东西,不搞 compatibility 垃圾
结果汇报 结果要如实汇报,不能假装测试过

反思 / 学到的教训:很多 coding agent 不稳定,根源不是”不会写代码”,而是行为发散。Claude Code 的解决方式不是依赖模型”更聪明”,而是把行为规范制度化——用明确的 prompt 规则消除模糊地带。

风险动作规范(getActionsSection())同样体现了这种思维:

  • 明确定义”需要确认的风险动作”:破坏性操作、难以回滚的操作、修改共享状态、对外可见动作、上传到第三方工具
  • 强调”不要用破坏性操作当捷径”
  • 遇到 merge conflict 或 lock file 不要粗暴删除

实际场景:当你让 Claude Code 删除一个看起来很旧的配置文件时,它不会立即执行 rm,而是先检查这个文件是否被其他进程引用、是否在 git 历史中有特殊含义、删除后是否会影响团队其他成员。这种”blast radius 意识”不是模型自己悟出来的,是 prompt 里写死的。


四、工具治理:从”模型决定”到”流水线执行”

核心问题:Claude Code 的工具调用经历了怎样的治理流程?

工具执行不是”模型说调就调”的简单映射。实际链路是:

  1. 找 tool definition
  2. 解析 MCP metadata
  3. Zod schema 输入校验
  4. 工具特定的 validateInput
  5. Bash 命令的 speculative classifier 风险预判
  6. 运行 PreToolUse hooks
  7. 解析 hook 权限结果
  8. 走正式 permission 决策
  9. 根据 permission 修正输入
  10. 真正执行 tool.call()
  11. 记录 analytics/tracing/OTel
  12. 运行 PostToolUse hooks
  13. 处理结构化输出
  14. 失败则走 PostToolUseFailure hooks

Hook 系统的运行时治理力

Hook 支持三种介入点:

  • PreToolUse:工具执行前拦截
  • PostToolUse:工具成功后处理
  • PostToolUseFailure:工具失败后处理

Hook 不仅能记日志,还能:

  • 返回 message / blockingError
  • 改写 updatedInput
  • 给出 permissionBehavior(allow/ask/deny)
  • 阻止 preventContinuation
  • 补充 additionalContexts

关键设计resolveHookPermissionDecision() 函数定义了 Hook 权限语义与总权限模型的关系——Hook 说 allow 不一定绕过系统设置的 deny/ask 规则;Hook 说 deny 则直接生效。这种”强大但受控”的设计是工程成熟度的体现。

应用场景:假设你在一个金融项目中使用 Claude Code,可以通过 Hook 实现:

  • 所有涉及数据库写入的操作必须经过二次确认
  • 所有对外部 API 的调用必须记录审计日志
  • 所有删除操作必须先备份到指定目录

这些策略不需要修改核心代码,通过 Hook 配置即可实现。


五、多 Agent 分工:为什么一个人做不好所有事?

核心问题:Claude Code 如何通过 Agent 专业化提升稳定性?

源码确认了至少六个内建 Agent,每个都有明确的职责边界:

Agent 类型 职责定位 关键约束
General Purpose Agent 通用任务处理 无特殊限制
Explore Agent 纯读模式代码探索 绝对只读:不能创建、修改、删除文件;Bash 只允许 ls/git status/git log/git diff/find/grep/cat/head/tail
Plan Agent 纯规划,不做编辑 只读;输出 step-by-step implementation plan;必须列出 Critical Files for Implementation
Verification Agent 对抗性验证 目标是 try to break it;必须跑 build/test/linter;每个检查必须带 command 和 output observed;最终必须输出 VERDICT: PASS/FAIL/PARTIAL
Claude Code Guide Agent 产品使用指导 帮助用户理解 Claude Code 功能
Statusline Setup Agent 状态栏配置 处理状态栏相关设置

Verification Agent:最值得学习的设计

Verification Agent 的 prompt 可能是整个系统中最”狠”的。它明确点出两类验证失败模式:

  1. Verification avoidance:只看代码不跑检查,写个 PASS 就走
  2. 被前 80% 迷惑:UI 看起来还行、测试也过了,就忽略剩下 20% 的问题

强制要求包括:

  • 跑 build、test suite、linter/type-check
  • 前端改动要跑浏览器自动化/页面子资源验证
  • 后端改动要用 curl/fetch 实测响应
  • CLI 要看 stdout/stderr/exit code
  • Migration 要测 up/down 和已有数据
  • Refactor 也要测 public API surface
  • 必须做 adversarial probes(主动找边界情况)

反思 / 独特见解:传统软件工程中”实现者和验证者分离”是常识,但在 AI Agent 系统里,大部分产品还没做到这一步。Claude Code 把 Verification Agent 独立出来,让它和”写代码的 Agent”没有利益关联,从根本上对抗了”实现者 bias”——写代码的 Agent 会倾向于觉得自己写得没问题,但验证 Agent 的工作就是找问题。


六、Agent 调度链:14 步 Pipeline 的工程考量

核心问题:一个子 Agent 从被触发到执行完成经历了什么?

完整的调度链路可以抽象为:

  1. 主模型决定调用 Agent 工具
  2. AgentTool.call() 解析输入
  3. 解析是否 teammate/fork/built-in/background/worktree/remote
  4. 选择 agent definition
  5. 构造 prompt messages
  6. 构造/继承 system prompt
  7. 组装工具池
  8. 创建 agent-specific ToolUseContext
  9. 注册 hooks/skills/MCP servers
  10. 调用 runAgent()
  11. runAgent() 内部调用 query()
  12. query 产出消息流
  13. runAgent 记录 transcript、处理 lifecycle、清理资源
  14. AgentTool 汇总结果或走异步任务通知

Fork Path vs Normal Path

维度 Fork Path Normal Path
触发条件 subagent_type 省略且 fork 特性开启 明确指定 built-in/custom agent type
System Prompt 继承主线程 基于 agentDefinition 生成新的
上下文 完整继承父线程 只给该 agent 所需上下文
工具集 尽量与父线程一致(保证 cache 命中) 走该 agent 的 tool restrictions
设计目标 复用主线程 cache,不白烧 token 严格隔离,角色清晰

关键洞察:Fork 不是”再开一个普通 agent”,而是为了 cache 和 context 继承专门优化的执行路径。注释中明确提到”保持 API request prefix byte-identical 以提高 prompt cache 命中”——这种对 token 成本的精细化考量,体现了产品级系统思维。

生命周期管理的产品化细节

runAgent() 中包含大量产品级细节:

  • recordSidechainTranscript():记录旁路对话
  • writeAgentMetadata():写入 Agent 元数据
  • registerPerfettoAgent():性能追踪注册
  • cleanupAgentTracking():清理追踪状态
  • killShellTasksForAgent():终止该 Agent 的 shell 任务
  • 清理 session hooks、cloned file state、todos entry

应用场景:当你在后台启动一个耗时较长的代码分析任务(比如让 Explore Agent 遍历整个代码库找模式),你可以关闭终端去做别的事。当任务完成,Claude Code 会通过 notification 机制回到主线程,你可以选择查看摘要或完整输出。这种”前台/后台”无缝切换的体验,来自对 Agent 生命周期的完整管理。


七、Skill、Plugin、MCP:生态的关键是模型”知道”

核心问题:Claude Code 的扩展机制如何让模型感知到自己的能力?

Skill:Workflow Package

Skill 不是文档,而是带 frontmatter metadata 的 markdown prompt bundle:

  • 可声明 allowed-tools
  • 可按需注入当前上下文
  • 可把重复工作流压缩成可复用能力包

系统要求:当任务匹配到 skill 时,必须调用 Skill tool 执行,不能只提 skill 不执行。

Plugin:Prompt + Metadata + Runtime Constraints

Plugin 能提供的能力包括:

  • Markdown commands
  • SKILL.md skill 目录
  • commandsMetadata
  • userConfig(敏感值存系统 keychain,不落盘)
  • Shell frontmatter
  • allowed-tools
  • Model/effort hints
  • Runtime 变量替换(支持 ${CLAUDE_PLUGIN_ROOT}${CLAUDE_SESSION_ID} 等)

MCP:不只是工具桥

当 MCP server 连接时,如果 server 提供了 instructions,这些 instructions 会被拼进 system prompt。这意味着 MCP 能同时注入:

  1. 新工具
  2. 如何使用这些工具的说明

反思 / 学到的教训:很多平台也有插件系统、工具市场,但模型本身不知道”有哪些扩展、什么时候该用、怎么用”。Claude Code 通过 skills 列表、agent 列表、MCP instructions、session-specific guidance、command integration 让模型”知道自己的扩展能力是什么”。这才是生态真正能发挥作用的关键——你给一个人配了专业工具箱,但他不知道箱子里有什么,那这些工具就等于不存在。


八、上下文经济学:把 Token 当钱花

核心问题:Claude Code 如何在有限上下文窗口内最大化信息价值?

源码中大量设计围绕”上下文是稀缺资源”展开:

机制 作用 场景价值
System prompt 动静边界 静态部分缓存,动态部分按需注入 降低重复计算成本
Fork path cache-identical prefix 子任务复用主线程缓存 复杂任务并行执行时不白烧 token
Skill 按需注入 不是一开始就全部塞进去 保持初始上下文简洁
MCP instructions 按连接状态注入 没连上的 server 的说明不占空间 避免无效信息干扰
Function result clearing 主动清理已完成的函数结果 释放上下文空间
Summarize tool results 长结果自动摘要 避免单条输出占满窗口
Compact / transcript / resume 上下文压缩与会话恢复 长会话不中断

独特见解:对于做 Demo 的人来说,上下文管理不是问题——Demo 跑几次就结束了。但对于做产品的人来说,上下文经济学直接关系到成本和体验。每天处理几万次请求,每次请求的 system prompt 有几千个 token,缓存命中率提高 10%,一个月下来省下的成本可能够多雇一个人。Claude Code 的这些设计不是”过度优化”,而是产品规模化后的必选项。


九、产品化的最后一公里:为什么它不像原型而像正式产品?

核心问题:Claude Code 在工程细节上做了哪些让体验更”稳”的设计?

权限与安全的架构化

Claude Code 不是简单告诉模型”be careful”,而是通过多层机制强制执行安全:

  • Sandbox isolation:工具运行在受控环境
  • Layered permissions:Hook → Policy → User approval 的分层决策
  • Human-in-the-loop:关键操作必须用户确认
  • PreToolUse Hook:比大多数 AI 工具的总安全基础设施还完善

行为规范的制度化

前文提到的”不要加用户没要求的功能”、”先读代码再改代码”、”结果要如实汇报”等规则,本质上是在解决一个核心问题:不要把”好习惯”交给模型即兴发挥,而是写进 prompt 和 runtime 规则里

Agent 专业化的分工价值

Explore / Plan / Verification 这套 built-in agents 的价值不在于”多了三个 agent”,而在于:

  • 研究和探索不污染主线程
  • 规划和实现分离,降低混乱
  • 验证独立出来,对抗实现者 bias

很多系统的问题是一个 agent 既研究、又规划、又实现、又验收,最终哪件事都不够稳定。Claude Code 的明确分工让每类任务都有专门优化的执行路径。


实用摘要 / 操作清单

如果你是技术负责人或正在评估 AI 编程工具,这份清单帮你快速判断 Claude Code 是否适合你的场景:

✅ 适合使用 Claude Code 的场景

  • 需要跨多文件协调的复杂重构
  • 需要自动化 CI/CD 集成的团队
  • 有明确安全合规要求(需要权限分层)
  • 需要后台长时间运行的分析任务
  • 希望通过 MCP 连接内部工具链

⚠️ 需要谨慎评估的场景

  • 只需要 IDE 实时补全(Copilot/Cursor 更合适)
  • 需要完全离线的 air-gapped 环境(Claude Code 需要云连接)
  • 团队对 token 消耗敏感(Agent Teams 用量较大)

🔧 快速上手建议

  1. 在项目根目录创建 CLAUDE.md 记录项目规范
  2. 通过 /mcp 连接团队常用的外部工具(Jira、Slack、Notion 等)
  3. 使用 /plan 让 Plan Agent 先输出实现方案,再执行
  4. 对关键任务启用 Verification Agent 做对抗性验证
  5. 通过 Hook 配置团队特定的安全策略(如数据库写入二次确认)

一页速览(One-page Summary)

Claude Code 核心架构
├── 入口层:CLI / MCP / SDK / 初始化
├── 提示词架构:静态前缀 + 动态边界(缓存优化)
├── 工具治理:输入校验 → Hook 拦截 → 权限决策 → 执行 → PostHook
├── 多 Agent 分工:Explore(只读)/ Plan(规划)/ Verification(验证)
├── 调度链:14 步 Pipeline,Fork 复用主线程缓存
├── 扩展生态:Skill(工作流包)/ Plugin(行为扩展)/ MCP(工具+说明注入)
├── 上下文经济学:动静分离、按需注入、压缩恢复
└── 生命周期:Transcript 记录、性能追踪、资源清理、前后台切换

设计哲学:不把"好行为"交给模型即兴发挥,而是写成制度
护城河:不是某个 prompt,而是整套 Agent Operating System

常见问答(FAQ)

Q1: Claude Code 和 GitHub Copilot 有什么区别?
Copilot 是 IDE 内的实时补全工具,Claude Code 是终端原生 Agent,处理任务级委托(跨文件重构、测试、Git 工作流)。两者可以互补使用。

Q2: 为什么 Claude Code 需要那么多”Agent”?不能一个 Agent 做所有事吗?
单一 Agent 同时承担研究、规划、实现、验证会导致角色混乱和偏见。Claude Code 通过专业化分工(Explore 只读、Plan 只规划、Verification 对抗性验证)提升每类任务的稳定性。

Q3: 什么是 MCP?为什么重要?
MCP(Model Context Protocol)是 Anthropic 推出的开放协议,允许 Claude Code 连接外部数据源和工具。关键是 MCP 不仅提供工具,还能注入”如何使用这些工具”的说明,让模型真正感知到扩展能力。

Q4: “Fork”一个子任务和直接创建新 Agent 有什么区别?
Fork 继承主线程的 system prompt 和完整上下文,工具集保持一致,目的是复用主线程的 prompt cache,降低 token 成本。适合研究类子任务。

Q5: Claude Code 的”记忆”功能是如何工作的?
通过 src/memdir/ 模块实现跨会话记忆,包括用户偏好、项目约束、团队规范等。记忆以 Markdown 文件形式存储,按需注入上下文,不是每次会话都全量加载。

Q6: Hook 系统能做什么?
Hook 可以在工具执行前拦截调用、改写输入、调整权限行为,或在执行后追加消息、补充上下文。适合实现团队特定的安全策略或审计需求。

Q7: 为什么 Claude Code 强调”先读代码再改代码”?
这是 getSimpleDoingTasksSection() 中的明确规则,目的是避免模型在不了解上下文的情况下盲目修改,减少重构错误和不必要的抽象。

Q8: Verification Agent 的”try to break it”是什么意思?
Verification Agent 的 prompt 明确要求它主动寻找代码缺陷(adversarial probes),而不是简单确认”看起来没问题”。它必须跑 build、test、linter,并输出明确的 VERDICT: PASS/FAIL/PARTIAL。

退出移动版