[{"data":1,"prerenderedAt":1993},["ShallowReactive",2],{"navigation":3,"\u002Fcore-features\u002Fedit-generate":189,"\u002Fcore-features\u002Fedit-generate-surround":1989},[4,35,57,75,101,123,149,171],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":34},"第 1 章：认识 Claude Code","i-lucide-rocket","\u002Fintro","1.intro",[10,14,18,22,26,30],{"title":11,"path":12,"stem":13},"什么是 Claude Code","\u002Fintro\u002Fwhat-is-claude-code","1.intro\u002F1.what-is-claude-code",{"title":15,"path":16,"stem":17},"Claude Code 与 Copilot、Cursor、Windsurf 的本质区别","\u002Fintro\u002Fvs-competitors","1.intro\u002F2.vs-competitors",{"title":19,"path":20,"stem":21},"AI 编程助手生态全景与选型指南","\u002Fintro\u002Fecosystem-guide","1.intro\u002F3.ecosystem-guide",{"title":23,"path":24,"stem":25},"LLM 的概率本质","\u002Fintro\u002Fllm-probability","1.intro\u002F4.llm-probability",{"title":27,"path":28,"stem":29},"从聊天机器人到 Agent","\u002Fintro\u002Ffrom-chatbot-to-agent","1.intro\u002F5.from-chatbot-to-agent",{"title":31,"path":32,"stem":33},"Claude Code 的 Agentic Loop 全拆解","\u002Fintro\u002Fagentic-loop","1.intro\u002F6.agentic-loop",false,{"title":36,"icon":37,"path":38,"stem":39,"children":40,"page":34},"第 2 章：安装与配置","i-lucide-settings","\u002Fsetup","2.setup",[41,45,49,53],{"title":42,"path":43,"stem":44},"系统要求与安装方式","\u002Fsetup\u002Fsystem-requirements","2.setup\u002F1.system-requirements",{"title":46,"path":47,"stem":48},"认证、登录与多账户管理","\u002Fsetup\u002Fauthentication","2.setup\u002F2.authentication",{"title":50,"path":51,"stem":52},"选择你的界面","\u002Fsetup\u002Fchoose-interface","2.setup\u002F3.choose-interface",{"title":54,"path":55,"stem":56},"Coding Plan","\u002Fsetup\u002Fcoding-plan","2.setup\u002F4.coding-plan",{"title":58,"icon":59,"path":60,"stem":61,"children":62,"page":34},"第 3 章：快速上手","i-lucide-hand","\u002Fquickstart","3.quickstart",[63,67,71],{"title":64,"path":65,"stem":66},"启动、交互模式与基本命令","\u002Fquickstart\u002Fstartup","3.quickstart\u002F1.startup",{"title":68,"path":69,"stem":70},"让 Claude 理解你的项目","\u002Fquickstart\u002Fcodebase-understanding","3.quickstart\u002F2.codebase-understanding",{"title":72,"path":73,"stem":74},"第一次代码变更","\u002Fquickstart\u002Ffirst-change","3.quickstart\u002F3.first-change",{"title":76,"icon":77,"path":78,"stem":79,"children":80,"page":34},"第 4 章：核心功能","i-lucide-laptop","\u002Fcore-features","4.core-features",[81,85,89,93,97],{"title":82,"path":83,"stem":84},"代码库全景扫描与模块关系分析","\u002Fcore-features\u002Fcodebase-scan","4.core-features\u002F1.codebase-scan",{"title":86,"path":87,"stem":88},"代码编辑与生成","\u002Fcore-features\u002Fedit-generate","4.core-features\u002F2.edit-generate",{"title":90,"path":91,"stem":92},"测试与调试","\u002Fcore-features\u002Ftest-debug","4.core-features\u002F3.test-debug",{"title":94,"path":95,"stem":96},"Git 工作流","\u002Fcore-features\u002Fgit-workflow","4.core-features\u002F4.git-workflow",{"title":98,"path":99,"stem":100},"工具链执行","\u002Fcore-features\u002Ftoolchain","4.core-features\u002F5.toolchain",{"title":102,"icon":103,"path":104,"stem":105,"children":106,"page":34},"第 5 章：进阶配置","i-lucide-wrench","\u002Fadvanced","5.advanced",[107,111,115,119],{"title":108,"path":109,"stem":110},"CLAUDE.md","\u002Fadvanced\u002Fclaude-md","5.advanced\u002F1.claude-md",{"title":112,"path":113,"stem":114},"Skills","\u002Fadvanced\u002Fskills","5.advanced\u002F2.skills",{"title":116,"path":117,"stem":118},"MCP","\u002Fadvanced\u002Fmcp","5.advanced\u002F3.mcp",{"title":120,"path":121,"stem":122},"Hooks 与 Plan 模式","\u002Fadvanced\u002Fhooks-plan","5.advanced\u002F4.hooks-plan",{"title":124,"icon":125,"path":126,"stem":127,"children":128,"page":34},"第 6 章：实战开发","i-lucide-hammer","\u002Fpractice","6.practice",[129,133,137,141,145],{"title":130,"path":131,"stem":132},"需求分析与架构设计","\u002Fpractice\u002Frequirements-architecture","6.practice\u002F1.requirements-architecture",{"title":134,"path":135,"stem":136},"项目脚手架搭建与技术选型","\u002Fpractice\u002Fscaffolding","6.practice\u002F2.scaffolding",{"title":138,"path":139,"stem":140},"核心功能实现","\u002Fpractice\u002Fcore-features","6.practice\u002F3.core-features",{"title":142,"path":143,"stem":144},"测试覆盖、代码审查与质量调优","\u002Fpractice\u002Ftesting-quality","6.practice\u002F4.testing-quality",{"title":146,"path":147,"stem":148},"部署上线与成果分享","\u002Fpractice\u002Fdeployment","6.practice\u002F5.deployment",{"title":150,"icon":151,"path":152,"stem":153,"children":154,"page":34},"第 7 章：心法层","i-lucide-brain","\u002Fmindset","7.mindset",[155,159,163,167],{"title":156,"path":157,"stem":158},"提示词设计原则","\u002Fmindset\u002Fprompt-design","7.mindset\u002F1.prompt-design",{"title":160,"path":161,"stem":162},"上下文管理策略","\u002Fmindset\u002Fcontext-management","7.mindset\u002F2.context-management",{"title":164,"path":165,"stem":166},"安全与权限控制","\u002Fmindset\u002Fsecurity","7.mindset\u002F3.security",{"title":168,"path":169,"stem":170},"Boris Cherny 的 9 条实战心法与团队推广经验","\u002Fmindset\u002Fboris-cherny-tips","7.mindset\u002F4.boris-cherny-tips",{"title":172,"icon":173,"path":174,"stem":175,"children":176,"page":34},"附录","i-lucide-paperclip","\u002Fappendix","8.appendix",[177,181,185],{"title":178,"path":179,"stem":180},"常用命令速查表","\u002Fappendix\u002Fa.command-cheatsheet","8.appendix\u002Fa.command-cheatsheet",{"title":182,"path":183,"stem":184},"AI 核心术语汇编","\u002Fappendix\u002Fb.ai-terminology","8.appendix\u002Fb.ai-terminology",{"title":186,"path":187,"stem":188},"资源链接与延伸阅读","\u002Fappendix\u002Fc.resources","8.appendix\u002Fc.resources",{"id":190,"title":86,"body":191,"description":1982,"extension":1983,"links":1984,"meta":1985,"navigation":574,"path":87,"seo":1987,"stem":88,"__hash__":1988},"docs\u002F4.core-features\u002F2.edit-generate.md",{"type":192,"value":193,"toc":1939},"minimark",[194,207,212,221,226,236,242,268,273,287,292,302,306,317,321,332,336,342,346,349,354,360,365,371,375,378,383,389,394,400,404,407,411,414,430,457,462,468,472,475,489,495,499,511,518,522,533,598,605,609,620,625,647,651,654,658,667,705,709,712,717,723,728,734,739,745,749,758,772,775,779,782,786,789,795,801,805,808,814,818,821,827,831,834,838,852,858,1025,1038,1056,1060,1074,1080,1083,1141,1145,1159,1268,1271,1275,1278,1284,1288,1291,1295,1306,1316,1376,1386,1390,1406,1412,1416,1419,1499,1503,1512,1518,1521,1525,1529,1647,1651,1656,1662,1667,1673,1678,1684,1689,1695,1699,1747,1751,1935],[195,196,197,198,202,203,206],"p",{},"Claude Code 的核心价值在于它能够像一位经验丰富的开发者一样，直接在你的代码库中执行编辑操作。不同于传统的 AI 补全工具只提供建议，Claude Code 使用 ",[199,200,201],"code",{},"Edit"," 和 ",[199,204,205],{},"Write"," 工具直接修改文件，并通过代理循环（Agentic Loop）自主规划、执行和验证跨文件的复杂变更。本章将深入探讨如何高效利用这些能力进行单文件编辑、多文件协同修改、代码生成以及编辑审查。",[208,209,211],"h2",{"id":210},"_1-单文件编辑","1. 单文件编辑",[195,213,214,215,217,218,220],{},"单文件编辑是 Claude Code 最基础也最常用的功能。它通过两个核心工具实现：",[199,216,201],{}," 用于精确修改现有文件，",[199,219,205],{}," 用于创建新文件或完全重写。",[222,223,225],"h3",{"id":224},"_11-edit-工具精确替换","1.1 Edit 工具：精确替换",[195,227,228,230,231,235],{},[199,229,201],{}," 工具是 Claude Code 进行单文件修改的首选方式。它通过查找文件中的",[232,233,234],"strong",{},"精确字符串","并将其替换为新内容来实现修改。这种机制类似于一个理解上下文的有针对性的查找替换，但比简单的文本替换更安全和精确。",[195,237,238,241],{},[232,239,240],{},"工作原理","：",[243,244,245,249,256,262],"ul",{},[246,247,248],"li",{},"Claude 首先读取目标文件的内容",[246,250,251,252,255],{},"定位需要修改的精确文本片段（",[199,253,254],{},"old_string","）",[246,257,258,259,255],{},"将其替换为新的文本片段（",[199,260,261],{},"new_string",[246,263,264,265,267],{},"如果 ",[199,266,254],{}," 在文件中找不到精确匹配，编辑会失败，而不会进行错误的修改",[195,269,270,241],{},[232,271,272],{},"适用场景",[243,274,275,278,281,284],{},[246,276,277],{},"修改函数签名并传播到调用点",[246,279,280],{},"为函数添加新参数",[246,282,283],{},"更新类型定义及其下游引用",[246,285,286],{},"将一种代码模式替换为另一种（如回调改为 async\u002Fawait）",[195,288,289,241],{},[232,290,291],{},"对话示例",[293,294,299],"pre",{"className":295,"code":297,"language":298},[296],"language-text","用户: 在 src\u002Futils\u002Fapi.ts 中，给 fetchUser 函数添加一个可选的 options 参数\n\nClaude: 我来修改 fetchUser 函数的签名。\n\nEdit: src\u002Futils\u002Fapi.ts\nOld: export function fetchUser(id: string) {\nNew: export function fetchUser(id: string, options?: FetchOptions) {\n","text",[199,300,297],{"__ignoreMap":301},"",[222,303,305],{"id":304},"_12-write-工具全量写入","1.2 Write 工具：全量写入",[195,307,308,310,311,313,314,316],{},[199,309,205],{}," 工具用于创建新文件或完全替换现有文件的内容。与 ",[199,312,201],{}," 的手术刀式精确修改不同，",[199,315,205],{}," 会覆盖整个文件。",[195,318,319,241],{},[232,320,272],{},[243,322,323,326,329],{},[246,324,325],{},"创建重构所需的新文件（新模块、新测试文件、新类型定义）",[246,327,328],{},"当单个编辑操作过于复杂时，重写整个文件",[246,330,331],{},"生成样板代码，如测试存根、配置文件或迁移脚本",[195,333,334,241],{},[232,335,291],{},[293,337,340],{"className":338,"code":339,"language":298},[296],"用户: 创建一个 Result 类型工具模块，放在 src\u002Ftypes\u002Fresult.ts\n\nClaude: 我来创建 Result 类型模块。\n\nWrite: src\u002Ftypes\u002Fresult.ts\nexport type Result\u003CT, E = Error> =\n  | { ok: true; value: T }\n  | { ok: false; error: E };\n\nexport const Ok = \u003CT>(value: T): Result\u003CT, never> => ({\n  ok: true,\n  value,\n});\n\nexport const Err = \u003CE>(error: E): Result\u003Cnever, E> => ({\n  ok: false,\n  error,\n});\n",[199,341,339],{"__ignoreMap":301},[222,343,345],{"id":344},"_13-添加函数与修改逻辑","1.3 添加函数与修改逻辑",[195,347,348],{},"在现有文件中添加新函数或修改业务逻辑时，Claude 会根据上下文选择最合适的工具。",[195,350,351,241],{},[232,352,353],{},"添加函数示例",[293,355,358],{"className":356,"code":357,"language":298},[296],"用户: 在 src\u002Fservices\u002Fuser.ts 中添加一个根据邮箱查找用户的函数\n\nClaude: 我先读取文件了解现有结构，然后添加新函数。\n\n[读取 src\u002Fservices\u002Fuser.ts]\n\nEdit: src\u002Fservices\u002Fuser.ts\nOld: export async function deleteUser(id: string): Promise\u003Cvoid> {\n  \u002F\u002F ...\n}\nNew: export async function deleteUser(id: string): Promise\u003Cvoid> {\n  \u002F\u002F ...\n}\n\nexport async function findUserByEmail(email: string): Promise\u003CUser | null> {\n  const user = await db.query.users.findFirst({\n    where: eq(users.email, email),\n  });\n  return user ?? null;\n}\n",[199,359,357],{"__ignoreMap":301},[195,361,362,241],{},[232,363,364],{},"修改逻辑示例",[293,366,369],{"className":367,"code":368,"language":298},[296],"用户: 把 validateInput 函数中的正则校验改成使用 zod schema\n\nClaude: 我来修改 validateInput 函数的实现。\n\nEdit: src\u002Futils\u002Fvalidation.ts\nOld: export function validateInput(data: unknown): boolean {\n  if (typeof data !== 'object' || data === null) return false;\n  const { email, age } = data as Record\u003Cstring, unknown>;\n  if (typeof email !== 'string' || !email.includes('@')) return false;\n  if (typeof age !== 'number' || age \u003C 0 || age > 150) return false;\n  return true;\n}\nNew: const inputSchema = z.object({\n  email: z.string().email(),\n  age: z.number().int().min(0).max(150),\n});\n\nexport function validateInput(data: unknown) {\n  return inputSchema.safeParse(data);\n}\n",[199,370,368],{"__ignoreMap":301},[222,372,374],{"id":373},"_14-重构代码与优化性能","1.4 重构代码与优化性能",[195,376,377],{},"Claude 可以执行各种重构操作，如提取函数、重命名变量、简化条件表达式等。",[195,379,380,241],{},[232,381,382],{},"提取函数示例",[293,384,387],{"className":385,"code":386,"language":298},[296],"用户: 把这段重复的错误处理逻辑提取成一个共享函数\n\nClaude: 我发现多处重复的错误处理逻辑。我来提取一个 handleApiError 函数。\n\nEdit: src\u002Fservices\u002Fapi.ts\nOld: try {\n  const response = await fetch('\u002Fapi\u002Fusers');\n  if (!response.ok) {\n    const error = await response.json();\n    logger.error('API error', error);\n    throw new ApiError(error.message, response.status);\n  }\n  return response.json();\n} catch (err) {\n  logger.error('Network error', err);\n  throw new ApiError('Network failed', 0);\n}\nNew: try {\n  const response = await fetch('\u002Fapi\u002Fusers');\n  return await handleApiResponse(response);\n} catch (err) {\n  return handleApiError(err);\n}\n",[199,388,386],{"__ignoreMap":301},[195,390,391,241],{},[232,392,393],{},"性能优化示例",[293,395,398],{"className":396,"code":397,"language":298},[296],"用户: 优化这个组件的渲染性能，避免不必要的重渲染\n\nClaude: 我来分析并优化这个组件。\n\nEdit: src\u002Fcomponents\u002FUserList.tsx\nOld: export function UserList({ users }: { users: User[] }) {\n  const [filter, setFilter] = useState('');\n  const filtered = users.filter(u => u.name.includes(filter));\n  \u002F\u002F ...\n}\nNew: export const UserList = memo(function UserList({ users }: { users: User[] }) {\n  const [filter, setFilter] = useState('');\n  const filtered = useMemo(\n    () => users.filter(u => u.name.includes(filter)),\n    [users, filter]\n  );\n  \u002F\u002F ...\n});\n",[199,399,397],{"__ignoreMap":301},[208,401,403],{"id":402},"_2-多文件协同修改","2. 多文件协同修改",[195,405,406],{},"多文件编辑是 Claude Code 相比传统 AI 工具的最大优势。它能够理解文件间的依赖关系，协调跨文件的变更，确保整个代码库的一致性。",[222,408,410],{"id":409},"_21-跨文件引用更新","2.1 跨文件引用更新",[195,412,413],{},"当你重命名一个函数、类或变量时，Claude 会自动找到所有引用它的地方并同步更新。",[195,415,416,419,241],{},[232,417,418],{},"代理循环的四个阶段",[420,421,422],"sup",{},[423,424,429],"a",{"href":425,"ariaDescribedBy":426,"dataFootnoteRef":301,"id":428},"#user-content-fn-1",[427],"footnote-label","user-content-fnref-1","1",[431,432,433,439,445,451],"ol",{},[246,434,435,438],{},[232,436,437],{},"发现（Discovery）","：使用 Grep 工具搜索项目中所有引用目标的内容，包括导入语句、类型引用、测试中的 mock、甚至字符串引用",[246,440,441,444],{},[232,442,443],{},"规划（Planning）","：在执行任何编辑前，Claude 会先写出变更计划，确定编辑顺序以避免级联错误",[246,446,447,450],{},[232,448,449],{},"批量编辑（Editing in batches）","：按逻辑分组执行编辑（源文件优先，然后是 barrel exports，接着是应用代码，最后是测试）",[246,452,453,456],{},[232,454,455],{},"验证（Verification）","：运行测试或类型检查，发现问题后进入自纠正循环",[195,458,459,241],{},[232,460,461],{},"重命名示例",[293,463,466],{"className":464,"code":465,"language":298},[296],"用户: 把 getUserById 重命名为 findUser，并更新所有引用\n\nClaude: 我发现了 23 个文件引用了 getUserById。我的计划是：\n1. 重命名源文件中的函数定义\n2. 批量更新导入语句\n3. 更新所有调用点\n4. 更新测试文件\n5. 运行测试验证\n\n[执行 15+ 次 Edit 操作，跨多个文件]\n\nClaude: 所有文件已更新，测试通过。\n",[199,467,465],{"__ignoreMap":301},[222,469,471],{"id":470},"_22-接口变更的级联修改","2.2 接口变更的级联修改",[195,473,474],{},"当接口定义发生变化时，Claude 能够追踪类型变更的影响范围，并自动更新所有受影响的实现和调用方。",[195,476,477,480,481,484,485,488],{},[232,478,479],{},"示例场景","：将 API 响应格式从 ",[199,482,483],{},"{ data, error }"," 改为 ",[199,486,487],{},"Result"," 类型",[293,490,493],{"className":491,"code":492,"language":298},[296],"用户: 把所有 API handler 从 { data, error } 响应格式迁移到 Result 类型\n\nClaude: 我来执行这个迁移。\n\n1. 读取 src\u002Ftypes\u002Fresult.ts 了解目标类型\n2. 搜索所有返回旧格式的 API handler\n3. 逐个修改 handler 的返回逻辑\n4. 搜索所有前端消费代码\n5. 更新调用方以使用新的 Result 模式\n6. 更新对应的测试文件\n7. 运行测试验证\n",[199,494,492],{"__ignoreMap":301},[222,496,498],{"id":497},"_23-使用子代理并行处理","2.3 使用子代理并行处理",[195,500,501,502,510],{},"对于大规模变更，Claude Code 可以将工作委托给子代理（Subagents）进行分工处理",[420,503,504],{},[423,505,509],{"href":506,"ariaDescribedBy":507,"dataFootnoteRef":301,"id":508},"#user-content-fn-2",[427],"user-content-fnref-2","2","。",[195,512,513,514,517],{},"主 Claude 会话充当协调器：规划工作、将文件级任务委派给子代理、协调结果。每个子代理获得一个聚焦的范围（一个文件或一小群相关文件）和所需的上下文。但子代理在执行期间不共享上下文，且受限于单次只能生成一个子代理分支，因此",[232,515,516],{},"顺序处理","仍是默认模式。如果 File A 的变更依赖于 File B 的确切变更内容，使用主会话的顺序编辑更安全。只有当各文件间的变更相互独立时，才适合使用子代理。",[222,519,521],{"id":520},"_24-git-worktree-隔离实验","2.4 Git Worktree 隔离实验",[195,523,524,525,510],{},"对于大型重构，你可以使用 Git Worktree 创建隔离的工作目录，让 Claude 在独立分支上进行实验性修改",[420,526,527],{},[423,528,532],{"href":529,"ariaDescribedBy":530,"dataFootnoteRef":301,"id":531},"#user-content-fn-3",[427],"user-content-fnref-3","3",[293,534,538],{"className":535,"code":536,"language":537,"meta":301,"style":301},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","# 为重构创建 worktree\ngit worktree add ..\u002Fmy-project-refactor feature\u002Fapi-v2\n\n# 进入 worktree 启动 Claude Code\ncd ..\u002Fmy-project-refactor\nclaude\n","bash",[199,539,540,549,569,576,582,592],{"__ignoreMap":301},[541,542,545],"span",{"class":543,"line":544},"line",1,[541,546,548],{"class":547},"sHwdD","# 为重构创建 worktree\n",[541,550,552,556,560,563,566],{"class":543,"line":551},2,[541,553,555],{"class":554},"sBMFI","git",[541,557,559],{"class":558},"sfazB"," worktree",[541,561,562],{"class":558}," add",[541,564,565],{"class":558}," ..\u002Fmy-project-refactor",[541,567,568],{"class":558}," feature\u002Fapi-v2\n",[541,570,572],{"class":543,"line":571},3,[541,573,575],{"emptyLinePlaceholder":574},true,"\n",[541,577,579],{"class":543,"line":578},4,[541,580,581],{"class":547},"# 进入 worktree 启动 Claude Code\n",[541,583,585,589],{"class":543,"line":584},5,[541,586,588],{"class":587},"s2Zo4","cd",[541,590,591],{"class":558}," ..\u002Fmy-project-refactor\n",[541,593,595],{"class":543,"line":594},6,[541,596,597],{"class":554},"claude\n",[195,599,600,601,604],{},"如果修改成功，合并即可；如果失败，",[199,602,603],{},"git worktree remove"," 即可零成本回滚。",[222,606,608],{"id":607},"_25-上下文管理与批量策略","2.5 上下文管理与批量策略",[195,610,611,612,510],{},"Claude Code 在单个会话中可以处理多文件编辑，具体数量取决于文件复杂度和上下文消耗。大型变更建议分解为批次，每次聚焦一个逻辑模块。超过合理范围，上下文消耗会增加，导致后续变更不一致的风险上升",[420,613,614],{},[423,615,619],{"href":616,"ariaDescribedBy":617,"dataFootnoteRef":301,"id":618},"#user-content-fn-4",[427],"user-content-fnref-4","4",[195,621,622,241],{},[232,623,624],{},"最佳实践",[243,626,627,630,637,644],{},[246,628,629],{},"将大型变更分解为批次：\"先迁移 src\u002Fapi\u002Fusers\u002F，然后是 src\u002Fapi\u002Forders\u002F\"",[246,631,632,633,636],{},"使用 ",[199,634,635],{},"\u002Fclear"," 在不同任务间重置上下文",[246,638,639,640,643],{},"在关键节点使用 ",[199,641,642],{},"\u002Fcompact"," 压缩对话历史，释放上下文空间",[246,645,646],{},"每次批量变更后提交代码，创建恢复点",[208,648,650],{"id":649},"_3-自主规划与执行","3. 自主规划与执行",[195,652,653],{},"Claude Code 的代理循环使其能够自主决定修改哪些文件、以什么顺序修改。理解这个机制有助于你更好地指导 Claude 完成复杂任务。",[222,655,657],{"id":656},"_31-代理循环的工作机制","3.1 代理循环的工作机制",[195,659,660,661,241],{},"当你给出一个任务时，Claude 会经历以下决策过程",[420,662,663],{},[423,664,429],{"href":425,"ariaDescribedBy":665,"dataFootnoteRef":301,"id":666},[427],"user-content-fnref-1-2",[431,668,669,675,681,687,693,699],{},[246,670,671,674],{},[232,672,673],{},"分析请求","：理解你想要做什么变更",[246,676,677,680],{},[232,678,679],{},"探索代码库","：使用 Grep、Glob 等工具发现相关文件",[246,682,683,686],{},[232,684,685],{},"制定计划","：确定需要修改的文件列表和修改顺序",[246,688,689,692],{},[232,690,691],{},"执行编辑","：按依赖顺序执行 Edit\u002FWrite 操作",[246,694,695,698],{},[232,696,697],{},"验证结果","：运行测试或构建命令检查变更的正确性",[246,700,701,704],{},[232,702,703],{},"自纠正","：如果发现问题，回到第 4 步修复",[222,706,708],{"id":707},"_32-如何引导-claude-的规划","3.2 如何引导 Claude 的规划",[195,710,711],{},"你可以通过提问方式来影响 Claude 的规划质量：",[195,713,714,241],{},[232,715,716],{},"先要求计划",[293,718,721],{"className":719,"code":720,"language":298},[296],"用户: 先制定计划，不要立即执行：我想给所有 API 路由添加请求 ID 追踪\n\nClaude: 这是我的计划：\n1. 创建 src\u002Fmiddleware\u002FrequestId.ts 中间件\n2. 在 src\u002Fapp.ts 中注册中间件\n3. 更新所有 handler 在日志中包含 requestId\n4. 更新类型定义使 requestId 可在请求对象上访问\n5. 添加测试验证中间件行为\n\n用户: 计划很好，执行吧。\n",[199,722,720],{"__ignoreMap":301},[195,724,725,241],{},[232,726,727],{},"指定依赖顺序",[293,729,732],{"className":730,"code":731,"language":298},[296],"用户: 按这个顺序执行：先改类型定义，再改实现，最后改测试\n",[199,733,731],{"__ignoreMap":301},[195,735,736,241],{},[232,737,738],{},"限制范围",[293,740,743],{"className":741,"code":742,"language":298},[296],"用户: 只修改 src\u002Fapi\u002F 和 src\u002Fhooks\u002F 目录下的文件，不要碰 src\u002Fcomponents\u002F\n",[199,744,742],{"__ignoreMap":301},[222,746,748],{"id":747},"_33-处理中间状态的技巧","3.3 处理中间状态的技巧",[195,750,751,752,241],{},"多文件编辑会创建中间状态，此时代码可能暂时无法编译。Claude 通过以下方式处理",[420,753,754],{},[423,755,509],{"href":506,"ariaDescribedBy":756,"dataFootnoteRef":301,"id":757},[427],"user-content-fnref-2-2",[243,759,760,763,766,769],{},[246,761,762],{},"在开始前规划完整的变更集",[246,764,765],{},"尽可能按依赖顺序修改（类型优先，然后是消费者）",[246,767,768],{},"在所有编辑完成后才运行验证，而不是每次编辑后",[246,770,771],{},"在验证步骤发现问题时修复级联错误",[195,773,774],{},"如果你使用了 PostToolUse hooks（在每次编辑后自动运行脚本），大型重构期间可能会报告中间错误。建议临时放宽 lint hooks 或将其配置为警告而非阻塞。",[208,776,778],{"id":777},"_4-代码生成","4. 代码生成",[195,780,781],{},"Claude Code 不仅能修改现有代码，还能从零开始生成新模块、测试和文档。",[222,783,785],{"id":784},"_41-从零编写新模块","4.1 从零编写新模块",[195,787,788],{},"当你需要实现一个新功能时，Claude 可以创建完整的文件结构。",[195,790,791,794],{},[232,792,793],{},"示例","：实现一个评论系统",[293,796,799],{"className":797,"code":798,"language":298},[296],"用户: 实现一个博客评论系统：\n- 数据库：comments 表，包含 user_id、post_id、content\n- API：评论的 CRUD 端点\n- 前端：评论展示和提交组件\n- 支持嵌套回复\n\nClaude: 我将按以下顺序实现：\n1. 创建数据库迁移文件\n2. 添加模型定义\n3. 实现 API 路由\n4. 构建 React 组件\n5. 添加测试\n\n[创建多个新文件...]\n",[199,800,798],{"__ignoreMap":301},[222,802,804],{"id":803},"_42-生成测试代码","4.2 生成测试代码",[195,806,807],{},"Claude 可以为现有代码生成测试，包括单元测试和集成测试。",[293,809,812],{"className":810,"code":811,"language":298},[296],"用户: 为 src\u002Fservices\u002Fauth.ts 中的函数生成单元测试\n\nClaude: 我来创建测试文件。\n\nWrite: src\u002Fservices\u002Fauth.test.ts\nimport { describe, it, expect, vi } from 'vitest';\nimport { authenticateUser, hashPassword } from '.\u002Fauth';\n\ndescribe('authenticateUser', () => {\n  it('should return user when credentials are valid', async () => {\n    \u002F\u002F ...\n  });\n\n  it('should throw when password is incorrect', async () => {\n    \u002F\u002F ...\n  });\n\n  it('should throw when user does not exist', async () => {\n    \u002F\u002F ...\n  });\n});\n",[199,813,811],{"__ignoreMap":301},[222,815,817],{"id":816},"_43-生成文档","4.3 生成文档",[195,819,820],{},"Claude 可以生成各种文档，包括 README、API 文档、代码注释等。",[293,822,825],{"className":823,"code":824,"language":298},[296],"用户: 为 src\u002Fservices\u002Fpayment.ts 生成 JSDoc 注释\n\nClaude: 我来为所有导出函数添加 JSDoc。\n\nEdit: src\u002Fservices\u002Fpayment.ts\nOld: export async function processPayment(\n  amount: number,\n  currency: string,\n  source: PaymentSource\n): Promise\u003CPaymentResult> {\nNew: \u002F**\n * 处理支付请求，与支付网关交互完成扣款\n *\n * @param amount - 支付金额（以分为单位）\n * @param currency - ISO 4217 货币代码，如 'USD'、'CNY'\n * @param source - 支付来源信息\n * @returns 支付结果，包含交易 ID 和状态\n * @throws {PaymentError} 当支付网关返回错误时\n * @example\n * ```ts\n * const result = await processPayment(1000, 'USD', { token: 'tok_xxx' });\n * ```\n *\u002F\nexport async function processPayment(\n  amount: number,\n  currency: string,\n  source: PaymentSource\n): Promise\u003CPaymentResult> {\n",[199,826,824],{"__ignoreMap":301},[208,828,830],{"id":829},"_5-代码风格一致性","5. 代码风格一致性",[195,832,833],{},"让 Claude 遵循项目的编码规范是确保生成代码质量的关键。Claude Code 提供了多种机制来实现这一点。",[222,835,837],{"id":836},"_51-claudemd-项目指令","5.1 CLAUDE.md 项目指令",[195,839,840,842,843,851],{},[199,841,108],{}," 是放在项目根目录的特殊配置文件，Claude 会在每次会话开始时自动读取它",[420,844,845],{},[423,846,850],{"href":847,"ariaDescribedBy":848,"dataFootnoteRef":301,"id":849},"#user-content-fn-5",[427],"user-content-fnref-5","5","。它是让 Claude 了解项目规范的最有效方式。",[195,853,854,857],{},[232,855,856],{},"推荐的 CLAUDE.md 结构","（使用 WHY（为什么）\u002FWHAT（是什么）\u002FHOW（怎么做）框架）：",[293,859,863],{"className":860,"code":861,"language":862,"meta":301,"style":301},"language-markdown shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","# Project: MyApp\n\nA task management API built with Node.js and Express.\n\n## Tech stack\n- Node.js 20, Express 4, TypeScript\n- PostgreSQL with Prisma ORM\n- Jest for testing\n\n## Commands\n- `npm run dev` - Start dev server (port 3000)\n- `npm test` - Run all tests\n- `npm run lint` - ESLint check\n\n## Conventions\n- Use async\u002Fawait over raw promises\n- Named exports preferred over defaults\n- Error responses follow RFC 7807 format\n- Type hints required on all public functions\n","markdown",[199,864,865,874,878,884,888,896,904,912,920,925,933,950,965,980,985,993,1001,1009,1017],{"__ignoreMap":301},[541,866,867,871],{"class":543,"line":544},[541,868,870],{"class":869},"sMK4o","# ",[541,872,873],{"class":554},"Project: MyApp\n",[541,875,876],{"class":543,"line":551},[541,877,575],{"emptyLinePlaceholder":574},[541,879,880],{"class":543,"line":571},[541,881,883],{"class":882},"sTEyZ","A task management API built with Node.js and Express.\n",[541,885,886],{"class":543,"line":578},[541,887,575],{"emptyLinePlaceholder":574},[541,889,890,893],{"class":543,"line":584},[541,891,892],{"class":869},"## ",[541,894,895],{"class":554},"Tech stack\n",[541,897,898,901],{"class":543,"line":594},[541,899,900],{"class":869},"-",[541,902,903],{"class":882}," Node.js 20, Express 4, TypeScript\n",[541,905,907,909],{"class":543,"line":906},7,[541,908,900],{"class":869},[541,910,911],{"class":882}," PostgreSQL with Prisma ORM\n",[541,913,915,917],{"class":543,"line":914},8,[541,916,900],{"class":869},[541,918,919],{"class":882}," Jest for testing\n",[541,921,923],{"class":543,"line":922},9,[541,924,575],{"emptyLinePlaceholder":574},[541,926,928,930],{"class":543,"line":927},10,[541,929,892],{"class":869},[541,931,932],{"class":554},"Commands\n",[541,934,936,938,941,944,947],{"class":543,"line":935},11,[541,937,900],{"class":869},[541,939,940],{"class":869}," `",[541,942,943],{"class":558},"npm run dev",[541,945,946],{"class":869},"`",[541,948,949],{"class":882}," - Start dev server (port 3000)\n",[541,951,953,955,957,960,962],{"class":543,"line":952},12,[541,954,900],{"class":869},[541,956,940],{"class":869},[541,958,959],{"class":558},"npm test",[541,961,946],{"class":869},[541,963,964],{"class":882}," - Run all tests\n",[541,966,968,970,972,975,977],{"class":543,"line":967},13,[541,969,900],{"class":869},[541,971,940],{"class":869},[541,973,974],{"class":558},"npm run lint",[541,976,946],{"class":869},[541,978,979],{"class":882}," - ESLint check\n",[541,981,983],{"class":543,"line":982},14,[541,984,575],{"emptyLinePlaceholder":574},[541,986,988,990],{"class":543,"line":987},15,[541,989,892],{"class":869},[541,991,992],{"class":554},"Conventions\n",[541,994,996,998],{"class":543,"line":995},16,[541,997,900],{"class":869},[541,999,1000],{"class":882}," Use async\u002Fawait over raw promises\n",[541,1002,1004,1006],{"class":543,"line":1003},17,[541,1005,900],{"class":869},[541,1007,1008],{"class":882}," Named exports preferred over defaults\n",[541,1010,1012,1014],{"class":543,"line":1011},18,[541,1013,900],{"class":869},[541,1015,1016],{"class":882}," Error responses follow RFC 7807 format\n",[541,1018,1020,1022],{"class":543,"line":1019},19,[541,1021,900],{"class":869},[541,1023,1024],{"class":882}," Type hints required on all public functions\n",[195,1026,1027,1030,241],{},[232,1028,1029],{},"关键原则",[420,1031,1032],{},[423,1033,1037],{"href":1034,"ariaDescribedBy":1035,"dataFootnoteRef":301,"id":1036},"#user-content-fn-6",[427],"user-content-fnref-6","6",[243,1039,1040,1047,1050,1053],{},[246,1041,1042,1043,1046],{},"保持在 200 行以内（官方建议），过长的指令会降低优先级。对于大型项目，可拆分到 ",[199,1044,1045],{},".claude\u002Frules\u002F"," 目录",[246,1048,1049],{},"使用具体指令而非抽象描述（\"使用 2 空格缩进\"比\"格式化代码\"更有效）",[246,1051,1052],{},"不要重复代码本身已经表达的信息",[246,1054,1055],{},"将代码风格规则交给 linter\u002Fformatter，CLAUDE.md 只包含无法自动化的规范",[222,1057,1059],{"id":1058},"_52-clauderules-目录","5.2 .claude\u002Frules\u002F 目录",[195,1061,1062,1063,1065,1066,241],{},"对于大型项目，可以将规则拆分到 ",[199,1064,1045],{}," 目录中",[420,1067,1068],{},[423,1069,1073],{"href":1070,"ariaDescribedBy":1071,"dataFootnoteRef":301,"id":1072},"#user-content-fn-7",[427],"user-content-fnref-7","7",[293,1075,1078],{"className":1076,"code":1077,"language":298},[296],".claude\u002F\n├── CLAUDE.md          # 主文件（保持简短）\n├── rules\u002F\n│   ├── frontend.md    # React\u002FCSS 规范\n│   ├── api.md         # API 端点模式\n│   └── testing.md     # 测试要求\n",[199,1079,1077],{"__ignoreMap":301},[195,1081,1082],{},"规则文件可以使用 YAML frontmatter 限定作用范围：",[293,1084,1086],{"className":860,"code":1085,"language":862,"meta":301,"style":301},"---\npaths:\n  - \"src\u002Fapi\u002F**\u002F*.ts\"\n---\n# API 开发规则\n- 所有端点必须包含输入验证\n- 客户端错误返回 4xx，服务端错误返回 5xx\n",[199,1087,1088,1093,1102,1116,1120,1127,1134],{"__ignoreMap":301},[541,1089,1090],{"class":543,"line":544},[541,1091,1092],{"class":869},"---\n",[541,1094,1095,1099],{"class":543,"line":551},[541,1096,1098],{"class":1097},"swJcz","paths",[541,1100,1101],{"class":869},":\n",[541,1103,1104,1107,1110,1113],{"class":543,"line":571},[541,1105,1106],{"class":869},"  -",[541,1108,1109],{"class":869}," \"",[541,1111,1112],{"class":558},"src\u002Fapi\u002F**\u002F*.ts",[541,1114,1115],{"class":869},"\"\n",[541,1117,1118],{"class":543,"line":578},[541,1119,1092],{"class":869},[541,1121,1122,1124],{"class":543,"line":584},[541,1123,870],{"class":869},[541,1125,1126],{"class":554},"API 开发规则\n",[541,1128,1129,1131],{"class":543,"line":594},[541,1130,900],{"class":869},[541,1132,1133],{"class":882}," 所有端点必须包含输入验证\n",[541,1135,1136,1138],{"class":543,"line":906},[541,1137,900],{"class":869},[541,1139,1140],{"class":882}," 客户端错误返回 4xx，服务端错误返回 5xx\n",[222,1142,1144],{"id":1143},"_53-使用-hooks-自动格式化","5.3 使用 Hooks 自动格式化",[195,1146,1147,1148,1151,1152,1158],{},"Hooks 是在 Claude Code 生命周期特定点触发的 shell 命令，配置在 ",[199,1149,1150],{},"settings.json"," 中",[420,1153,1154],{},[423,1155,1037],{"href":1034,"ariaDescribedBy":1156,"dataFootnoteRef":301,"id":1157},[427],"user-content-fnref-6-2","。与 CLAUDE.md 中的\"建议\"不同，Hooks 是强制执行的。",[293,1160,1164],{"className":1161,"code":1162,"language":1163,"meta":301,"style":301},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u002F\u002F 以下为示意性配置，具体事件名和模板变量请以官方 Hooks 文档为准\n\u002F\u002F https:\u002F\u002Fcode.claude.com\u002Fdocs\u002Fen\u002Fhooks\n{\n  \"hooks\": {\n    \"PostToolUse\": {\n      \"edit\": \"npx prettier --write {{file}}\",\n      \"write\": \"npx prettier --write {{file}}\"\n    }\n  }\n}\n","json",[199,1165,1166,1171,1176,1181,1199,1213,1236,1253,1258,1263],{"__ignoreMap":301},[541,1167,1168],{"class":543,"line":544},[541,1169,1170],{"class":547},"\u002F\u002F 以下为示意性配置，具体事件名和模板变量请以官方 Hooks 文档为准\n",[541,1172,1173],{"class":543,"line":551},[541,1174,1175],{"class":547},"\u002F\u002F https:\u002F\u002Fcode.claude.com\u002Fdocs\u002Fen\u002Fhooks\n",[541,1177,1178],{"class":543,"line":571},[541,1179,1180],{"class":869},"{\n",[541,1182,1183,1186,1190,1193,1196],{"class":543,"line":578},[541,1184,1185],{"class":869},"  \"",[541,1187,1189],{"class":1188},"spNyl","hooks",[541,1191,1192],{"class":869},"\"",[541,1194,1195],{"class":869},":",[541,1197,1198],{"class":869}," {\n",[541,1200,1201,1204,1207,1209,1211],{"class":543,"line":584},[541,1202,1203],{"class":869},"    \"",[541,1205,1206],{"class":554},"PostToolUse",[541,1208,1192],{"class":869},[541,1210,1195],{"class":869},[541,1212,1198],{"class":869},[541,1214,1215,1218,1222,1224,1226,1228,1231,1233],{"class":543,"line":594},[541,1216,1217],{"class":869},"      \"",[541,1219,1221],{"class":1220},"sbssI","edit",[541,1223,1192],{"class":869},[541,1225,1195],{"class":869},[541,1227,1109],{"class":869},[541,1229,1230],{"class":558},"npx prettier --write {{file}}",[541,1232,1192],{"class":869},[541,1234,1235],{"class":869},",\n",[541,1237,1238,1240,1243,1245,1247,1249,1251],{"class":543,"line":906},[541,1239,1217],{"class":869},[541,1241,1242],{"class":1220},"write",[541,1244,1192],{"class":869},[541,1246,1195],{"class":869},[541,1248,1109],{"class":869},[541,1250,1230],{"class":558},[541,1252,1115],{"class":869},[541,1254,1255],{"class":543,"line":914},[541,1256,1257],{"class":869},"    }\n",[541,1259,1260],{"class":543,"line":922},[541,1261,1262],{"class":869},"  }\n",[541,1264,1265],{"class":543,"line":927},[541,1266,1267],{"class":869},"}\n",[195,1269,1270],{},"这确保每次编辑或写入后，代码都会自动格式化，无需依赖 Claude\"记住\"格式规则。",[222,1272,1274],{"id":1273},"_54-通过对话指定风格","5.4 通过对话指定风格",[195,1276,1277],{},"对于一次性任务，可以直接在对话中指定风格要求：",[293,1279,1282],{"className":1280,"code":1281,"language":298},[296],"用户: 按照项目中现有的错误处理模式，给这些函数添加 try-catch。\n参考 src\u002Fservices\u002Fuser.ts 中的处理方式。\n",[199,1283,1281],{"__ignoreMap":301},[208,1285,1287],{"id":1286},"_6-编辑审查技巧","6. 编辑审查技巧",[195,1289,1290],{},"审查 Claude 生成的代码修改是确保质量的关键步骤。Claude Code 提供了多种审查机制。",[222,1292,1294],{"id":1293},"_61-diff-查看与快捷键","6.1 Diff 查看与快捷键",[195,1296,1297,1298,241],{},"当 Claude 提议修改时，你可以使用快捷键控制审查流程",[420,1299,1300],{},[423,1301,1305],{"href":1302,"ariaDescribedBy":1303,"dataFootnoteRef":301,"id":1304},"#user-content-fn-8",[427],"user-content-fnref-8","8",[1307,1308,1309],"blockquote",{},[195,1310,1311,1312,1315],{},"📌 ",[232,1313,1314],{},"快捷键以实际界面为准","：以下快捷键符合常见 diff 工具约定，Claude Code 的具体快捷键列表可能随版本更新。建议在实际 diff 界面查看提示。",[1317,1318,1319,1332],"table",{},[1320,1321,1322],"thead",{},[1323,1324,1325,1329],"tr",{},[1326,1327,1328],"th",{},"快捷键",[1326,1330,1331],{},"操作",[1333,1334,1335,1346,1356,1366],"tbody",{},[1323,1336,1337,1343],{},[1338,1339,1340],"td",{},[199,1341,1342],{},"d",[1338,1344,1345],{},"查看完整 diff",[1323,1347,1348,1353],{},[1338,1349,1350],{},[199,1351,1352],{},"e",[1338,1354,1355],{},"编辑修改内容",[1323,1357,1358,1363],{},[1338,1359,1360],{},[199,1361,1362],{},"y",[1338,1364,1365],{},"接受修改",[1323,1367,1368,1373],{},[1338,1369,1370],{},[199,1371,1372],{},"n",[1338,1374,1375],{},"拒绝修改",[195,1377,1378,1379,1381,1382,1385],{},"Diff 格式显示：红色 ",[199,1380,900],{}," 行表示删除，绿色 ",[199,1383,1384],{},"+"," 行表示新增。",[222,1387,1389],{"id":1388},"_62-plan-mode计划模式","6.2 Plan Mode（计划模式）",[195,1391,1392,1393,1396,1397,1405],{},"对于复杂变更，使用 Plan Mode（按 ",[199,1394,1395],{},"Shift+Tab"," 两次进入）让 Claude 先展示变更计划而不实际执行",[420,1398,1399],{},[423,1400,1404],{"href":1401,"ariaDescribedBy":1402,"dataFootnoteRef":301,"id":1403},"#user-content-fn-9",[427],"user-content-fnref-9","9","。你可以审查计划、提出修改意见，确认后再批准执行。",[293,1407,1410],{"className":1408,"code":1409,"language":298},[296],"用户: [Shift+Tab x2] 重构认证模块\n\nClaude: [Plan Mode] 这是我的计划：\n1. 将 src\u002Fauth\u002Flogin.ts 中的逻辑提取到 src\u002Fauth\u002Fservice.ts\n2. 更新所有导入引用\n3. 添加单元测试\n\n用户: 计划看起来不错，执行吧。\n",[199,1411,1409],{"__ignoreMap":301},[222,1413,1415],{"id":1414},"_63-使用-git-审查变更","6.3 使用 Git 审查变更",[195,1417,1418],{},"在 Claude 完成修改后，使用 Git 命令审查完整的变更集：",[293,1420,1422],{"className":535,"code":1421,"language":537,"meta":301,"style":301},"# 查看所有变更的统计\ngit diff --stat\n\n# 查看具体 diff\ngit diff\n\n# 选择性恢复某些文件\ngit checkout -- specific-file.ts\n\n# 如果全部不满意，完全回滚\ngit reset --hard HEAD\n",[199,1423,1424,1429,1439,1443,1448,1455,1459,1464,1477,1481,1486],{"__ignoreMap":301},[541,1425,1426],{"class":543,"line":544},[541,1427,1428],{"class":547},"# 查看所有变更的统计\n",[541,1430,1431,1433,1436],{"class":543,"line":551},[541,1432,555],{"class":554},[541,1434,1435],{"class":558}," diff",[541,1437,1438],{"class":558}," --stat\n",[541,1440,1441],{"class":543,"line":571},[541,1442,575],{"emptyLinePlaceholder":574},[541,1444,1445],{"class":543,"line":578},[541,1446,1447],{"class":547},"# 查看具体 diff\n",[541,1449,1450,1452],{"class":543,"line":584},[541,1451,555],{"class":554},[541,1453,1454],{"class":558}," diff\n",[541,1456,1457],{"class":543,"line":594},[541,1458,575],{"emptyLinePlaceholder":574},[541,1460,1461],{"class":543,"line":906},[541,1462,1463],{"class":547},"# 选择性恢复某些文件\n",[541,1465,1466,1468,1471,1474],{"class":543,"line":914},[541,1467,555],{"class":554},[541,1469,1470],{"class":558}," checkout",[541,1472,1473],{"class":558}," --",[541,1475,1476],{"class":558}," specific-file.ts\n",[541,1478,1479],{"class":543,"line":922},[541,1480,575],{"emptyLinePlaceholder":574},[541,1482,1483],{"class":543,"line":927},[541,1484,1485],{"class":547},"# 如果全部不满意，完全回滚\n",[541,1487,1488,1490,1493,1496],{"class":543,"line":935},[541,1489,555],{"class":554},[541,1491,1492],{"class":558}," reset",[541,1494,1495],{"class":558}," --hard",[541,1497,1498],{"class":558}," HEAD\n",[222,1500,1502],{"id":1501},"_64-验证与自纠正循环","6.4 验证与自纠正循环",[195,1504,1505,1506,241],{},"最有效的审查方式是让 Claude 自己验证修改",[420,1507,1508],{},[423,1509,429],{"href":425,"ariaDescribedBy":1510,"dataFootnoteRef":301,"id":1511},[427],"user-content-fnref-1-3",[293,1513,1516],{"className":1514,"code":1515,"language":298},[296],"用户: 重命名 UserService 为 AccountService，然后运行测试并修复任何失败\n\nClaude: [执行重命名...]\n[运行测试...]\n发现 1 个测试失败：mock 路径使用了字符串字面量\n[修复测试...]\n[重新运行测试...]\n所有测试通过。\n",[199,1517,1515],{"__ignoreMap":301},[195,1519,1520],{},"这种自纠正循环是 Claude Code 区别于简单查找替换工具的核心优势。",[208,1522,1524],{"id":1523},"_7-常见编辑场景与最佳提问方式","7. 常见编辑场景与最佳提问方式",[222,1526,1528],{"id":1527},"_71-场景速查表","7.1 场景速查表",[1317,1530,1531,1541],{},[1320,1532,1533],{},[1323,1534,1535,1538],{},[1326,1536,1537],{},"场景",[1326,1539,1540],{},"推荐提问方式",[1333,1542,1543,1555,1567,1583,1600,1616,1627,1639],{},[1323,1544,1545,1548],{},[1338,1546,1547],{},"添加新函数",[1338,1549,1550,1551,1554],{},"\"在 ",[199,1552,1553],{},"src\u002Fxxx.ts"," 中添加一个函数，实现...\"",[1323,1556,1557,1560],{},[1338,1558,1559],{},"修改函数逻辑",[1338,1561,1562,1563,1566],{},"\"修改 ",[199,1564,1565],{},"functionName"," 的实现，将...改为...\"",[1323,1568,1569,1572],{},[1338,1570,1571],{},"重命名",[1338,1573,1574,1575,1578,1579,1582],{},"\"将 ",[199,1576,1577],{},"oldName"," 重命名为 ",[199,1580,1581],{},"newName","，更新所有引用\"",[1323,1584,1585,1588],{},[1338,1586,1587],{},"提取公共逻辑",[1338,1589,1574,1590,202,1593,1596,1597,1192],{},[199,1591,1592],{},"src\u002Fa.ts",[199,1594,1595],{},"src\u002Fb.ts"," 中的重复逻辑提取到 ",[199,1598,1599],{},"src\u002Futils\u002F",[1323,1601,1602,1605],{},[1338,1603,1604],{},"类型变更",[1338,1606,1607,1608,1611,1612,1615],{},"\"更新 ",[199,1609,1610],{},"User"," 接口添加 ",[199,1613,1614],{},"roles"," 字段，修复所有类型错误\"",[1323,1617,1618,1621],{},[1338,1619,1620],{},"添加测试",[1338,1622,1623,1624,1626],{},"\"为 ",[199,1625,1553],{}," 生成单元测试，覆盖正常和边界情况\"",[1323,1628,1629,1632],{},[1338,1630,1631],{},"性能优化",[1338,1633,1634,1635,1638],{},"\"优化 ",[199,1636,1637],{},"ComponentName"," 的渲染性能，减少不必要的重渲染\"",[1323,1640,1641,1644],{},[1338,1642,1643],{},"迁移模式",[1338,1645,1646],{},"\"将项目中的所有回调改为 async\u002Fawait 模式\"",[222,1648,1650],{"id":1649},"_72-高效提问的原则","7.2 高效提问的原则",[195,1652,1653,241],{},[232,1654,1655],{},"明确范围",[293,1657,1660],{"className":1658,"code":1659,"language":298},[296],"# 差\n\"更新所有文件\"\n\n# 好\n\"更新 src\u002Fapi\u002F 和 src\u002Fhooks\u002F 中从 @\u002Flib\u002Fauth 导入的所有文件\"\n",[199,1661,1659],{"__ignoreMap":301},[195,1663,1664,241],{},[232,1665,1666],{},"引用模式而非实例",[293,1668,1671],{"className":1669,"code":1670,"language":298},[296],"# 差\n\"把 file1.ts、file2.ts、file3.ts 中的 fetchData 改成 async\u002Fawait\"\n\n# 好\n\"把全盘中 fetchData 的 .then() 链改为 async\u002Fawait，Claude 会自己找到所有实例\"\n",[199,1672,1670],{"__ignoreMap":301},[195,1674,1675,241],{},[232,1676,1677],{},"要求先计划再执行",[293,1679,1682],{"className":1680,"code":1681,"language":298},[296],"\"先制定计划，列出受影响的文件和修改策略，我确认后再执行\"\n",[199,1683,1681],{"__ignoreMap":301},[195,1685,1686,241],{},[232,1687,1688],{},"指定验证步骤",[293,1690,1693],{"className":1691,"code":1692,"language":298},[296],"\"修改后运行 npm test，修复任何失败\"\n",[199,1694,1692],{"__ignoreMap":301},[222,1696,1698],{"id":1697},"_73-避免常见陷阱","7.3 避免常见陷阱",[431,1700,1701,1713,1719,1725,1737],{},[246,1702,1703,1706,1707],{},[232,1704,1705],{},"上下文过载","：不要一次性要求修改太多文件。超过 50 个文件时，分批处理",[420,1708,1709],{},[423,1710,619],{"href":616,"ariaDescribedBy":1711,"dataFootnoteRef":301,"id":1712},[427],"user-content-fnref-4-2",[246,1714,1715,1718],{},[232,1716,1717],{},"模糊指令","：避免\"优化一下\"\"改好看点\"这类模糊描述",[246,1720,1721,1724],{},[232,1722,1723],{},"忽略中间状态","：大型重构期间代码可能暂时无法编译，这是正常的",[246,1726,1727,1730,1731],{},[232,1728,1729],{},"过度信任","：始终审查 Claude 的修改，特别是涉及业务逻辑的部分",[420,1732,1733],{},[423,1734,429],{"href":425,"ariaDescribedBy":1735,"dataFootnoteRef":301,"id":1736},[427],"user-content-fnref-1-4",[246,1738,1739,1742,1743,1746],{},[232,1740,1741],{},"忽视范围蔓延","：Claude 有时会\"好心\"修改你未要求的文件，使用 ",[199,1744,1745],{},"git diff --stat"," 检查变更范围",[208,1748,1750],{"id":1749},"_8-参考来源","8. 参考来源",[1752,1753,1756,1761],"section",{"className":1754,"dataFootnotes":301},[1755],"footnotes",[208,1757,1760],{"className":1758,"id":427},[1759],"sr-only","Footnotes",[431,1762,1763,1802,1823,1837,1858,1872,1893,1907,1921],{},[246,1764,1766,1772,1773,1780,1781,1780,1788,1780,1795],{"id":1765},"user-content-fn-1",[423,1767,1771],{"href":1768,"rel":1769},"https:\u002F\u002Fwww.openaitoolshub.org\u002Fen\u002Fblog\u002Fclaude-code-multi-file-refactoring",[1770],"nofollow","How Claude Code Handles Multi-File Refactoring: A Practical Deep-Dive"," - OpenAIToolsHub（第三方技术博客，与 OpenAI 无隶属关系）, 2026-03-31 ",[423,1774,1779],{"href":1775,"ariaLabel":1776,"className":1777,"dataFootnoteBackref":301},"#user-content-fnref-1","Back to reference 1",[1778],"data-footnote-backref","↩"," ",[423,1782,1779,1786],{"href":1783,"ariaLabel":1784,"className":1785,"dataFootnoteBackref":301},"#user-content-fnref-1-2","Back to reference 1-2",[1778],[420,1787,509],{},[423,1789,1779,1793],{"href":1790,"ariaLabel":1791,"className":1792,"dataFootnoteBackref":301},"#user-content-fnref-1-3","Back to reference 1-3",[1778],[420,1794,532],{},[423,1796,1779,1800],{"href":1797,"ariaLabel":1798,"className":1799,"dataFootnoteBackref":301},"#user-content-fnref-1-4","Back to reference 1-4",[1778],[420,1801,619],{},[246,1803,1805,1810,1811,1780,1816],{"id":1804},"user-content-fn-2",[423,1806,1809],{"href":1807,"rel":1808},"https:\u002F\u002Fclaudify.tech\u002Fblog\u002Fclaude-code-multi-file-editing",[1770],"Claude Code Multi-File Editing Guide"," - Claudify ",[423,1812,1779],{"href":1813,"ariaLabel":1814,"className":1815,"dataFootnoteBackref":301},"#user-content-fnref-2","Back to reference 2",[1778],[423,1817,1779,1821],{"href":1818,"ariaLabel":1819,"className":1820,"dataFootnoteBackref":301},"#user-content-fnref-2-2","Back to reference 2-2",[1778],[420,1822,509],{},[246,1824,1826,1831,1832],{"id":1825},"user-content-fn-3",[423,1827,1830],{"href":1828,"rel":1829},"https:\u002F\u002Fdevelopertoolkit.ai\u002Fen\u002Fclaude-code\u002Fproductivity-patterns\u002Fmulti-file-workflows\u002F",[1770],"Multi-File Workflows | Developer Toolkit"," - Developer Toolkit ",[423,1833,1779],{"href":1834,"ariaLabel":1835,"className":1836,"dataFootnoteBackref":301},"#user-content-fnref-3","Back to reference 3",[1778],[246,1838,1840,1845,1846,1780,1851],{"id":1839},"user-content-fn-4",[423,1841,1844],{"href":1842,"rel":1843},"https:\u002F\u002Fwww.lowcode.agency\u002Fblog\u002Fclaude-code-large-files-multi-file-edits",[1770],"How to Handle Large Files and Multi-File Edits in Claude Code"," - LowCode Agency ",[423,1847,1779],{"href":1848,"ariaLabel":1849,"className":1850,"dataFootnoteBackref":301},"#user-content-fnref-4","Back to reference 4",[1778],[423,1852,1779,1856],{"href":1853,"ariaLabel":1854,"className":1855,"dataFootnoteBackref":301},"#user-content-fnref-4-2","Back to reference 4-2",[1778],[420,1857,509],{},[246,1859,1861,1866,1867],{"id":1860},"user-content-fn-5",[423,1862,1865],{"href":1863,"rel":1864},"https:\u002F\u002Fclaude.com\u002Fblog\u002Fusing-claude-md-files",[1770],"Using CLAUDE.md files: Customizing Claude Code for your codebase"," - Anthropic, 2025-11-25 ",[423,1868,1779],{"href":1869,"ariaLabel":1870,"className":1871,"dataFootnoteBackref":301},"#user-content-fnref-5","Back to reference 5",[1778],[246,1873,1875,1880,1881,1780,1886],{"id":1874},"user-content-fn-6",[423,1876,1879],{"href":1877,"rel":1878},"https:\u002F\u002Fwww.jdhodges.com\u002Fblog\u002Fclaude-code-claudemd-project-instructions\u002F",[1770],"Claude Code CLAUDE.md Guide: Project Instructions That Work"," - J.D. Hodges, 2026-03-27 ",[423,1882,1779],{"href":1883,"ariaLabel":1884,"className":1885,"dataFootnoteBackref":301},"#user-content-fnref-6","Back to reference 6",[1778],[423,1887,1779,1891],{"href":1888,"ariaLabel":1889,"className":1890,"dataFootnoteBackref":301},"#user-content-fnref-6-2","Back to reference 6-2",[1778],[420,1892,509],{},[246,1894,1896,1901,1902],{"id":1895},"user-content-fn-7",[423,1897,1900],{"href":1898,"rel":1899},"https:\u002F\u002Fwww.builder.io\u002Fblog\u002Fsetting-up-claude-code-project",[1770],"Setting Up a New Claude Code Project: The Complete Guide"," - Builder.io, 2026-04-24 ",[423,1903,1779],{"href":1904,"ariaLabel":1905,"className":1906,"dataFootnoteBackref":301},"#user-content-fnref-7","Back to reference 7",[1778],[246,1908,1910,1915,1916],{"id":1909},"user-content-fn-8",[423,1911,1914],{"href":1912,"rel":1913},"https:\u002F\u002Fclaudefa.st\u002Fblog\u002Fguide\u002Fmechanics\u002Foutput-formatting",[1770],"Claude Code Diff Review: 4 Essential Shortcuts"," - ClaudeFast ",[423,1917,1779],{"href":1918,"ariaLabel":1919,"className":1920,"dataFootnoteBackref":301},"#user-content-fnref-8","Back to reference 8",[1778],[246,1922,1924,1929,1930],{"id":1923},"user-content-fn-9",[423,1925,1928],{"href":1926,"rel":1927},"https:\u002F\u002Fcode.claude.com\u002Fdocs\u002Fen\u002Foverview",[1770],"Claude Code overview"," - Claude Code Docs ",[423,1931,1779],{"href":1932,"ariaLabel":1933,"className":1934,"dataFootnoteBackref":301},"#user-content-fnref-9","Back to reference 9",[1778],[1936,1937,1938],"style",{},"html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}",{"title":301,"searchDepth":544,"depth":551,"links":1940},[1941,1947,1954,1959,1964,1970,1976,1981],{"id":210,"depth":551,"text":211,"children":1942},[1943,1944,1945,1946],{"id":224,"depth":571,"text":225},{"id":304,"depth":571,"text":305},{"id":344,"depth":571,"text":345},{"id":373,"depth":571,"text":374},{"id":402,"depth":551,"text":403,"children":1948},[1949,1950,1951,1952,1953],{"id":409,"depth":571,"text":410},{"id":470,"depth":571,"text":471},{"id":497,"depth":571,"text":498},{"id":520,"depth":571,"text":521},{"id":607,"depth":571,"text":608},{"id":649,"depth":551,"text":650,"children":1955},[1956,1957,1958],{"id":656,"depth":571,"text":657},{"id":707,"depth":571,"text":708},{"id":747,"depth":571,"text":748},{"id":777,"depth":551,"text":778,"children":1960},[1961,1962,1963],{"id":784,"depth":571,"text":785},{"id":803,"depth":571,"text":804},{"id":816,"depth":571,"text":817},{"id":829,"depth":551,"text":830,"children":1965},[1966,1967,1968,1969],{"id":836,"depth":571,"text":837},{"id":1058,"depth":571,"text":1059},{"id":1143,"depth":571,"text":1144},{"id":1273,"depth":571,"text":1274},{"id":1286,"depth":551,"text":1287,"children":1971},[1972,1973,1974,1975],{"id":1293,"depth":571,"text":1294},{"id":1388,"depth":571,"text":1389},{"id":1414,"depth":571,"text":1415},{"id":1501,"depth":571,"text":1502},{"id":1523,"depth":551,"text":1524,"children":1977},[1978,1979,1980],{"id":1527,"depth":571,"text":1528},{"id":1649,"depth":571,"text":1650},{"id":1697,"depth":571,"text":1698},{"id":1749,"depth":551,"text":1750},"Claude Code 的核心价值在于它能够像一位经验丰富的开发者一样，直接在你的代码库中执行编辑操作。不同于传统的 AI 补全工具只提供建议，Claude Code 使用 Edit 和 Write 工具直接修改文件，并通过代理循环（Agentic Loop）自主规划、执行和验证跨文件的复杂变更。本章将深入探讨如何高效利用这些能力进行单文件编辑、多文件协同修改、代码生成以及编辑审查。","md",null,{"date":1986},"2026-04-26",{"title":86,"description":1982},"DfuzP9vOjcLyi07AmzPGbf9B0-bbKqNJWbeaUlxsZ0Y",[1990,1991],{"title":82,"path":83,"stem":84,"description":301,"children":-1},{"title":90,"path":91,"stem":92,"description":1992,"children":-1},"测试与调试是软件开发的两大支柱，也是 Claude Code 展现其 Agentic 能力最充分的场景之一。不同于传统 IDE 中孤立的代码补全或静态分析，Claude Code 能够在一个连续的代理循环中完成\"编写测试 → 运行测试 → 解析失败 → 定位 Bug → 修复代码 → 验证通过\"的完整闭环。本章将深入探讨如何利用 Claude Code 进行高效的测试驱动开发、自动化测试生成、迭代式 Bug 修复以及复杂问题的系统性调试。",1777395308300]