🔍 Claude Code 如何理解代码库

从文件搜索到 AST 解析的完整流程

步骤 1:用户发起搜索请求

用户说:"帮我找到所有处理用户认证的代码"

步骤 2:Claude 选择工具并生成参数

// Claude 决定使用 GrepTool { "tool": "GrepTool", "parameters": { "pattern": "(auth|authenticate|login|session)", "path": "src/", "include": "*.{ts,tsx,js,jsx}", "exclude": "node_modules/**" } }

步骤 3:GrepTool 执行 ripgrep 搜索

typescript
async call(args, context) {
// 1. 构建 ripgrep 命令
const rgArgs = [
'--json', // JSON 输出便于解析
'--max-count', '100', // 限制结果数量
'--context', '2', // 显示上下文 2 行
'--glob', args.include, // 文件类型过滤
'--glob', `!${args.exclude}`, // 排除目录
args.pattern,
args.path || '.'
];
// 2. 执行 ripgrep
const result = await execRipgrep(rgArgs);
// 3. 解析 JSON 输出
const matches = result.split('\n')
.filter(line => line.trim())
.map(line => JSON.parse(line));
// 4. 格式化输出(可折叠显示)
return {
data: formatMatches(matches),
isCollapsible: true
};
}

步骤 4:ripgrep 返回结果

// ripgrep JSON 输出示例 { "type": "match", "data": { "path": { "text": "src/auth/login.ts" }, "lines": { "text": "export async function authenticateUser(credentials) {", "line_number": 15 }, "submatches": [ { "match": "authenticate", "start": 22, "end": 34 } ] } }

步骤 5:Claude 分析搜索结果

Claude 看到搜索结果后:

  • 识别出 `src/auth/login.ts` 包含认证逻辑
  • 识别出 `src/middleware/auth.ts` 是认证中间件
  • 识别出 `src/utils/session.ts` 处理会话管理
  • 决定下一步读取这些文件的完整内容
💡 关键技术点
ripgrep 优化:使用 `--json` 输出便于程序解析,`--context` 显示上下文帮助理解
可折叠显示:搜索结果标记为可折叠,避免占用过多上下文空间
智能过滤:自动排除 `node_modules`、`.git` 等目录,聚焦业务代码
多文件类型:通过 `--glob` 支持 TypeScript/JavaScript/Python 等多种语言

✏️ Claude Code 如何编辑文件

从 diff 匹配到多轮修正的完整流程

步骤 1:用户请求修改

用户说:"在 authenticateUser 函数中添加密码强度验证"

步骤 2:Claude 读取文件内容

// FileReadTool 读取文件 async call(args, context) { const content = await fs.readFile(args.path, 'utf-8'); return { data: { path: args.path, content: content, size: content.length } }; }

步骤 3:Claude 生成编辑指令

// Claude 决定使用 FileEditTool { "tool": "FileEditTool", "parameters": { "path": "src/auth/login.ts", "old_text": `export async function authenticateUser(credentials) { const user = await findUserByEmail(credentials.email); if (!user) throw new Error('User not found'); const isValid = await comparePassword(credentials.password, user.password); if (!isValid) throw new Error('Invalid password'); return createSession(user); }`, "new_text": `export async function authenticateUser(credentials) { // 密码强度验证 if (!validatePasswordStrength(credentials.password)) { throw new Error('Password does not meet requirements'); } const user = await findUserByEmail(credentials.email); if (!user) throw new Error('User not found'); const isValid = await comparePassword(credentials.password, user.password); if (!isValid) throw new Error('Invalid password'); return createSession(user); }` } }

步骤 4:FileEditTool 执行编辑

// FileEditTool.ts 核心实现 async call(args, context) { // 1. 读取文件当前内容 const fileContent = await fs.readFile(args.path, 'utf-8'); // 2. 查找 old_text 出现位置 const occurrences = countOccurrences(fileContent, args.old_text); if (occurrences === 0) { throw new Error(`Text not found in file: ${args.path}`); } if (occurrences > 1 && !args.multiple_replaces) { throw new Error(`Found ${occurrences} occurrences. Use multiple_replaces=true`); } // 3. 应用替换 const newContent = fileContent.replace(args.old_text, args.new_text); // 4. 写回文件 await fs.writeFile(args.path, newContent, 'utf-8'); // 5. 生成 diff const diff = generateDiff(fileContent, newContent); return { data: { path: args.path, diff: diff, occurrences: occurrences } }; }

步骤 5:处理编辑失败(多轮修正)

// 场景:old_text 不匹配 FileEditTool 返回错误: { "error": "Text not found in file", "suggestion": "The code may have changed. Here's the current content:", "current_content": "..." } Claude 分析错误后: 1. 读取当前文件内容 2. 重新定位要修改的代码 3. 生成新的编辑指令(使用正确的 old_text) 4. 再次尝试编辑
💡 关键技术点
精确匹配:使用字符串精确匹配而非模糊匹配,避免误修改
多处检测:检测多处匹配并询问用户,避免批量误改
diff 生成:生成标准 diff 格式,便于用户审查
多轮修正:编辑失败时自动分析原因并重新尝试

💻 Claude Code 如何运行终端命令

6 层安全检查 + AST 解析 + 沙箱执行

终端命令执行完整流程 用户:"运行 npm install" ↓ ┌─────────────────────────────────────────────────────────┐ │ 第 1 层:命令分类 │ │ - 识别为"包管理命令" │ │ - 标记为"中等风险"(需要网络访问) │ └─────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────┐ │ 第 2 层:安全检测(bashSecurity.ts) │ │ - 检测命令替换:$()、`` │ │ - 检测参数注入:${} │ │ - 检测进程替换:<()、>() │ │ - 检测 Unicode 攻击:\u00A0、\u200B │ │ - 结果:✅ 安全,无危险模式 │ └─────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────┐ │ 第 3 层:权限规则匹配(bashPermissions.ts) │ │ - 检查用户规则:allow: ["npm:*"] │ │ - 匹配成功 → 自动批准 │ │ - 无规则 → 询问用户 │ └─────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────┐ │ 第 4 层:路径约束检查(pathValidation.ts) │ │ - 检查工作目录:/Users/yzt/project │ │ - 检查输出重定向:无 │ │ - 检查危险路径:无 │ └─────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────┐ │ 第 5 层:沙箱执行(shouldUseSandbox.ts) │ │ - 判断:npm install 不需要沙箱 │ │ - 原因:需要网络访问、需要修改 node_modules │ └─────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────┐ │ 第 6 层:执行与输出 │ │ - spawn('npm', ['install'], {cwd: '/Users/yzt/project'}) │ │ - 捕获 stdout/stderr │ │ - 超时控制:300 秒 │ │ - 输出格式化:截断大输出 │ └─────────────────────────────────────────────────────────┘

核心代码:BashTool 执行流程

// BashTool.ts 简化实现 async call(args, context) { // 1. 命令分类 const commandType = classifyCommand(args.command); // 2. 安全检测 const securityCheck = await runSecurityChecks(args.command); if (!securityCheck.safe) { throw new Error(securityCheck.reason); } // 3. 权限检查 const permission = await checkPermissions(args.command, context); if (permission.decision === 'deny') { throw new Error('Command denied by permission rules'); } if (permission.decision === 'ask') { await askUserPermission(permission); } // 4. 路径约束检查 const pathCheck = await checkPathConstraints(args.command); if (!pathCheck.valid) { throw new Error(pathCheck.reason); } // 5. 沙箱决策 const useSandbox = shouldUseSandbox(args); // 6. 执行命令 const child = spawn(args.command, [], { shell: true, cwd: context.cwd, stdio: ['pipe', 'pipe', 'pipe'] }); // 7. 捕获输出 const [stdout, stderr] = await Promise.all([ readStream(child.stdout), readStream(child.stderr) ]); // 8. 输出处理 return { data: { stdout: truncateOutput(stdout), stderr: truncateOutput(stderr), exitCode: child.exitCode, persistedOutputPath: persistIfLarge(stdout, stderr) } }; }
💡 关键技术点
AST 解析:使用 Tree-sitter 解析 Bash AST,准确识别命令结构
20+ 危险模式:命令替换/参数注入/进程替换/Unicode 攻击/IFS 注入等
通配符规则:支持"npm:*"、"git:*"等前缀规则,灵活授权
输出持久化:大输出(>100KB)自动存储到临时文件,避免上下文溢出
后台执行:run_in_background=true 支持长时间运行命令

🔄 Claude Code 如何处理完整工作流

多 Agent 协作 + 任务编排 + 文件系统上下文传递

完整工作流:实现用户登录功能 用户:"帮我实现一个用户登录功能" ↓ ┌─────────────────────────────────────────────────────────┐ │ 协调器(Claude)分析任务 │ │ - 这是一个复杂任务,需要多步完成 │ │ - 需要:研究现有代码 → 实现功能 → 测试验证 → 提交代码 │ │ - 决策:启动多个 Worker 并行处理 │ └─────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────┐ │ 阶段 1: Research(并行启动 2 个 Worker) │ ├─────────────────────────────────────────────────────────┤ │ Worker 1: 分析代码结构 │ │ Prompt: "分析 src/目录结构,找出认证相关文件" │ │ 工具:GlobTool("**/*.ts"), FileReadTool │ │ 输出:写入 research-notes.md │ │ │ │ Worker 2: 查找认证代码 │ │ Prompt: "搜索所有与认证相关的代码" │ │ 工具:GrepTool("(auth|login|session)") │ │ 输出:写入 auth-analysis.md │ └─────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────┐ │ 阶段 2: Synthesis(协调器综合) │ │ - 读取 research-notes.md │ │ - 读取 auth-analysis.md │ │ - 综合理解:项目使用 JWT 认证,有现成的 auth 中间件 │ │ - 制定实现规格: │ │ 1. 创建 LoginForm 组件 │ │ 2. 实现 login API 端点 │ │ 3. 添加密码强度验证 │ │ 4. 编写单元测试 │ └─────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────┐ │ 阶段 3: Implementation(串行执行) │ ├─────────────────────────────────────────────────────────┤ │ Worker 3: 实现登录 API │ │ Prompt: "在 src/auth/login.ts 实现 login 函数,包含:" │ │ "1. 密码强度验证 │ │ "2. 用户查找 │ │ "3. 密码比对 │ │ "4. JWT 令牌生成 │ │ 工具:FileEditTool, BashTool(运行测试) │ │ 输出:src/auth/login.ts + 测试通过 │ │ │ │ Worker 4: 实现前端表单 │ │ Prompt: "创建 LoginForm 组件,包含:" │ │ "1. 邮箱和密码输入框 │ │ "2. 表单验证 │ │ "3. 提交处理 │ │ 工具:FileEditTool │ │ 输出:src/components/LoginForm.tsx │ └─────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────┐ │ 阶段 4: Verification(并行执行) │ ├─────────────────────────────────────────────────────────┤ │ Worker 5: 运行测试套件 │ │ Prompt: "运行所有测试,确保登录功能正常" │ │ 工具:BashTool("npm test") │ │ 输出:测试报告 + 覆盖率 │ │ │ │ Worker 6: 代码审查 │ │ Prompt: "审查登录功能代码,检查安全问题" │ │ 工具:FileReadTool, SkillTool(/verify) │ │ 输出:代码审查报告 │ └─────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────┐ │ 阶段 5: Deployment(提交代码) │ │ Worker 7: 提交并创建 PR │ │ Prompt: "提交代码并创建 PR" │ │ 工具:BashTool(git add/commit/push), gh pr create │ │ 输出:commit hash + PR URL │ └─────────────────────────────────────────────────────────┘

关键代码:协调器启动 Worker

// 协调器调用 AgentTool 启动 Worker { "tool": "AgentTool", "parameters": { "description": "分析代码结构", "subagent_type": "worker", "prompt": "分析 src/目录结构,找出认证相关文件。 使用 GlobTool 列出所有.ts 文件,然后用 FileReadTool 读取关键文件。 将分析结果写入 research-notes.md。" } } // 并行启动多个 Worker { "tool": "AgentTool", "parameters": { "description": "查找认证代码", "subagent_type": "worker", "prompt": "搜索所有与认证相关的代码。 使用 GrepTool 搜索 (auth|login|session) 模式。 将搜索结果和分析写入 auth-analysis.md。" } }

关键代码:Worker 通过文件传递上下文

// Worker 1 写入研究笔记 // research-notes.md # 代码结构分析 ## 认证相关文件 - src/auth/login.ts - 登录逻辑 - src/auth/middleware.ts - 认证中间件 - src/utils/session.ts - 会话管理 ## 依赖 - jsonwebtoken - JWT 处理 - bcrypt - 密码加密 --- // Worker 2 写入分析报告 // auth-analysis.md # 认证代码分析 ## 现有功能 - 用户查找:findUserByEmail() - 密码比对:comparePassword() - 会话创建:createSession() ## 缺失功能 - 密码强度验证 - 登录失败限流 - JWT 令牌刷新 --- // 协调器读取文件综合理解 const researchNotes = await readFile('research-notes.md'); const authAnalysis = await readFile('auth-analysis.md'); // 综合理解后制定实现规格 const spec = synthesizeSpec(researchNotes, authAnalysis);
💡 关键技术点
并行是超能力:Research 阶段多 Worker 并行,Implementation 阶段单 Worker 写文件
Worker 看不到协调器对话:每个提示必须自包含所有上下文
文件系统协作:通过文件传递上下文,避免单 Agent 上下文溢出
Continue vs Spawn:高上下文重叠→SendMessageTool 继续,低重叠→AgentTool 新建
任务通知:Worker 完成通过<task-notification>消息通知协调器
← 返回 Claude Code 源码分析