[{"data":1,"prerenderedAt":703},["ShallowReactive",2],{"header-counts":3,"playbook-refactor\u002Flarge-refactor-with-ai-agent":6,"footer-counts":702},{"tools":4,"reviews":5},65,7,{"id":7,"title":8,"body":9,"category":682,"cover":683,"description":684,"extension":685,"meta":686,"navigation":269,"path":687,"published":688,"relatedTools":689,"seo":693,"stem":694,"tags":695,"updated":700,"__hash__":701},"playbook\u002Fplaybook\u002Frefactor\u002Flarge-refactor-with-ai-agent.md","用 AI Agent 跑大型重构：不翻车工作流",{"type":10,"value":11,"toc":655},"minimark",[12,16,25,44,50,53,56,64,67,70,87,90,97,104,125,131,138,145,147,151,155,158,168,178,182,188,194,198,244,253,328,334,338,341,347,352,372,376,379,429,435,438,442,466,468,471,541,544,548,555,559,565,568,578,582,589,593,599,601,605,612,631,642,644,651],[13,14,15],"h2",{"id":15},"适用场景",[17,18,19,20,24],"p",{},"任何",[21,22,23],"strong",{},"符合下列任意一条","的重构都属于\"大型重构\"：",[26,27,28,32,35,38,41],"ul",{},[29,30,31],"li",{},"影响超过 30 个文件",[29,33,34],{},"涉及 API 签名变更（调用方需要同步改）",[29,36,37],{},"涉及数据格式变更（DB schema \u002F 序列化协议）",[29,39,40],{},"跨模块、跨进程",[29,42,43],{},"需要保留向后兼容",[17,45,46,49],{},[21,47,48],{},"这类任务用 IDE 手改太慢，让 AI 一次性跑完又容易翻车。"," 本工作流的目标是：让 AI 跑大头，但每一步可验证、可回滚。",[51,52],"hr",{},[13,54,55],{"id":55},"核心原则",[57,58,60,61],"h3",{"id":59},"_1-任务必须拆","1. ",[21,62,63],{},"任务必须拆",[17,65,66],{},"不要给 AI：\"把整个项目从 Pinia 1 迁到 Pinia 2\"。",[17,68,69],{},"要给 AI：",[26,71,72,75,78,81,84],{},[29,73,74],{},"Step A: 找出所有用 Pinia 1 API 的文件，输出清单",[29,76,77],{},"Step B: 改第 1-10 个文件，跑测试",[29,79,80],{},"Step C: 改第 11-20 个，跑测试",[29,82,83],{},"...",[29,85,86],{},"Step Z: 全跑通后删 Pinia 1 依赖",[17,88,89],{},"每步独立 commit。",[57,91,93,94],{"id":92},"_2-每步都有-checkpoint","2. ",[21,95,96],{},"每步都有 checkpoint",[17,98,99,100,103],{},"checkpoint = 一个",[21,101,102],{},"可机器验证","的状态。比如：",[26,105,106,113,118],{},[29,107,108,112],{},[109,110,111],"code",{},"pnpm typecheck"," 通过",[29,114,115,112],{},[109,116,117],{},"pnpm test",[29,119,120,121,124],{},"启动 dev server 后 ",[109,122,123],{},"curl \u002Fhealth"," 返 200",[17,126,127,130],{},[21,128,129],{},"没有 checkpoint 的步骤不要放进工作流","——因为你没法知道它对不对。",[57,132,134,135],{"id":133},"_3-git-隔离","3. ",[21,136,137],{},"git 隔离",[17,139,140,141,144],{},"每个大任务开独立分支。每个 step 一个 commit。\n",[21,142,143],{},"不要让 AI 直接 push 到主干","，永远先 PR。",[51,146],{},[13,148,150],{"id":149},"完整工作流6-阶段","完整工作流：6 阶段",[57,152,154],{"id":153},"阶段-1调研人工-ai30-min","阶段 1：调研（人工 + AI，30 min）",[17,156,157],{},"让 AI 帮你回答 4 个问题：",[159,160,166],"pre",{"className":161,"code":163,"language":164,"meta":165},[162],"language-text","针对【重构目标】，请回答：\n\n1. 影响面：哪些文件会被修改？给出完整列表 + 行数估算\n2. 阻塞依赖：有没有外部库 \u002F API 升级也需要做？\n3. 不可逆操作：有没有数据迁移 \u002F 二进制格式变更？\n4. 测试覆盖：现有测试能 cover 多少？哪些路径无测试？\n\n不要开始改代码，只产出调研报告。\n","text","",[109,167,163],{"__ignoreMap":165},[17,169,170,173,174,177],{},[21,171,172],{},"输出物","：一份 markdown 报告。",[21,175,176],{},"人工 review 这份报告再决定是否继续","——很多时候你会发现\"这个重构不该做\"或\"该用别的方案\"。",[57,179,181],{"id":180},"阶段-2拆任务人工-ai20-min","阶段 2：拆任务（人工 + AI，20 min）",[159,183,186],{"className":184,"code":185,"language":164,"meta":165},[162],"基于调研报告，请把整个重构拆成 N 个 step。每个 step 满足：\n\n- 影响 ≤ 5 个文件\n- 有明确的 checkpoint（typecheck \u002F 测试 \u002F 编译）\n- 每步独立可 commit、可回滚\n- step 之间有依赖时显式标出\n\n输出 markdown 表格：step 编号 | 描述 | 影响文件 | checkpoint | 依赖 step\n",[109,187,185],{"__ignoreMap":165},[17,189,190,193],{},[21,191,192],{},"人工 review 这份拆解","——如果某 step 影响超过 5 文件，强制再拆。",[57,195,197],{"id":196},"阶段-3建脚手架ai10-min","阶段 3：建脚手架（AI，10 min）",[159,199,203],{"className":200,"code":201,"language":202,"meta":165,"style":165},"language-bash shiki shiki-themes github-light github-dark","git checkout -b refactor\u002Fpinia-2-migration\nmkdir -p .refactor\n# 把拆解后的 task list 存进去\n","bash",[109,204,205,225,237],{"__ignoreMap":165},[206,207,210,214,218,222],"span",{"class":208,"line":209},"line",1,[206,211,213],{"class":212},"sScJk","git",[206,215,217],{"class":216},"sZZnC"," checkout",[206,219,221],{"class":220},"sj4cs"," -b",[206,223,224],{"class":216}," refactor\u002Fpinia-2-migration\n",[206,226,228,231,234],{"class":208,"line":227},2,[206,229,230],{"class":212},"mkdir",[206,232,233],{"class":220}," -p",[206,235,236],{"class":216}," .refactor\n",[206,238,240],{"class":208,"line":239},3,[206,241,243],{"class":242},"sJ8bj","# 把拆解后的 task list 存进去\n",[17,245,246,249,250],{},[21,247,248],{},"关键文件","：",[109,251,252],{},".refactor\u002FSTATUS.md",[159,254,258],{"className":255,"code":256,"language":257,"meta":165,"style":165},"language-markdown shiki shiki-themes github-light github-dark","# Pinia 2 Migration Status\n\n- [ ] step-01: 列出所有 Pinia 1 调用点\n- [ ] step-02: 改 stores\u002Fuser.ts + 调用方\n- [ ] step-03: 改 stores\u002Fcart.ts + 调用方\n...\n\n## Checkpoints\n- [ ] all `pnpm typecheck` passes\n- [ ] all `pnpm test` passes\n- [ ] dev server boots\n- [ ] e2e smoke test passes\n","markdown",[109,259,260,265,271,276,282,288,294,298,304,310,316,322],{"__ignoreMap":165},[206,261,262],{"class":208,"line":209},[206,263,264],{},"# Pinia 2 Migration Status\n",[206,266,267],{"class":208,"line":227},[206,268,270],{"emptyLinePlaceholder":269},true,"\n",[206,272,273],{"class":208,"line":239},[206,274,275],{},"- [ ] step-01: 列出所有 Pinia 1 调用点\n",[206,277,279],{"class":208,"line":278},4,[206,280,281],{},"- [ ] step-02: 改 stores\u002Fuser.ts + 调用方\n",[206,283,285],{"class":208,"line":284},5,[206,286,287],{},"- [ ] step-03: 改 stores\u002Fcart.ts + 调用方\n",[206,289,291],{"class":208,"line":290},6,[206,292,293],{},"...\n",[206,295,296],{"class":208,"line":5},[206,297,270],{"emptyLinePlaceholder":269},[206,299,301],{"class":208,"line":300},8,[206,302,303],{},"## Checkpoints\n",[206,305,307],{"class":208,"line":306},9,[206,308,309],{},"- [ ] all `pnpm typecheck` passes\n",[206,311,313],{"class":208,"line":312},10,[206,314,315],{},"- [ ] all `pnpm test` passes\n",[206,317,319],{"class":208,"line":318},11,[206,320,321],{},"- [ ] dev server boots\n",[206,323,325],{"class":208,"line":324},12,[206,326,327],{},"- [ ] e2e smoke test passes\n",[17,329,330,333],{},[21,331,332],{},"让 AI 每完成一步就更新这份文件","。",[57,335,337],{"id":336},"阶段-4执行ai-主导1-n-小时","阶段 4：执行（AI 主导，1-N 小时）",[17,339,340],{},"每个 step 用同一个 prompt 模板：",[159,342,345],{"className":343,"code":344,"language":164,"meta":165},[162],"现在执行 step-{N}：{描述}。\n\n要求：\n1. 只改清单内的文件，不要碰其他文件\n2. 改完后跑 checkpoint：{checkpoint 命令}\n3. 如果 checkpoint 失败，先 debug 失败原因，再决定是修改还是回滚\n4. 成功后：\n   a. 在 .refactor\u002FSTATUS.md 把这一项打勾\n   b. git add 改动 + git commit -m \"refactor(step-{N}): {描述}\"\n5. 不要继续下一步，等我确认\n",[109,346,344],{"__ignoreMap":165},[17,348,349],{},[21,350,351],{},"关键纪律：",[26,353,354,360,366],{},[29,355,356,359],{},[21,357,358],{},"每步 commit","，不要憋一个大 commit",[29,361,362,365],{},[21,363,364],{},"每步等人确认","，AI 不要连续跑 5 步——很容易在第 3 步偏轨道但你没发现",[29,367,368,369],{},"如果 step 失败 2 次，",[21,370,371],{},"停下来人工介入",[57,373,375],{"id":374},"阶段-5合并验证人工-ai30-min","阶段 5：合并验证（人工 + AI，30 min）",[17,377,378],{},"所有 step 完成后：",[159,380,382],{"className":200,"code":381,"language":202,"meta":165,"style":165},"# 1. 跑全套测试\npnpm test\npnpm e2e\n\n# 2. 启动 dev server，手测核心路径\npnpm dev\n\n# 3. 让 AI 做\"自我代码审查\"\n",[109,383,384,389,397,404,408,413,420,424],{"__ignoreMap":165},[206,385,386],{"class":208,"line":209},[206,387,388],{"class":242},"# 1. 跑全套测试\n",[206,390,391,394],{"class":208,"line":227},[206,392,393],{"class":212},"pnpm",[206,395,396],{"class":216}," test\n",[206,398,399,401],{"class":208,"line":239},[206,400,393],{"class":212},[206,402,403],{"class":216}," e2e\n",[206,405,406],{"class":208,"line":278},[206,407,270],{"emptyLinePlaceholder":269},[206,409,410],{"class":208,"line":284},[206,411,412],{"class":242},"# 2. 启动 dev server，手测核心路径\n",[206,414,415,417],{"class":208,"line":290},[206,416,393],{"class":212},[206,418,419],{"class":216}," dev\n",[206,421,422],{"class":208,"line":5},[206,423,270],{"emptyLinePlaceholder":269},[206,425,426],{"class":208,"line":300},[206,427,428],{"class":242},"# 3. 让 AI 做\"自我代码审查\"\n",[159,430,433],{"className":431,"code":432,"language":164,"meta":165},[162],"请审视本分支相对 main 的所有改动，找出：\n- 不一致：相同模式有没有漏改的地方\n- 风险：有没有可能的运行时错误（null deref、type 转换失败）\n- 兼容：旧代码调用新代码会不会出问题\n- 性能：有没有 N+1 查询、不必要的循环\n\n输出 markdown 报告，每条带文件路径和行号。\n",[109,434,432],{"__ignoreMap":165},[17,436,437],{},"人工 review 报告，必要时再开新 step 修补。",[57,439,441],{"id":440},"阶段-6发布人工时间不定","阶段 6：发布（人工，时间不定）",[26,443,444,447,452,455],{},[29,445,446],{},"发 PR，标题写清楚 \"Refactor: ...\" + 影响面摘要",[29,448,449],{},[21,450,451],{},"PR description 直接贴 .refactor\u002FSTATUS.md 内容",[29,453,454],{},"至少一个 reviewer 看",[29,456,457,458,461,462,465],{},"合并后保留 ",[109,459,460],{},".refactor\u002F"," 目录在 git 里",[21,463,464],{},"作为历史记录","——下次类似重构可参考",[51,467],{},[13,469,470],{"id":470},"工具选择",[472,473,474,490],"table",{},[475,476,477],"thead",{},[478,479,480,484,487],"tr",{},[481,482,483],"th",{},"阶段",[481,485,486],{},"推荐工具",[481,488,489],{},"原因",[491,492,493,505,519,530],"tbody",{},[478,494,495,499,502],{},[496,497,498],"td",{},"调研 \u002F 拆任务",[496,500,501],{},"Claude Code",[496,503,504],{},"自由探索能力强",[478,506,507,510,516],{},[496,508,509],{},"执行 step",[496,511,512,515],{},[21,513,514],{},"Windsurf Cascade"," 或 Claude Code",[496,517,518],{},"长任务能力",[478,520,521,524,527],{},[496,522,523],{},"单步快速改",[496,525,526],{},"Cursor Composer",[496,528,529],{},"Tab 流畅",[478,531,532,535,538],{},[496,533,534],{},"自我代码审查",[496,536,537],{},"Claude Code（独立 session）",[496,539,540],{},"切换 context 更客观",[13,542,543],{"id":543},"踩坑",[57,545,547],{"id":546},"_1-不要相信-ai-说我已完成","1. 不要相信 AI 说\"我已完成\"",[17,549,550,551,554],{},"每步都要",[21,552,553],{},"自己跑 checkpoint"," 确认，不能信 AI 的口头报告。",[57,556,558],{"id":557},"_2-别让-ai-改测试","2. 别让 AI 改测试",[17,560,561,562,333],{},"如果跑测试失败，AI 倾向于\"修测试让它通过\"——这是",[21,563,564],{},"最危险的反模式",[17,566,567],{},"明确禁止：",[569,570,571],"blockquote",{},[17,572,573,574,577],{},"\"如果测试失败，分析为什么失败。",[21,575,576],{},"不允许修改测试文件","——除非测试本身有 bug 且你能在改之前向我证明。\"",[57,579,581],{"id":580},"_3-不要跨大版本改依赖","3. 不要跨大版本改依赖",[17,583,584,585,588],{},"step 中遇到\"顺便升一下这个库\"的诱惑——",[21,586,587],{},"说不","。把依赖升级单独开 PR。",[57,590,592],{"id":591},"_4-注意-token-成本","4. 注意 token 成本",[17,594,595,596,333],{},"跨 50 文件的重构容易烧掉 $10-50 的 token（Claude Sonnet 4.5）。",[21,597,598],{},"先估预算再开始",[51,600],{},[13,602,604],{"id":603},"实战案例本站项目从-src-改根级","实战案例：本站项目从 src\u002F 改根级",[17,606,607,608,611],{},"我们自己用这套工作流把姊妹站 oltools.net 从 ",[109,609,610],{},"src\u002F"," 根布局改成 Nuxt 4 标准布局，影响 200+ 文件。",[26,613,614,617,620,623,626],{},[29,615,616],{},"调研：30 min",[29,618,619],{},"拆任务：拆成 14 个 step",[29,621,622],{},"执行：4 小时（Windsurf Cascade，重度人工 review）",[29,624,625],{},"合并验证：1 小时",[29,627,628],{},[21,629,630],{},"零线上事故",[17,632,633,634,641],{},"完整 commit 历史可看 ",[635,636,640],"a",{"href":637,"rel":638},"https:\u002F\u002Fgithub.com\u002Faiho\u002Foltools",[639],"nofollow","oltools.net 仓库","（即将开放）。",[51,643],{},[17,645,646,647,333],{},"继续阅读：",[635,648,650],{"href":649},"\u002Fplaybook\u002Freview\u002Fai-code-review-workflow","AI 做 PR review 工作流",[652,653,654],"style",{},"html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}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);}",{"title":165,"searchDepth":239,"depth":239,"links":656},[657,658,666,674,675,681],{"id":15,"depth":227,"text":15},{"id":55,"depth":227,"text":55,"children":659},[660,662,664],{"id":59,"depth":239,"text":661},"1. 任务必须拆",{"id":92,"depth":239,"text":663},"2. 每步都有 checkpoint",{"id":133,"depth":239,"text":665},"3. git 隔离",{"id":149,"depth":227,"text":150,"children":667},[668,669,670,671,672,673],{"id":153,"depth":239,"text":154},{"id":180,"depth":239,"text":181},{"id":196,"depth":239,"text":197},{"id":336,"depth":239,"text":337},{"id":374,"depth":239,"text":375},{"id":440,"depth":239,"text":441},{"id":470,"depth":227,"text":470},{"id":543,"depth":227,"text":543,"children":676},[677,678,679,680],{"id":546,"depth":239,"text":547},{"id":557,"depth":239,"text":558},{"id":580,"depth":239,"text":581},{"id":591,"depth":239,"text":592},{"id":603,"depth":227,"text":604},"refactor","\u002Fog\u002Fplaybook\u002Flarge-refactor.png","跨 50+ 文件的重构任务如何让 AI Agent 安全完成？任务拆解、checkpoint、git 隔离、验证策略与回滚预案的完整 playbook。","md",{},"\u002Fplaybook\u002Frefactor\u002Flarge-refactor-with-ai-agent","2026-05-15",[690,691,692],"coding\u002Fcli\u002Fclaude-code","coding\u002Fide\u002Fwindsurf","coding\u002Fagent\u002Faugment",{"title":8,"description":684},"playbook\u002Frefactor\u002Flarge-refactor-with-ai-agent",[696,697,501,698,699],"重构","Agent","Windsurf","工作流","2026-06-12","wtg_idmRZ3PBBQlCMTaD7GBi9U74mmV8uBlvN5dIArQ",{"tools":4,"reviews":5,"playbooks":312,"news":300},1782316489336]