Claude Code架构解析
一、Claude Code整体概述
Claude Code是Anthropic开发的终端AI编程工具,直接集成在开发者终端环境中,无需额外服务器或复杂配置。与Cursor相比,它更像是一个熟悉整个项目的高级程序员,输出代码更简练。
二、Claude Code系统架构深度拆解
2.1 系统架构三层核心
- 交互层:用户与Claude Code的接触点
- 核心引擎:负责协调各组件工作的"大脑"
- 工具系统:Claude Code的"手脚",用于与外部环境交互
2.2 执行流程
从用户提交命令到渲染结果的完整流程:
- 用户输入 → 输入处理 → 核心引擎 → 工具调度 → 结果渲染
2.3 交互层实现细节
主要由REPL.tsx和PromptInput.tsx等组件实现,包含三个关键模块:
2.3.1 输入逻辑处理
function processUserInput(input: string, mode: InputMode): UserMessage {
if (input.startsWith('/')) {
return handleSlashCommand(input); // 处理斜杠命令
} else if (input.startsWith('!')) {
return handleBashCommand(input.slice(1)); // 处理bash命令
} else {
return createUserMessage(input); // 创建普通用户消息
}
}
输入模式分类:
/开头:斜杠命令!开头:Bash命令- 其他:自然语言输入
2.3.2 渲染系统
渲染分为两个阶段:
- 工具调用阶段(Assistant侧):显示工具名称、参数和执行状态
- 工具结果阶段(User侧):显示执行结果
核心组件:
AssistantToolUseMessage:渲染助手调用工具时的消息- 显示工具名称(通过
tool.userFacingName()) - 显示参数(通过
tool.renderToolUseMessage()) - 使用
ToolUseLoader显示执行状态动画
- 显示工具名称(通过
UserToolSuccessMessage:渲染工具执行成功后的结果- 调用
tool.renderToolResultMessage()渲染具体内容
- 调用
工具接口定义规范:
userFacingName():显示给用户的工具名称renderToolUseMessage(input, options):渲染工具参数renderToolResultMessage(output, options):渲染工具结果renderToolUseRejectedMessage():渲染拒绝消息
UI渲染特性:
- 使用Ink框架的Box和Text组件构建终端UI
- 支持主题系统(通过
getTheme()) - 响应式布局(flexDirection, justifyContent)
- 详细/简洁模式切换(verbose参数)
- 执行成本和时间显示(Cost组件)
2.4 核心引擎(Core Engine)
核心引擎是Claude Code的"大脑",负责:
- 消息系统:管理用户输入、AI响应和工具结果的消息流
- 查询引擎:与AI模型交互,发送请求并处理响应
- 工具调度器:协调工具的调用和结果处理
关键组件query.ts实现逻辑:
async function* query(
messages: Message[],
systemPrompt: string,
context: Context,
canUseTool: CanUseToolFn,
toolUseContext: ToolUseContext,
): AsyncGenerator<Message> {
// 1. 初始化大模型prompt
const fullSystemPrompt = formatSystemPromptWithContext(systemPrompt, context)
// 2. 获取大模型返回
const result = await queryWithBinaryFeedback(
toolUseContext,
getAssistantResponse,
getBinaryFeedbackResponse,
)
// 3. 处理模型返回的工具请求
const toolUseMessages = assistantMessage.message.content.filter(
_ => _.type === 'tool_use',
)
// 4. 并行/串行执行工具
if (
toolUseMessages.every(msg =>
toolUseContext.options.tools.find(t => t.name === msg.name)?.isReadOnly(),
)
) {
for await (const message of runToolsConcurrently) // 并行执行
} else {
for await (const message of runToolsSerially) // 串行执行
}
// 5. 处理后续交互
yield* await query()
}
执行策略智能判断:
- 并行执行:当所有工具都是只读操作(
isReadOnly())时,可以并发执行 - 串行执行:当包含写操作时,必须串行执行以保证安全
2.5 工具系统
工具系统使Claude Code能够与外部环境交互,包含四类工具:
- 文件工具:读取、写入、搜索文件
- 执行工具:运行shell命令、执行代码
- 分析工具:代码分析、依赖检查等
- 元工具:复合工具,可执行更复杂的任务
工具接口定义:
interface Tool {
name: string;
description: string;
inputSchema: z.ZodType;
execute(params: any): Promise<ToolResult>;
}
技术亮点:
- 每个工具遵循统一接口,包含名称、描述、参数模式和执行逻辑
- Claude Code内置15个工具,实现和提示词都值得学习
- 特别强大的bash工具可调用shell所有命令
- 包含agent tool,可发挥更强大的能力
2.6 上下文管理
上下文管理是Claude Code的"记忆",负责收集和组织代码相关信息:
- 项目结构:目录和文件结构
- 代码内容:关键文件的内容
- 版本控制:Git历史和状态
- 配置信息:项目配置和依赖
核心挑战:在有限的上下文窗口内提供最相关的信息
2.6.1 LRU缓存机制
const fileEncodingCache = new LRUCache<string, BufferEncoding>({
fetchMethod: path => detectFileEncodingDirect(path),
ttl: 5 * 60 * 1000, // 5分钟过期
ttlAutopurge: false,
max: 1000, // 最大缓存1000个文件
})
const lineEndingCache = new LRUCache<string, LineEndingType>({
fetchMethod: path => detectLineEndingsDirect(path),
ttl: 5 * 60 * 1000,
ttlAutopurge: false,
max: 1000,
})
缓存策略:对文件编码、行尾类型等信息实现缓存,减少重复操作
2.6.2 按需加载策略
不会一次性加载整个代码库,而是根据查询需要智能加载相关文件:
async *call({ pattern, path }, { abortController }){
const start = Date.now()
const { files, truncated } = await glob(
pattern,
path ?? getCwd(),
{ limit: 100, offset: 0 },
abortController.signal,
)
const output: Output = {
filenames: files,
durationMs: Date.now() - start,
numFiles: files.length,
truncated,
}
yield {
type: 'result',
resultForAssistant: this.renderResultForAssistant(output),
data: output,
}
}
- 搜索结果限制100个,避免上下文溢出
- 提供截断提示(truncated)
2.6.3 结果截断处理
const MAX_LINES = 4
const MAX_FILES = 1000
const TRUNCATED_MESSAGE = `There are more than ${MAX_FILES} files in the repository. Use the LS tool (passing a specific path), Bash tool, and other tools to explore nested directories. The first ${MAX_FILES} files and directories are included below:\n\n`
- 对大量搜索结果实现智能截断
- 提供清晰的截断提示和操作引导
2.6.4 上下文拼装
async function getContext(): Context {
return {
directoryStructure: await getDirectoryStructure(),
gitStatus: await getGitStatus(),
codeStyle: await getCodeStyle(),
// 其他上下文...
};
}
2.7 安全机制
安全与权限是Claude Code的"护栏",确保工具使用的安全性:
- 权限验证:工具执行前的权限检查
- 用户确认:关键操作的用户确认机制
- 最小权限原则:只向用户索要完成任务的最小权限
- 安全边界:文件操作和命令执行的限制
权限检查实现:
export const hasPermissionsToUseTool
// 跳过
if (context.options.dangerouslySkipPermissions) {
return { result: true }
}
if (context.abortController.signal.aborted) {
throw new AbortError()
}
// 允许每个工具单独配置,由工具声明安全性
try {
if (!tool.needsPermissions(input as never)) {
return { result: true }
}
} catch (e) {
logError(`Error checking permissions: ${e}`)
return { result: false, message: 'Error checking permissions' }
}
三、关键技术启发
3.1 Binary Feedback机制
用于程序员测试prompt质量的核心机制:
async function queryWithBinaryFeedback(
toolUseContext: ToolUseContext,
getAssistantResponse: () => Promise<AssistantMessage>,
getBinaryFeedbackResponse?: (
m1: AssistantMessage,
m2: AssistantMessage,
) => Promise<BinaryFeedbackResult>,
): Promise<BinaryFeedbackResult> {
if (
process.env.USER_TYPE !== 'ant' ||
!getBinaryFeedbackResponse ||
!(await shouldUseBinaryFeedback())
)
const [m1, m2] = await Promise.all([
getAssistantResponse(),
getAssistantResponse(),
])
}
机制原理:
- 使用完全相同的请求调用两次,观察模型是否给出不同输出
- 如果AI返回两个不同答案,说明模型对此次请求是犹豫的、考虑不清楚的,需要让用户做选择
- 检测对象不是文本,而是生成的tool use是否相同(结构化数据输出的稳定性远大于文本)
- 仅在程序员自己测试时生效,说明这种测试逻辑对开发自己的Agent很有用
- 出现差异说明需要提高prompt质量
3.2 MCP工具分层管理
Claude Code自身只维护一个tengu_mcp_server,同时支持用户添加MCP Server,通过三级分层结构管理:
三层结构:
- Global:全局配置的通用MCP
- Mcprc:配置文件,可以共享(
.mcprc文件) - Project:项目级别,当前代码库可单独配置
优先级规则:下层结构的MCP配置可以覆盖上层配置
添加MCP Server实现:
export function addMcpServer(
name: McpName,
server: McpServerConfig,
scope: ConfigScope = 'project',
): void {
if (scope === 'mcprc') {
// 写入.mcprc配置文件
const mcprcPath = join(getCwd(), '.mcprc')
// ... 读取现有配置,添加新server,写回文件
} else if (scope === 'global') {
// 写入全局配置
const config = getGlobalConfig()
config.mcpServers[name] = server
saveGlobalConfig(config)
} else {
// 写入项目配置
const config = getCurrentProjectConfig()
config.mcpServers[name] = server
saveCurrentProjectConfig(config)
}
}
工具聚合逻辑:
- 请求所有MCP Server,获取所有tools
- 将tools聚合后发送给大模型
3.3 通过AI检测安全
利用AI做安全辅助,例如判断命令是否有被注入的可能性:
export const getCommandSubcommandPrefix = memoize(
async (
command: string,
abortSignal: AbortSignal,
): Promise<CommandSubcommandPrefixResult | null> => {
const subcommands = splitCommand(command)
// 获取命令前缀观察是否在安全执行列表
const [fullCommandPrefix, ...subcommandPrefixesResults] = await Promise.all([
getCommandPrefix(command, abortSignal),
...subcommands.map(async subcommand => ({
subcommand,
prefix: await getCommandPrefix(subcommand, abortSignal),
})),
])
},
command => command,
)
3.4 上下文压缩处理
核心功能:清空对话历史但保留上下文摘要,解决长对话导致的上下文窗口问题
技术亮点:
- 智能摘要生成:使用Sonnet模型生成对话摘要,保留关键信息供后续使用
- Fork机制应用:利用
setForkConvoWithMessagesOnTheNextRender创建新的对话分支,摘要作为新对话起点 - Token使用优化:将摘要的token使用量设为0,避免触发上下文窗口警告
- 缓存清理:清理
getContext和getCodeStyle缓存,确保新对话环境干净
核心代码流程:
- 获取当前对话历史
- 构造摘要请求并调用Sonnet模型
- 提取并验证摘要内容
- 清屏、清空消息历史
- 创建包含摘要的新对话分支
3.5 简单任务交给小模型
Claude内部有多个模型实例,对于只判断对错或简单任务,会交给Haiku模型:
示例1:创建标题任务
async function generateTitle(description: string): Promise<string> {
const response = await queryHaiku({
systemPrompt: ['Generate a concise issue title (max 80 chars)...'],
userPrompt: description,
})
// ... 处理响应
}
示例2:确认前缀任务
const getCommandPrefix = memoize(
async (command: string, abortSignal: AbortSignal): Promise<CommandPrefixResult | null> => {
const response = await queryHaiku({
systemPrompt: [`Your task is to process Bash commands...`],
// ... 包含大量示例
})
},
)
优势:节省成本、提升速度、分工明确
3.6 高效的文件系统策略
- 分层拉取:先获取高层次项目结构,再根据需要深入特定目录,避免一次性加载过多内容
- Ripgrep集成:利用Rust编写的高性能搜索工具,实现毫秒级代码库搜索
- 内置二进制支持:包含预编译的ripgrep二进制文件,确保跨平台一致性和性能
- 智能结果排序:搜索结果按修改时间排序,优先展示最近更改的文件
- 并发搜索能力:支持同时发起多个搜索请求,提高大型代码库分析效率
- LRU缓存机制:对文件编码、行尾类型等信息实现缓存,减少重复操作
3.7 精妙的工具设计
Claude Code中内置的15个工具的实现和提示词都值得学习,正是这些极致的工具才保证了任务执行的高效性。
总结要点
- Claude Code的核心优势:系统架构清晰、工具系统极致、上下文管理智能、安全机制完善
- 关键启发:Binary Feedback机制、MCP分层管理、AI安全检测、上下文压缩、模型分级使用
- 应用场景:从日常开发到复杂任务(DeepResearch),CLI+AI模式展现出强大潜力
- 技术趋势:MCP协议正在成为AI工具标准接口,构建自主可控的AI编程基础设施是重要方向

浙公网安备 33010602011771号