什么是 Claude Code?它是如何工作的?
Claude Code 是一个 CLI 工具,它连接你的电脑和 Claude AI 模型,让 AI 能够帮你写代码、修改文件、执行命令。
想象一下:你有一个永远不会累的程序员助手,你告诉它"帮我把这个按钮改成蓝色",它就会自动找到相关代码并修改。这就是 Claude Code。
Claude Code 不是直接在 AI 模型里运行——它是一个"翻译官",把你的指令转换成 AI 能理解的形式,然后把 AI 的回应转换成实际的代码操作。
Claude Code 的源码在 src/ 目录下,有 62 个子文件夹。让我们看看最重要的几个:
这是一个通过 source map 逆向还原的 Claude Code 源码树。由于 source map 不能包含完整的原始仓库,部分文件无法恢复,所以有些模块使用了临时的"兼容垫片"(shim)来替代。
如果你要做二次开发,注意 vendor/ 和 shims/ 目录——这些是兼容性替代品,可能需要用真实实现替换它们。
理解 Claude Code 的"演员阵容"——它们各自做什么,如何对话
Claude Code 有几个核心"角色",每个都有自己明确的职责。就像一个剧组有不同的演员,Claude Code 的每个组件也有自己的角色。
整个应用的大脑,指挥所有操作,决定下一步做什么
AI 可以调用的能力——读写文件、执行命令、搜索代码等
用户在 CLI 输入的指令,如 /commit、/review、/diff
全局状态管理器,存储所有组件共享的数据
表示一个正在运行的工作单元,有自己的生命周期
在 src/Task.ts 中,定义了一个 Task 的基本结构:
export type TaskType =
| 'local_bash'
| 'local_agent'
| 'remote_agent'
| 'in_process_teammate'
| 'local_workflow'
| 'monitor_mcp'
| 'dream'
任务类型就像不同类型的"工作岗位"——
'local_bash' = 在本地执行命令行
'local_agent' = 本地 AI 助手
'remote_agent' = 远程 AI 助手(通过网络)
'in_process_teammate' = 同进程内的"队友"
'local_workflow' = 本地工作流
'monitor_mcp' = 监控 MCP 服务器
'dream' = 思考/规划模式
每种任务类型都有自己独特的 ID 前缀——local_bash 用 'b',local_agent 用 'a',remote_agent 用 'r'。这样看到任务 ID 就知道它是什么类型!
AppState 是 Claude Code 的"仪表盘"。它存储了所有重要的运行时信息。
用户配置:主题、模型、权限模式等
自定义 Agent 的配置和定义
对话中的所有消息
Model Context Protocol 服务器连接
正在运行和已完成的任务
组件之间是如何通信的?让我们看看它们如何"聊天":
50+ 工具让 AI 能够读写文件、执行命令、搜索代码...
Tool 是 Claude Code 赋予 AI 的"超能力"。每个工具让 AI 能够做一件特定的事:
FileReadTool、GlobTool、GrepTool
FileEditTool、FileWriteTool、NotebookEditTool
BashTool、PowerShellTool、REPLTool
WebSearchTool、WebFetchTool、ToolSearchTool
AgentTool、TaskCreateTool、TaskStopTool
所有工具都在 src/tools/ 目录下,共有 50+ 个工具。以下是最重要的几个:
执行命令行命令,如 git、npm、ls 等
智能编辑文件,AI 描述修改内容即可
读取文件内容,支持大文件
在代码库中搜索关键词
搜索互联网获取信息
创建和管理子 Agent
这是最常用的工具之一。让我看看它的核心逻辑:
export class BashTool {
execute(command: string, timeout?: number) {
return new Promise((resolve, reject) => {
const child = spawn('bash', ['-c', command])
child.on('close', (code) => {
resolve({ code, output: this.buffer })
})
})
}
}
定义一个 BashTool 类,里面有个 execute 方法
execute 接收两个参数:命令字符串和超时时间
返回一个 Promise(异步结果)
用 spawn 启动一个 bash 进程来执行命令
当命令执行完毕,resolve 返回退出码和输出
如果要给 AI 添加新能力(比如操作数据库),你可以参考 BashTool 的结构,创建一个新的 Tool 类,然后注册到 tools.ts 中。
所有工具在 src/tools.ts 中注册。这是工具的"目录":
import { AgentTool } from './tools/AgentTool/AgentTool.js'
import { SkillTool } from './tools/SkillTool/SkillTool.js'
import { BashTool } from './tools/BashTool/BashTool.js'
import { FileEditTool } from './tools/FileEditTool/FileEditTool.js'
// ... 更多工具导入
export const getTools = (): Tools => [
new BashTool(),
new FileEditTool(),
new AgentTool(),
// ... 更多工具实例
]
从各个工具模块导入工具类
定义一个 getTools 函数返回所有工具
创建并返回工具实例的数组
这就是 AI 能调用的所有"能力清单"
100+ 命令让用户与 Claude Code 交互
当你输入 /commit、/diff 或 /review 时,你就是在调用一个Command。命令和工具的区别在于:
AI 调用的能力
用于 AI 自动执行任务
如:读写文件、执行命令
用户调用的指令
用于用户控制 Claude Code
如:/commit、/help、/model
所有命令在 src/commands/ 目录下,有 100+ 个!以下是分类整理:
/commit、/diff、/branch、/merge
/review、/security-review
/grep、/files、/session
/model、/config、/theme
/task、/tasks、/resume
/mcp、/skills、/plugin
命令定义在 src/commands.ts 中。看看 /help 命令是如何注册的:
import help from './commands/help/index.js'
import diff from './commands/diff/index.js'
import commit from './commands/commit.js'
import review from './commands/review.js'
// ... 100+ more commands
export const getCommands = (): Command[] => [
help,
diff,
commit,
review,
// ...
]
从各自的目录导入命令模块
getCommands 函数返回所有命令
这个列表就是用户在 CLI 可以调用的所有命令
假设你想添加一个 /hello 命令。你需要:
创建 src/commands/hello/index.ts
指定 name、description、和处理逻辑
导入并添加到 getCommands 返回值
const hello: Command = {
name: 'hello',
description: 'Say hello',
execute: async (args, context) => {
return 'Hello, world!'
}
}
定义一个 hello 命令对象
name 是命令名(用户输入 /hello)
description 是帮助文本
execute 是实际执行的函数
理解 Claude Code 如何思考和决策
QueryEngine 是 Claude Code 的"大脑"。它位于 src/QueryEngine.ts,负责:
维护用户和 AI 之间的消息历史
发送请求、接收响应、处理错误
当 AI 决定调用工具时,协调执行并返回结果
跟踪使用的 token 数量,控制成本
当你输入一条指令时,QueryEngine 是如何工作的?
看看 QueryEngineConfig 包含什么——这是启动大脑需要的所有配置:
export type QueryEngineConfig = {
cwd: string
tools: Tools
commands: Command[]
mcpClients: MCPServerConnection[]
agents: AgentDefinition[]
canUseTool: CanUseToolFn
getAppState: () => AppState
setAppState: SetAppState
userSpecifiedModel?: string
maxTurns?: number
maxBudgetUsd?: number
}
cwd = 当前工作目录(你的项目路径)
tools = AI 能调用的所有工具
commands = 用户能调用的所有命令
mcpClients = MCP 服务器连接
agents = 自定义 Agent 定义
getAppState / setAppState = 读写全局状态
userSpecifiedModel = 指定的 AI 模型
maxTurns = 最大交互次数(防止死循环)
maxBudgetUsd = 最大花费(美元)
实际的查询逻辑在 src/query.ts 中。核心函数签名:
export type QueryParams = {
messages: Message[]
systemPrompt: SystemPrompt
userContext: { [k: string]: string }
systemContext: { [k: string]: string }
canUseTool: CanUseToolFn
toolUseContext: ToolUseContext
querySource: QuerySource
maxOutputTokensOverride?: number
maxTurns?: number
taskBudget?: { total: number }
}
messages = 对话历史(用户说了什么,AI 回复了什么)
systemPrompt = 系统提示词(给 AI 的指令)
userContext = 用户上下文(如当前日期、项目信息)
systemContext = 系统上下文(如 git 状态)
canUseTool = 判断某个工具是否可用的函数
toolUseContext = 工具执行的上下文信息
API、MCP、Analytics 等核心服务
Services 是 Claude Code 的"基础设施团队"——它们提供各种底层能力,让上层的工具和命令能够正常工作。
与 Claude AI 云端通信,处理认证、重试、限流
Model Context Protocol,连接外部工具和服务
追踪使用情况、事件、错误报告
会话历史、设置、插件管理
MCP 是 Claude Code 的"扩展接口"。它允许连接外部工具和服务。
如果你想给 Claude Code 添加一个新能力(如连接某个 API),可以通过 MCP 来实现。MCP 支持 stdio、SSE、WebSocket 等多种传输方式。
Claude Code 支持Bridge 模式,允许远程协作。相关代码在 src/bridge/:
当启用 COORDINATOR_MODE 时,Claude Code 可以协调多个Agent 同时工作。相关代码在 src/coordinator/:
// coordinator/coordinatorMode.ts
export type CoordinatorConfig = {
agents: Agent[]
tasks: Task[]
onMessage: (msg: Message) => void
onAgentUpdate: (id: string, state: AgentState) => void
}
CoordinatorConfig 定义协调器的配置
agents = 所有参与的 Agent
tasks = 待分配的任务
onMessage = 收到消息时的回调
onAgentUpdate = Agent 状态变化时的回调
如何基于 Claude Code 做二次开发
首先确保你安装了正确的依赖:
bun 1.3.5+
Node.js 包管理器,类似 npm 但更快
node 24+
JavaScript 运行时
安装依赖并验证安装:
# 安装依赖
bun install
# 验证版本
bun run version
# 运行开发模式
bun run dev
安装所有项目依赖
检查 CLI 是否正常启动
启动交互式开发模式
假设你想添加一个"数据库查询工具":
在 src/tools/DatabaseTool/ 下创建 DatabaseTool.ts
导入并添加到 getTools() 返回数组
export class DatabaseTool implements Tool {
name = 'database'
description = 'Execute SQL queries'
async execute(query: string) {
// 连接数据库、执行查询
return { rows: await db.query(query) }
}
}
定义一个 DatabaseTool 类,实现 Tool 接口
name 是工具名(AI 调用的标识)
description 是工具描述(让 AI 知道何时使用)
execute 是实际执行 SQL 的函数
假设你想添加一个 /database 命令:
在 src/commands/database/ 下创建 index.ts
导入并添加到 getCommands() 数组
export default {
name: 'database',
description: 'Query the database',
async getPrompt(args, context) {
return { prompt: `Query: ${args}` }
}
} as Command
导出默认命令对象
name = 命令名(用户输入 /database)
description = 帮助文本
getPrompt = 返回要执行的提示词
通过 MCP 连接外部能力:
// 在 claude_desktop_config.json 或项目 .mcp.json
{
"mcpServers": {
"my-database": {
command": "npx",
"args": ["-e", "my-mcp-server"],
"env": {
"DATABASE_URL": "postgres://..."
}
}
}
}
在 MCP 配置文件中添加服务器
my-database 是服务器名字
command 和 args 指定如何启动服务器
env 可以传递环境变量
Claude Code 是用 TypeScript 编写的,了解类型定义很重要:
// 定义一个简单的类型
type TaskStatus =
| 'pending'
| 'running'
| 'completed'
| 'failed'
| 'killed'
// 定义一个接口
interface Task {
id: string
status: TaskStatus
execute(): Promise<void>
}
type 定义一个类型别名
TaskStatus 是一个字符串,只能是这几个值之一
interface 定义一个对象的结构
Task 有 id(字符串)、status(TaskStatus)、execute(异步函数)
当你做二次开发时,这些文件是最重要的参考:
程序入口点,所有初始化从这里开始
工具注册表,添加新工具在这里
命令注册表,添加新命令在这里
核心查询逻辑,修改 AI 行为看这里
全局状态定义
查询引擎核心
你现在对 Claude Code 的架构有了全面的理解。记住:二次开发的关键是找到正确的层次——工具在 tools/,命令在 commands/,核心逻辑在 query.ts 和 QueryEngine.ts。