今天分享Claude Code技术分析文档-有想研究的拿去
目录
-
研究背景与核心发现
-
整体架构设计哲学
-
系统提示词工程体系
-
Prompt 模块化拆解
-
Agent 子系统设计与分工
-
Agent 调度链路全解析
-
技能/插件/钩子/MCP 生态
-
权限控制与工具执行链
-
技术护城河分析
-
核心文件索引与后续研究方向
1. 研究背景与核心发现
1.1 研究范围
本次技术分析基于从 npm 包中提取的完整源码映射(source map),对 Claude Code 的工程实现进行了系统性拆解。研究覆盖以下核心维度:
-
整体架构层级与模块划分
-
系统提示词的动态组装机制
-
AgentTool / SkillTool 的协议设计
-
Agent 的角色边界定义
-
Agent 调度与生命周期管理
-
Plugin / Skill / Hook / MCP 的集成模式
-
权限决策与工具执行链路
-
产品体验背后的工程支撑
1.2 已确认的技术事实
通过源码还原,以下信息已得到验证:
-
源码规模:从 cli.js.map 中提取出 4756 个源码文件,总计约 51 万行 TypeScript 代码
-
核心入口文件:src/constants/prompts.ts 承担系统提示词的总装配职责
-
Agent 协议定义:src/tools/AgentTool/prompt.ts 规范了 Agent 的调用契约
-
技能系统定义:src/tools/SkillTool/prompt.ts 定义了 Skill 的执行语义
-
Agent 调度中枢:src/tools/AgentTool/AgentTool.tsx 与 src/tools/AgentTool/runAgent.ts 构成子 Agent 的完整运行时
-
工具执行管线:src/services/tools/toolExecution.ts 与 src/services/tools/toolHooks.ts 实现工具调用的治理层
1.3 核心判断
Claude Code 的技术优势并非源于某段”神奇的系统提示词”,而是来自一套完整的软件工程体系:
-
Prompt 即运行时:提示词不是静态文本,而是可按会话条件动态编排的运行时资源
-
工具治理化:工具调用不走裸函数直连,而是经过 permission / hook / analytics / MCP-aware 的完整管线
-
Agent 专业化:不是万能 Worker 模式,而是基于场景的 Specialist 分工体系
-
Skill 工作流化:不是文档说明,而是 prompt-native 的 workflow package
-
插件行为化:不只是功能扩展,而是 prompt + metadata + runtime constraint 的模型感知层
-
MCP 双向化:既是工具桥,也是行为说明的注入通道
一句话概括:Claude Code 的本质不是一段 prompt,而是一套将 prompt、tool、permission、agent、skill、plugin、hook、MCP、cache 和产品体验统一治理的 Agent Operating System。
2. 整体架构设计哲学
2.1 从架构复杂度透视
src/ 目录的顶层结构可以观察到,Claude Code 的模块划分体现了平台级产品的设计思维:
|
目录 |
职责 |
|---|---|
|
src/entrypoints/ |
多入口适配层(CLI / MCP / SDK) |
|
src/constants/ |
系统常量、提示词模板、安全策略 |
|
src/tools/ |
工具定义与具体实现 |
|
src/services/ |
运行时服务(tools / mcp / analytics) |
|
src/utils/ |
底层共用能力 |
|
src/commands/ |
Slash 命令与命令系统 |
|
src/components/ |
TUI / UI 组件层 |
|
src/coordinator/ |
多 Agent 协调器模式 |
|
src/memdir/ |
记忆与 memory prompt 管理 |
|
src/plugins/ |
插件生态 |
|
src/hooks/ |
钩子治理层 |
|
src/bootstrap/ |
状态初始化 |
|
src/tasks/ |
任务调度(本地 / 远程 / 异步 Agent) |
这种模块密度说明:Claude Code 不是简单的 CLI 包装器,而是一个完整的 Agent 运行时平台。
2.2 多入口的平台化思维
可见的入口点包括:
-
src/entrypoints/cli.tsx — 本地 CLI 交互
-
src/entrypoints/init.ts — 初始化流程
-
src/entrypoints/mcp.ts — MCP 模式
-
src/entrypoints/sdk/ — SDK 消费端
这种设计表明,同一个 Agent Runtime 可以服务多个交互表面,是典型的平台化架构思维。
2.3 命令系统作为控制面板
src/commands.ts 暴露的系统级命令规模庞大:
/mcp, /memory, /permissions, /hooks, /plugin, /reload-plugins,/skills, /tasks, /plan, /review, /status, /model, /output-style,/agents, /sandbox-toggle ...
命令系统不仅是用户交互界面,更是生态入口:
-
统一加载 builtin commands
-
集成 plugin commands
-
管理 skill commands
-
支持 bundled skills 与动态 skills
-
按可用性过滤命令集合
2.4 工具层:从”回答器”到”执行体”
确认的核心工具集:
-
文件操作:FileRead, FileEdit, FileWrite
-
搜索工具:Glob, Grep
-
系统交互:Bash
-
任务管理:TodoWrite, TaskCreate
-
用户交互:AskUserQuestion
-
扩展能力:Skill, Agent, MCPTool, Sleep
工具层的工程完备性,是 Claude Code 从”聊天机器人”跃迁为”工程协作者”的关键支撑。
3. 系统提示词工程体系
3.1 主入口:src/constants/prompts.ts
这份文件是整个系统最关键的工程资产之一。它的核心价值不在于文案本身,而在于承担了以下职责:
-
主系统提示词的总装配器
-
环境信息的动态注入
-
工具使用规范的策略植入
-
安全与风险动作的边界定义
-
Session-specific guidance 的条件注入
-
语言与输出风格的偏好适配
-
MCP instructions 的桥接注入
-
Memory prompt 的记忆整合
-
Scratchpad 与 function result clearing 的上下文管理
-
Token budget 与 brief mode 的资源管控
结论:Claude Code 的 prompt 不是静态字符串,而是一个 System Prompt Assembly Architecture。
3.2 getSystemPrompt() 的编排逻辑
该函数的核心结构是静态前缀 + 动态后缀的分层设计:
静态前缀(Cache 优化区)
-
getSimpleIntroSection() — 身份定义
-
getSimpleSystemSection() — 基础系统规范
-
getSimpleDoingTasksSection() — 任务执行哲学
-
getActionsSection() — 风险动作规范
-
getUsingYourToolsSection() — 工具使用策略
-
getSimpleToneAndStyleSection() — 交互风格
-
getOutputEfficiencySection() — 输出效率
动态后缀(会话特定区)
-
Session guidance — 当前会话的局部规则
-
Memory — 记忆上下文
-
Ant model override — 模型覆盖配置
-
Env info — 环境信息
-
Language — 语言偏好
-
Output style — 输出风格
-
MCP instructions — MCP 服务器指令
-
Scratchpad — 草稿板
-
Function result clearing — 函数结果清理策略
-
Summarize tool results — 工具结果摘要
-
Numeric length anchors — 长度锚点
-
Token budget — Token 预算
-
Brief mode — 简洁模式
3.3 Prompt Cache Boundary:基础设施级优化
源码中明确定义了 SYSTEM_PROMPT_DYNAMIC_BOUNDARY,其工程意图为:
-
边界前:尽量保持可 cache,降低重复开销
-
边界后:用户/会话特定内容,按需注入
-
稳定性要求:不能随意改动,否则会破坏 cache 逻辑
这种设计体现了 Prompt Assembly with Cache Economics 的思维——将 token 成本与缓存命中纳入运行时预算管理。
4. Prompt 模块化拆解
4.1 身份与基础定位:getSimpleIntroSection()
该 section 的核心功能:
-
定义自身为 interactive agent(交互式代理)
-
明确服务领域:软件工程任务协助
-
声明输出风格受 Output Style 约束
-
注入 CYBER_RISK_INSTRUCTION(网络安全风险指令)
-
硬性禁止:随意生成或猜测 URL
行为基调设定:
-
不是普通聊天机器人
-
是工具驱动的工程协作者
-
风险防护从第一屏开始植入
4.2 基础系统规范:getSimpleSystemSection()
该 section 定义了 runtime reality:
-
所有非工具输出直接面向用户
-
工具运行在 permission mode 下
-
用户拒绝后禁止原样重试
-
工具结果/用户消息可能包含 <system-reminder> 等标签
-
外部工具结果可能包含 prompt injection 风险
-
存在 hooks 治理层
-
上下文会被自动压缩,非硬性上下文窗口
关键价值:将模型从”语言模型的幻觉世界”拉回”受控 runtime 世界”。
4.3 任务执行哲学:getSimpleDoingTasksSection()
这是 Claude Code 行为稳定性的核心来源。明确的约束包括:
|
禁止行为 |
规范要求 |
|---|---|
|
不要添加用户未要求的功能 |
严格按需求执行,不多不少 |
|
不要过度抽象 |
避免不必要的架构分层 |
|
不要瞎重构 |
先理解再修改 |
|
不要乱加注释/文档/类型注解 |
除非必要 |
|
不要过度错误处理 |
避免防御式编程泛滥 |
|
不要设计未来兼容的抽象 |
解决当前问题即可 |
|
先读代码再改代码 |
禁止盲目修改 |
|
不要轻易创建新文件 |
优先编辑现有文件 |
|
不要给时间估计 |
避免虚假承诺 |
|
方法失败先诊断再换策略 |
禁止盲目重试 |
|
注意安全漏洞 |
安全优先 |
|
删除确认无用的代码 |
不搞兼容性垃圾 |
|
结果如实汇报 |
禁止假装测试通过 |
本质:Anthropic 对 AI 工程师行为规范的制度化表达,解决行为漂移问题。
4.4 风险动作规范:getActionsSection()
定义了需要确认的风险动作类型:
-
Destructive operations — 破坏性操作
-
Hard-to-reverse operations — 难以撤销的操作
-
修改共享状态 — 影响范围超出当前会话
-
对外可见动作 — 产生外部副作用
-
上传到第三方工具 — 数据出境风险
额外约束:
-
禁止用破坏性动作当捷径
-
发现陌生状态先调查
-
Merge conflict / lock file 禁止粗暴删除
价值:将 blast radius 思维编码进系统提示词。
4.5 工具使用规范:getUsingYourToolsSection()
明确的工具策略:
|
场景 |
正确工具 |
禁止用法 |
|---|---|---|
|
读文件 |
FileRead / cat / head / tail / sed |
– |
|
改文件 |
FileEdit |
sed / awk |
|
新建文件 |
FileWrite |
echo 重定向 |
|
搜文件 |
Glob |
无 |
|
搜内容 |
Grep |
无 |
|
Shell 场景 |
Bash |
保留给真正需要 shell 的场景 |
|
任务管理 |
TodoWrite / TaskCreate |
有依赖时串行,无依赖时并行 |
关键价值:不只是”你有工具,而是”你要以正确的操作语法使用这些工具”。
4.6 会话特定指引:getSessionSpecificGuidanceSection()
这是动态 section 的核心,根据当前工具集和 feature gate 拼接:
-
如果存在 AskUserQuestion,被拒绝后可询问用户
-
非交互模式下的行为差异
-
AgentTool 是否启用
-
Explore / Plan agents 是否可用
-
Slash skill 的使用规则
-
DiscoverSkills 工具的调用指引
-
Verification agent 的强制验证合同
设计意图:系统提示词 = 总规则 + 当前会话的局部规则。
4.7 输出效率:getOutputEfficiencySection()
高价值但常被忽视的 section,核心目标:
-
用户看的是自然语言,不是日志
-
先说动作或结论,不要铺垫
-
该更新时更新,但不要废话
-
不要过度解释
-
不要塞无谓表格
-
短句直给
4.8 交互风格:getSimpleToneAndStyleSection()
统一产品质感的细节:
-
不要乱用 emoji
-
响应简洁
-
引用代码位置时用 file_path:line_number
-
GitHub issue / PR 用 owner/repo#123
-
Tool call 前不要加冒号”:”
4.9 子 Agent 基础人格:DEFAULT_AGENT_PROMPT
在 prompts.ts 中定义的子 Agent 默认人格:
-
你是 Claude Code 的 agent
-
用工具完成任务
-
任务要完整,不要半成品
-
完成后给简洁报告
分层结构:主线程与子 Agent 在 prompt 结构上有明确分层。
5. Agent 子系统设计与分工
5.1 AgentTool 协议说明书:src/tools/AgentTool/prompt.ts
这份文件是 AgentTool 的模型侧协议文档,核心价值:
-
Agent list 的展示格式
-
每个 agent 的描述规范
-
fork 语义的定义与使用场景
-
subagent_type 的显式指定规则
-
fork 与 fresh agent 的区别
-
什么情况下不要用 AgentTool
-
如何写给子 agent 的 prompt
-
foreground / background 的行为差异
-
isolation: worktree / remote 的语义
结论:多 Agent 不是暗箱,而是明确写给模型看的使用协议。
5.2 Fork 语义的设计强度
当 fork 开启时,prompt 明确告知模型:
-
omit subagent_type 即表示 fork 自己
-
Fork 继承完整 conversation context
-
研究任务适合 fork
-
实现任务如果会产生大量中间输出,也适合 fork
-
Fork 成本低廉,因为共享 prompt cache
-
禁止给 fork 单独设 model(会破坏 cache 命中)
-
禁止偷窥 fork 输出文件
-
禁止预言 fork 结果
解决的问题:如何让复杂子任务并行运行,但不污染主上下文——这是多 Agent 系统的核心难题。
5.3 Prompt 编写规范:”How to write the prompt”
Agent prompt 中教育模型的关键原则:
-
Fresh agent 没有上下文,要像对新同事 briefing 一样写 prompt
-
说明目标和原因
-
说明你已经排除了什么
-
提供足够背景,让它能做判断
-
如果要短答,明确说
-
禁止把理解任务的工作外包给 agent
-
禁止写”基于你的发现再去修 bug”这种偷懒 prompt
-
应该给到 file path、line、具体改动要求
价值:限制”懒 delegation”,强制主 agent 承担 synthesis 责任。
5.4 内置 Agent:职责分工而非万能 Worker
确认的内置 agents:
|
Agent |
职责 |
|---|---|
|
General Purpose Agent |
通用任务处理 |
|
Explore Agent |
纯读模式代码探索 |
|
Plan Agent |
纯规划,不做编辑 |
|
Verification Agent |
对抗性验证 |
|
Claude Code Guide Agent |
产品使用指导 |
|
Statusline Setup Agent |
终端状态栏配置 |
设计哲学:不是让一个 agent 什么都做,而是 Specialization——探索给 Explore,规划给 Plan,验证给 Verification,通用任务给 General Purpose。
5.5 Explore Agent:纯读模式专家
exploreAgent.ts 的 system prompt 核心约束:绝对只读
-
禁止创建文件
-
禁止修改文件
-
禁止删除文件
-
禁止移动文件
-
禁止写临时文件
-
禁止用重定向 / heredoc 写文件
-
禁止运行任何改变系统状态的命令
核心能力
-
用 Glob / Grep / FileRead 快速探索代码库
-
Bash 只允许读操作:ls, head, tail, git status, git log, git diff, find, grep, cat
-
尽量并行用工具
-
快速给出结果
定位:不是”会搜索的普通 agent”,而是被故意裁成 read-only specialist。
5.6 Plan Agent:纯规划,零编辑
planAgent.ts 的 system prompt:
-
只读,不准改文件
-
需要先理解需求
-
需要探索代码库、模式、架构
-
需要输出 step-by-step implementation plan
-
最后必须列出 Critical Files for Implementation
价值:将 Plan Agent 定义为 architect / planner,而非 executor,降低角色混杂。
5.7 Verification Agent:对抗性验证的价值
verificationAgent.ts 是本轮挖掘中最重要的新增部分。
核心方向:不是”确认实现看起来没问题”,而是 try to break it。
识别的失败模式:
-
Verification avoidance — 只看代码、不跑检查、写 PASS 就走
-
被前 80% 迷惑 — UI 看起来还行、测试也过了,就忽略最后 20% 的问题
强制要求:
-
必须 build
-
必须跑 test suite
-
必须跑 linter / type-check
-
根据变更类型做专项验证
-
Frontend 要跑浏览器自动化 / 页面子资源验证
-
Backend 要 curl/fetch 实测响应
-
CLI 要看 stdout/stderr/exit code
-
Migration 要测 up/down 和已有数据
-
Refactor 也要测 public API surface
-
必须做 adversarial probes
-
每个 check 必须带 command 和 observed output
-
最后必须输出 VERDICT: PASS / FAIL / PARTIAL
本质:Verification Agent 不是”再跑一次测试”,而是一个 adversarial validator,直接用 prompt 反制”差不多就算了”的 LLM 通病。
6. Agent 调度链路全解析
6.1 总体调用链
从 AgentTool.tsx 与 runAgent.ts 观察,主链路抽象为: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 汇总结果或走异步任务通知
这是一条完整的 subagent runtime pipeline。
6.2 AgentTool.call():调度总控
职责远比”转发到子 agent”复杂:
-
解析输入参数:description, prompt, subagent_type, model, run_in_background, name, team_name, mode, isolation, cwd
-
判断是否 multi-agent teammate spawn
-
解析 team context
-
判断是否允许 background
-
区分 fork path 与 normal path
-
根据 permission rules 过滤 agent
-
检查 MCP requirements
-
计算 selectedAgent
-
处理 remote isolation
-
构造 system prompt / prompt messages
-
注册 foreground / async agent task
-
启动 worktree isolation
-
调用 runAgent()
本质:AgentTool 是 agent orchestration controller。
6.3 Fork Path vs Normal Path
源码中的明显分叉:
Fork Path
-
subagent_type 省略且 fork feature 开启
-
继承主线程 system prompt
-
用 buildForkedMessages() 构造 prompt messages
-
用父线程完整 context
-
工具集尽量与父线程一致,保证 prompt cache 命中
-
useExactTools = true
Normal Path
-
明确指定 built-in / custom agent type
-
基于 agentDefinition 生成新的 agent system prompt
-
只给该 agent 所需上下文
-
走该 agent 的 tool restrictions
关键价值:fork 不是”再开一个普通 agent”,而是为了 cache 和 context 继承专门优化的执行路径。
6.4 Cache-Identical Prefix 的强调
Fork path 会尽量继承父线程的 system prompt 和 tool defs,以保持 API request prefix byte-identical,从而提高 prompt cache 命中。
对比:
-
普通人只想”子任务能跑”
-
Claude Code 想的是”子任务能跑,而且尽量复用主线程 cache,不白烧 token”
这是产品级系统思维的体现。
6.5 Background vs Foreground:两套生命周期
AgentTool.call() 根据条件决定:
-
Foreground sync path
-
Async background path
-
Remote launched path
-
Teammate spawned path
Background Path 特点
-
注册 async agent task
-
独立 abort controller
-
可在后台运行
-
完成后通过 notification 回到主线程
-
可选自动 summarization
-
可查看 outputFile 但不鼓励偷看
Foreground Path 特点
-
主线程等待结果
-
可在执行中被 background 化
-
有 foreground task 注册与 progress tracking
结论:Claude Code 对 agent lifecycle 的处理是产品化的,不是”一次函数调用”。
6.6 runAgent():子 Agent 运行时
runAgent.ts 的职责:
-
初始化 agent-specific MCP servers
-
过滤 / 克隆 context messages
-
处理 file state cache
-
获取 system/user context
-
对 read-only agent 做 claudeMd / gitStatus slimming
-
构造 agent-specific permission mode
-
组装 resolved tools
-
获取 agent system prompt
-
创建 abortController
-
执行 SubagentStart hooks
-
注册 frontmatter hooks
-
预加载 frontmatter skills
-
合并 agent MCP tools
-
构造 subagent ToolUseContext
-
调用 query() 进入主循环
-
记录 transcript
-
清理 MCP、hooks、perfetto、todo、bash tasks 等资源
本质:runAgent 不是简单 wrapper,而是子 agent 的 complete runtime constructor。
6.7 Agent-Specific MCP Servers:能力注入
initializeAgentMcpServers() 支持:
-
从现有配置按名字引用服务器
-
在 frontmatter 里内联定义 agent-specific MCP server
-
连接 server
-
拉取 tools
-
把 agent-specific MCP tools 合并进当前 agent 的 tools
-
在 agent 结束时做 cleanup
价值:Agent 不只是消费全局 MCP,还可以自带外接能力,对插件 agent / 专职 agent 很强。
6.8 Frontmatter Hooks 与 Frontmatter Skills
runAgent() 还会:
-
registerFrontmatterHooks(…)
-
读取 agentDefinition.skills
-
通过 getSkillToolCommands() 加载技能
-
把 skill prompt 内容预加载成 meta user messages 注入初始消息
关键:agent 本身也是可配置的 prompt container,而非固定硬编码角色。
6.9 query():最终主循环执行器
从 runAgent() 可见:
-
真正的模型对话循环发生在 query({ … })
-
runAgent() 只是子 agent 的上下文准备与生命周期控制器
分层清晰:
-
AgentTool:调度与模式分流
-
runAgent:子 agent 上下文构造与生命周期管理
-
query:真正的模型消息流与 tool-calling 主循环
6.10 Transcript / Metadata / Cleanup:产品化 Runtime 证据
runAgent() 中的产品级细节:
-
recordSidechainTranscript()
-
writeAgentMetadata()
-
registerPerfettoAgent()
-
cleanupAgentTracking()
-
killShellTasksForAgent()
-
清理 session hooks
-
清理 cloned file state
-
清理 todos entry
结论:Anthropic 不只是让 subagent “跑起来”,而是把 transcript、telemetry、cleanup、resume 都纳入正式生命周期。
7. 技能/插件/钩子/MCP 生态
7.1 Skill:Workflow Package
源码中:SKILL_TOOL_NAME = ‘Skill’
在 SkillTool/prompt.ts 以及命令系统相关代码中,明确要求:
-
Task 匹配 skill 时必须调用 Skill tool
-
禁止只提 skill 不执行
-
Slash command 可视为 skill 入口
-
如果 skill 已通过 tag 注入,则不要重复调用
Skill 的本质:
-
Markdown prompt bundle
-
带 frontmatter metadata
-
可声明 allowed-tools
-
可按需注入当前上下文
-
可把重复工作流压缩成可复用能力包
这比”在 system prompt 里塞一堆固定流程”高级很多,实现了工作流的模块化复用。
7.2 Plugin:Prompt + Metadata + Runtime Constraints
关键文件:src/utils/plugins/loadPluginCommands.ts
插件能力:
-
Markdown commands
-
SKILL.md skill 目录
-
commandsMetadata
-
userConfig
-
Shell frontmatter
-
allowed-tools
-
Model/effort hints
-
user-invocable
-
disable-model-invocation
支持变量:
-
${CLAUDE_PLUGIN_ROOT}
-
${CLAUDE_PLUGIN_DATA}
-
${CLAUDE_SKILL_DIR}
-
${CLAUDE_SESSION_ID}
-
${user_config.X}
结论:plugin 不是普通 CLI 插件,而是模型行为层面的扩展单元,核心是 prompt + metadata + runtime constraints 的组合。
7.3 Hook:运行时治理层
关键文件:src/services/tools/toolHooks.ts
Hook 支持:
-
PreToolUse
-
PostToolUse
-
PostToolUseFailure
Hook 结果可产出:
-
message
-
blockingError
-
updatedInput
-
permissionBehavior
-
preventContinuation
-
stopReason
-
additionalContexts
-
updatedMCPToolOutput
本质:Hook 是 runtime policy layer,用于实现对工具执行、Agent 运行、插件调用的全流程治理,避免运行失控。
7.4 Hook 与权限的耦合
resolveHookPermissionDecision() 说明:
-
hook 可给出 allow/ask/deny
-
但 hook 的 allow 不自动突破 settings deny/ask rules
-
如果需要 user interaction 或 requireCanUseTool,仍要走统一 permission flow
-
hook 还能通过 updatedInput 满足交互输入
结论:Hook 强,但没有绕开核心安全模型,始终被权限体系约束。
7.5 MCP:不只是工具桥
从 prompts.ts 可见:
-
getMcpInstructionsSection()
-
getMcpInstructions(mcpClients)
逻辑:如果 connected MCP server 提供 instructions,就把这些 instructions 拼进 system prompt。
MCP 双向价值:
-
注入新工具
-
注入如何使用这些工具的说明
这让 MCP 的价值远高于简单 tool registry,实现了工具能力与使用说明的同步注入。
8. 权限控制与工具执行链
8.1 toolExecution.ts:工具 Runtime 主线
Claude Code 的工具执行不是”模型决定 → 直接跑函数”,实际链路:
1. 找 tool2. 解析 MCP metadata3. 做 input schema 校验 (Zod)4. 做 validateInput5. 为 Bash 启动 speculative classifier check6. 运行 PreToolUse hooks7. 解析 hook permission result8. 走 permission 决策9. 再次根据 permission updatedInput 修正输入10. 真正执行 tool.call()11. 记录 analytics / tracing / OTel12. 运行 PostToolUse hooks13. 处理 structured output / tool_result block14. 失败则走 PostToolUseFailure hooks15. 输出结果
这是标准的 runtime pipeline,而非直连函数调用,确保工具执行的可治理性。
8.2 输入校验:先挡低级错误
工具执行前:
-
Zod schema parse
-
tool-specific validateInput
如果失败:
-
直接生成 tool_result 错误消息
-
记录 tengu_tool_use_error
价值:保证模型随便乱生成参数时不会直接污染执行层。
8.3 PreToolUse Hooks:关键拦截点
runPreToolUseHooks() 中,hook 可产出:
-
普通 message
-
hookPermissionResult
-
hookUpdatedInput
-
preventContinuation
-
stopReason
-
additionalContext
-
stopUpdatedInput
hook 可改写输入,但不一定做权限决策。
8.4 resolveHookPermissionDecision():权限语义粘合层
逻辑定义:
-
hook allow 不一定绕过 settings 规则
-
如果 tool 要求 user interaction,而 hook 没提供 updatedInput,则仍要走 canUseTool
-
ask 类型 hook 会作为 forceDecision 传递下去
-
deny 类型直接生效
结论:Hook 的权限语义被严格嵌进总权限模型,不是外挂旁路。
8.5 工具执行后:不是终点
runPostToolUseHooks() 与 runPostToolUseFailureHooks() 说明:
-
成功后 hook 还能:追加 message、注入 additional context、阻断 continuation
-
失败后 hook 还能:补充失败上下文、发阻断说明、给用户更多恢复线索
价值:整个系统比”tool call 一把梭”可治理得多。
9. 技术护城河分析
9.1 不是 Prompt,而是 Operating Model
很多人复刻 coding agent 时只会拿走:
-
一个 system prompt
-
一个文件编辑工具
-
一个 bash 工具
-
一个 CLI 壳
但 Claude Code 真实的护城河是:
|
维度 |
工程实现 |
|
Prompt Architecture |
模块化动态组装 |
|
Tool Runtime Govern |
Permission / Hook / Analytics / MCP-aware Pipeline |
|
Permission Model |
多层决策与拦截 |
|
Hook Policy Layer |
运行时策略注入 |
|
Agent Specialization |
内置 Specialist 分工 |
|
Skill Workflow Packaging |
prompt-native 复用单元 |
|
Plugin Integration |
模型感知型扩展 |
|
MCP Instruction Injection |
双向能力桥接 |
|
Context Hygiene |
Cache / Fork / Fresh 优化 |
|
Transcript / Telemetry / Cleanup |
产品化生命周期管理 |
少一个都行,但会显著掉”手感”。
9.2 “好行为”的制度化
Claude Code 的最大优势:不把”好习惯”交给模型即兴发挥,而是写进 prompt 和 runtime 规则。
制度化示例:
-
不要乱加功能
-
不要过度抽象
-
不要瞎重试被拒绝的工具
-
不要未验证就说成功
-
不要随便做风险操作
-
不要让 fork 输出污染主上下文
-
匹配 skill 时必须执行 skill
-
Verification 不能只看代码,必须跑命令
这种制度化极大提高了系统一致性。
9.3 上下文是稀缺资源
源码中大量设计围绕上下文优化:
-
System prompt 动静边界
-
Prompt cache boundary
-
Fork path 共享 cache
-
Summarize tool results
-
Compact / transcript / resume
思维:不是把 token 当免费空气,而是当 runtime 预算来管理。
9.4 Agent Specialization 的设计优势
Explore / Plan / Verification 这套内置 Agents 的价值:
-
研究和探索不用污染主线程
-
规划和实现分离,降低混乱
-
验证独立出来,对抗”实现者 bias”
很多系统的问题:一个 agent 既研究、又规划、又实现、又验收,最终哪件事都不够稳定。
9.5 生态的模型感知性
Claude Code 的另一个强点:让模型”知道自己的扩展能力是什么”。
实现方式:
-
Skills 列表
-
Agent 列表
-
MCP instructions
-
Session-specific guidance
这才是生态真正能发挥作用的关键。
10. 核心文件索引与后续研究方向
10.1 核心 Prompt 文件
-
主系统提示词:src/constants/prompts.ts
-
Agent Tool Prompt:src/tools/AgentTool/prompt.ts
-
Skill Tool Prompt:src/tools/SkillTool/prompt.ts
10.2 核心 Agent 文件
-
src/tools/AgentTool/AgentTool.tsx
-
src/tools/AgentTool/runAgent.ts
-
src/tools/AgentTool/resumeAgent.ts
-
src/tools/AgentTool/forkSubagent.ts
-
src/tools/AgentTool/agentMemory.ts
-
src/tools/AgentTool/agentMemorySnapshot.ts
10.3 核心 Skill/Plugin/Hook 文件
-
src/tools/SkillTool/constants.ts
-
src/tools/SkillTool/prompt.ts
-
src/utils/plugins/loadPluginCommands.ts
-
src/services/tools/toolHooks.ts
10.4 核心 MCP 文件
-
src/services/mcp/types.ts
-
src/services/mcp/normalization.ts
-
src/services/mcp/mcpStringUtils.ts
-
src/entrypoints/mcp.ts
10.5 核心工具执行文件
-
src/services/tools/toolExecution.ts
-
src/services/tools/toolHooks.ts
-
src/services/tools/resolveHookPermissionDecision.ts
10.6 后续研究方向
下一轮深挖建议重点:
-
query.ts — 主会话循环与模型交互流
-
resumeAgent.ts — agent 恢复机制
-
loadSkillsDir — skills 完整加载链
-
pluginLoader — 插件加载与内建插件生态
-
coordinator/* — 多 Agent 协调器模式
-
attachments.ts — skill/agent listing/MCP delta 的消息注入方式
10.7 最终结论
一句话总结:Claude Code 的真正秘密,不是一段 system prompt,而是一个把 prompt architecture、tool runtime、permission model、agent orchestration、skill packaging、plugin system、hooks govern、MCP integration、context hygiene 和 product engineering 全部统一起来的系统。
这就是为什么它不像一个”会调工具的聊天机器人”,而是一个 Agent Operating System。
夜雨聆风