[{"data":1,"prerenderedAt":7450},["ShallowReactive",2],{"article-/topics/ai/ai-agent-secret-rotation-policy-cadence":3,"related-ai":2572,"content-query-19UkgpBpMq":5327},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"date":10,"topic":5,"author":11,"tags":12,"image":18,"featured":6,"readingTime":19,"body":20,"_type":2566,"_id":2567,"_source":2568,"_file":2569,"_stem":2570,"_extension":2571},"/topics/ai/ai-agent-secret-rotation-policy-cadence","ai",false,"","AI agent Secret Rotation Policy：密钥多久轮换一次，才不至于让旧凭证继续跑在生产环境","密钥轮换不是越频繁越好，也不是永远不轮换。本文给出不同凭证类型的轮换节奏建议（API Key、OAuth Token、Database Password），并提供自动化轮换、失败降级和紧急撤销的完整流程，避免旧凭证泄露后仍在生产环境运行数周。","2026-06-15","HTMLPAGE 团队",[13,14,15,16,17],"secret rotation","credential rotation policy","key rotation cadence","automatic rotation","rotation failure handling","/images/articles/as02-featured.jpeg",14,{"type":21,"children":22,"toc":2523},"root",[23,32,46,58,63,98,110,115,122,127,160,165,198,206,211,546,556,589,594,601,611,629,638,702,719,725,733,746,754,807,816,822,830,843,851,894,903,908,914,919,928,951,960,973,982,1000,1009,1022,1028,1033,1041,1064,1072,1083,1092,1103,1111,1129,1137,1155,1161,1166,1174,1192,1201,1210,1219,1230,1238,1256,1264,1282,1287,1293,1298,1341,1346,1379,1385,1395,1404,1413,1422,1431,1439,1452,1460,1473,1479,1488,1496,1505,1514,1565,1573,1586,1594,1607,1613,1622,1630,1639,1648,1666,1675,1693,1698,1703,1708,1866,1871,1882,1887,1898,1904,1910,1920,1953,1958,1964,1973,2006,2012,2021,2072,2078,2086,2109,2114,2120,2129,2152,2157,2163,2171,2214,2220,2228,2270,2276,2285,2318,2323,2341,2346,2391,2397,2402,2501,2505],{"type":24,"tag":25,"props":26,"children":28},"element","h2",{"id":27},"为什么密钥轮换如此重要",[29],{"type":30,"value":31},"text","为什么密钥轮换如此重要？",{"type":24,"tag":33,"props":34,"children":35},"p",{},[36,38,44],{"type":30,"value":37},"2024 年 9 月，某金融科技公司的安全团队发现一个令人不安的事实：他们的生产数据库密码已经 ",{"type":24,"tag":39,"props":40,"children":41},"strong",{},[42],{"type":30,"value":43},"18 个月没有轮换",{"type":30,"value":45},"了。更糟糕的是，这个密码曾在 6 个月前被一位离职工程师分享到 Slack 的一个公开频道中，虽然很快删除了消息，但无法确定是否有人已经保存了这个密码。",{"type":24,"tag":33,"props":47,"children":48},{},[49,51,56],{"type":30,"value":50},"幸运的是，这次是内部安全扫描发现的，而不是外部攻击者利用了这个漏洞。但这种情况并不罕见。根据 Verizon 2025 年数据泄露调查报告，",{"type":24,"tag":39,"props":52,"children":53},{},[54],{"type":30,"value":55},"34% 的数据泄露事件涉及被盗用的凭证",{"type":30,"value":57},"，其中大部分是因为凭证长期未轮换或轮换不及时。",{"type":24,"tag":33,"props":59,"children":60},{},[61],{"type":30,"value":62},"对于 AI agent 系统来说，密钥轮换的挑战更大：",{"type":24,"tag":64,"props":65,"children":66},"ul",{},[67,78,88],{"type":24,"tag":68,"props":69,"children":70},"li",{},[71,76],{"type":24,"tag":39,"props":72,"children":73},{},[74],{"type":30,"value":75},"凭证数量多",{"type":30,"value":77},"：一个 agent 可能需要访问 OpenAI、Anthropic、数据库、向量存储、外部 API 等十几个服务。",{"type":24,"tag":68,"props":79,"children":80},{},[81,86],{"type":24,"tag":39,"props":82,"children":83},{},[84],{"type":30,"value":85},"依赖关系复杂",{"type":30,"value":87},"：轮换一个凭证可能影响多个 agent、多个环境、多个下游系统。",{"type":24,"tag":68,"props":89,"children":90},{},[91,96],{"type":24,"tag":39,"props":92,"children":93},{},[94],{"type":30,"value":95},"自动化难度高",{"type":30,"value":97},"：手动轮换容易遗漏，自动化轮换又担心出错导致服务中断。",{"type":24,"tag":33,"props":99,"children":100},{},[101,103,108],{"type":30,"value":102},"Secret Rotation Policy（密钥轮换策略）就是为了解决这些问题而设计的系统性方案。它不是简单的\"定期改密码\"，而是提供",{"type":24,"tag":39,"props":104,"children":105},{},[106],{"type":30,"value":107},"轮换节奏、自动化流程、失败降级、紧急撤销和监控告警",{"type":30,"value":109},"的完整框架。",{"type":24,"tag":25,"props":111,"children":113},{"id":112},"不同凭证的轮换节奏",[114],{"type":30,"value":112},{"type":24,"tag":116,"props":117,"children":119},"h3",{"id":118},"核心原则风险与成本的平衡",[120],{"type":30,"value":121},"核心原则：风险与成本的平衡",{"type":24,"tag":33,"props":123,"children":124},{},[125],{"type":30,"value":126},"轮换频率不是越高越好。过于频繁的轮换会带来：",{"type":24,"tag":64,"props":128,"children":129},{},[130,140,150],{"type":24,"tag":68,"props":131,"children":132},{},[133,138],{"type":24,"tag":39,"props":134,"children":135},{},[136],{"type":30,"value":137},"运维成本增加",{"type":30,"value":139},"：每次轮换都需要测试、验证、更新配置。",{"type":24,"tag":68,"props":141,"children":142},{},[143,148],{"type":24,"tag":39,"props":144,"children":145},{},[146],{"type":30,"value":147},"服务中断风险",{"type":30,"value":149},"：如果轮换过程中出现错误，可能导致服务不可用。",{"type":24,"tag":68,"props":151,"children":152},{},[153,158],{"type":24,"tag":39,"props":154,"children":155},{},[156],{"type":30,"value":157},"开发者体验下降",{"type":30,"value":159},"：频繁更换凭证会影响开发和调试效率。",{"type":24,"tag":33,"props":161,"children":162},{},[163],{"type":30,"value":164},"但轮换频率也不能太低，否则：",{"type":24,"tag":64,"props":166,"children":167},{},[168,178,188],{"type":24,"tag":68,"props":169,"children":170},{},[171,176],{"type":24,"tag":39,"props":172,"children":173},{},[174],{"type":30,"value":175},"泄露窗口期长",{"type":30,"value":177},"：凭证一旦泄露，攻击者可以长期使用。",{"type":24,"tag":68,"props":179,"children":180},{},[181,186],{"type":24,"tag":39,"props":182,"children":183},{},[184],{"type":30,"value":185},"合规风险",{"type":30,"value":187},"：某些行业标准（如 PCI DSS）要求至少每 90 天轮换一次密钥。",{"type":24,"tag":68,"props":189,"children":190},{},[191,196],{"type":24,"tag":39,"props":192,"children":193},{},[194],{"type":30,"value":195},"审计困难",{"type":30,"value":197},"：长期不变的凭证难以追踪使用情况。",{"type":24,"tag":33,"props":199,"children":200},{},[201],{"type":24,"tag":39,"props":202,"children":203},{},[204],{"type":30,"value":205},"最佳实践是根据凭证类型、使用场景和风险等级，制定差异化的轮换节奏。",{"type":24,"tag":116,"props":207,"children":209},{"id":208},"推荐轮换节奏表",[210],{"type":30,"value":208},{"type":24,"tag":212,"props":213,"children":214},"table",{},[215,249],{"type":24,"tag":216,"props":217,"children":218},"thead",{},[219],{"type":24,"tag":220,"props":221,"children":222},"tr",{},[223,229,234,239,244],{"type":24,"tag":224,"props":225,"children":226},"th",{},[227],{"type":30,"value":228},"凭证类型",{"type":24,"tag":224,"props":230,"children":231},{},[232],{"type":30,"value":233},"推荐轮换周期",{"type":24,"tag":224,"props":235,"children":236},{},[237],{"type":30,"value":238},"最大租约（Max TTL）",{"type":24,"tag":224,"props":240,"children":241},{},[242],{"type":30,"value":243},"风险等级",{"type":24,"tag":224,"props":245,"children":246},{},[247],{"type":30,"value":248},"说明",{"type":24,"tag":250,"props":251,"children":252},"tbody",{},[253,285,316,344,373,402,430,459,488,517],{"type":24,"tag":220,"props":254,"children":255},{},[256,265,270,275,280],{"type":24,"tag":257,"props":258,"children":259},"td",{},[260],{"type":24,"tag":39,"props":261,"children":262},{},[263],{"type":30,"value":264},"API Key（第三方服务）",{"type":24,"tag":257,"props":266,"children":267},{},[268],{"type":30,"value":269},"90 天",{"type":24,"tag":257,"props":271,"children":272},{},[273],{"type":30,"value":274},"180 天",{"type":24,"tag":257,"props":276,"children":277},{},[278],{"type":30,"value":279},"中",{"type":24,"tag":257,"props":281,"children":282},{},[283],{"type":30,"value":284},"如 OpenAI、Anthropic、AWS API Key",{"type":24,"tag":220,"props":286,"children":287},{},[288,296,301,306,311],{"type":24,"tag":257,"props":289,"children":290},{},[291],{"type":24,"tag":39,"props":292,"children":293},{},[294],{"type":30,"value":295},"OAuth Access Token",{"type":24,"tag":257,"props":297,"children":298},{},[299],{"type":30,"value":300},"7 天",{"type":24,"tag":257,"props":302,"children":303},{},[304],{"type":30,"value":305},"30 天",{"type":24,"tag":257,"props":307,"children":308},{},[309],{"type":30,"value":310},"高",{"type":24,"tag":257,"props":312,"children":313},{},[314],{"type":30,"value":315},"短期有效，支持刷新机制",{"type":24,"tag":220,"props":317,"children":318},{},[319,327,331,335,339],{"type":24,"tag":257,"props":320,"children":321},{},[322],{"type":24,"tag":39,"props":323,"children":324},{},[325],{"type":30,"value":326},"OAuth Refresh Token",{"type":24,"tag":257,"props":328,"children":329},{},[330],{"type":30,"value":305},{"type":24,"tag":257,"props":332,"children":333},{},[334],{"type":30,"value":269},{"type":24,"tag":257,"props":336,"children":337},{},[338],{"type":30,"value":310},{"type":24,"tag":257,"props":340,"children":341},{},[342],{"type":30,"value":343},"用于获取新的 Access Token",{"type":24,"tag":220,"props":345,"children":346},{},[347,355,359,364,368],{"type":24,"tag":257,"props":348,"children":349},{},[350],{"type":24,"tag":39,"props":351,"children":352},{},[353],{"type":30,"value":354},"Database Password",{"type":24,"tag":257,"props":356,"children":357},{},[358],{"type":30,"value":305},{"type":24,"tag":257,"props":360,"children":361},{},[362],{"type":30,"value":363},"60 天",{"type":24,"tag":257,"props":365,"children":366},{},[367],{"type":30,"value":310},{"type":24,"tag":257,"props":369,"children":370},{},[371],{"type":30,"value":372},"生产数据库凭证必须严格轮换",{"type":24,"tag":220,"props":374,"children":375},{},[376,384,388,393,397],{"type":24,"tag":257,"props":377,"children":378},{},[379],{"type":24,"tag":39,"props":380,"children":381},{},[382],{"type":30,"value":383},"Service Account Key",{"type":24,"tag":257,"props":385,"children":386},{},[387],{"type":30,"value":274},{"type":24,"tag":257,"props":389,"children":390},{},[391],{"type":30,"value":392},"365 天",{"type":24,"tag":257,"props":394,"children":395},{},[396],{"type":30,"value":279},{"type":24,"tag":257,"props":398,"children":399},{},[400],{"type":30,"value":401},"GCP/AWS Service Account",{"type":24,"tag":220,"props":403,"children":404},{},[405,413,417,421,425],{"type":24,"tag":257,"props":406,"children":407},{},[408],{"type":24,"tag":39,"props":409,"children":410},{},[411],{"type":30,"value":412},"JWT Signing Key",{"type":24,"tag":257,"props":414,"children":415},{},[416],{"type":30,"value":305},{"type":24,"tag":257,"props":418,"children":419},{},[420],{"type":30,"value":269},{"type":24,"tag":257,"props":422,"children":423},{},[424],{"type":30,"value":310},{"type":24,"tag":257,"props":426,"children":427},{},[428],{"type":30,"value":429},"用于签名和验证 JWT",{"type":24,"tag":220,"props":431,"children":432},{},[433,441,445,450,454],{"type":24,"tag":257,"props":434,"children":435},{},[436],{"type":24,"tag":39,"props":437,"children":438},{},[439],{"type":30,"value":440},"TLS Certificate",{"type":24,"tag":257,"props":442,"children":443},{},[444],{"type":30,"value":392},{"type":24,"tag":257,"props":446,"children":447},{},[448],{"type":30,"value":449},"730 天",{"type":24,"tag":257,"props":451,"children":452},{},[453],{"type":30,"value":279},{"type":24,"tag":257,"props":455,"children":456},{},[457],{"type":30,"value":458},"可使用 Let's Encrypt 自动续期",{"type":24,"tag":220,"props":460,"children":461},{},[462,470,474,478,483],{"type":24,"tag":257,"props":463,"children":464},{},[465],{"type":24,"tag":39,"props":466,"children":467},{},[468],{"type":30,"value":469},"Webhook Secret",{"type":24,"tag":257,"props":471,"children":472},{},[473],{"type":30,"value":269},{"type":24,"tag":257,"props":475,"children":476},{},[477],{"type":30,"value":274},{"type":24,"tag":257,"props":479,"children":480},{},[481],{"type":30,"value":482},"低",{"type":24,"tag":257,"props":484,"children":485},{},[486],{"type":30,"value":487},"用于验证 webhook 签名",{"type":24,"tag":220,"props":489,"children":490},{},[491,499,503,508,512],{"type":24,"tag":257,"props":492,"children":493},{},[494],{"type":24,"tag":39,"props":495,"children":496},{},[497],{"type":30,"value":498},"Internal API Token",{"type":24,"tag":257,"props":500,"children":501},{},[502],{"type":30,"value":363},{"type":24,"tag":257,"props":504,"children":505},{},[506],{"type":30,"value":507},"120 天",{"type":24,"tag":257,"props":509,"children":510},{},[511],{"type":30,"value":279},{"type":24,"tag":257,"props":513,"children":514},{},[515],{"type":30,"value":516},"内部微服务间通信",{"type":24,"tag":220,"props":518,"children":519},{},[520,528,532,536,541],{"type":24,"tag":257,"props":521,"children":522},{},[523],{"type":24,"tag":39,"props":524,"children":525},{},[526],{"type":30,"value":527},"Admin Password",{"type":24,"tag":257,"props":529,"children":530},{},[531],{"type":30,"value":305},{"type":24,"tag":257,"props":533,"children":534},{},[535],{"type":30,"value":363},{"type":24,"tag":257,"props":537,"children":538},{},[539],{"type":30,"value":540},"极高",{"type":24,"tag":257,"props":542,"children":543},{},[544],{"type":30,"value":545},"管理员账户必须严格管控",{"type":24,"tag":33,"props":547,"children":548},{},[549,554],{"type":24,"tag":39,"props":550,"children":551},{},[552],{"type":30,"value":553},"注意",{"type":30,"value":555},"：这些是通用建议，具体节奏应根据你的业务场景调整。例如：",{"type":24,"tag":64,"props":557,"children":558},{},[559,569,579],{"type":24,"tag":68,"props":560,"children":561},{},[562,567],{"type":24,"tag":39,"props":563,"children":564},{},[565],{"type":30,"value":566},"金融行业",{"type":30,"value":568},"：可能需要更短的轮换周期（如 API Key 30 天、Database Password 7 天）。",{"type":24,"tag":68,"props":570,"children":571},{},[572,577],{"type":24,"tag":39,"props":573,"children":574},{},[575],{"type":30,"value":576},"初创公司",{"type":30,"value":578},"：可以适当延长轮换周期，优先保证开发效率。",{"type":24,"tag":68,"props":580,"children":581},{},[582,587],{"type":24,"tag":39,"props":583,"children":584},{},[585],{"type":30,"value":586},"合规要求严格的行业",{"type":30,"value":588},"：必须遵循行业标准（如 PCI DSS、HIPAA、SOC 2）。",{"type":24,"tag":116,"props":590,"children":592},{"id":591},"特殊场景的轮换策略",[593],{"type":30,"value":591},{"type":24,"tag":595,"props":596,"children":598},"h4",{"id":597},"场景一凭证泄露后的紧急轮换",[599],{"type":30,"value":600},"场景一：凭证泄露后的紧急轮换",{"type":24,"tag":33,"props":602,"children":603},{},[604,609],{"type":24,"tag":39,"props":605,"children":606},{},[607],{"type":30,"value":608},"触发条件",{"type":30,"value":610},"：",{"type":24,"tag":64,"props":612,"children":613},{},[614,619,624],{"type":24,"tag":68,"props":615,"children":616},{},[617],{"type":30,"value":618},"检测到凭证在代码仓库、日志文件或公共论坛中泄露。",{"type":24,"tag":68,"props":620,"children":621},{},[622],{"type":30,"value":623},"收到安全厂商或云服务商的泄露通知。",{"type":24,"tag":68,"props":625,"children":626},{},[627],{"type":30,"value":628},"发现异常的凭证使用模式（如来自未知 IP 的大量请求）。",{"type":24,"tag":33,"props":630,"children":631},{},[632,637],{"type":24,"tag":39,"props":633,"children":634},{},[635],{"type":30,"value":636},"响应流程",{"type":30,"value":610},{"type":24,"tag":639,"props":640,"children":641},"ol",{},[642,652,662,672,682,692],{"type":24,"tag":68,"props":643,"children":644},{},[645,650],{"type":24,"tag":39,"props":646,"children":647},{},[648],{"type":30,"value":649},"立即撤销",{"type":30,"value":651},"：在 Vault 或云控制台中立即吊销泄露的凭证。",{"type":24,"tag":68,"props":653,"children":654},{},[655,660],{"type":24,"tag":39,"props":656,"children":657},{},[658],{"type":30,"value":659},"生成新凭证",{"type":30,"value":661},"：创建新的凭证并部署到所有使用该凭证的服务。",{"type":24,"tag":68,"props":663,"children":664},{},[665,670],{"type":24,"tag":39,"props":666,"children":667},{},[668],{"type":30,"value":669},"验证功能",{"type":30,"value":671},"：确保新凭证正常工作，服务恢复正常运行。",{"type":24,"tag":68,"props":673,"children":674},{},[675,680],{"type":24,"tag":39,"props":676,"children":677},{},[678],{"type":30,"value":679},"影响评估",{"type":30,"value":681},"：检查泄露期间是否有异常操作或数据泄露。",{"type":24,"tag":68,"props":683,"children":684},{},[685,690],{"type":24,"tag":39,"props":686,"children":687},{},[688],{"type":30,"value":689},"根本原因分析",{"type":30,"value":691},"：找出泄露原因，修复流程漏洞。",{"type":24,"tag":68,"props":693,"children":694},{},[695,700],{"type":24,"tag":39,"props":696,"children":697},{},[698],{"type":30,"value":699},"事后复盘",{"type":30,"value":701},"：更新轮换策略，防止类似事件再次发生。",{"type":24,"tag":33,"props":703,"children":704},{},[705,710,712,717],{"type":24,"tag":39,"props":706,"children":707},{},[708],{"type":30,"value":709},"时间目标",{"type":30,"value":711},"：从发现泄露到完成轮换，应在 ",{"type":24,"tag":39,"props":713,"children":714},{},[715],{"type":30,"value":716},"1 小时内",{"type":30,"value":718},"完成。",{"type":24,"tag":595,"props":720,"children":722},{"id":721},"场景二员工离职时的凭证清理",[723],{"type":30,"value":724},"场景二：员工离职时的凭证清理",{"type":24,"tag":33,"props":726,"children":727},{},[728,732],{"type":24,"tag":39,"props":729,"children":730},{},[731],{"type":30,"value":608},{"type":30,"value":610},{"type":24,"tag":64,"props":734,"children":735},{},[736,741],{"type":24,"tag":68,"props":737,"children":738},{},[739],{"type":30,"value":740},"员工离职或转岗。",{"type":24,"tag":68,"props":742,"children":743},{},[744],{"type":30,"value":745},"员工的访问权限发生变化。",{"type":24,"tag":33,"props":747,"children":748},{},[749,753],{"type":24,"tag":39,"props":750,"children":751},{},[752],{"type":30,"value":636},{"type":30,"value":610},{"type":24,"tag":639,"props":755,"children":756},{},[757,767,777,787,797],{"type":24,"tag":68,"props":758,"children":759},{},[760,765],{"type":24,"tag":39,"props":761,"children":762},{},[763],{"type":30,"value":764},"权限审查",{"type":30,"value":766},"：列出该员工有权访问的所有凭证和服务。",{"type":24,"tag":68,"props":768,"children":769},{},[770,775],{"type":24,"tag":39,"props":771,"children":772},{},[773],{"type":30,"value":774},"凭证轮换",{"type":30,"value":776},"：轮换该员工知道的所有共享凭证（如团队共用的 API Key）。",{"type":24,"tag":68,"props":778,"children":779},{},[780,785],{"type":24,"tag":39,"props":781,"children":782},{},[783],{"type":30,"value":784},"个人账户禁用",{"type":30,"value":786},"：禁用或删除该员工的个人账户和 Service Account。",{"type":24,"tag":68,"props":788,"children":789},{},[790,795],{"type":24,"tag":39,"props":791,"children":792},{},[793],{"type":30,"value":794},"审计日志检查",{"type":30,"value":796},"：检查该员工最近的操作记录，发现异常行为。",{"type":24,"tag":68,"props":798,"children":799},{},[800,805],{"type":24,"tag":39,"props":801,"children":802},{},[803],{"type":30,"value":804},"通知相关方",{"type":30,"value":806},"：告知团队成员凭证已轮换，更新本地配置。",{"type":24,"tag":33,"props":808,"children":809},{},[810,814],{"type":24,"tag":39,"props":811,"children":812},{},[813],{"type":30,"value":709},{"type":30,"value":815},"：员工离职当天完成所有凭证轮换。",{"type":24,"tag":595,"props":817,"children":819},{"id":818},"场景三合规审计前的集中轮换",[820],{"type":30,"value":821},"场景三：合规审计前的集中轮换",{"type":24,"tag":33,"props":823,"children":824},{},[825,829],{"type":24,"tag":39,"props":826,"children":827},{},[828],{"type":30,"value":608},{"type":30,"value":610},{"type":24,"tag":64,"props":831,"children":832},{},[833,838],{"type":24,"tag":68,"props":834,"children":835},{},[836],{"type":30,"value":837},"即将进行 SOC 2、ISO 27001、PCI DSS 等合规审计。",{"type":24,"tag":68,"props":839,"children":840},{},[841],{"type":30,"value":842},"内部审计发现部分凭证超过轮换周期。",{"type":24,"tag":33,"props":844,"children":845},{},[846,850],{"type":24,"tag":39,"props":847,"children":848},{},[849],{"type":30,"value":636},{"type":30,"value":610},{"type":24,"tag":639,"props":852,"children":853},{},[854,864,874,884],{"type":24,"tag":68,"props":855,"children":856},{},[857,862],{"type":24,"tag":39,"props":858,"children":859},{},[860],{"type":30,"value":861},"凭证盘点",{"type":30,"value":863},"：列出所有超过轮换周期的凭证。",{"type":24,"tag":68,"props":865,"children":866},{},[867,872],{"type":24,"tag":39,"props":868,"children":869},{},[870],{"type":30,"value":871},"分批轮换",{"type":30,"value":873},"：按优先级分批轮换，避免一次性轮换过多导致服务中断。",{"type":24,"tag":68,"props":875,"children":876},{},[877,882],{"type":24,"tag":39,"props":878,"children":879},{},[880],{"type":30,"value":881},"文档更新",{"type":30,"value":883},"：更新凭证管理文档和审计报告。",{"type":24,"tag":68,"props":885,"children":886},{},[887,892],{"type":24,"tag":39,"props":888,"children":889},{},[890],{"type":30,"value":891},"证据收集",{"type":30,"value":893},"：保存轮换记录作为合规证据。",{"type":24,"tag":33,"props":895,"children":896},{},[897,901],{"type":24,"tag":39,"props":898,"children":899},{},[900],{"type":30,"value":709},{"type":30,"value":902},"：审计前 2 周完成所有过期凭证的轮换。",{"type":24,"tag":25,"props":904,"children":906},{"id":905},"自动化轮换架构",[907],{"type":30,"value":905},{"type":24,"tag":116,"props":909,"children":911},{"id":910},"方案一vault-agent-自动轮换",[912],{"type":30,"value":913},"方案一：Vault Agent 自动轮换",{"type":24,"tag":33,"props":915,"children":916},{},[917],{"type":30,"value":918},"HashiCorp Vault 提供了内置的自动轮换功能，适合大多数场景。",{"type":24,"tag":33,"props":920,"children":921},{},[922,927],{"type":24,"tag":39,"props":923,"children":924},{},[925],{"type":30,"value":926},"工作原理",{"type":30,"value":610},{"type":24,"tag":639,"props":929,"children":930},{},[931,936,941,946],{"type":24,"tag":68,"props":932,"children":933},{},[934],{"type":30,"value":935},"Vault Agent 以 Sidecar 或 DaemonSet 形式运行在每个节点上。",{"type":24,"tag":68,"props":937,"children":938},{},[939],{"type":30,"value":940},"Agent 定期向 Vault Server 请求 renew lease（续期租约）。",{"type":24,"tag":68,"props":942,"children":943},{},[944],{"type":30,"value":945},"如果租约即将过期，Agent 自动获取新凭证并更新本地文件。",{"type":24,"tag":68,"props":947,"children":948},{},[949],{"type":30,"value":950},"Agent 通过信号通知应用程序重新加载配置。",{"type":24,"tag":33,"props":952,"children":953},{},[954,959],{"type":24,"tag":39,"props":955,"children":956},{},[957],{"type":30,"value":958},"配置示例",{"type":30,"value":610},{"type":24,"tag":961,"props":962,"children":967},"pre",{"className":963,"code":965,"language":966,"meta":7},[964],"language-hcl","# vault-agent.hcl\nauto_auth {\n  method \"approle\" {\n    config = {\n      role_id_file_path = \"/etc/vault/role-id\"\n      secret_id_file_path = \"/etc/vault/secret-id\"\n    }\n  }\n  \n  sink \"file\" {\n    config = {\n      path = \"/home/vault/token\"\n    }\n  }\n}\n\nlistener \"tcp\" {\n  address = \"127.0.0.1:8100\"\n  tls_disable = true\n}\n\ncache {\n  use_auto_auth_token = true\n}\n\ntemplate {\n  destination = \"/etc/secrets/openai-api-key.txt\"\n  contents = \u003C\u003CEOH\n{{ with secret \"secret/data/openai/api-key\" }}\n{{ .Data.data.value }}\n{{ end }}\nEOH\n  \n  # 每 1 小时渲染一次（即轮换一次）\n  wait {\n    min = \"1h\"\n    max = \"2h\"\n  }\n  \n  # 渲染完成后发送信号给应用程序\n  command = \"kill -HUP $(cat /var/run/my-app.pid)\"\n}\n","hcl",[968],{"type":24,"tag":969,"props":970,"children":971},"code",{"__ignoreMap":7},[972],{"type":30,"value":965},{"type":24,"tag":33,"props":974,"children":975},{},[976,981],{"type":24,"tag":39,"props":977,"children":978},{},[979],{"type":30,"value":980},"优点",{"type":30,"value":610},{"type":24,"tag":64,"props":983,"children":984},{},[985,990,995],{"type":24,"tag":68,"props":986,"children":987},{},[988],{"type":30,"value":989},"完全自动化，无需人工干预。",{"type":24,"tag":68,"props":991,"children":992},{},[993],{"type":30,"value":994},"支持动态凭证，Vault 自动生成新凭证。",{"type":24,"tag":68,"props":996,"children":997},{},[998],{"type":30,"value":999},"与 Kubernetes、Consul 等基础设施深度集成。",{"type":24,"tag":33,"props":1001,"children":1002},{},[1003,1008],{"type":24,"tag":39,"props":1004,"children":1005},{},[1006],{"type":30,"value":1007},"缺点",{"type":30,"value":610},{"type":24,"tag":64,"props":1010,"children":1011},{},[1012,1017],{"type":24,"tag":68,"props":1013,"children":1014},{},[1015],{"type":30,"value":1016},"需要部署和维护 Vault Agent。",{"type":24,"tag":68,"props":1018,"children":1019},{},[1020],{"type":30,"value":1021},"应用程序需要支持热重载配置（接收 SIGHUP 信号）。",{"type":24,"tag":116,"props":1023,"children":1025},{"id":1024},"方案二aws-secrets-manager-自动轮换",[1026],{"type":30,"value":1027},"方案二：AWS Secrets Manager 自动轮换",{"type":24,"tag":33,"props":1029,"children":1030},{},[1031],{"type":30,"value":1032},"如果你使用 AWS，可以利用 Secrets Manager 的内置轮换功能。",{"type":24,"tag":33,"props":1034,"children":1035},{},[1036,1040],{"type":24,"tag":39,"props":1037,"children":1038},{},[1039],{"type":30,"value":926},{"type":30,"value":610},{"type":24,"tag":639,"props":1042,"children":1043},{},[1044,1049,1054,1059],{"type":24,"tag":68,"props":1045,"children":1046},{},[1047],{"type":30,"value":1048},"在 Secrets Manager 中启用自动轮换，指定轮换周期（如 30 天）。",{"type":24,"tag":68,"props":1050,"children":1051},{},[1052],{"type":30,"value":1053},"AWS Lambda 函数定期执行轮换逻辑（由 AWS 托管）。",{"type":24,"tag":68,"props":1055,"children":1056},{},[1057],{"type":30,"value":1058},"Lambda 函数调用 RDS、Redshift 等服务的 API 生成新密码。",{"type":24,"tag":68,"props":1060,"children":1061},{},[1062],{"type":30,"value":1063},"新密码更新到 Secrets Manager，并通知应用程序。",{"type":24,"tag":33,"props":1065,"children":1066},{},[1067,1071],{"type":24,"tag":39,"props":1068,"children":1069},{},[1070],{"type":30,"value":958},{"type":30,"value":610},{"type":24,"tag":961,"props":1073,"children":1078},{"className":1074,"code":1076,"language":1077,"meta":7},[1075],"language-typescript","// Lambda 轮换函数示例（AWS 提供的模板）\nimport { SecretsManagerClient, RotateSecretCommand } from \"@aws-sdk/client-secrets-manager\";\n\nexport const handler = async (event: any) => {\n  const client = new SecretsManagerClient({ region: \"us-east-1\" });\n  \n  // Step 1: 创建新密码\n  const newPassword = generateRandomPassword();\n  \n  // Step 2: 设置新密码到数据库\n  await setDatabasePassword(event.SecretId, newPassword);\n  \n  // Step 3: 更新 Secrets Manager\n  await client.send(new RotateSecretCommand({\n    SecretId: event.SecretId,\n    ClientRequestToken: event.ClientRequestToken,\n  }));\n  \n  // Step 4: 验证新密码可用\n  await verifyDatabaseConnection(event.SecretId, newPassword);\n  \n  // Step 5: 完成轮换\n  console.log(\"Secret rotation completed successfully\");\n};\n","typescript",[1079],{"type":24,"tag":969,"props":1080,"children":1081},{"__ignoreMap":7},[1082],{"type":30,"value":1076},{"type":24,"tag":33,"props":1084,"children":1085},{},[1086,1091],{"type":24,"tag":39,"props":1087,"children":1088},{},[1089],{"type":30,"value":1090},"启用自动轮换",{"type":30,"value":610},{"type":24,"tag":961,"props":1093,"children":1098},{"className":1094,"code":1096,"language":1097,"meta":7},[1095],"language-bash","aws secretsmanager rotate-secret \\\n  --secret-id prod/database/password \\\n  --rotation-rules AutomaticallyAfterDays=30 \\\n  --rotation-lambda-arn arn:aws:lambda:us-east-1:123456789:function:SecretsManagerRotation\n","bash",[1099],{"type":24,"tag":969,"props":1100,"children":1101},{"__ignoreMap":7},[1102],{"type":30,"value":1096},{"type":24,"tag":33,"props":1104,"children":1105},{},[1106,1110],{"type":24,"tag":39,"props":1107,"children":1108},{},[1109],{"type":30,"value":980},{"type":30,"value":610},{"type":24,"tag":64,"props":1112,"children":1113},{},[1114,1119,1124],{"type":24,"tag":68,"props":1115,"children":1116},{},[1117],{"type":30,"value":1118},"零运维，AWS 完全托管轮换逻辑。",{"type":24,"tag":68,"props":1120,"children":1121},{},[1122],{"type":30,"value":1123},"与 RDS、Redshift、DocumentDB 等 AWS 服务无缝集成。",{"type":24,"tag":68,"props":1125,"children":1126},{},[1127],{"type":30,"value":1128},"支持自定义 Lambda 函数，满足特殊需求。",{"type":24,"tag":33,"props":1130,"children":1131},{},[1132,1136],{"type":24,"tag":39,"props":1133,"children":1134},{},[1135],{"type":30,"value":1007},{"type":30,"value":610},{"type":24,"tag":64,"props":1138,"children":1139},{},[1140,1145,1150],{"type":24,"tag":68,"props":1141,"children":1142},{},[1143],{"type":30,"value":1144},"仅支持 AWS 生态，多云环境不适用。",{"type":24,"tag":68,"props":1146,"children":1147},{},[1148],{"type":30,"value":1149},"自定义轮换逻辑需要编写和维护 Lambda 函数。",{"type":24,"tag":68,"props":1151,"children":1152},{},[1153],{"type":30,"value":1154},"按轮换次数收费，高频轮换可能增加成本。",{"type":24,"tag":116,"props":1156,"children":1158},{"id":1157},"方案三cron-job-自定义脚本",[1159],{"type":30,"value":1160},"方案三：Cron Job + 自定义脚本",{"type":24,"tag":33,"props":1162,"children":1163},{},[1164],{"type":30,"value":1165},"对于小规模团队或特殊场景，可以使用 Cron Job 定期执行自定义轮换脚本。",{"type":24,"tag":33,"props":1167,"children":1168},{},[1169,1173],{"type":24,"tag":39,"props":1170,"children":1171},{},[1172],{"type":30,"value":926},{"type":30,"value":610},{"type":24,"tag":639,"props":1175,"children":1176},{},[1177,1182,1187],{"type":24,"tag":68,"props":1178,"children":1179},{},[1180],{"type":30,"value":1181},"编写轮换脚本，实现凭证生成、更新、验证逻辑。",{"type":24,"tag":68,"props":1183,"children":1184},{},[1185],{"type":30,"value":1186},"配置 Cron Job，定期执行轮换脚本（如每月 1 号凌晨 2 点）。",{"type":24,"tag":68,"props":1188,"children":1189},{},[1190],{"type":30,"value":1191},"脚本执行成功后，发送通知给团队；失败则发送告警。",{"type":24,"tag":33,"props":1193,"children":1194},{},[1195,1200],{"type":24,"tag":39,"props":1196,"children":1197},{},[1198],{"type":30,"value":1199},"示例脚本",{"type":30,"value":610},{"type":24,"tag":961,"props":1202,"children":1205},{"className":1203,"code":1204,"language":1097,"meta":7},[1095],"#!/bin/bash\n# rotate-openai-key.sh\n\nset -e\n\n# 配置\nVAULT_ADDR=\"https://vault.example.com\"\nVAULT_TOKEN=\"${VAULT_TOKEN}\"\nSECRET_PATH=\"secret/data/openai/api-key\"\nNOTIFICATION_CHANNEL=\"#security-alerts\"\n\n# 生成新 API Key（调用 OpenAI API）\nNEW_KEY=$(curl -s -X POST https://api.openai.com/v1/api-keys \\\n  -H \"Authorization: Bearer ${ADMIN_API_KEY}\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"name\": \"production-key-'$(date +%Y%m%d)'\"}' \\\n  | jq -r '.key')\n\n# 更新 Vault\ncurl -s -X PUT ${VAULT_ADDR}/v1/${SECRET_PATH} \\\n  -H \"X-Vault-Token: ${VAULT_TOKEN}\" \\\n  -d \"{\\\"data\\\": {\\\"value\\\": \\\"${NEW_KEY}\\\"}}\"\n\n# 验证新 Key 可用\nRESPONSE=$(curl -s -o /dev/null -w \"%{http_code}\" \\\n  https://api.openai.com/v1/models \\\n  -H \"Authorization: Bearer ${NEW_KEY}\")\n\nif [ \"$RESPONSE\" != \"200\" ]; then\n  echo \"ERROR: New API key verification failed with status ${RESPONSE}\"\n  # 发送告警\n  curl -X POST ${SLACK_WEBHOOK_URL} \\\n    -H 'Content-type: application/json' \\\n    --data \"{\\\"text\\\": \\\"❌ OpenAI API Key rotation failed! Status: ${RESPONSE}\\\"}\"\n  exit 1\nfi\n\n# 通知团队\ncurl -X POST ${SLACK_WEBHOOK_URL} \\\n  -H 'Content-type: application/json' \\\n  --data \"{\\\"text\\\": \\\"✅ OpenAI API Key rotated successfully at $(date)\\\"}\"\n\necho \"Secret rotation completed successfully\"\n",[1206],{"type":24,"tag":969,"props":1207,"children":1208},{"__ignoreMap":7},[1209],{"type":30,"value":1204},{"type":24,"tag":33,"props":1211,"children":1212},{},[1213,1218],{"type":24,"tag":39,"props":1214,"children":1215},{},[1216],{"type":30,"value":1217},"Cron 配置",{"type":30,"value":610},{"type":24,"tag":961,"props":1220,"children":1225},{"className":1221,"code":1223,"language":1224,"meta":7},[1222],"language-cron","# 每月 1 号凌晨 2 点执行轮换\n0 2 1 * * /usr/local/bin/rotate-openai-key.sh >> /var/log/secret-rotation.log 2>&1\n","cron",[1226],{"type":24,"tag":969,"props":1227,"children":1228},{"__ignoreMap":7},[1229],{"type":30,"value":1223},{"type":24,"tag":33,"props":1231,"children":1232},{},[1233,1237],{"type":24,"tag":39,"props":1234,"children":1235},{},[1236],{"type":30,"value":980},{"type":30,"value":610},{"type":24,"tag":64,"props":1239,"children":1240},{},[1241,1246,1251],{"type":24,"tag":68,"props":1242,"children":1243},{},[1244],{"type":30,"value":1245},"简单直接，易于理解和维护。",{"type":24,"tag":68,"props":1247,"children":1248},{},[1249],{"type":30,"value":1250},"灵活定制，可以满足特殊业务需求。",{"type":24,"tag":68,"props":1252,"children":1253},{},[1254],{"type":30,"value":1255},"成本低，只需支付服务器费用。",{"type":24,"tag":33,"props":1257,"children":1258},{},[1259,1263],{"type":24,"tag":39,"props":1260,"children":1261},{},[1262],{"type":30,"value":1007},{"type":30,"value":610},{"type":24,"tag":64,"props":1265,"children":1266},{},[1267,1272,1277],{"type":24,"tag":68,"props":1268,"children":1269},{},[1270],{"type":30,"value":1271},"需要自己处理错误重试、告警通知、幂等性等问题。",{"type":24,"tag":68,"props":1273,"children":1274},{},[1275],{"type":30,"value":1276},"缺乏 Vault 的动态凭证、租约管理等高级功能。",{"type":24,"tag":68,"props":1278,"children":1279},{},[1280],{"type":30,"value":1281},"安全性依赖于脚本的实现质量，容易出错。",{"type":24,"tag":25,"props":1283,"children":1285},{"id":1284},"失败降级策略",[1286],{"type":30,"value":1284},{"type":24,"tag":116,"props":1288,"children":1290},{"id":1289},"问题轮换失败了怎么办",[1291],{"type":30,"value":1292},"问题：轮换失败了怎么办？",{"type":24,"tag":33,"props":1294,"children":1295},{},[1296],{"type":30,"value":1297},"即使设计了完善的自动化轮换流程，仍然可能遇到各种失败场景：",{"type":24,"tag":64,"props":1299,"children":1300},{},[1301,1311,1321,1331],{"type":24,"tag":68,"props":1302,"children":1303},{},[1304,1309],{"type":24,"tag":39,"props":1305,"children":1306},{},[1307],{"type":30,"value":1308},"网络故障",{"type":30,"value":1310},"：Vault Server 不可达，无法获取新凭证。",{"type":24,"tag":68,"props":1312,"children":1313},{},[1314,1319],{"type":24,"tag":39,"props":1315,"children":1316},{},[1317],{"type":30,"value":1318},"权限问题",{"type":30,"value":1320},"：轮换脚本没有足够的权限更新凭证。",{"type":24,"tag":68,"props":1322,"children":1323},{},[1324,1329],{"type":24,"tag":39,"props":1325,"children":1326},{},[1327],{"type":30,"value":1328},"依赖服务故障",{"type":30,"value":1330},"：OpenAI API 暂时不可用，无法生成新 Key。",{"type":24,"tag":68,"props":1332,"children":1333},{},[1334,1339],{"type":24,"tag":39,"props":1335,"children":1336},{},[1337],{"type":30,"value":1338},"配置错误",{"type":30,"value":1340},"：轮换脚本有 bug，导致新凭证格式错误。",{"type":24,"tag":33,"props":1342,"children":1343},{},[1344],{"type":30,"value":1345},"如果处理不当，轮换失败可能导致：",{"type":24,"tag":64,"props":1347,"children":1348},{},[1349,1359,1369],{"type":24,"tag":68,"props":1350,"children":1351},{},[1352,1357],{"type":24,"tag":39,"props":1353,"children":1354},{},[1355],{"type":30,"value":1356},"服务中断",{"type":30,"value":1358},"：旧凭证过期，新凭证未生效，服务无法访问依赖的资源。",{"type":24,"tag":68,"props":1360,"children":1361},{},[1362,1367],{"type":24,"tag":39,"props":1363,"children":1364},{},[1365],{"type":30,"value":1366},"数据丢失",{"type":30,"value":1368},"：数据库密码轮换失败，应用无法连接数据库。",{"type":24,"tag":68,"props":1370,"children":1371},{},[1372,1377],{"type":24,"tag":39,"props":1373,"children":1374},{},[1375],{"type":30,"value":1376},"安全风险",{"type":30,"value":1378},"：轮换失败后未及时告警，旧凭证继续使用，增加泄露风险。",{"type":24,"tag":116,"props":1380,"children":1382},{"id":1381},"策略一旧凭证保留期grace-period",[1383],{"type":30,"value":1384},"策略一：旧凭证保留期（Grace Period）",{"type":24,"tag":33,"props":1386,"children":1387},{},[1388,1393],{"type":24,"tag":39,"props":1389,"children":1390},{},[1391],{"type":30,"value":1392},"原理",{"type":30,"value":1394},"：在生成新凭证后，不立即删除旧凭证，而是保留一段时间（如 24 小时），让应用程序有时间切换到新凭证。",{"type":24,"tag":33,"props":1396,"children":1397},{},[1398,1403],{"type":24,"tag":39,"props":1399,"children":1400},{},[1401],{"type":30,"value":1402},"实现",{"type":30,"value":610},{"type":24,"tag":961,"props":1405,"children":1408},{"className":1406,"code":1407,"language":1077,"meta":7},[1075],"async function rotateSecret(secretId: string) {\n  // Step 1: 生成新凭证\n  const newCredential = await generateNewCredential(secretId);\n  \n  // Step 2: 将新凭证写入 Vault，标记为 \"active\"\n  await vault.write(`${secretId}/active`, newCredential);\n  \n  // Step 3: 将旧凭证标记为 \"deprecated\"，设置 24 小时后过期\n  const oldCredential = await vault.read(`${secretId}/active`);\n  await vault.write(`${secretId}/deprecated`, {\n    ...oldCredential,\n    expires_at: Date.now() + 24 * 60 * 60 * 1000, // 24 小时后过期\n  });\n  \n  // Step 4: 通知应用程序重新加载配置\n  await notifyApplications(secretId);\n  \n  // Step 5: 等待 24 小时后，删除旧凭证\n  setTimeout(async () => {\n    await vault.delete(`${secretId}/deprecated`);\n    console.log(`Old credential for ${secretId} has been removed`);\n  }, 24 * 60 * 60 * 1000);\n}\n",[1409],{"type":24,"tag":969,"props":1410,"children":1411},{"__ignoreMap":7},[1412],{"type":30,"value":1407},{"type":24,"tag":33,"props":1414,"children":1415},{},[1416,1421],{"type":24,"tag":39,"props":1417,"children":1418},{},[1419],{"type":30,"value":1420},"应用程序端",{"type":30,"value":610},{"type":24,"tag":961,"props":1423,"children":1426},{"className":1424,"code":1425,"language":1077,"meta":7},[1075],"async function getCredential(secretId: string) {\n  // 优先使用 active 凭证\n  try {\n    const active = await vault.read(`${secretId}/active`);\n    return active.data;\n  } catch (error) {\n    // 如果 active 凭证不可用，尝试使用 deprecated 凭证（降级）\n    console.warn(`Failed to get active credential for ${secretId}, falling back to deprecated`);\n    const deprecated = await vault.read(`${secretId}/deprecated`);\n    \n    // 检查是否已过期\n    if (deprecated.data.expires_at \u003C Date.now()) {\n      throw new Error(\"Deprecated credential has expired\");\n    }\n    \n    return deprecated.data;\n  }\n}\n",[1427],{"type":24,"tag":969,"props":1428,"children":1429},{"__ignoreMap":7},[1430],{"type":30,"value":1425},{"type":24,"tag":33,"props":1432,"children":1433},{},[1434,1438],{"type":24,"tag":39,"props":1435,"children":1436},{},[1437],{"type":30,"value":980},{"type":30,"value":610},{"type":24,"tag":64,"props":1440,"children":1441},{},[1442,1447],{"type":24,"tag":68,"props":1443,"children":1444},{},[1445],{"type":30,"value":1446},"即使轮换过程中出现问题，服务仍可使用旧凭证继续运行。",{"type":24,"tag":68,"props":1448,"children":1449},{},[1450],{"type":30,"value":1451},"给应用程序足够的时间切换到新凭证，避免服务中断。",{"type":24,"tag":33,"props":1453,"children":1454},{},[1455,1459],{"type":24,"tag":39,"props":1456,"children":1457},{},[1458],{"type":30,"value":1007},{"type":30,"value":610},{"type":24,"tag":64,"props":1461,"children":1462},{},[1463,1468],{"type":24,"tag":68,"props":1464,"children":1465},{},[1466],{"type":30,"value":1467},"旧凭证在保留期内仍然有效，增加了泄露风险。",{"type":24,"tag":68,"props":1469,"children":1470},{},[1471],{"type":30,"value":1472},"需要应用程序支持双凭证逻辑，增加了复杂度。",{"type":24,"tag":116,"props":1474,"children":1476},{"id":1475},"策略二告警机制与人工干预",[1477],{"type":30,"value":1478},"策略二：告警机制与人工干预",{"type":24,"tag":33,"props":1480,"children":1481},{},[1482,1486],{"type":24,"tag":39,"props":1483,"children":1484},{},[1485],{"type":30,"value":1392},{"type":30,"value":1487},"：轮换失败时立即发送告警，通知 on-call 工程师手动介入处理。",{"type":24,"tag":33,"props":1489,"children":1490},{},[1491,1495],{"type":24,"tag":39,"props":1492,"children":1493},{},[1494],{"type":30,"value":1402},{"type":30,"value":610},{"type":24,"tag":961,"props":1497,"children":1500},{"className":1498,"code":1499,"language":1077,"meta":7},[1075],"async function rotateWithAlerts(secretId: string) {\n  const startTime = Date.now();\n  \n  try {\n    await rotateSecret(secretId);\n    \n    // 轮换成功，发送成功通知\n    await sendNotification({\n      channel: \"#security-alerts\",\n      message: `✅ Secret rotation succeeded for ${secretId}`,\n      level: \"info\",\n    });\n  } catch (error) {\n    const duration = Date.now() - startTime;\n    \n    // 轮换失败，发送紧急告警\n    await sendNotification({\n      channel: \"#security-alerts\",\n      message: `🚨 Secret rotation FAILED for ${secretId}\\nError: ${error.message}\\nDuration: ${duration}ms`,\n      level: \"critical\",\n      pagerduty: true, // 触发 PagerDuty 告警\n    });\n    \n    // 记录失败指标\n    metrics.increment(\"secret_rotation.failures\", { secret_id: secretId });\n    \n    // 抛出错误，阻止后续流程\n    throw error;\n  }\n}\n",[1501],{"type":24,"tag":969,"props":1502,"children":1503},{"__ignoreMap":7},[1504],{"type":30,"value":1499},{"type":24,"tag":33,"props":1506,"children":1507},{},[1508,1513],{"type":24,"tag":39,"props":1509,"children":1510},{},[1511],{"type":30,"value":1512},"告警升级策略",{"type":30,"value":610},{"type":24,"tag":64,"props":1515,"children":1516},{},[1517,1535,1545,1555],{"type":24,"tag":68,"props":1518,"children":1519},{},[1520,1525,1527,1533],{"type":24,"tag":39,"props":1521,"children":1522},{},[1523],{"type":30,"value":1524},"T+0 分钟",{"type":30,"value":1526},"：轮换失败，发送 Slack 告警到 ",{"type":24,"tag":969,"props":1528,"children":1530},{"className":1529},[],[1531],{"type":30,"value":1532},"#security-alerts",{"type":30,"value":1534}," 频道。",{"type":24,"tag":68,"props":1536,"children":1537},{},[1538,1543],{"type":24,"tag":39,"props":1539,"children":1540},{},[1541],{"type":30,"value":1542},"T+5 分钟",{"type":30,"value":1544},"：如果未确认告警，发送 PagerDuty 告警给 on-call 工程师。",{"type":24,"tag":68,"props":1546,"children":1547},{},[1548,1553],{"type":24,"tag":39,"props":1549,"children":1550},{},[1551],{"type":30,"value":1552},"T+15 分钟",{"type":30,"value":1554},"：如果仍未处理，升级告警给安全团队负责人。",{"type":24,"tag":68,"props":1556,"children":1557},{},[1558,1563],{"type":24,"tag":39,"props":1559,"children":1560},{},[1561],{"type":30,"value":1562},"T+30 分钟",{"type":30,"value":1564},"：如果问题仍未解决，启动应急响应流程，召集相关人员开会。",{"type":24,"tag":33,"props":1566,"children":1567},{},[1568,1572],{"type":24,"tag":39,"props":1569,"children":1570},{},[1571],{"type":30,"value":980},{"type":30,"value":610},{"type":24,"tag":64,"props":1574,"children":1575},{},[1576,1581],{"type":24,"tag":68,"props":1577,"children":1578},{},[1579],{"type":30,"value":1580},"快速发现问题，减少服务中断时间。",{"type":24,"tag":68,"props":1582,"children":1583},{},[1584],{"type":30,"value":1585},"明确的责任分工和升级路径，避免无人处理的情况。",{"type":24,"tag":33,"props":1587,"children":1588},{},[1589,1593],{"type":24,"tag":39,"props":1590,"children":1591},{},[1592],{"type":30,"value":1007},{"type":30,"value":610},{"type":24,"tag":64,"props":1595,"children":1596},{},[1597,1602],{"type":24,"tag":68,"props":1598,"children":1599},{},[1600],{"type":30,"value":1601},"依赖人工干预，可能在非工作时间响应延迟。",{"type":24,"tag":68,"props":1603,"children":1604},{},[1605],{"type":30,"value":1606},"频繁的告警可能导致告警疲劳，忽略真正重要的问题。",{"type":24,"tag":116,"props":1608,"children":1610},{"id":1609},"策略三手动紧急撤销",[1611],{"type":30,"value":1612},"策略三：手动紧急撤销",{"type":24,"tag":33,"props":1614,"children":1615},{},[1616,1620],{"type":24,"tag":39,"props":1617,"children":1618},{},[1619],{"type":30,"value":1392},{"type":30,"value":1621},"：当自动化轮换失败且无法快速修复时，提供手动紧急撤销凭证的能力。",{"type":24,"tag":33,"props":1623,"children":1624},{},[1625,1629],{"type":24,"tag":39,"props":1626,"children":1627},{},[1628],{"type":30,"value":1402},{"type":30,"value":610},{"type":24,"tag":961,"props":1631,"children":1634},{"className":1632,"code":1633,"language":1097,"meta":7},[1095],"#!/bin/bash\n# emergency-revoke.sh\n\nset -e\n\nSECRET_ID=$1\nREASON=$2\n\nif [ -z \"$SECRET_ID\" ] || [ -z \"$REASON\" ]; then\n  echo \"Usage: $0 \u003Csecret-id> \u003Creason>\"\n  exit 1\nfi\n\necho \"⚠️  Emergency revoking secret: ${SECRET_ID}\"\necho \"Reason: ${REASON}\"\necho \"Operator: $(whoami)\"\necho \"Timestamp: $(date -u)\"\n\n# 确认操作\nread -p \"Are you sure you want to revoke this secret? (yes/no): \" confirm\nif [ \"$confirm\" != \"yes\" ]; then\n  echo \"Operation cancelled\"\n  exit 0\nfi\n\n# 撤销凭证\ncurl -s -X DELETE ${VAULT_ADDR}/v1/${SECRET_ID}/active \\\n  -H \"X-Vault-Token: ${VAULT_TOKEN}\"\n\n# 记录审计日志\necho \"$(date -u) | ${SECRET_ID} | REVOKED | ${REASON} | $(whoami)\" >> /var/log/emergency-revocations.log\n\n# 通知团队\ncurl -X POST ${SLACK_WEBHOOK_URL} \\\n  -H 'Content-type: application/json' \\\n  --data \"{\\\"text\\\": \\\"🚨 Emergency revocation executed for ${SECRET_ID}\\\\nReason: ${REASON}\\\\nOperator: $(whoami)\\\"}\"\n\necho \"✅ Secret revoked successfully\"\n",[1635],{"type":24,"tag":969,"props":1636,"children":1637},{"__ignoreMap":7},[1638],{"type":30,"value":1633},{"type":24,"tag":33,"props":1640,"children":1641},{},[1642,1647],{"type":24,"tag":39,"props":1643,"children":1644},{},[1645],{"type":30,"value":1646},"使用场景",{"type":30,"value":610},{"type":24,"tag":64,"props":1649,"children":1650},{},[1651,1656,1661],{"type":24,"tag":68,"props":1652,"children":1653},{},[1654],{"type":30,"value":1655},"检测到凭证泄露，需要立即撤销。",{"type":24,"tag":68,"props":1657,"children":1658},{},[1659],{"type":30,"value":1660},"自动化轮换失败，且旧凭证已过期，服务中断。",{"type":24,"tag":68,"props":1662,"children":1663},{},[1664],{"type":30,"value":1665},"员工离职，需要立即禁用其访问权限。",{"type":24,"tag":33,"props":1667,"children":1668},{},[1669,1674],{"type":24,"tag":39,"props":1670,"children":1671},{},[1672],{"type":30,"value":1673},"注意事项",{"type":30,"value":610},{"type":24,"tag":64,"props":1676,"children":1677},{},[1678,1683,1688],{"type":24,"tag":68,"props":1679,"children":1680},{},[1681],{"type":30,"value":1682},"紧急撤销操作必须记录审计日志，包括操作人、时间、原因。",{"type":24,"tag":68,"props":1684,"children":1685},{},[1686],{"type":30,"value":1687},"撤销后应立即生成新凭证并部署，避免服务长时间中断。",{"type":24,"tag":68,"props":1689,"children":1690},{},[1691],{"type":30,"value":1692},"定期进行紧急撤销演练，确保流程畅通。",{"type":24,"tag":25,"props":1694,"children":1696},{"id":1695},"监控与告警",[1697],{"type":30,"value":1695},{"type":24,"tag":116,"props":1699,"children":1701},{"id":1700},"关键指标",[1702],{"type":30,"value":1700},{"type":24,"tag":33,"props":1704,"children":1705},{},[1706],{"type":30,"value":1707},"监控以下指标，及时发现轮换问题：",{"type":24,"tag":212,"props":1709,"children":1710},{},[1711,1731],{"type":24,"tag":216,"props":1712,"children":1713},{},[1714],{"type":24,"tag":220,"props":1715,"children":1716},{},[1717,1722,1726],{"type":24,"tag":224,"props":1718,"children":1719},{},[1720],{"type":30,"value":1721},"指标名称",{"type":24,"tag":224,"props":1723,"children":1724},{},[1725],{"type":30,"value":248},{"type":24,"tag":224,"props":1727,"children":1728},{},[1729],{"type":30,"value":1730},"告警阈值",{"type":24,"tag":250,"props":1732,"children":1733},{},[1734,1756,1778,1800,1822,1844],{"type":24,"tag":220,"props":1735,"children":1736},{},[1737,1746,1751],{"type":24,"tag":257,"props":1738,"children":1739},{},[1740],{"type":24,"tag":969,"props":1741,"children":1743},{"className":1742},[],[1744],{"type":30,"value":1745},"secret_rotation.success_rate",{"type":24,"tag":257,"props":1747,"children":1748},{},[1749],{"type":30,"value":1750},"轮换成功率",{"type":24,"tag":257,"props":1752,"children":1753},{},[1754],{"type":30,"value":1755},"\u003C 95%",{"type":24,"tag":220,"props":1757,"children":1758},{},[1759,1768,1773],{"type":24,"tag":257,"props":1760,"children":1761},{},[1762],{"type":24,"tag":969,"props":1763,"children":1765},{"className":1764},[],[1766],{"type":30,"value":1767},"secret_rotation.duration_p95",{"type":24,"tag":257,"props":1769,"children":1770},{},[1771],{"type":30,"value":1772},"轮换耗时 P95",{"type":24,"tag":257,"props":1774,"children":1775},{},[1776],{"type":30,"value":1777},"> 30s",{"type":24,"tag":220,"props":1779,"children":1780},{},[1781,1790,1795],{"type":24,"tag":257,"props":1782,"children":1783},{},[1784],{"type":24,"tag":969,"props":1785,"children":1787},{"className":1786},[],[1788],{"type":30,"value":1789},"secret_rotation.failures",{"type":24,"tag":257,"props":1791,"children":1792},{},[1793],{"type":30,"value":1794},"轮换失败次数",{"type":24,"tag":257,"props":1796,"children":1797},{},[1798],{"type":30,"value":1799},"> 0（立即告警）",{"type":24,"tag":220,"props":1801,"children":1802},{},[1803,1812,1817],{"type":24,"tag":257,"props":1804,"children":1805},{},[1806],{"type":24,"tag":969,"props":1807,"children":1809},{"className":1808},[],[1810],{"type":30,"value":1811},"credential.age_days",{"type":24,"tag":257,"props":1813,"children":1814},{},[1815],{"type":30,"value":1816},"凭证已使用天数",{"type":24,"tag":257,"props":1818,"children":1819},{},[1820],{"type":30,"value":1821},"> 轮换周期的 80%",{"type":24,"tag":220,"props":1823,"children":1824},{},[1825,1834,1839],{"type":24,"tag":257,"props":1826,"children":1827},{},[1828],{"type":24,"tag":969,"props":1829,"children":1831},{"className":1830},[],[1832],{"type":30,"value":1833},"credential.expiry_soon",{"type":24,"tag":257,"props":1835,"children":1836},{},[1837],{"type":30,"value":1838},"即将过期的凭证数量",{"type":24,"tag":257,"props":1840,"children":1841},{},[1842],{"type":30,"value":1843},"> 0（提前 7 天告警）",{"type":24,"tag":220,"props":1845,"children":1846},{},[1847,1856,1861],{"type":24,"tag":257,"props":1848,"children":1849},{},[1850],{"type":24,"tag":969,"props":1851,"children":1853},{"className":1852},[],[1854],{"type":30,"value":1855},"credential.unused",{"type":24,"tag":257,"props":1857,"children":1858},{},[1859],{"type":30,"value":1860},"未使用的凭证数量",{"type":24,"tag":257,"props":1862,"children":1863},{},[1864],{"type":30,"value":1865},"> 0（可能存在遗漏）",{"type":24,"tag":116,"props":1867,"children":1869},{"id":1868},"仪表盘示例",[1870],{"type":30,"value":1868},{"type":24,"tag":961,"props":1872,"children":1877},{"className":1873,"code":1875,"language":1876,"meta":7},[1874],"language-json","{\n  \"dashboard\": \"Secret Rotation Health\",\n  \"panels\": [\n    {\n      \"title\": \"Rotation Success Rate (Last 7 Days)\",\n      \"type\": \"time_series\",\n      \"query\": \"sum(rate(secret_rotation_success_total[1h])) / sum(rate(secret_rotation_total[1h]))\"\n    },\n    {\n      \"title\": \"Credentials Expiring Soon\",\n      \"type\": \"table\",\n      \"query\": \"credential_age_days > (rotation_period_days * 0.8)\"\n    },\n    {\n      \"title\": \"Rotation Failures by Secret\",\n      \"type\": \"bar_chart\",\n      \"query\": \"sum by (secret_id) (increase(secret_rotation_failures_total[24h]))\"\n    }\n  ]\n}\n","json",[1878],{"type":24,"tag":969,"props":1879,"children":1880},{"__ignoreMap":7},[1881],{"type":30,"value":1875},{"type":24,"tag":116,"props":1883,"children":1885},{"id":1884},"告警规则",[1886],{"type":30,"value":1884},{"type":24,"tag":961,"props":1888,"children":1893},{"className":1889,"code":1891,"language":1892,"meta":7},[1890],"language-yaml","groups:\n  - name: secret_rotation\n    rules:\n      - alert: SecretRotationFailure\n        expr: increase(secret_rotation_failures_total[1h]) > 0\n        for: 5m\n        labels:\n          severity: critical\n        annotations:\n          summary: \"Secret rotation failed for {{ $labels.secret_id }}\"\n          description: \"Rotation failed {{ $value }} times in the last hour\"\n      \n      - alert: CredentialExpiringSoon\n        expr: credential_age_days > (rotation_period_days * 0.8)\n        for: 1h\n        labels:\n          severity: warning\n        annotations:\n          summary: \"Credential {{ $labels.secret_id }} is expiring soon\"\n          description: \"Credential will expire in {{ $value | humanizeDuration }}\"\n      \n      - alert: UnusedCredential\n        expr: increase(credential_usage_total[7d]) == 0\n        for: 24h\n        labels:\n          severity: info\n        annotations:\n          summary: \"Credential {{ $labels.secret_id }} has not been used in 7 days\"\n          description: \"Consider removing this unused credential\"\n","yaml",[1894],{"type":24,"tag":969,"props":1895,"children":1896},{"__ignoreMap":7},[1897],{"type":30,"value":1891},{"type":24,"tag":25,"props":1899,"children":1901},{"id":1900},"faq",[1902],{"type":30,"value":1903},"FAQ",{"type":24,"tag":116,"props":1905,"children":1907},{"id":1906},"q1-密钥轮换会影响正在运行的服务吗",[1908],{"type":30,"value":1909},"Q1: 密钥轮换会影响正在运行的服务吗？",{"type":24,"tag":33,"props":1911,"children":1912},{},[1913,1918],{"type":24,"tag":39,"props":1914,"children":1915},{},[1916],{"type":30,"value":1917},"A",{"type":30,"value":1919},": 如果实施得当，不会影响。关键是要做到：",{"type":24,"tag":64,"props":1921,"children":1922},{},[1923,1933,1943],{"type":24,"tag":68,"props":1924,"children":1925},{},[1926,1931],{"type":24,"tag":39,"props":1927,"children":1928},{},[1929],{"type":30,"value":1930},"平滑切换",{"type":30,"value":1932},"：使用旧凭证保留期（Grace Period），让服务有时间切换到新凭证。",{"type":24,"tag":68,"props":1934,"children":1935},{},[1936,1941],{"type":24,"tag":39,"props":1937,"children":1938},{},[1939],{"type":30,"value":1940},"热重载",{"type":30,"value":1942},"：应用程序支持在不重启的情况下重新加载配置。",{"type":24,"tag":68,"props":1944,"children":1945},{},[1946,1951],{"type":24,"tag":39,"props":1947,"children":1948},{},[1949],{"type":30,"value":1950},"健康检查",{"type":30,"value":1952},"：轮换后立即验证新凭证可用，确认服务正常运行。",{"type":24,"tag":33,"props":1954,"children":1955},{},[1956],{"type":30,"value":1957},"但如果轮换过程中出现错误（如新凭证格式错误、权限不足），仍可能导致短暂的服务中断。因此，建议在测试环境充分验证轮换流程，并在低峰期执行生产环境的轮换。",{"type":24,"tag":116,"props":1959,"children":1961},{"id":1960},"q2-轮换失败了怎么办",[1962],{"type":30,"value":1963},"Q2: 轮换失败了怎么办？",{"type":24,"tag":33,"props":1965,"children":1966},{},[1967,1971],{"type":24,"tag":39,"props":1968,"children":1969},{},[1970],{"type":30,"value":1917},{"type":30,"value":1972},": 参考上文\"失败降级策略\"部分，主要有三种方式：",{"type":24,"tag":639,"props":1974,"children":1975},{},[1976,1986,1996],{"type":24,"tag":68,"props":1977,"children":1978},{},[1979,1984],{"type":24,"tag":39,"props":1980,"children":1981},{},[1982],{"type":30,"value":1983},"旧凭证保留期",{"type":30,"value":1985},"：保留旧凭证 24 小时，让服务有时间切换。",{"type":24,"tag":68,"props":1987,"children":1988},{},[1989,1994],{"type":24,"tag":39,"props":1990,"children":1991},{},[1992],{"type":30,"value":1993},"告警机制",{"type":30,"value":1995},"：立即发送告警，通知 on-call 工程师手动介入。",{"type":24,"tag":68,"props":1997,"children":1998},{},[1999,2004],{"type":24,"tag":39,"props":2000,"children":2001},{},[2002],{"type":30,"value":2003},"紧急撤销",{"type":30,"value":2005},"：提供手动紧急撤销凭证的能力，应对泄露等紧急情况。",{"type":24,"tag":116,"props":2007,"children":2009},{"id":2008},"q3-如何知道哪些服务还在用旧凭证",[2010],{"type":30,"value":2011},"Q3: 如何知道哪些服务还在用旧凭证？",{"type":24,"tag":33,"props":2013,"children":2014},{},[2015,2019],{"type":24,"tag":39,"props":2016,"children":2017},{},[2018],{"type":30,"value":1917},{"type":30,"value":2020},":",{"type":24,"tag":64,"props":2022,"children":2023},{},[2024,2034,2044,2054],{"type":24,"tag":68,"props":2025,"children":2026},{},[2027,2032],{"type":24,"tag":39,"props":2028,"children":2029},{},[2030],{"type":30,"value":2031},"审计日志分析",{"type":30,"value":2033},"：查询 Vault 审计日志，查看哪些 Actor 在最近访问了该凭证。",{"type":24,"tag":68,"props":2035,"children":2036},{},[2037,2042],{"type":24,"tag":39,"props":2038,"children":2039},{},[2040],{"type":30,"value":2041},"应用程序注册表",{"type":30,"value":2043},"：维护一个服务注册表，记录每个服务使用的凭证列表。",{"type":24,"tag":68,"props":2045,"children":2046},{},[2047,2052],{"type":24,"tag":39,"props":2048,"children":2049},{},[2050],{"type":30,"value":2051},"主动探测",{"type":30,"value":2053},"：轮换后监控服务健康状态，发现异常时快速定位受影响的服务。",{"type":24,"tag":68,"props":2055,"children":2056},{},[2057,2062,2064,2070],{"type":24,"tag":39,"props":2058,"children":2059},{},[2060],{"type":30,"value":2061},"标签系统",{"type":30,"value":2063},"：在 Vault 中为凭证添加标签（如 ",{"type":24,"tag":969,"props":2065,"children":2067},{"className":2066},[],[2068],{"type":30,"value":2069},"used_by: customer-support-agent",{"type":30,"value":2071},"），便于查询。",{"type":24,"tag":116,"props":2073,"children":2075},{"id":2074},"q4-oauth-token-刷新和轮换有什么区别",[2076],{"type":30,"value":2077},"Q4: OAuth Token 刷新和轮换有什么区别？",{"type":24,"tag":33,"props":2079,"children":2080},{},[2081,2085],{"type":24,"tag":39,"props":2082,"children":2083},{},[2084],{"type":30,"value":1917},{"type":30,"value":2020},{"type":24,"tag":64,"props":2087,"children":2088},{},[2089,2099],{"type":24,"tag":68,"props":2090,"children":2091},{},[2092,2097],{"type":24,"tag":39,"props":2093,"children":2094},{},[2095],{"type":30,"value":2096},"OAuth Token 刷新",{"type":30,"value":2098},"：Access Token 过期后，使用 Refresh Token 获取新的 Access Token。这是 OAuth 协议的正常流程，通常由 SDK 自动处理，不需要人工干预。",{"type":24,"tag":68,"props":2100,"children":2101},{},[2102,2107],{"type":24,"tag":39,"props":2103,"children":2104},{},[2105],{"type":30,"value":2106},"OAuth Token 轮换",{"type":30,"value":2108},"：定期更换 Refresh Token 本身，或者更换用于获取 Token 的 Client Secret。这是安全策略，需要主动执行。",{"type":24,"tag":33,"props":2110,"children":2111},{},[2112],{"type":30,"value":2113},"简单来说，刷新是\"续期\"，轮换是\"换锁\"。",{"type":24,"tag":116,"props":2115,"children":2117},{"id":2116},"q5-轮换频率越高越安全吗",[2118],{"type":30,"value":2119},"Q5: 轮换频率越高越安全吗？",{"type":24,"tag":33,"props":2121,"children":2122},{},[2123,2127],{"type":24,"tag":39,"props":2124,"children":2125},{},[2126],{"type":30,"value":1917},{"type":30,"value":2128},": 不一定。轮换频率需要在安全性和可用性之间找到平衡：",{"type":24,"tag":64,"props":2130,"children":2131},{},[2132,2142],{"type":24,"tag":68,"props":2133,"children":2134},{},[2135,2140],{"type":24,"tag":39,"props":2136,"children":2137},{},[2138],{"type":30,"value":2139},"过于频繁",{"type":30,"value":2141},"：增加运维成本、服务中断风险、开发者负担。",{"type":24,"tag":68,"props":2143,"children":2144},{},[2145,2150],{"type":24,"tag":39,"props":2146,"children":2147},{},[2148],{"type":30,"value":2149},"过于稀疏",{"type":30,"value":2151},"：增加泄露窗口期、合规风险。",{"type":24,"tag":33,"props":2153,"children":2154},{},[2155],{"type":30,"value":2156},"最佳实践是根据凭证类型、风险等级、业务场景制定差异化的轮换节奏，而不是一刀切地追求高频轮换。",{"type":24,"tag":116,"props":2158,"children":2160},{"id":2159},"q6-如何实现零停机轮换",[2161],{"type":30,"value":2162},"Q6: 如何实现零停机轮换？",{"type":24,"tag":33,"props":2164,"children":2165},{},[2166,2170],{"type":24,"tag":39,"props":2167,"children":2168},{},[2169],{"type":30,"value":1917},{"type":30,"value":2020},{"type":24,"tag":64,"props":2172,"children":2173},{},[2174,2184,2194,2204],{"type":24,"tag":68,"props":2175,"children":2176},{},[2177,2182],{"type":24,"tag":39,"props":2178,"children":2179},{},[2180],{"type":30,"value":2181},"双凭证并行",{"type":30,"value":2183},"：在轮换期间，同时保留新旧两个凭证，服务可以任选其一。",{"type":24,"tag":68,"props":2185,"children":2186},{},[2187,2192],{"type":24,"tag":39,"props":2188,"children":2189},{},[2190],{"type":30,"value":2191},"渐进式切换",{"type":30,"value":2193},"：先将一部分流量切换到新凭证，验证无误后再切换全部流量。",{"type":24,"tag":68,"props":2195,"children":2196},{},[2197,2202],{"type":24,"tag":39,"props":2198,"children":2199},{},[2200],{"type":30,"value":2201},"蓝绿部署",{"type":30,"value":2203},"：部署新版本的应用程序（使用新凭证），验证通过后切换流量，然后下线旧版本。",{"type":24,"tag":68,"props":2205,"children":2206},{},[2207,2212],{"type":24,"tag":39,"props":2208,"children":2209},{},[2210],{"type":30,"value":2211},"Canary 发布",{"type":30,"value":2213},"：先在少量实例上测试新凭证，逐步扩大范围。",{"type":24,"tag":116,"props":2215,"children":2217},{"id":2216},"q7-轮换后如何验证新凭证有效",[2218],{"type":30,"value":2219},"Q7: 轮换后如何验证新凭证有效？",{"type":24,"tag":33,"props":2221,"children":2222},{},[2223,2227],{"type":24,"tag":39,"props":2224,"children":2225},{},[2226],{"type":30,"value":1917},{"type":30,"value":2020},{"type":24,"tag":64,"props":2229,"children":2230},{},[2231,2240,2250,2260],{"type":24,"tag":68,"props":2232,"children":2233},{},[2234,2238],{"type":24,"tag":39,"props":2235,"children":2236},{},[2237],{"type":30,"value":1950},{"type":30,"value":2239},"：调用依赖服务的健康检查接口，确认新凭证可以正常访问。",{"type":24,"tag":68,"props":2241,"children":2242},{},[2243,2248],{"type":24,"tag":39,"props":2244,"children":2245},{},[2246],{"type":30,"value":2247},"功能测试",{"type":30,"value":2249},"：执行一个简单的操作（如查询一条记录、发送一条消息），验证功能正常。",{"type":24,"tag":68,"props":2251,"children":2252},{},[2253,2258],{"type":24,"tag":39,"props":2254,"children":2255},{},[2256],{"type":30,"value":2257},"监控指标",{"type":30,"value":2259},"：观察错误率、延迟等指标，确认没有出现异常。",{"type":24,"tag":68,"props":2261,"children":2262},{},[2263,2268],{"type":24,"tag":39,"props":2264,"children":2265},{},[2266],{"type":30,"value":2267},"自动化测试",{"type":30,"value":2269},"：在 CI/CD 流水线中加入凭证验证步骤，轮换后自动运行测试。",{"type":24,"tag":116,"props":2271,"children":2273},{"id":2272},"q8-历史凭证需要保留多久",[2274],{"type":30,"value":2275},"Q8: 历史凭证需要保留多久？",{"type":24,"tag":33,"props":2277,"children":2278},{},[2279,2283],{"type":24,"tag":39,"props":2280,"children":2281},{},[2282],{"type":30,"value":1917},{"type":30,"value":2284},": 这取决于合规要求和业务需求：",{"type":24,"tag":64,"props":2286,"children":2287},{},[2288,2298,2308],{"type":24,"tag":68,"props":2289,"children":2290},{},[2291,2296],{"type":24,"tag":39,"props":2292,"children":2293},{},[2294],{"type":30,"value":2295},"审计要求",{"type":30,"value":2297},"：SOC 2、PCI DSS 等标准通常要求保留 1-7 年的审计日志，包括凭证轮换记录。",{"type":24,"tag":68,"props":2299,"children":2300},{},[2301,2306],{"type":24,"tag":39,"props":2302,"children":2303},{},[2304],{"type":30,"value":2305},"故障排查",{"type":30,"value":2307},"：保留最近 30-90 天的凭证历史，便于回溯问题。",{"type":24,"tag":68,"props":2309,"children":2310},{},[2311,2316],{"type":24,"tag":39,"props":2312,"children":2313},{},[2314],{"type":30,"value":2315},"法律要求",{"type":30,"value":2317},"：某些行业（如金融、医疗）可能有更严格的保留要求。",{"type":24,"tag":33,"props":2319,"children":2320},{},[2321],{"type":30,"value":2322},"建议：",{"type":24,"tag":64,"props":2324,"children":2325},{},[2326,2331,2336],{"type":24,"tag":68,"props":2327,"children":2328},{},[2329],{"type":30,"value":2330},"将历史凭证存储在安全的归档系统中，与活跃凭证隔离。",{"type":24,"tag":68,"props":2332,"children":2333},{},[2334],{"type":30,"value":2335},"设置自动清理策略，超过保留期限的凭证自动删除。",{"type":24,"tag":68,"props":2337,"children":2338},{},[2339],{"type":30,"value":2340},"确保归档系统的访问权限严格控制，只有授权人员可以访问。",{"type":24,"tag":25,"props":2342,"children":2344},{"id":2343},"延伸阅读",[2345],{"type":30,"value":2343},{"type":24,"tag":64,"props":2347,"children":2348},{},[2349,2361,2371,2381],{"type":24,"tag":68,"props":2350,"children":2351},{},[2352],{"type":24,"tag":2353,"props":2354,"children":2358},"a",{"href":2355,"rel":2356},"https://csrc.nist.gov/publications/detail/sp/800-57-part-1/rev-5/final",[2357],"nofollow",[2359],{"type":30,"value":2360},"NIST SP 800-57: Recommendation for Key Management",{"type":24,"tag":68,"props":2362,"children":2363},{},[2364],{"type":24,"tag":2353,"props":2365,"children":2368},{"href":2366,"rel":2367},"https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html",[2357],[2369],{"type":30,"value":2370},"OWASP Secret Management Cheat Sheet",{"type":24,"tag":68,"props":2372,"children":2373},{},[2374],{"type":24,"tag":2353,"props":2375,"children":2378},{"href":2376,"rel":2377},"https://docs.aws.amazon.com/secretsmanager/latest/userguide/rotating-secrets.html",[2357],[2379],{"type":30,"value":2380},"AWS Secrets Manager Automatic Rotation",{"type":24,"tag":68,"props":2382,"children":2383},{},[2384],{"type":24,"tag":2353,"props":2385,"children":2388},{"href":2386,"rel":2387},"https://www.vaultproject.io/docs/secrets",[2357],[2389],{"type":30,"value":2390},"HashiCorp Vault Dynamic Secrets",{"type":24,"tag":25,"props":2392,"children":2394},{"id":2393},"checklist",[2395],{"type":30,"value":2396},"Checklist",{"type":24,"tag":33,"props":2398,"children":2399},{},[2400],{"type":30,"value":2401},"在实施 Secret Rotation Policy 之前，请确认以下事项：",{"type":24,"tag":64,"props":2403,"children":2406},{"className":2404},[2405],"contains-task-list",[2407,2420,2429,2438,2447,2456,2465,2474,2483,2492],{"type":24,"tag":68,"props":2408,"children":2411},{"className":2409},[2410],"task-list-item",[2412,2418],{"type":24,"tag":2413,"props":2414,"children":2417},"input",{"disabled":2415,"type":2416},true,"checkbox",[],{"type":30,"value":2419}," 已制定差异化轮换节奏表，覆盖所有凭证类型",{"type":24,"tag":68,"props":2421,"children":2423},{"className":2422},[2410],[2424,2427],{"type":24,"tag":2413,"props":2425,"children":2426},{"disabled":2415,"type":2416},[],{"type":30,"value":2428}," 已选择自动化轮换方案（Vault Agent / AWS Secrets Manager / Cron Job）",{"type":24,"tag":68,"props":2430,"children":2432},{"className":2431},[2410],[2433,2436],{"type":24,"tag":2413,"props":2434,"children":2435},{"disabled":2415,"type":2416},[],{"type":30,"value":2437}," 已实现旧凭证保留期（Grace Period）机制",{"type":24,"tag":68,"props":2439,"children":2441},{"className":2440},[2410],[2442,2445],{"type":24,"tag":2413,"props":2443,"children":2444},{"disabled":2415,"type":2416},[],{"type":30,"value":2446}," 已配置告警规则，轮换失败时立即通知",{"type":24,"tag":68,"props":2448,"children":2450},{"className":2449},[2410],[2451,2454],{"type":24,"tag":2413,"props":2452,"children":2453},{"disabled":2415,"type":2416},[],{"type":30,"value":2455}," 已编写紧急撤销脚本，并进行过演练",{"type":24,"tag":68,"props":2457,"children":2459},{"className":2458},[2410],[2460,2463],{"type":24,"tag":2413,"props":2461,"children":2462},{"disabled":2415,"type":2416},[],{"type":30,"value":2464}," 已设置监控仪表盘，跟踪轮换成功率、凭证年龄等指标",{"type":24,"tag":68,"props":2466,"children":2468},{"className":2467},[2410],[2469,2472],{"type":24,"tag":2413,"props":2470,"children":2471},{"disabled":2415,"type":2416},[],{"type":30,"value":2473}," 已在测试环境充分验证轮换流程",{"type":24,"tag":68,"props":2475,"children":2477},{"className":2476},[2410],[2478,2481],{"type":24,"tag":2413,"props":2479,"children":2480},{"disabled":2415,"type":2416},[],{"type":30,"value":2482}," 已制定轮换失败的手动干预流程",{"type":24,"tag":68,"props":2484,"children":2486},{"className":2485},[2410],[2487,2490],{"type":24,"tag":2413,"props":2488,"children":2489},{"disabled":2415,"type":2416},[],{"type":30,"value":2491}," 已记录历史凭证轮换日志，满足合规要求",{"type":24,"tag":68,"props":2493,"children":2495},{"className":2494},[2410],[2496,2499],{"type":24,"tag":2413,"props":2497,"children":2498},{"disabled":2415,"type":2416},[],{"type":30,"value":2500}," 已组织团队培训，确保所有开发者了解轮换流程",{"type":24,"tag":2502,"props":2503,"children":2504},"hr",{},[],{"type":24,"tag":33,"props":2506,"children":2507},{},[2508,2513,2515,2521],{"type":24,"tag":39,"props":2509,"children":2510},{},[2511],{"type":30,"value":2512},"下一步行动",{"type":30,"value":2514},"：阅读 ",{"type":24,"tag":2353,"props":2516,"children":2518},{"href":2517},"./ai-agent-operation-audit-trail-immutability",[2519],{"type":30,"value":2520},"AI agent Operation Audit Trail",{"type":30,"value":2522},"，了解如何记录每次工具调用、状态变更和人工干预，留下不可篡改的审计日志。",{"title":7,"searchDepth":2524,"depth":2524,"links":2525},3,[2526,2528,2538,2543,2549,2554,2564,2565],{"id":27,"depth":2527,"text":31},2,{"id":112,"depth":2527,"text":112,"children":2529},[2530,2531,2532],{"id":118,"depth":2524,"text":121},{"id":208,"depth":2524,"text":208},{"id":591,"depth":2524,"text":591,"children":2533},[2534,2536,2537],{"id":597,"depth":2535,"text":600},4,{"id":721,"depth":2535,"text":724},{"id":818,"depth":2535,"text":821},{"id":905,"depth":2527,"text":905,"children":2539},[2540,2541,2542],{"id":910,"depth":2524,"text":913},{"id":1024,"depth":2524,"text":1027},{"id":1157,"depth":2524,"text":1160},{"id":1284,"depth":2527,"text":1284,"children":2544},[2545,2546,2547,2548],{"id":1289,"depth":2524,"text":1292},{"id":1381,"depth":2524,"text":1384},{"id":1475,"depth":2524,"text":1478},{"id":1609,"depth":2524,"text":1612},{"id":1695,"depth":2527,"text":1695,"children":2550},[2551,2552,2553],{"id":1700,"depth":2524,"text":1700},{"id":1868,"depth":2524,"text":1868},{"id":1884,"depth":2524,"text":1884},{"id":1900,"depth":2527,"text":1903,"children":2555},[2556,2557,2558,2559,2560,2561,2562,2563],{"id":1906,"depth":2524,"text":1909},{"id":1960,"depth":2524,"text":1963},{"id":2008,"depth":2524,"text":2011},{"id":2074,"depth":2524,"text":2077},{"id":2116,"depth":2524,"text":2119},{"id":2159,"depth":2524,"text":2162},{"id":2216,"depth":2524,"text":2219},{"id":2272,"depth":2524,"text":2275},{"id":2343,"depth":2527,"text":2343},{"id":2393,"depth":2527,"text":2396},"markdown","content:topics:ai:ai-agent-secret-rotation-policy-cadence.md","content","topics/ai/ai-agent-secret-rotation-policy-cadence.md","topics/ai/ai-agent-secret-rotation-policy-cadence","md",[2573,3723,4667],{"_path":2574,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":2575,"description":2576,"date":2577,"topic":5,"author":11,"tags":2578,"image":2584,"imageAlt":2585,"pexelsPhotoId":2586,"pexelsUrl":2587,"readingTime":2588,"body":2589,"_type":2566,"_id":3720,"_source":2568,"_file":3721,"_stem":3722,"_extension":2571},"/topics/ai/cursor-keyboard-shortcuts-cheatsheet","Cursor 快捷键速查表（macOS/Windows）：从“会用”到“能提效”的 10 个工作流","把 Cursor 常用快捷键按任务分组（查代码、改代码、多文件、对话、审查与回滚），给出可直接照抄的工作流与最小回归清单，避免“快捷键背了也没变快”。","2026-03-02",[2579,2580,2581,2582,2583],"Cursor","快捷键","AI IDE","VS Code","开发效率","/images/topics/ai/cursor-keyboard-shortcuts-cheatsheet.jpg","彩色机械键盘与鼠标的工作台面",34563105,"https://www.pexels.com/photo/colorful-mechanical-keyboard-and-mouse-setup-34563105/",12,{"type":21,"children":2590,"toc":3694},[2591,2596,2614,2619,2646,2651,2687,2690,2696,2701,2734,2739,2762,2765,2771,2776,2994,3003,3006,3012,3018,3037,3045,3066,3071,3077,3092,3123,3128,3141,3147,3166,3184,3192,3197,3203,3208,3229,3237,3243,3248,3271,3276,3282,3295,3301,3318,3336,3342,3353,3371,3377,3388,3394,3399,3442,3445,3451,3459,3512,3515,3521,3527,3532,3537,3560,3578,3583,3608,3611,3617,3623,3628,3634,3639,3645,3650,3653,3659],{"type":24,"tag":33,"props":2592,"children":2593},{},[2594],{"type":30,"value":2595},"如果你在搜“Cursor 快捷键”，你大概率不是想背一张表，而是想解决这类问题：",{"type":24,"tag":64,"props":2597,"children":2598},{},[2599,2604,2609],{"type":24,"tag":68,"props":2600,"children":2601},{},[2602],{"type":30,"value":2603},"为什么我用了 AI，还是很慢？（对话来回太多、改动不可控）",{"type":24,"tag":68,"props":2605,"children":2606},{},[2607],{"type":30,"value":2608},"为什么它“看起来懂了”，却改错文件/改出回归？（上下文与范围没锁住）",{"type":24,"tag":68,"props":2610,"children":2611},{},[2612],{"type":30,"value":2613},"多文件改动怎么做得安全？（验收、回滚、最小回归集）",{"type":24,"tag":33,"props":2615,"children":2616},{},[2617],{"type":30,"value":2618},"这篇文章给你两份东西：",{"type":24,"tag":639,"props":2620,"children":2621},{},[2622,2634],{"type":24,"tag":68,"props":2623,"children":2624},{},[2625,2627,2632],{"type":30,"value":2626},"一张",{"type":24,"tag":39,"props":2628,"children":2629},{},[2630],{"type":30,"value":2631},"按任务分组",{"type":30,"value":2633},"的快捷键表（不是按功能堆在一起）",{"type":24,"tag":68,"props":2635,"children":2636},{},[2637,2639,2644],{"type":30,"value":2638},"一套“从需求到落地”的",{"type":24,"tag":39,"props":2640,"children":2641},{},[2642],{"type":30,"value":2643},"最小闭环工作流",{"type":30,"value":2645},"（每一步都有快捷键）",{"type":24,"tag":33,"props":2647,"children":2648},{},[2649],{"type":30,"value":2650},"想看系统玩法：",{"type":24,"tag":64,"props":2652,"children":2653},{},[2654,2665,2676],{"type":24,"tag":68,"props":2655,"children":2656},{},[2657,2659],{"type":30,"value":2658},"入门教程看：",{"type":24,"tag":2353,"props":2660,"children":2662},{"href":2661},"/topics/ai/cursor-tutorial",[2663],{"type":30,"value":2664},"Cursor 使用教程（2026）",{"type":24,"tag":68,"props":2666,"children":2667},{},[2668,2670],{"type":30,"value":2669},"进阶玩法看：",{"type":24,"tag":2353,"props":2671,"children":2673},{"href":2672},"/topics/ai/cursor-editor-guide",[2674],{"type":30,"value":2675},"Cursor 编辑器深度玩法",{"type":24,"tag":68,"props":2677,"children":2678},{},[2679,2681],{"type":30,"value":2680},"规则与忽略看：",{"type":24,"tag":2353,"props":2682,"children":2684},{"href":2683},"/topics/ai/cursor-rules-cursorrules",[2685],{"type":30,"value":2686},"Cursor Rules 与 .cursorrules",{"type":24,"tag":2502,"props":2688,"children":2689},{},[],{"type":24,"tag":25,"props":2691,"children":2693},{"id":2692},"先给结论提效不是按得快而是闭环更短",[2694],{"type":30,"value":2695},"先给结论：提效不是“按得快”，而是“闭环更短”",{"type":24,"tag":33,"props":2697,"children":2698},{},[2699],{"type":30,"value":2700},"你可以把 Cursor 的快捷键理解为 3 条流水线：",{"type":24,"tag":64,"props":2702,"children":2703},{},[2704,2714,2724],{"type":24,"tag":68,"props":2705,"children":2706},{},[2707,2712],{"type":24,"tag":39,"props":2708,"children":2709},{},[2710],{"type":30,"value":2711},"改一小段",{"type":30,"value":2713},"（内联编辑）：把改动限制在一个函数/一段样式",{"type":24,"tag":68,"props":2715,"children":2716},{},[2717,2722],{"type":24,"tag":39,"props":2718,"children":2719},{},[2720],{"type":30,"value":2721},"改一组文件",{"type":30,"value":2723},"（Composer）：把改动限制在一组明确文件，并要求输出 diff + 验收点",{"type":24,"tag":68,"props":2725,"children":2726},{},[2727,2732],{"type":24,"tag":39,"props":2728,"children":2729},{},[2730],{"type":30,"value":2731},"聊清楚再动手",{"type":30,"value":2733},"（侧边对话）：先对齐目标、范围、验收、回滚",{"type":24,"tag":33,"props":2735,"children":2736},{},[2737],{"type":30,"value":2738},"当你觉得“它乱改/改太大”时，往往不是快捷键没记住，而是缺了两件事：",{"type":24,"tag":64,"props":2740,"children":2741},{},[2742,2752],{"type":24,"tag":68,"props":2743,"children":2744},{},[2745,2747],{"type":30,"value":2746},"没有在动手前锁定",{"type":24,"tag":39,"props":2748,"children":2749},{},[2750],{"type":30,"value":2751},"范围",{"type":24,"tag":68,"props":2753,"children":2754},{},[2755,2757],{"type":30,"value":2756},"没有在接受改动前准备",{"type":24,"tag":39,"props":2758,"children":2759},{},[2760],{"type":30,"value":2761},"验收/回滚",{"type":24,"tag":2502,"props":2763,"children":2764},{},[],{"type":24,"tag":25,"props":2766,"children":2768},{"id":2767},"快捷键速查表按任务分组",[2769],{"type":30,"value":2770},"快捷键速查表（按任务分组）",{"type":24,"tag":33,"props":2772,"children":2773},{},[2774],{"type":30,"value":2775},"说明：下表按“你正在做什么”组织，而不是按“功能名字”组织。不同版本快捷键可能略有差异，但核心逻辑一致。",{"type":24,"tag":212,"props":2777,"children":2778},{},[2779,2805],{"type":24,"tag":216,"props":2780,"children":2781},{},[2782],{"type":24,"tag":220,"props":2783,"children":2784},{},[2785,2790,2795,2800],{"type":24,"tag":224,"props":2786,"children":2787},{},[2788],{"type":30,"value":2789},"任务",{"type":24,"tag":224,"props":2791,"children":2792},{},[2793],{"type":30,"value":2794},"macOS",{"type":24,"tag":224,"props":2796,"children":2797},{},[2798],{"type":30,"value":2799},"Windows",{"type":24,"tag":224,"props":2801,"children":2802},{},[2803],{"type":30,"value":2804},"你该在什么时候用",{"type":24,"tag":250,"props":2806,"children":2807},{},[2808,2839,2870,2901,2932,2963],{"type":24,"tag":220,"props":2809,"children":2810},{},[2811,2816,2825,2834],{"type":24,"tag":257,"props":2812,"children":2813},{},[2814],{"type":30,"value":2815},"改一小段（最安全）",{"type":24,"tag":257,"props":2817,"children":2818},{},[2819],{"type":24,"tag":969,"props":2820,"children":2822},{"className":2821},[],[2823],{"type":30,"value":2824},"Cmd + K",{"type":24,"tag":257,"props":2826,"children":2827},{},[2828],{"type":24,"tag":969,"props":2829,"children":2831},{"className":2830},[],[2832],{"type":30,"value":2833},"Ctrl + K",{"type":24,"tag":257,"props":2835,"children":2836},{},[2837],{"type":30,"value":2838},"只想改一个函数/一段 CSS，不想动别的",{"type":24,"tag":220,"props":2840,"children":2841},{},[2842,2847,2856,2865],{"type":24,"tag":257,"props":2843,"children":2844},{},[2845],{"type":30,"value":2846},"打开 AI 对话（先对齐再动手）",{"type":24,"tag":257,"props":2848,"children":2849},{},[2850],{"type":24,"tag":969,"props":2851,"children":2853},{"className":2852},[],[2854],{"type":30,"value":2855},"Cmd + L",{"type":24,"tag":257,"props":2857,"children":2858},{},[2859],{"type":24,"tag":969,"props":2860,"children":2862},{"className":2861},[],[2863],{"type":30,"value":2864},"Ctrl + L",{"type":24,"tag":257,"props":2866,"children":2867},{},[2868],{"type":30,"value":2869},"需要澄清目标、制定步骤、给验收点",{"type":24,"tag":220,"props":2871,"children":2872},{},[2873,2878,2887,2896],{"type":24,"tag":257,"props":2874,"children":2875},{},[2876],{"type":30,"value":2877},"多文件编辑（有组织地改一组文件）",{"type":24,"tag":257,"props":2879,"children":2880},{},[2881],{"type":24,"tag":969,"props":2882,"children":2884},{"className":2883},[],[2885],{"type":30,"value":2886},"Cmd + I",{"type":24,"tag":257,"props":2888,"children":2889},{},[2890],{"type":24,"tag":969,"props":2891,"children":2893},{"className":2892},[],[2894],{"type":30,"value":2895},"Ctrl + I",{"type":24,"tag":257,"props":2897,"children":2898},{},[2899],{"type":30,"value":2900},"改动涉及多个文件：组件+样式+测试",{"type":24,"tag":220,"props":2902,"children":2903},{},[2904,2909,2918,2927],{"type":24,"tag":257,"props":2905,"children":2906},{},[2907],{"type":30,"value":2908},"把选中代码加入对话上下文",{"type":24,"tag":257,"props":2910,"children":2911},{},[2912],{"type":24,"tag":969,"props":2913,"children":2915},{"className":2914},[],[2916],{"type":30,"value":2917},"Cmd + Shift + L",{"type":24,"tag":257,"props":2919,"children":2920},{},[2921],{"type":24,"tag":969,"props":2922,"children":2924},{"className":2923},[],[2925],{"type":30,"value":2926},"Ctrl + Shift + L",{"type":24,"tag":257,"props":2928,"children":2929},{},[2930],{"type":30,"value":2931},"让 AI 只看你选的片段（降低噪音）",{"type":24,"tag":220,"props":2933,"children":2934},{},[2935,2940,2949,2958],{"type":24,"tag":257,"props":2936,"children":2937},{},[2938],{"type":30,"value":2939},"接受当前建议",{"type":24,"tag":257,"props":2941,"children":2942},{},[2943],{"type":24,"tag":969,"props":2944,"children":2946},{"className":2945},[],[2947],{"type":30,"value":2948},"Cmd + Y",{"type":24,"tag":257,"props":2950,"children":2951},{},[2952],{"type":24,"tag":969,"props":2953,"children":2955},{"className":2954},[],[2956],{"type":30,"value":2957},"Ctrl + Y",{"type":24,"tag":257,"props":2959,"children":2960},{},[2961],{"type":30,"value":2962},"你已经准备好验收/回滚，并确认改动范围",{"type":24,"tag":220,"props":2964,"children":2965},{},[2966,2971,2980,2989],{"type":24,"tag":257,"props":2967,"children":2968},{},[2969],{"type":30,"value":2970},"拒绝当前建议",{"type":24,"tag":257,"props":2972,"children":2973},{},[2974],{"type":24,"tag":969,"props":2975,"children":2977},{"className":2976},[],[2978],{"type":30,"value":2979},"Cmd + N",{"type":24,"tag":257,"props":2981,"children":2982},{},[2983],{"type":24,"tag":969,"props":2984,"children":2986},{"className":2985},[],[2987],{"type":30,"value":2988},"Ctrl + N",{"type":24,"tag":257,"props":2990,"children":2991},{},[2992],{"type":30,"value":2993},"改得太大、改错方向，立刻收手",{"type":24,"tag":2995,"props":2996,"children":2997},"blockquote",{},[2998],{"type":24,"tag":33,"props":2999,"children":3000},{},[3001],{"type":30,"value":3002},"小技巧：把“改一小段”当默认路径。只有当你能清晰写出“会改哪几类文件、怎么验收”时再进入多文件。",{"type":24,"tag":2502,"props":3004,"children":3005},{},[],{"type":24,"tag":25,"props":3007,"children":3009},{"id":3008},"_10-个可直接照抄的提效工作流每个都能闭环",[3010],{"type":30,"value":3011},"10 个可直接照抄的提效工作流（每个都能闭环）",{"type":24,"tag":116,"props":3013,"children":3015},{"id":3014},"工作流-1需求计划小步改新手最稳",[3016],{"type":30,"value":3017},"工作流 1：需求→计划→小步改（新手最稳）",{"type":24,"tag":639,"props":3019,"children":3020},{},[3021,3032],{"type":24,"tag":68,"props":3022,"children":3023},{},[3024,3030],{"type":24,"tag":969,"props":3025,"children":3027},{"className":3026},[],[3028],{"type":30,"value":3029},"Cmd/Ctrl + L",{"type":30,"value":3031}," 打开对话",{"type":24,"tag":68,"props":3033,"children":3034},{},[3035],{"type":30,"value":3036},"先发这段（可复制）：",{"type":24,"tag":2995,"props":3038,"children":3039},{},[3040],{"type":24,"tag":33,"props":3041,"children":3042},{},[3043],{"type":30,"value":3044},"目标：……\n范围：只修改以下文件/模块：……\n非目标：……（明确不做）\n验收：……（可测试/可手动检查）\n输出格式：先给计划，再逐步执行；每一步写出 diff 摘要。",{"type":24,"tag":639,"props":3046,"children":3047},{"start":2524},[3048,3053],{"type":24,"tag":68,"props":3049,"children":3050},{},[3051],{"type":30,"value":3052},"让 AI 先给“计划（3~6 步）”，你确认后再执行",{"type":24,"tag":68,"props":3054,"children":3055},{},[3056,3058,3064],{"type":30,"value":3057},"任何一步涉及改代码：优先回到编辑区，选中片段用 ",{"type":24,"tag":969,"props":3059,"children":3061},{"className":3060},[],[3062],{"type":30,"value":3063},"Cmd/Ctrl + K",{"type":30,"value":3065}," 小步改",{"type":24,"tag":33,"props":3067,"children":3068},{},[3069],{"type":30,"value":3070},"为什么有效：你把“想法”变成了“可执行约束”，这就是 GEO（面向 AI/模型的可理解结构）。",{"type":24,"tag":116,"props":3072,"children":3074},{"id":3073},"工作流-2只改一个函数高频低风险",[3075],{"type":30,"value":3076},"工作流 2：只改一个函数（高频、低风险）",{"type":24,"tag":64,"props":3078,"children":3079},{},[3080],{"type":24,"tag":68,"props":3081,"children":3082},{},[3083,3085,3090],{"type":30,"value":3084},"选中函数 → ",{"type":24,"tag":969,"props":3086,"children":3088},{"className":3087},[],[3089],{"type":30,"value":3063},{"type":30,"value":3091}," → 输入指令：",{"type":24,"tag":2995,"props":3093,"children":3094},{},[3095,3100],{"type":24,"tag":33,"props":3096,"children":3097},{},[3098],{"type":30,"value":3099},"把这段改成更可读：",{"type":24,"tag":64,"props":3101,"children":3102},{},[3103,3108,3113,3118],{"type":24,"tag":68,"props":3104,"children":3105},{},[3106],{"type":30,"value":3107},"用 async/await",{"type":24,"tag":68,"props":3109,"children":3110},{},[3111],{"type":30,"value":3112},"错误处理不要吞掉",{"type":24,"tag":68,"props":3114,"children":3115},{},[3116],{"type":30,"value":3117},"添加类型（若可推断）",{"type":24,"tag":68,"props":3119,"children":3120},{},[3121],{"type":30,"value":3122},"不要改函数签名",{"type":24,"tag":33,"props":3124,"children":3125},{},[3126],{"type":30,"value":3127},"验收方式（强制）：",{"type":24,"tag":64,"props":3129,"children":3130},{},[3131,3136],{"type":24,"tag":68,"props":3132,"children":3133},{},[3134],{"type":30,"value":3135},"输出前后函数行为一致（输入/输出）",{"type":24,"tag":68,"props":3137,"children":3138},{},[3139],{"type":30,"value":3140},"失败分支有可观测日志（不要悄悄 return null）",{"type":24,"tag":116,"props":3142,"children":3144},{"id":3143},"工作流-3多文件改动先定文件清单",[3145],{"type":30,"value":3146},"工作流 3：多文件改动（先定“文件清单”）",{"type":24,"tag":639,"props":3148,"children":3149},{},[3150,3161],{"type":24,"tag":68,"props":3151,"children":3152},{},[3153,3159],{"type":24,"tag":969,"props":3154,"children":3156},{"className":3155},[],[3157],{"type":30,"value":3158},"Cmd/Ctrl + I",{"type":30,"value":3160}," 进入多文件",{"type":24,"tag":68,"props":3162,"children":3163},{},[3164],{"type":30,"value":3165},"先让 AI 输出：",{"type":24,"tag":64,"props":3167,"children":3168},{},[3169,3174,3179],{"type":24,"tag":68,"props":3170,"children":3171},{},[3172],{"type":30,"value":3173},"预计会改哪些文件（最多 5 个）",{"type":24,"tag":68,"props":3175,"children":3176},{},[3177],{"type":30,"value":3178},"每个文件改什么",{"type":24,"tag":68,"props":3180,"children":3181},{},[3182],{"type":30,"value":3183},"每一步怎么验收",{"type":24,"tag":639,"props":3185,"children":3186},{"start":2524},[3187],{"type":24,"tag":68,"props":3188,"children":3189},{},[3190],{"type":30,"value":3191},"你确认文件清单后再开始生成改动",{"type":24,"tag":33,"props":3193,"children":3194},{},[3195],{"type":30,"value":3196},"关键点：多文件最容易翻车的是“它把你没想到的文件也改了”。所以文件清单是第一道闸门。",{"type":24,"tag":116,"props":3198,"children":3200},{"id":3199},"工作流-4把上下文噪音砍掉防跑偏",[3201],{"type":30,"value":3202},"工作流 4：把“上下文噪音”砍掉（防跑偏）",{"type":24,"tag":33,"props":3204,"children":3205},{},[3206],{"type":30,"value":3207},"当你怀疑它在胡说/乱改时：",{"type":24,"tag":64,"props":3209,"children":3210},{},[3211,3224],{"type":24,"tag":68,"props":3212,"children":3213},{},[3214,3216,3222],{"type":30,"value":3215},"只选择关键代码片段 → ",{"type":24,"tag":969,"props":3217,"children":3219},{"className":3218},[],[3220],{"type":30,"value":3221},"Cmd/Ctrl + Shift + L",{"type":30,"value":3223}," 加入对话",{"type":24,"tag":68,"props":3225,"children":3226},{},[3227],{"type":30,"value":3228},"然后在对话里要求：",{"type":24,"tag":2995,"props":3230,"children":3231},{},[3232],{"type":24,"tag":33,"props":3233,"children":3234},{},[3235],{"type":30,"value":3236},"只基于我提供的代码片段回答，不要假设其它文件存在。",{"type":24,"tag":116,"props":3238,"children":3240},{"id":3239},"工作流-5生成变更说明让-code-review-变快",[3241],{"type":30,"value":3242},"工作流 5：生成变更说明（让 code review 变快）",{"type":24,"tag":33,"props":3244,"children":3245},{},[3246],{"type":30,"value":3247},"改完后在对话里让它输出：",{"type":24,"tag":64,"props":3249,"children":3250},{},[3251,3256,3261,3266],{"type":24,"tag":68,"props":3252,"children":3253},{},[3254],{"type":30,"value":3255},"改动摘要（3~7 条）",{"type":24,"tag":68,"props":3257,"children":3258},{},[3259],{"type":30,"value":3260},"风险点（依赖/边界条件）",{"type":24,"tag":68,"props":3262,"children":3263},{},[3264],{"type":30,"value":3265},"回滚方式",{"type":24,"tag":68,"props":3267,"children":3268},{},[3269],{"type":30,"value":3270},"验收步骤",{"type":24,"tag":33,"props":3272,"children":3273},{},[3274],{"type":30,"value":3275},"这套结构能直接贴进 PR 描述。",{"type":24,"tag":116,"props":3277,"children":3279},{"id":3278},"工作流-6写最小回归集不写回归-等事故",[3280],{"type":30,"value":3281},"工作流 6：写“最小回归集”（不写回归 = 等事故）",{"type":24,"tag":33,"props":3283,"children":3284},{},[3285,3287,3293],{"type":30,"value":3286},"每次改动都至少做 10 条最小回归（见下文清单）。你可以把它写在 ",{"type":24,"tag":969,"props":3288,"children":3290},{"className":3289},[],[3291],{"type":30,"value":3292},"README",{"type":30,"value":3294}," 或团队 wiki。",{"type":24,"tag":116,"props":3296,"children":3298},{"id":3297},"工作流-7把接受建议变成最后一步",[3299],{"type":30,"value":3300},"工作流 7：把“接受建议”变成最后一步",{"type":24,"tag":33,"props":3302,"children":3303},{},[3304,3310,3312,3317],{"type":24,"tag":969,"props":3305,"children":3307},{"className":3306},[],[3308],{"type":30,"value":3309},"Cmd/Ctrl + Y",{"type":30,"value":3311}," 应该是",{"type":24,"tag":39,"props":3313,"children":3314},{},[3315],{"type":30,"value":3316},"最后一步",{"type":30,"value":610},{"type":24,"tag":64,"props":3319,"children":3320},{},[3321,3326,3331],{"type":24,"tag":68,"props":3322,"children":3323},{},[3324],{"type":30,"value":3325},"你已经看过 diff",{"type":24,"tag":68,"props":3327,"children":3328},{},[3329],{"type":30,"value":3330},"你能说清楚“怎么验收”",{"type":24,"tag":68,"props":3332,"children":3333},{},[3334],{"type":30,"value":3335},"你知道“怎么回滚”",{"type":24,"tag":116,"props":3337,"children":3339},{"id":3338},"工作流-8拒绝建议不是失败是风控动作",[3340],{"type":30,"value":3341},"工作流 8：拒绝建议不是失败，是风控动作",{"type":24,"tag":33,"props":3343,"children":3344},{},[3345,3351],{"type":24,"tag":969,"props":3346,"children":3348},{"className":3347},[],[3349],{"type":30,"value":3350},"Cmd/Ctrl + N",{"type":30,"value":3352}," 的使用时机：",{"type":24,"tag":64,"props":3354,"children":3355},{},[3356,3361,3366],{"type":24,"tag":68,"props":3357,"children":3358},{},[3359],{"type":30,"value":3360},"它开始改你没提过的东西（范围漂移）",{"type":24,"tag":68,"props":3362,"children":3363},{},[3364],{"type":30,"value":3365},"它改了 10 个文件但你只想改 1 个",{"type":24,"tag":68,"props":3367,"children":3368},{},[3369],{"type":30,"value":3370},"它为了“更优雅”引入新依赖/新抽象",{"type":24,"tag":116,"props":3372,"children":3374},{"id":3373},"工作流-9重复任务做成模板提示词不是一次性",[3375],{"type":30,"value":3376},"工作流 9：重复任务做成模板（提示词不是一次性）",{"type":24,"tag":33,"props":3378,"children":3379},{},[3380,3382,3386],{"type":30,"value":3381},"把高频任务（比如“写组件+样式+验收”）固化成模板，放进 Rules（见：",{"type":24,"tag":2353,"props":3383,"children":3384},{"href":2683},[3385],{"type":30,"value":2686},{"type":30,"value":3387},"）。",{"type":24,"tag":116,"props":3389,"children":3391},{"id":3390},"工作流-10把快捷键表做成你自己的任务表",[3392],{"type":30,"value":3393},"工作流 10：把“快捷键表”做成你自己的任务表",{"type":24,"tag":33,"props":3395,"children":3396},{},[3397],{"type":30,"value":3398},"你不需要记住所有快捷键，只需要记住：",{"type":24,"tag":64,"props":3400,"children":3401},{},[3402,3412,3422,3432],{"type":24,"tag":68,"props":3403,"children":3404},{},[3405,3407],{"type":30,"value":3406},"小步改：",{"type":24,"tag":969,"props":3408,"children":3410},{"className":3409},[],[3411],{"type":30,"value":3063},{"type":24,"tag":68,"props":3413,"children":3414},{},[3415,3417],{"type":30,"value":3416},"先对齐：",{"type":24,"tag":969,"props":3418,"children":3420},{"className":3419},[],[3421],{"type":30,"value":3029},{"type":24,"tag":68,"props":3423,"children":3424},{},[3425,3427],{"type":30,"value":3426},"多文件：",{"type":24,"tag":969,"props":3428,"children":3430},{"className":3429},[],[3431],{"type":30,"value":3158},{"type":24,"tag":68,"props":3433,"children":3434},{},[3435,3437],{"type":30,"value":3436},"上下文聚焦：",{"type":24,"tag":969,"props":3438,"children":3440},{"className":3439},[],[3441],{"type":30,"value":3221},{"type":24,"tag":2502,"props":3443,"children":3444},{},[],{"type":24,"tag":25,"props":3446,"children":3448},{"id":3447},"必交付物-1最小回归任务清单10-条通用",[3449],{"type":30,"value":3450},"必交付物 1：最小回归任务清单（10 条，通用）",{"type":24,"tag":2995,"props":3452,"children":3453},{},[3454],{"type":24,"tag":33,"props":3455,"children":3456},{},[3457],{"type":30,"value":3458},"这份清单的意义：让每次 AI 改动都能“被验证”。否则你只是把不可控变成了更快的不可控。",{"type":24,"tag":639,"props":3460,"children":3461},{},[3462,3467,3472,3477,3482,3487,3492,3497,3502,3507],{"type":24,"tag":68,"props":3463,"children":3464},{},[3465],{"type":30,"value":3466},"关键路径能跑通（手动点击/请求一次）",{"type":24,"tag":68,"props":3468,"children":3469},{},[3470],{"type":30,"value":3471},"错误路径能触发（模拟一次失败输入）",{"type":24,"tag":68,"props":3473,"children":3474},{},[3475],{"type":30,"value":3476},"控制台无新增错误（至少关注 1 次真实操作）",{"type":24,"tag":68,"props":3478,"children":3479},{},[3480],{"type":30,"value":3481},"关键 UI 未错位（移动端/桌面端各看一眼）",{"type":24,"tag":68,"props":3483,"children":3484},{},[3485],{"type":30,"value":3486},"刷新后状态正确（尤其是表单/列表）",{"type":24,"tag":68,"props":3488,"children":3489},{},[3490],{"type":30,"value":3491},"路由跳转没断（从入口到目标页）",{"type":24,"tag":68,"props":3493,"children":3494},{},[3495],{"type":30,"value":3496},"相关接口未改变契约（字段名/类型）",{"type":24,"tag":68,"props":3498,"children":3499},{},[3500],{"type":30,"value":3501},"性能没有明显退化（首屏、交互卡顿）",{"type":24,"tag":68,"props":3503,"children":3504},{},[3505],{"type":30,"value":3506},"回滚方案可执行（知道回滚哪几个文件/commit）",{"type":24,"tag":68,"props":3508,"children":3509},{},[3510],{"type":30,"value":3511},"写下“这次改动解决了什么、风险是什么”（可贴 PR）",{"type":24,"tag":2502,"props":3513,"children":3514},{},[],{"type":24,"tag":25,"props":3516,"children":3518},{"id":3517},"必交付物-2失败案例复盘真实会发生",[3519],{"type":30,"value":3520},"必交付物 2：失败案例复盘（真实会发生）",{"type":24,"tag":116,"props":3522,"children":3524},{"id":3523},"现象快捷键用得很熟但交付还是慢",[3525],{"type":30,"value":3526},"现象：快捷键用得很熟，但交付还是慢",{"type":24,"tag":33,"props":3528,"children":3529},{},[3530],{"type":30,"value":3531},"典型原因：你把 Cursor 当成“更聪明的搜索框”，不断对话，直到它给出你想要的答案。",{"type":24,"tag":33,"props":3533,"children":3534},{},[3535],{"type":30,"value":3536},"复现路径：",{"type":24,"tag":64,"props":3538,"children":3539},{},[3540,3545,3550,3555],{"type":24,"tag":68,"props":3541,"children":3542},{},[3543],{"type":30,"value":3544},"你直接说“把页面做得更好看、更高级”",{"type":24,"tag":68,"props":3546,"children":3547},{},[3548],{"type":30,"value":3549},"AI 开始大改样式、抽象组件、甚至引入新依赖",{"type":24,"tag":68,"props":3551,"children":3552},{},[3553],{"type":30,"value":3554},"你为了省事按了“接受建议”",{"type":24,"tag":68,"props":3556,"children":3557},{},[3558],{"type":30,"value":3559},"最后发现：设计没统一、移动端崩、甚至埋了性能问题",{"type":24,"tag":33,"props":3561,"children":3562},{},[3563,3565,3569,3571,3576],{"type":30,"value":3564},"根因：缺少",{"type":24,"tag":39,"props":3566,"children":3567},{},[3568],{"type":30,"value":2751},{"type":30,"value":3570},"与",{"type":24,"tag":39,"props":3572,"children":3573},{},[3574],{"type":30,"value":3575},"验收",{"type":30,"value":3577},"。",{"type":24,"tag":33,"props":3579,"children":3580},{},[3581],{"type":30,"value":3582},"修复方式（可照抄）：",{"type":24,"tag":64,"props":3584,"children":3585},{},[3586,3591,3603],{"type":24,"tag":68,"props":3587,"children":3588},{},[3589],{"type":30,"value":3590},"把需求拆成 3 个可验证目标：例如“按钮样式统一”“首屏 CTA 更明显”“移动端间距不挤”",{"type":24,"tag":68,"props":3592,"children":3593},{},[3594,3596,3601],{"type":30,"value":3595},"每个目标只用 ",{"type":24,"tag":969,"props":3597,"children":3599},{"className":3598},[],[3600],{"type":30,"value":3063},{"type":30,"value":3602}," 改一个局部",{"type":24,"tag":68,"props":3604,"children":3605},{},[3606],{"type":30,"value":3607},"每次接受建议前跑一遍“最小回归集”",{"type":24,"tag":2502,"props":3609,"children":3610},{},[],{"type":24,"tag":25,"props":3612,"children":3614},{"id":3613},"faq高频问题",[3615],{"type":30,"value":3616},"FAQ（高频问题）",{"type":24,"tag":116,"props":3618,"children":3620},{"id":3619},"q1我应该先记快捷键还是先学工作流",[3621],{"type":30,"value":3622},"Q1：我应该先记快捷键还是先学工作流？",{"type":24,"tag":33,"props":3624,"children":3625},{},[3626],{"type":30,"value":3627},"先学工作流。快捷键只是把工作流的步骤变短。",{"type":24,"tag":116,"props":3629,"children":3631},{"id":3630},"q2为什么我一用多文件就容易翻车",[3632],{"type":30,"value":3633},"Q2：为什么我一用多文件就容易翻车？",{"type":24,"tag":33,"props":3635,"children":3636},{},[3637],{"type":30,"value":3638},"因为多文件意味着范围更大、依赖更多、验收更难。先锁定“文件清单 + 每步验收”，再让它动手。",{"type":24,"tag":116,"props":3640,"children":3642},{"id":3641},"q3有没有万能提示词",[3643],{"type":30,"value":3644},"Q3：有没有“万能提示词”？",{"type":24,"tag":33,"props":3646,"children":3647},{},[3648],{"type":30,"value":3649},"没有，但有“万能结构”：目标、范围、非目标、验收、输出格式。",{"type":24,"tag":2502,"props":3651,"children":3652},{},[],{"type":24,"tag":25,"props":3654,"children":3656},{"id":3655},"延伸阅读建议按顺序",[3657],{"type":30,"value":3658},"延伸阅读（建议按顺序）",{"type":24,"tag":64,"props":3660,"children":3661},{},[3662,3669,3676,3683],{"type":24,"tag":68,"props":3663,"children":3664},{},[3665],{"type":24,"tag":2353,"props":3666,"children":3667},{"href":2661},[3668],{"type":30,"value":2664},{"type":24,"tag":68,"props":3670,"children":3671},{},[3672],{"type":24,"tag":2353,"props":3673,"children":3674},{"href":2672},[3675],{"type":30,"value":2675},{"type":24,"tag":68,"props":3677,"children":3678},{},[3679],{"type":24,"tag":2353,"props":3680,"children":3681},{"href":2683},[3682],{"type":30,"value":2686},{"type":24,"tag":68,"props":3684,"children":3685},{},[3686,3688],{"type":30,"value":3687},"如果你更关心“网页制作落地”：看这篇 ",{"type":24,"tag":2353,"props":3689,"children":3691},{"href":3690},"/topics/practical-tips/htmlpage-quick-landing-page",[3692],{"type":30,"value":3693},"3 分钟用 HTMLPAGE 做落地页",{"title":7,"searchDepth":2524,"depth":2524,"links":3695},[3696,3697,3698,3710,3711,3714,3719],{"id":2692,"depth":2527,"text":2695},{"id":2767,"depth":2527,"text":2770},{"id":3008,"depth":2527,"text":3011,"children":3699},[3700,3701,3702,3703,3704,3705,3706,3707,3708,3709],{"id":3014,"depth":2524,"text":3017},{"id":3073,"depth":2524,"text":3076},{"id":3143,"depth":2524,"text":3146},{"id":3199,"depth":2524,"text":3202},{"id":3239,"depth":2524,"text":3242},{"id":3278,"depth":2524,"text":3281},{"id":3297,"depth":2524,"text":3300},{"id":3338,"depth":2524,"text":3341},{"id":3373,"depth":2524,"text":3376},{"id":3390,"depth":2524,"text":3393},{"id":3447,"depth":2527,"text":3450},{"id":3517,"depth":2527,"text":3520,"children":3712},[3713],{"id":3523,"depth":2524,"text":3526},{"id":3613,"depth":2527,"text":3616,"children":3715},[3716,3717,3718],{"id":3619,"depth":2524,"text":3622},{"id":3630,"depth":2524,"text":3633},{"id":3641,"depth":2524,"text":3644},{"id":3655,"depth":2527,"text":3658},"content:topics:ai:cursor-keyboard-shortcuts-cheatsheet.md","topics/ai/cursor-keyboard-shortcuts-cheatsheet.md","topics/ai/cursor-keyboard-shortcuts-cheatsheet",{"_path":3724,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":3725,"description":3726,"date":3727,"topic":5,"author":11,"tags":3728,"image":3732,"imageAlt":3733,"pexelsPhotoId":3734,"pexelsUrl":3735,"readingTime":3736,"body":3737,"_type":2566,"_id":4664,"_source":2568,"_file":4665,"_stem":4666,"_extension":2571},"/topics/ai/cursor-vs-copilot-vscode-workflow","Cursor vs GitHub Copilot vs VS Code：怎么选、怎么搭配、怎么把风险关在笼子里","用“任务类型×风险×验收成本”的选择矩阵解释 Cursor/Copilot/VS Code 的差异，并给出一套可落地的协作工作流（范围闸门、最小回归集、回滚策略）。","2026-03-01",[2579,3729,2582,3730,3731],"GitHub Copilot","AI 编程","工作流","/images/topics/ai/cursor-vs-copilot-vscode-workflow.jpg","团队在电脑前进行协作讨论",1181371,"https://www.pexels.com/photo/man-wearing-blue-dress-shirt-1181371/",15,{"type":21,"children":3738,"toc":4642},[3739,3744,3749,3767,3772,3790,3793,3799,3804,3835,3840,3843,3849,3857,4058,4066,4079,4082,4088,4094,4107,4112,4125,4131,4136,4169,4175,4180,4198,4201,4207,4212,4218,4223,4256,4262,4275,4280,4293,4299,4311,4317,4322,4335,4340,4343,4349,4354,4475,4478,4484,4494,4503,4521,4530,4538,4547,4565,4568,4572,4578,4583,4589,4594,4597,4601],{"type":24,"tag":33,"props":3740,"children":3741},{},[3742],{"type":30,"value":3743},"“Cursor 和 Copilot 到底有什么区别？”",{"type":24,"tag":33,"props":3745,"children":3746},{},[3747],{"type":30,"value":3748},"这个问题问得越早越好，因为你一旦把工具选错，后面所有痛苦都不是“提示词不够好”，而是：",{"type":24,"tag":64,"props":3750,"children":3751},{},[3752,3757,3762],{"type":24,"tag":68,"props":3753,"children":3754},{},[3755],{"type":30,"value":3756},"改动不可控（范围漂移、改错文件）",{"type":24,"tag":68,"props":3758,"children":3759},{},[3760],{"type":30,"value":3761},"验收成本爆炸（不知道要测什么）",{"type":24,"tag":68,"props":3763,"children":3764},{},[3765],{"type":30,"value":3766},"团队协作崩盘（没有闸门、没有回滚）",{"type":24,"tag":33,"props":3768,"children":3769},{},[3770],{"type":30,"value":3771},"这篇文章用一张选择矩阵 + 一套可执行工作流，帮你做到两件事：",{"type":24,"tag":639,"props":3773,"children":3774},{},[3775,3780],{"type":24,"tag":68,"props":3776,"children":3777},{},[3778],{"type":30,"value":3779},"知道什么时候用 Cursor、什么时候用 Copilot、什么时候“纯 VS Code 更快”",{"type":24,"tag":68,"props":3781,"children":3782},{},[3783,3785],{"type":30,"value":3784},"就算用 AI，也能把风险关在笼子里：",{"type":24,"tag":39,"props":3786,"children":3787},{},[3788],{"type":30,"value":3789},"可审查、可验证、可回滚",{"type":24,"tag":2502,"props":3791,"children":3792},{},[],{"type":24,"tag":25,"props":3794,"children":3796},{"id":3795},"结论先说三者不是互斥而是分工",[3797],{"type":30,"value":3798},"结论先说：三者不是互斥，而是分工",{"type":24,"tag":33,"props":3800,"children":3801},{},[3802],{"type":30,"value":3803},"你可以把它们看成三层能力：",{"type":24,"tag":64,"props":3805,"children":3806},{},[3807,3816,3826],{"type":24,"tag":68,"props":3808,"children":3809},{},[3810,3814],{"type":24,"tag":39,"props":3811,"children":3812},{},[3813],{"type":30,"value":2582},{"type":30,"value":3815},"：编辑器与生态（调试、插件、任务、终端、语言服务）",{"type":24,"tag":68,"props":3817,"children":3818},{},[3819,3824],{"type":24,"tag":39,"props":3820,"children":3821},{},[3822],{"type":30,"value":3823},"Copilot",{"type":30,"value":3825},"：代码补全与局部建议（“我正在写这一行/这一段”）",{"type":24,"tag":68,"props":3827,"children":3828},{},[3829,3833],{"type":24,"tag":39,"props":3830,"children":3831},{},[3832],{"type":30,"value":2579},{"type":30,"value":3834},"：以项目为单位的 AI 协作（对话、索引、多文件编辑、规则）",{"type":24,"tag":33,"props":3836,"children":3837},{},[3838],{"type":30,"value":3839},"最常见的误区是：把“局部补全能力”当作“能做架构与多文件落地”。",{"type":24,"tag":2502,"props":3841,"children":3842},{},[],{"type":24,"tag":25,"props":3844,"children":3846},{"id":3845},"选择矩阵按任务类型选工具不是按偏好",[3847],{"type":30,"value":3848},"选择矩阵：按任务类型选工具（不是按偏好）",{"type":24,"tag":2995,"props":3850,"children":3851},{},[3852],{"type":24,"tag":33,"props":3853,"children":3854},{},[3855],{"type":30,"value":3856},"你只要把自己的任务放进表格，就能得到推荐路径。",{"type":24,"tag":212,"props":3858,"children":3859},{},[3860,3892],{"type":24,"tag":216,"props":3861,"children":3862},{},[3863],{"type":24,"tag":220,"props":3864,"children":3865},{},[3866,3871,3877,3882,3887],{"type":24,"tag":224,"props":3867,"children":3868},{},[3869],{"type":30,"value":3870},"任务类型",{"type":24,"tag":224,"props":3872,"children":3874},{"align":3873},"right",[3875],{"type":30,"value":3876},"风险",{"type":24,"tag":224,"props":3878,"children":3879},{"align":3873},[3880],{"type":30,"value":3881},"验收成本",{"type":24,"tag":224,"props":3883,"children":3884},{},[3885],{"type":30,"value":3886},"更推荐",{"type":24,"tag":224,"props":3888,"children":3889},{},[3890],{"type":30,"value":3891},"为什么",{"type":24,"tag":250,"props":3893,"children":3894},{},[3895,3921,3953,3979,4005,4032],{"type":24,"tag":220,"props":3896,"children":3897},{},[3898,3903,3907,3911,3916],{"type":24,"tag":257,"props":3899,"children":3900},{},[3901],{"type":30,"value":3902},"写一段代码/补一个 if",{"type":24,"tag":257,"props":3904,"children":3905},{"align":3873},[3906],{"type":30,"value":482},{"type":24,"tag":257,"props":3908,"children":3909},{"align":3873},[3910],{"type":30,"value":482},{"type":24,"tag":257,"props":3912,"children":3913},{},[3914],{"type":30,"value":3915},"Copilot / Cursor 内联编辑",{"type":24,"tag":257,"props":3917,"children":3918},{},[3919],{"type":30,"value":3920},"局部建议足够，成本最低",{"type":24,"tag":220,"props":3922,"children":3923},{},[3924,3929,3933,3937,3948],{"type":24,"tag":257,"props":3925,"children":3926},{},[3927],{"type":30,"value":3928},"重构一个函数",{"type":24,"tag":257,"props":3930,"children":3931},{"align":3873},[3932],{"type":30,"value":279},{"type":24,"tag":257,"props":3934,"children":3935},{"align":3873},[3936],{"type":30,"value":279},{"type":24,"tag":257,"props":3938,"children":3939},{},[3940,3942],{"type":30,"value":3941},"Cursor ",{"type":24,"tag":969,"props":3943,"children":3945},{"className":3944},[],[3946],{"type":30,"value":3947},"内联编辑",{"type":24,"tag":257,"props":3949,"children":3950},{},[3951],{"type":30,"value":3952},"需要解释、需要约束输出",{"type":24,"tag":220,"props":3954,"children":3955},{},[3956,3961,3965,3969,3974],{"type":24,"tag":257,"props":3957,"children":3958},{},[3959],{"type":30,"value":3960},"改一个组件 + 样式",{"type":24,"tag":257,"props":3962,"children":3963},{"align":3873},[3964],{"type":30,"value":279},{"type":24,"tag":257,"props":3966,"children":3967},{"align":3873},[3968],{"type":30,"value":279},{"type":24,"tag":257,"props":3970,"children":3971},{},[3972],{"type":30,"value":3973},"Cursor（小范围多文件）",{"type":24,"tag":257,"props":3975,"children":3976},{},[3977],{"type":30,"value":3978},"需要同时改模板与样式",{"type":24,"tag":220,"props":3980,"children":3981},{},[3982,3987,3991,3995,4000],{"type":24,"tag":257,"props":3983,"children":3984},{},[3985],{"type":30,"value":3986},"改 3~5 个文件（组件+api+测试）",{"type":24,"tag":257,"props":3988,"children":3989},{"align":3873},[3990],{"type":30,"value":310},{"type":24,"tag":257,"props":3992,"children":3993},{"align":3873},[3994],{"type":30,"value":310},{"type":24,"tag":257,"props":3996,"children":3997},{},[3998],{"type":30,"value":3999},"Cursor Composer + 闸门",{"type":24,"tag":257,"props":4001,"children":4002},{},[4003],{"type":30,"value":4004},"需要计划、验收、回滚",{"type":24,"tag":220,"props":4006,"children":4007},{},[4008,4013,4018,4022,4027],{"type":24,"tag":257,"props":4009,"children":4010},{},[4011],{"type":30,"value":4012},"重写一段架构/引入新依赖",{"type":24,"tag":257,"props":4014,"children":4015},{"align":3873},[4016],{"type":30,"value":4017},"很高",{"type":24,"tag":257,"props":4019,"children":4020},{"align":3873},[4021],{"type":30,"value":4017},{"type":24,"tag":257,"props":4023,"children":4024},{},[4025],{"type":30,"value":4026},"先人脑设计 + VS Code 实现",{"type":24,"tag":257,"props":4028,"children":4029},{},[4030],{"type":30,"value":4031},"AI 易发散，最好先设计再执行",{"type":24,"tag":220,"props":4033,"children":4034},{},[4035,4040,4044,4048,4053],{"type":24,"tag":257,"props":4036,"children":4037},{},[4038],{"type":30,"value":4039},"排查线上问题/性能抖动",{"type":24,"tag":257,"props":4041,"children":4042},{"align":3873},[4043],{"type":30,"value":310},{"type":24,"tag":257,"props":4045,"children":4046},{"align":3873},[4047],{"type":30,"value":4017},{"type":24,"tag":257,"props":4049,"children":4050},{},[4051],{"type":30,"value":4052},"VS Code + 工具链优先，AI 辅助归纳",{"type":24,"tag":257,"props":4054,"children":4055},{},[4056],{"type":30,"value":4057},"需要证据，不要“猜”",{"type":24,"tag":33,"props":4059,"children":4060},{},[4061],{"type":24,"tag":39,"props":4062,"children":4063},{},[4064],{"type":30,"value":4065},"一句话规则：",{"type":24,"tag":64,"props":4067,"children":4068},{},[4069,4074],{"type":24,"tag":68,"props":4070,"children":4071},{},[4072],{"type":30,"value":4073},"当你的改动可以用“10 条最小回归集”覆盖时，用 Cursor。",{"type":24,"tag":68,"props":4075,"children":4076},{},[4077],{"type":30,"value":4078},"当你的改动无法验证时，先别让 AI 动手。",{"type":24,"tag":2502,"props":4080,"children":4081},{},[],{"type":24,"tag":25,"props":4083,"children":4085},{"id":4084},"差异拆解到底差在哪里",[4086],{"type":30,"value":4087},"差异拆解：到底差在哪里？",{"type":24,"tag":116,"props":4089,"children":4091},{"id":4090},"_1-上下文来源补全-vs-项目索引",[4092],{"type":30,"value":4093},"1) 上下文来源：补全 vs 项目索引",{"type":24,"tag":64,"props":4095,"children":4096},{},[4097,4102],{"type":24,"tag":68,"props":4098,"children":4099},{},[4100],{"type":30,"value":4101},"Copilot 更擅长：你正在写的这几行、当前文件的局部上下文",{"type":24,"tag":68,"props":4103,"children":4104},{},[4105],{"type":30,"value":4106},"Cursor 更擅长：项目级索引 + 多文件关联理解",{"type":24,"tag":33,"props":4108,"children":4109},{},[4110],{"type":30,"value":4111},"因此：",{"type":24,"tag":64,"props":4113,"children":4114},{},[4115,4120],{"type":24,"tag":68,"props":4116,"children":4117},{},[4118],{"type":30,"value":4119},"写代码片段：Copilot 速度更快",{"type":24,"tag":68,"props":4121,"children":4122},{},[4123],{"type":30,"value":4124},"改一坨工程：Cursor 更有胜算（但更需要闸门）",{"type":24,"tag":116,"props":4126,"children":4128},{"id":4127},"_2-交互方式你能不能控制范围",[4129],{"type":30,"value":4130},"2) 交互方式：你能不能控制范围",{"type":24,"tag":33,"props":4132,"children":4133},{},[4134],{"type":30,"value":4135},"范围控制的三个层级：",{"type":24,"tag":639,"props":4137,"children":4138},{},[4139,4149,4159],{"type":24,"tag":68,"props":4140,"children":4141},{},[4142,4144],{"type":30,"value":4143},"内联编辑（选中一段）→ ",{"type":24,"tag":39,"props":4145,"children":4146},{},[4147],{"type":30,"value":4148},"最强范围控制",{"type":24,"tag":68,"props":4150,"children":4151},{},[4152,4154],{"type":30,"value":4153},"Composer 多文件（先列文件清单）→ ",{"type":24,"tag":39,"props":4155,"children":4156},{},[4157],{"type":30,"value":4158},"可控但要闸门",{"type":24,"tag":68,"props":4160,"children":4161},{},[4162,4164],{"type":30,"value":4163},"大对话（泛目标）→ ",{"type":24,"tag":39,"props":4165,"children":4166},{},[4167],{"type":30,"value":4168},"最容易跑偏",{"type":24,"tag":116,"props":4170,"children":4172},{"id":4171},"_3-输出形态建议-vs-可审查的变更",[4173],{"type":30,"value":4174},"3) 输出形态：建议 vs 可审查的变更",{"type":24,"tag":33,"props":4176,"children":4177},{},[4178],{"type":30,"value":4179},"最好的 AI 输出不是“给我一段代码”，而是：",{"type":24,"tag":64,"props":4181,"children":4182},{},[4183,4188,4193],{"type":24,"tag":68,"props":4184,"children":4185},{},[4186],{"type":30,"value":4187},"改动摘要（做了什么）",{"type":24,"tag":68,"props":4189,"children":4190},{},[4191],{"type":30,"value":4192},"diff 级别的可审查变更",{"type":24,"tag":68,"props":4194,"children":4195},{},[4196],{"type":30,"value":4197},"验收步骤与回滚方案",{"type":24,"tag":2502,"props":4199,"children":4200},{},[],{"type":24,"tag":25,"props":4202,"children":4204},{"id":4203},"一套可落地的团队工作流把风险关住",[4205],{"type":30,"value":4206},"一套可落地的团队工作流（把风险关住）",{"type":24,"tag":33,"props":4208,"children":4209},{},[4210],{"type":30,"value":4211},"下面这套流程，你可以直接写进团队规范：",{"type":24,"tag":116,"props":4213,"children":4215},{"id":4214},"step-1先写任务单geo-友好结构",[4216],{"type":30,"value":4217},"Step 1：先写任务单（GEO 友好结构）",{"type":24,"tag":33,"props":4219,"children":4220},{},[4221],{"type":30,"value":4222},"模板：",{"type":24,"tag":64,"props":4224,"children":4225},{},[4226,4231,4236,4241,4246,4251],{"type":24,"tag":68,"props":4227,"children":4228},{},[4229],{"type":30,"value":4230},"目标：……",{"type":24,"tag":68,"props":4232,"children":4233},{},[4234],{"type":30,"value":4235},"背景：……",{"type":24,"tag":68,"props":4237,"children":4238},{},[4239],{"type":30,"value":4240},"范围：只改这些文件/模块：……",{"type":24,"tag":68,"props":4242,"children":4243},{},[4244],{"type":30,"value":4245},"非目标：不做哪些事情：……",{"type":24,"tag":68,"props":4247,"children":4248},{},[4249],{"type":30,"value":4250},"验收：如何判断完成（可测试/可观察）：……",{"type":24,"tag":68,"props":4252,"children":4253},{},[4254],{"type":30,"value":4255},"回滚：如果失败怎么撤回：……",{"type":24,"tag":116,"props":4257,"children":4259},{"id":4258},"step-2用范围闸门限制-ai",[4260],{"type":30,"value":4261},"Step 2：用“范围闸门”限制 AI",{"type":24,"tag":64,"props":4263,"children":4264},{},[4265,4270],{"type":24,"tag":68,"props":4266,"children":4267},{},[4268],{"type":30,"value":4269},"单文件改动：优先 Cursor 内联编辑",{"type":24,"tag":68,"props":4271,"children":4272},{},[4273],{"type":30,"value":4274},"多文件改动：必须先让 AI 输出“文件清单（≤5）+ 每步验收”",{"type":24,"tag":33,"props":4276,"children":4277},{},[4278],{"type":30,"value":4279},"如果 AI 输出的文件清单超过 5 个：",{"type":24,"tag":64,"props":4281,"children":4282},{},[4283,4288],{"type":24,"tag":68,"props":4284,"children":4285},{},[4286],{"type":30,"value":4287},"不是它太强，是任务太大",{"type":24,"tag":68,"props":4289,"children":4290},{},[4291],{"type":30,"value":4292},"你需要拆任务，而不是继续推进",{"type":24,"tag":116,"props":4294,"children":4296},{"id":4295},"step-3最小回归集10-条",[4297],{"type":30,"value":4298},"Step 3：最小回归集（10 条）",{"type":24,"tag":33,"props":4300,"children":4301},{},[4302,4304,4309],{"type":30,"value":4303},"每次接受改动前必须跑（可参考：",{"type":24,"tag":2353,"props":4305,"children":4306},{"href":2574},[4307],{"type":30,"value":4308},"Cursor 快捷键速查表",{"type":30,"value":4310}," 里的清单）。",{"type":24,"tag":116,"props":4312,"children":4314},{"id":4313},"step-4回滚策略不用等事故才想",[4315],{"type":30,"value":4316},"Step 4：回滚策略（不用等事故才想）",{"type":24,"tag":33,"props":4318,"children":4319},{},[4320],{"type":30,"value":4321},"回滚最常见的两条路：",{"type":24,"tag":64,"props":4323,"children":4324},{},[4325,4330],{"type":24,"tag":68,"props":4326,"children":4327},{},[4328],{"type":30,"value":4329},"git 回滚 commit",{"type":24,"tag":68,"props":4331,"children":4332},{},[4333],{"type":30,"value":4334},"对关键文件保留前版本（至少能快速恢复）",{"type":24,"tag":33,"props":4336,"children":4337},{},[4338],{"type":30,"value":4339},"你需要做到：任何一轮 AI 改动都能在 5 分钟内撤回。",{"type":24,"tag":2502,"props":4341,"children":4342},{},[],{"type":24,"tag":25,"props":4344,"children":4346},{"id":4345},"必交付物对比矩阵可复制",[4347],{"type":30,"value":4348},"必交付物：对比矩阵（可复制）",{"type":24,"tag":33,"props":4350,"children":4351},{},[4352],{"type":30,"value":4353},"下面这张表可以直接贴到你的团队 wiki：",{"type":24,"tag":212,"props":4355,"children":4356},{},[4357,4380],{"type":24,"tag":216,"props":4358,"children":4359},{},[4360],{"type":24,"tag":220,"props":4361,"children":4362},{},[4363,4368,4372,4376],{"type":24,"tag":224,"props":4364,"children":4365},{},[4366],{"type":30,"value":4367},"维度",{"type":24,"tag":224,"props":4369,"children":4370},{},[4371],{"type":30,"value":2582},{"type":24,"tag":224,"props":4373,"children":4374},{},[4375],{"type":30,"value":3823},{"type":24,"tag":224,"props":4377,"children":4378},{},[4379],{"type":30,"value":2579},{"type":24,"tag":250,"props":4381,"children":4382},{},[4383,4406,4429,4452],{"type":24,"tag":220,"props":4384,"children":4385},{},[4386,4391,4396,4401],{"type":24,"tag":257,"props":4387,"children":4388},{},[4389],{"type":30,"value":4390},"强项",{"type":24,"tag":257,"props":4392,"children":4393},{},[4394],{"type":30,"value":4395},"工具链、调试、生态",{"type":24,"tag":257,"props":4397,"children":4398},{},[4399],{"type":30,"value":4400},"补全与局部建议",{"type":24,"tag":257,"props":4402,"children":4403},{},[4404],{"type":30,"value":4405},"项目上下文、多文件落地",{"type":24,"tag":220,"props":4407,"children":4408},{},[4409,4414,4419,4424],{"type":24,"tag":257,"props":4410,"children":4411},{},[4412],{"type":30,"value":4413},"适合任务",{"type":24,"tag":257,"props":4415,"children":4416},{},[4417],{"type":30,"value":4418},"排查、调试、验证",{"type":24,"tag":257,"props":4420,"children":4421},{},[4422],{"type":30,"value":4423},"写一段、补一段",{"type":24,"tag":257,"props":4425,"children":4426},{},[4427],{"type":30,"value":4428},"改一段、改一组文件",{"type":24,"tag":220,"props":4430,"children":4431},{},[4432,4437,4442,4447],{"type":24,"tag":257,"props":4433,"children":4434},{},[4435],{"type":30,"value":4436},"最大风险",{"type":24,"tag":257,"props":4438,"children":4439},{},[4440],{"type":30,"value":4441},"无",{"type":24,"tag":257,"props":4443,"children":4444},{},[4445],{"type":30,"value":4446},"过度依赖建议",{"type":24,"tag":257,"props":4448,"children":4449},{},[4450],{"type":30,"value":4451},"范围漂移、多文件回归",{"type":24,"tag":220,"props":4453,"children":4454},{},[4455,4460,4465,4470],{"type":24,"tag":257,"props":4456,"children":4457},{},[4458],{"type":30,"value":4459},"必须搭配",{"type":24,"tag":257,"props":4461,"children":4462},{},[4463],{"type":30,"value":4464},"规范与检查",{"type":24,"tag":257,"props":4466,"children":4467},{},[4468],{"type":30,"value":4469},"代码评审",{"type":24,"tag":257,"props":4471,"children":4472},{},[4473],{"type":30,"value":4474},"闸门 + 最小回归集",{"type":24,"tag":2502,"props":4476,"children":4477},{},[],{"type":24,"tag":25,"props":4479,"children":4481},{"id":4480},"失败案例多文件看似成功实际埋雷",[4482],{"type":30,"value":4483},"失败案例：多文件“看似成功”，实际埋雷",{"type":24,"tag":33,"props":4485,"children":4486},{},[4487,4492],{"type":24,"tag":39,"props":4488,"children":4489},{},[4490],{"type":30,"value":4491},"现象",{"type":30,"value":4493},"：AI 说“我已经把所有地方都改了”，你也接受了，结果上线后 404 或样式错位。",{"type":24,"tag":33,"props":4495,"children":4496},{},[4497,4502],{"type":24,"tag":39,"props":4498,"children":4499},{},[4500],{"type":30,"value":4501},"复现条件",{"type":30,"value":610},{"type":24,"tag":64,"props":4504,"children":4505},{},[4506,4511,4516],{"type":24,"tag":68,"props":4507,"children":4508},{},[4509],{"type":30,"value":4510},"你给了一个大目标（例如“把所有按钮统一成主题色”）",{"type":24,"tag":68,"props":4512,"children":4513},{},[4514],{"type":30,"value":4515},"它改了组件、样式、甚至主题配置",{"type":24,"tag":68,"props":4517,"children":4518},{},[4519],{"type":30,"value":4520},"你没有按页面模块走一遍，直接合并",{"type":24,"tag":33,"props":4522,"children":4523},{},[4524,4529],{"type":24,"tag":39,"props":4525,"children":4526},{},[4527],{"type":30,"value":4528},"根因",{"type":30,"value":610},{"type":24,"tag":64,"props":4531,"children":4532},{},[4533],{"type":24,"tag":68,"props":4534,"children":4535},{},[4536],{"type":30,"value":4537},"改动范围大，但验收仍按“小改动”的方式做（只看一处）",{"type":24,"tag":33,"props":4539,"children":4540},{},[4541,4546],{"type":24,"tag":39,"props":4542,"children":4543},{},[4544],{"type":30,"value":4545},"修复",{"type":30,"value":610},{"type":24,"tag":64,"props":4548,"children":4549},{},[4550,4555,4560],{"type":24,"tag":68,"props":4551,"children":4552},{},[4553],{"type":30,"value":4554},"强制把任务拆成“模块级目标”：Hero、Feature、Pricing、Form",{"type":24,"tag":68,"props":4556,"children":4557},{},[4558],{"type":30,"value":4559},"每个模块改完就验收一次",{"type":24,"tag":68,"props":4561,"children":4562},{},[4563],{"type":30,"value":4564},"验收通过再进入下一个模块",{"type":24,"tag":2502,"props":4566,"children":4567},{},[],{"type":24,"tag":25,"props":4569,"children":4570},{"id":1900},[4571],{"type":30,"value":1903},{"type":24,"tag":116,"props":4573,"children":4575},{"id":4574},"q1我已经用了-cursor为什么还要用-copilot",[4576],{"type":30,"value":4577},"Q1：我已经用了 Cursor，为什么还要用 Copilot？",{"type":24,"tag":33,"props":4579,"children":4580},{},[4581],{"type":30,"value":4582},"因为“补全”这种高频低风险任务，Copilot 的交互成本更低；Cursor 更适合需要解释与约束的改动。",{"type":24,"tag":116,"props":4584,"children":4586},{"id":4585},"q2什么时候应该完全不用-ai",[4587],{"type":30,"value":4588},"Q2：什么时候应该完全不用 AI？",{"type":24,"tag":33,"props":4590,"children":4591},{},[4592],{"type":30,"value":4593},"当你无法定义验收标准时。比如“更高级”“更好看”这种目标，先做信息结构与设计规则，再让 AI 帮你落地局部。",{"type":24,"tag":2502,"props":4595,"children":4596},{},[],{"type":24,"tag":25,"props":4598,"children":4599},{"id":2343},[4600],{"type":30,"value":2343},{"type":24,"tag":64,"props":4602,"children":4603},{},[4604,4613,4622,4631],{"type":24,"tag":68,"props":4605,"children":4606},{},[4607,4609],{"type":30,"value":4608},"Cursor 入门：",{"type":24,"tag":2353,"props":4610,"children":4611},{"href":2661},[4612],{"type":30,"value":2664},{"type":24,"tag":68,"props":4614,"children":4615},{},[4616,4618],{"type":30,"value":4617},"Cursor 进阶：",{"type":24,"tag":2353,"props":4619,"children":4620},{"href":2672},[4621],{"type":30,"value":2675},{"type":24,"tag":68,"props":4623,"children":4624},{},[4625,4627],{"type":30,"value":4626},"规则配置：",{"type":24,"tag":2353,"props":4628,"children":4629},{"href":2683},[4630],{"type":30,"value":2686},{"type":24,"tag":68,"props":4632,"children":4633},{},[4634,4636],{"type":30,"value":4635},"Copilot 实战：",{"type":24,"tag":2353,"props":4637,"children":4639},{"href":4638},"/topics/ai/github-copilot-tips",[4640],{"type":30,"value":4641},"GitHub Copilot 实用技巧",{"title":7,"searchDepth":2524,"depth":2524,"links":4643},[4644,4645,4646,4651,4657,4658,4659,4663],{"id":3795,"depth":2527,"text":3798},{"id":3845,"depth":2527,"text":3848},{"id":4084,"depth":2527,"text":4087,"children":4647},[4648,4649,4650],{"id":4090,"depth":2524,"text":4093},{"id":4127,"depth":2524,"text":4130},{"id":4171,"depth":2524,"text":4174},{"id":4203,"depth":2527,"text":4206,"children":4652},[4653,4654,4655,4656],{"id":4214,"depth":2524,"text":4217},{"id":4258,"depth":2524,"text":4261},{"id":4295,"depth":2524,"text":4298},{"id":4313,"depth":2524,"text":4316},{"id":4345,"depth":2527,"text":4348},{"id":4480,"depth":2527,"text":4483},{"id":1900,"depth":2527,"text":1903,"children":4660},[4661,4662],{"id":4574,"depth":2524,"text":4577},{"id":4585,"depth":2524,"text":4588},{"id":2343,"depth":2527,"text":2343},"content:topics:ai:cursor-vs-copilot-vscode-workflow.md","topics/ai/cursor-vs-copilot-vscode-workflow.md","topics/ai/cursor-vs-copilot-vscode-workflow",{"_path":4668,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":4669,"description":4670,"date":4671,"topic":5,"author":11,"tags":4672,"image":4677,"featured":2415,"readingTime":3736,"body":4678,"_type":2566,"_id":5324,"_source":2568,"_file":5325,"_stem":5326,"_extension":2571},"/topics/ai/ai-debugging-troubleshooting-guide","AI 辅助调试与问题排查：让 AI 成为你的调试搭档","深入探讨如何利用 AI 工具提升调试效率，包括错误信息分析、日志解读、性能问题定位、复杂 bug 排查等实战场景，构建 AI 驱动的调试工作流。","2026-01-18",[4673,4674,4675,2583,4676],"AI 调试","问题排查","Debug","错误处理","/images/topics/ai/ai-debugging-guide.jpg",{"type":21,"children":4679,"toc":5295},[4680,4686,4692,4697,4702,4707,4713,4719,4724,4732,4760,4768,4791,4797,4807,4816,4824,4832,4865,4873,4903,4916,4924,4929,4937,4945,4954,4960,4968,4979,4987,4996,5002,5008,5013,5022,5028,5033,5042,5048,5054,5063,5069,5078,5084,5095,5101,5107,5116,5122,5131,5137,5143,5151,5157,5166,5174,5182,5185,5191,5196,5215,5227,5230,5236,5241,5250,5255,5258,5264,5269,5287],{"type":24,"tag":25,"props":4681,"children":4683},{"id":4682},"ai-辅助调试与问题排查",[4684],{"type":30,"value":4685},"AI 辅助调试与问题排查",{"type":24,"tag":25,"props":4687,"children":4689},{"id":4688},"引言调试的痛与-ai-的解药",[4690],{"type":30,"value":4691},"引言：调试的痛与 AI 的解药",{"type":24,"tag":33,"props":4693,"children":4694},{},[4695],{"type":30,"value":4696},"调试是每个程序员的日常，也是最消耗时间和精力的工作之一。我们都有过这样的经历：盯着一个莫名其妙的错误信息，翻遍 Stack Overflow，尝试各种方案，几个小时后才发现是一个愚蠢的拼写错误。",{"type":24,"tag":33,"props":4698,"children":4699},{},[4700],{"type":30,"value":4701},"AI 工具的出现，正在改变调试的方式。不是替代你的思考，而是加速你的分析过程——帮你快速理解错误、缩小排查范围、验证假设。",{"type":24,"tag":33,"props":4703,"children":4704},{},[4705],{"type":30,"value":4706},"这篇文章分享我在实际项目中使用 AI 辅助调试的经验和方法论。",{"type":24,"tag":25,"props":4708,"children":4710},{"id":4709},"第一部分建立-ai-调试的思维模型",[4711],{"type":30,"value":4712},"第一部分：建立 AI 调试的思维模型",{"type":24,"tag":116,"props":4714,"children":4716},{"id":4715},"_11-ai-在调试中的角色",[4717],{"type":30,"value":4718},"1.1 AI 在调试中的角色",{"type":24,"tag":33,"props":4720,"children":4721},{},[4722],{"type":30,"value":4723},"把 AI 想象成一个经验丰富但不了解你项目的高级工程师。它：",{"type":24,"tag":33,"props":4725,"children":4726},{},[4727],{"type":24,"tag":39,"props":4728,"children":4729},{},[4730],{"type":30,"value":4731},"擅长的事情：",{"type":24,"tag":64,"props":4733,"children":4734},{},[4735,4740,4745,4750,4755],{"type":24,"tag":68,"props":4736,"children":4737},{},[4738],{"type":30,"value":4739},"解读错误信息的含义",{"type":24,"tag":68,"props":4741,"children":4742},{},[4743],{"type":30,"value":4744},"提供可能的原因列表",{"type":24,"tag":68,"props":4746,"children":4747},{},[4748],{"type":30,"value":4749},"给出排查方向建议",{"type":24,"tag":68,"props":4751,"children":4752},{},[4753],{"type":30,"value":4754},"解释复杂的技术概念",{"type":24,"tag":68,"props":4756,"children":4757},{},[4758],{"type":30,"value":4759},"生成调试代码片段",{"type":24,"tag":33,"props":4761,"children":4762},{},[4763],{"type":24,"tag":39,"props":4764,"children":4765},{},[4766],{"type":30,"value":4767},"不擅长的事情：",{"type":24,"tag":64,"props":4769,"children":4770},{},[4771,4776,4781,4786],{"type":24,"tag":68,"props":4772,"children":4773},{},[4774],{"type":30,"value":4775},"了解你的业务逻辑",{"type":24,"tag":68,"props":4777,"children":4778},{},[4779],{"type":30,"value":4780},"知道你的代码历史",{"type":24,"tag":68,"props":4782,"children":4783},{},[4784],{"type":30,"value":4785},"理解项目特定的约定",{"type":24,"tag":68,"props":4787,"children":4788},{},[4789],{"type":30,"value":4790},"做出架构级判断",{"type":24,"tag":116,"props":4792,"children":4794},{"id":4793},"_12-有效提问的结构",[4795],{"type":30,"value":4796},"1.2 有效提问的结构",{"type":24,"tag":961,"props":4798,"children":4802},{"code":4799,"language":2566,"meta":7,"className":4800},"## 高效的调试提问模板\n\n**问题描述**\n[简洁描述遇到的问题]\n\n**错误信息**\n",[4801],"language-markdown",[4803],{"type":24,"tag":969,"props":4804,"children":4805},{"__ignoreMap":7},[4806],{"type":30,"value":4799},{"type":24,"tag":33,"props":4808,"children":4809},{},[4810],{"type":24,"tag":4811,"props":4812,"children":4813},"span",{},[4814],{"type":30,"value":4815},"完整的错误信息，不要截断",{"type":24,"tag":961,"props":4817,"children":4819},{"code":4818},"\n**相关代码**\n```javascript\n[精简但完整的相关代码]\n",[4820],{"type":24,"tag":969,"props":4821,"children":4822},{"__ignoreMap":7},[4823],{"type":30,"value":4818},{"type":24,"tag":33,"props":4825,"children":4826},{},[4827],{"type":24,"tag":39,"props":4828,"children":4829},{},[4830],{"type":30,"value":4831},"环境信息",{"type":24,"tag":64,"props":4833,"children":4834},{},[4835,4845,4855],{"type":24,"tag":68,"props":4836,"children":4837},{},[4838,4840],{"type":30,"value":4839},"运行环境：",{"type":24,"tag":4811,"props":4841,"children":4842},{},[4843],{"type":30,"value":4844},"Node 版本/浏览器版本",{"type":24,"tag":68,"props":4846,"children":4847},{},[4848,4850],{"type":30,"value":4849},"框架版本：",{"type":24,"tag":4811,"props":4851,"children":4852},{},[4853],{"type":30,"value":4854},"相关框架版本",{"type":24,"tag":68,"props":4856,"children":4857},{},[4858,4860],{"type":30,"value":4859},"操作系统：",{"type":24,"tag":4811,"props":4861,"children":4862},{},[4863],{"type":30,"value":4864},"如果相关",{"type":24,"tag":33,"props":4866,"children":4867},{},[4868],{"type":24,"tag":39,"props":4869,"children":4870},{},[4871],{"type":30,"value":4872},"已尝试的方案",{"type":24,"tag":64,"props":4874,"children":4875},{},[4876,4890],{"type":24,"tag":68,"props":4877,"children":4878},{},[4879,4884,4885],{"type":24,"tag":4811,"props":4880,"children":4881},{},[4882],{"type":30,"value":4883},"方案1",{"type":30,"value":610},{"type":24,"tag":4811,"props":4886,"children":4887},{},[4888],{"type":30,"value":4889},"结果",{"type":24,"tag":68,"props":4891,"children":4892},{},[4893,4898,4899],{"type":24,"tag":4811,"props":4894,"children":4895},{},[4896],{"type":30,"value":4897},"方案2",{"type":30,"value":610},{"type":24,"tag":4811,"props":4900,"children":4901},{},[4902],{"type":30,"value":4889},{"type":24,"tag":33,"props":4904,"children":4905},{},[4906,4911],{"type":24,"tag":39,"props":4907,"children":4908},{},[4909],{"type":30,"value":4910},"期望的结果",{"type":24,"tag":4811,"props":4912,"children":4913},{},[4914],{"type":30,"value":4915},"描述期望的行为",{"type":24,"tag":961,"props":4917,"children":4919},{"code":4918},"\n### 1.3 分级调试策略\n\n",[4920],{"type":24,"tag":969,"props":4921,"children":4922},{"__ignoreMap":7},[4923],{"type":30,"value":4918},{"type":24,"tag":33,"props":4925,"children":4926},{},[4927],{"type":30,"value":4928},"┌───────────────────────────────────────────────────────────┐\n│                    AI 辅助调试决策树                        │\n├───────────────────────────────────────────────────────────┤\n│                                                           │\n│  Level 1：简单错误（5分钟内解决）                           │\n│  ├── 语法错误、拼写错误                                    │\n│  ├── 方法：直接复制错误信息给 AI                           │\n│  └── 工具：Copilot Chat / ChatGPT                        │\n│                                                           │\n│  Level 2：中等复杂度（30分钟内解决）                        │\n│  ├── 类型错误、逻辑错误、API 使用错误                      │\n│  ├── 方法：提供错误信息 + 相关代码 + 上下文                 │\n│  └── 工具：Cursor Chat / Claude                          │\n│                                                           │\n│  Level 3：复杂问题（需要深入分析）                          │\n│  ├── 竞态条件、内存泄漏、性能问题                          │\n│  ├── 方法：详细描述场景 + 提供多个文件 + 讨论               │\n│  └── 工具：Cursor Composer / 专门的 AI 会话                │\n│                                                           │\n│  Level 4：架构级问题                                       │\n│  ├── 设计缺陷、技术债务                                    │\n│  ├── 方法：AI 辅助分析 + 人工判断                          │\n│  └── 工具：与团队讨论 + AI 作为顾问                        │\n│                                                           │\n└───────────────────────────────────────────────────────────┘",{"type":24,"tag":961,"props":4930,"children":4932},{"code":4931},"\n## 第二部分：错误信息分析\n\n### 2.1 前端错误分析\n\n**场景 1：React 错误边界触发**\n\n```typescript\n// 错误信息：\n// Error: Hydration failed because the initial UI does not match \n// what was rendered on the server.\n\n// 提问方式：\n/**\n * 我在 Next.js 14 App Router 项目中遇到这个错误：\n * \n * Error: Hydration failed because the initial UI does not match \n * what was rendered on the server.\n * \n * 相关代码：\n */\nfunction UserStatus() {\n  const [isLoggedIn, setIsLoggedIn] = useState(false);\n  \n  useEffect(() => {\n    setIsLoggedIn(localStorage.getItem('token') !== null);\n  }, []);\n  \n  return \u003Cdiv>{isLoggedIn ? '已登录' : '未登录'}\u003C/div>;\n}\n\n// AI 会分析出：\n// 1. 服务端渲染时 localStorage 不可用，默认 false\n// 2. 客户端 hydration 时可能是 true\n// 3. 导致服务端和客户端渲染结果不一致\n\n// AI 建议的解决方案：\nfunction UserStatus() {\n  const [isLoggedIn, setIsLoggedIn] = useState\u003Cboolean | null>(null);\n  \n  useEffect(() => {\n    setIsLoggedIn(localStorage.getItem('token') !== null);\n  }, []);\n  \n  // 初始状态显示加载中，避免 hydration 不匹配\n  if (isLoggedIn === null) {\n    return \u003Cdiv>加载中...\u003C/div>;\n  }\n  \n  return \u003Cdiv>{isLoggedIn ? '已登录' : '未登录'}\u003C/div>;\n}\n",[4933],{"type":24,"tag":969,"props":4934,"children":4935},{"__ignoreMap":7},[4936],{"type":30,"value":4931},{"type":24,"tag":33,"props":4938,"children":4939},{},[4940],{"type":24,"tag":39,"props":4941,"children":4942},{},[4943],{"type":30,"value":4944},"场景 2：Vue 响应式警告",{"type":24,"tag":961,"props":4946,"children":4949},{"code":4947,"language":1077,"meta":7,"className":4948},"// 警告信息：\n// [Vue warn]: Property \"xxx\" was accessed during render but is not \n// defined on instance.\n\n// 提问方式：\n/**\n * Vue 3 项目中出现这个警告：\n * [Vue warn]: Property \"userInfo\" was accessed during render \n * but is not defined on instance.\n * \n * 组件代码：\n */\n\u003Ctemplate>\n  \u003Cdiv>{{ userInfo.name }}\u003C/div>\n\u003C/template>\n\n\u003Cscript setup>\nconst { data: userInfo } = await useFetch('/api/user');\n\u003C/script>\n\n// AI 分析：\n// 1. useFetch 是异步的，初始渲染时 userInfo 可能是 undefined\n// 2. 直接访问 userInfo.name 会报错\n\n// AI 建议：\n\u003Ctemplate>\n  \u003Cdiv v-if=\"userInfo\">{{ userInfo.name }}\u003C/div>\n  \u003Cdiv v-else>加载中...\u003C/div>\n\u003C/template>\n\n\u003Cscript setup>\nconst { data: userInfo, pending } = await useFetch('/api/user');\n\u003C/script>\n",[1075],[4950],{"type":24,"tag":969,"props":4951,"children":4952},{"__ignoreMap":7},[4953],{"type":30,"value":4947},{"type":24,"tag":116,"props":4955,"children":4957},{"id":4956},"_22-后端错误分析",[4958],{"type":30,"value":4959},"2.2 后端错误分析",{"type":24,"tag":33,"props":4961,"children":4962},{},[4963],{"type":24,"tag":39,"props":4964,"children":4965},{},[4966],{"type":30,"value":4967},"场景 1：Node.js 内存问题",{"type":24,"tag":961,"props":4969,"children":4974},{"code":4970,"language":4971,"meta":7,"className":4972},"// 错误信息：\n// FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - \n// JavaScript heap out of memory\n\n// 提问方式（包含上下文）：\n/**\n * Node.js 服务运行几小时后崩溃，错误信息：\n * FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - \n * JavaScript heap out of memory\n * \n * 服务功能：处理 CSV 文件上传，每次约 100MB\n * \n * 处理代码：\n */\nasync function processCSV(filePath) {\n  const content = fs.readFileSync(filePath, 'utf-8');\n  const rows = content.split('\\n');\n  const results = [];\n  \n  for (const row of rows) {\n    const processed = await processRow(row);\n    results.push(processed);\n  }\n  \n  return results;\n}\n\n// AI 分析会指出：\n// 1. 一次性读取整个文件到内存\n// 2. 所有处理结果累积在 results 数组\n// 3. 建议使用流式处理\n\n// AI 提供的优化方案：\nconst { createReadStream } = require('fs');\nconst { createInterface } = require('readline');\n\nasync function processCSVStream(filePath, onRow) {\n  const fileStream = createReadStream(filePath);\n  const rl = createInterface({\n    input: fileStream,\n    crlfDelay: Infinity\n  });\n  \n  let count = 0;\n  for await (const line of rl) {\n    await onRow(line);\n    count++;\n    \n    // 每处理 1000 行，给 GC 机会运行\n    if (count % 1000 === 0) {\n      await new Promise(r => setImmediate(r));\n    }\n  }\n}\n","javascript",[4973],"language-javascript",[4975],{"type":24,"tag":969,"props":4976,"children":4977},{"__ignoreMap":7},[4978],{"type":30,"value":4970},{"type":24,"tag":33,"props":4980,"children":4981},{},[4982],{"type":24,"tag":39,"props":4983,"children":4984},{},[4985],{"type":30,"value":4986},"场景 2：数据库连接问题",{"type":24,"tag":961,"props":4988,"children":4991},{"code":4989,"language":1077,"meta":7,"className":4990},"// 错误信息：\n// Error: Connection pool exhausted - \n// max connections (10) already in use\n\n// 提问方式：\n/**\n * PostgreSQL 连接池耗尽错误，高并发时出现：\n * Error: Connection pool exhausted\n * \n * 当前配置：\n * - max connections: 10\n * - 并发请求: 约 100/秒\n * \n * 数据库调用代码：\n */\nasync function getUserData(userId: string) {\n  const client = await pool.connect();\n  try {\n    const user = await client.query('SELECT * FROM users WHERE id = $1', [userId]);\n    const orders = await client.query('SELECT * FROM orders WHERE user_id = $1', [userId]);\n    const payments = await client.query('SELECT * FROM payments WHERE user_id = $1', [userId]);\n    return { user: user.rows[0], orders: orders.rows, payments: payments.rows };\n  } finally {\n    client.release();\n  }\n}\n\n// AI 会分析出多个可能原因并给出综合方案\n",[1075],[4992],{"type":24,"tag":969,"props":4993,"children":4994},{"__ignoreMap":7},[4995],{"type":30,"value":4989},{"type":24,"tag":25,"props":4997,"children":4999},{"id":4998},"第三部分日志分析与问题定位",[5000],{"type":30,"value":5001},"第三部分：日志分析与问题定位",{"type":24,"tag":116,"props":5003,"children":5005},{"id":5004},"_31-结构化日志分析",[5006],{"type":30,"value":5007},"3.1 结构化日志分析",{"type":24,"tag":33,"props":5009,"children":5010},{},[5011],{"type":30,"value":5012},"当面对大量日志时，让 AI 帮你快速定位问题：",{"type":24,"tag":961,"props":5014,"children":5017},{"code":5015,"language":4971,"meta":7,"className":5016},"// 提问示例：\n/**\n * 分析以下日志，找出导致请求失败的原因：\n * \n * 日志片段：\n */\nconst logs = `\n2024-01-15 10:23:45.123 INFO  [req-abc123] 收到请求 POST /api/order\n2024-01-15 10:23:45.125 DEBUG [req-abc123] 用户认证通过 userId=u001\n2024-01-15 10:23:45.130 DEBUG [req-abc123] 开始库存检查 productId=p001\n2024-01-15 10:23:45.145 DEBUG [req-abc123] 库存检查通过 available=50\n2024-01-15 10:23:45.150 DEBUG [req-abc123] 开始创建订单\n2024-01-15 10:23:45.200 DEBUG [req-abc123] 数据库连接获取成功\n2024-01-15 10:23:45.250 ERROR [req-abc123] 订单创建失败 error=\"deadlock detected\"\n2024-01-15 10:23:45.251 WARN  [req-abc123] 事务回滚\n2024-01-15 10:23:45.255 INFO  [req-abc123] 响应 500 耗时 132ms\n`;\n\n// AI 分析结果会包括：\n// 1. 问题定位：数据库死锁\n// 2. 可能原因：并发订单创建导致锁竞争\n// 3. 排查建议：检查事务隔离级别、锁顺序\n",[4973],[5018],{"type":24,"tag":969,"props":5019,"children":5020},{"__ignoreMap":7},[5021],{"type":30,"value":5015},{"type":24,"tag":116,"props":5023,"children":5025},{"id":5024},"_32-创建调试日志",[5026],{"type":30,"value":5027},"3.2 创建调试日志",{"type":24,"tag":33,"props":5029,"children":5030},{},[5031],{"type":30,"value":5032},"让 AI 帮你生成调试用的日志代码：",{"type":24,"tag":961,"props":5034,"children":5037},{"code":5035,"language":1077,"meta":7,"className":5036},"// 请求：\n// \"为这个函数添加详细的调试日志，包括入参、关键步骤、耗时和结果\"\n\n// 原代码：\nasync function processOrder(order: Order): Promise\u003COrderResult> {\n  const inventory = await checkInventory(order.items);\n  const payment = await processPayment(order.userId, order.total);\n  const result = await createOrder(order, payment.transactionId);\n  return result;\n}\n\n// AI 生成的带日志版本：\nasync function processOrder(order: Order): Promise\u003COrderResult> {\n  const requestId = generateRequestId();\n  const startTime = performance.now();\n  \n  logger.info({\n    requestId,\n    event: 'order_processing_start',\n    orderId: order.id,\n    userId: order.userId,\n    itemCount: order.items.length,\n    total: order.total\n  });\n  \n  try {\n    // 库存检查\n    const inventoryStart = performance.now();\n    const inventory = await checkInventory(order.items);\n    logger.debug({\n      requestId,\n      event: 'inventory_check_complete',\n      duration: performance.now() - inventoryStart,\n      available: inventory.allAvailable\n    });\n    \n    // 支付处理\n    const paymentStart = performance.now();\n    const payment = await processPayment(order.userId, order.total);\n    logger.debug({\n      requestId,\n      event: 'payment_complete',\n      duration: performance.now() - paymentStart,\n      transactionId: payment.transactionId\n    });\n    \n    // 创建订单\n    const createStart = performance.now();\n    const result = await createOrder(order, payment.transactionId);\n    logger.debug({\n      requestId,\n      event: 'order_created',\n      duration: performance.now() - createStart,\n      resultOrderId: result.orderId\n    });\n    \n    logger.info({\n      requestId,\n      event: 'order_processing_complete',\n      duration: performance.now() - startTime,\n      success: true\n    });\n    \n    return result;\n  } catch (error) {\n    logger.error({\n      requestId,\n      event: 'order_processing_failed',\n      duration: performance.now() - startTime,\n      error: error.message,\n      stack: error.stack\n    });\n    throw error;\n  }\n}\n",[1075],[5038],{"type":24,"tag":969,"props":5039,"children":5040},{"__ignoreMap":7},[5041],{"type":30,"value":5035},{"type":24,"tag":25,"props":5043,"children":5045},{"id":5044},"第四部分性能问题排查",[5046],{"type":30,"value":5047},"第四部分：性能问题排查",{"type":24,"tag":116,"props":5049,"children":5051},{"id":5050},"_41-前端性能分析",[5052],{"type":30,"value":5053},"4.1 前端性能分析",{"type":24,"tag":961,"props":5055,"children":5058},{"code":5056,"language":1077,"meta":7,"className":5057},"// 场景：页面加载慢，需要分析原因\n\n// 提问方式：\n/**\n * 页面首屏加载需要 5 秒，以下是 Performance API 数据，\n * 请分析性能瓶颈：\n */\nconst performanceData = {\n  // Navigation Timing\n  dns: 50,           // DNS 查询\n  tcp: 100,          // TCP 连接\n  ttfb: 800,         // 首字节时间\n  download: 200,     // 文档下载\n  domParsing: 300,   // DOM 解析\n  domContentLoaded: 1500,\n  load: 5000,\n  \n  // Resource Timing (主要资源)\n  resources: [\n    { name: 'main.js', size: '2.5MB', duration: 1200 },\n    { name: 'vendor.js', size: '1.8MB', duration: 900 },\n    { name: 'styles.css', size: '500KB', duration: 300 },\n    { name: 'hero-image.jpg', size: '3MB', duration: 1500 },\n  ],\n  \n  // Long Tasks\n  longTasks: [\n    { startTime: 1600, duration: 800, name: 'script-evaluation' },\n    { startTime: 2500, duration: 400, name: 'layout' }\n  ]\n};\n\n// AI 会分析出：\n// 1. JS bundle 过大（4.3MB），需要代码分割\n// 2. 图片未优化（3MB 的 hero 图片）\n// 3. 存在长任务阻塞主线程\n// 并给出具体优化建议\n",[1075],[5059],{"type":24,"tag":969,"props":5060,"children":5061},{"__ignoreMap":7},[5062],{"type":30,"value":5056},{"type":24,"tag":116,"props":5064,"children":5066},{"id":5065},"_42-内存泄漏排查",[5067],{"type":30,"value":5068},"4.2 内存泄漏排查",{"type":24,"tag":961,"props":5070,"children":5073},{"code":5071,"language":1077,"meta":7,"className":5072},"// 场景：应用运行一段时间后变卡\n\n// 提问方式：\n/**\n * React 应用运行一段时间后内存持续增长，以下是 Heap Snapshot 对比：\n * \n * 初始状态：50MB\n * 运行 1 小时后：150MB\n * 运行 2 小时后：280MB\n * \n * Retained objects 增长最快的：\n * - (closure) - 增长 50MB\n * - HTMLDivElement - 增长 30MB\n * - Array - 增长 20MB\n * \n * 可疑代码：\n */\nfunction DataDashboard() {\n  const [data, setData] = useState([]);\n  const chartRef = useRef(null);\n  \n  useEffect(() => {\n    // 每秒刷新数据\n    const interval = setInterval(async () => {\n      const newData = await fetchLatestData();\n      setData(prev => [...prev, ...newData]);  // 数据不断累积\n    }, 1000);\n    \n    // 初始化图表\n    const chart = new Chart(chartRef.current, {\n      // 配置...\n    });\n    \n    // 没有 cleanup！\n  }, []);\n  \n  return \u003Ccanvas ref={chartRef} />;\n}\n\n// AI 会指出：\n// 1. interval 没有清理\n// 2. Chart 实例没有销毁\n// 3. data 无限增长\n// 并提供修复代码\n",[1075],[5074],{"type":24,"tag":969,"props":5075,"children":5076},{"__ignoreMap":7},[5077],{"type":30,"value":5071},{"type":24,"tag":116,"props":5079,"children":5081},{"id":5080},"_43-数据库查询优化",[5082],{"type":30,"value":5083},"4.3 数据库查询优化",{"type":24,"tag":961,"props":5085,"children":5090},{"code":5086,"language":5087,"meta":7,"className":5088},"-- 场景：查询很慢，让 AI 分析执行计划\n\n-- 提问方式：\n-- 以下查询在数据量大时很慢（orders 表 1000 万行），\n-- 执行计划如下，请分析并优化：\n\nEXPLAIN ANALYZE\nSELECT o.*, u.name, u.email\nFROM orders o\nJOIN users u ON o.user_id = u.id\nWHERE o.status = 'pending'\n  AND o.created_at > '2024-01-01'\nORDER BY o.created_at DESC\nLIMIT 20;\n\n-- 执行计划：\n/*\nSort  (cost=156847.23..157847.23 rows=400000 width=250)\n  Sort Key: o.created_at DESC\n  ->  Hash Join  (cost=1500.00..89847.23 rows=400000 width=250)\n        Hash Cond: (o.user_id = u.id)\n        ->  Seq Scan on orders o  (cost=0.00..85000.00 rows=400000)\n              Filter: ((status = 'pending') AND (created_at > '2024-01-01'))\n        ->  Hash  (cost=1000.00..1000.00 rows=50000 width=100)\n              ->  Seq Scan on users u  (cost=0.00..1000.00 rows=50000)\nPlanning Time: 0.5 ms\nExecution Time: 3500 ms\n*/\n\n-- AI 会分析出问题并建议：\n-- 1. orders 表全表扫描 - 需要复合索引\n-- 2. 建议创建索引：\nCREATE INDEX idx_orders_status_created ON orders(status, created_at DESC);\n\n-- 3. 如果 status 选择性不高，考虑部分索引：\nCREATE INDEX idx_orders_pending ON orders(created_at DESC) \nWHERE status = 'pending';\n","sql",[5089],"language-sql",[5091],{"type":24,"tag":969,"props":5092,"children":5093},{"__ignoreMap":7},[5094],{"type":30,"value":5086},{"type":24,"tag":25,"props":5096,"children":5098},{"id":5097},"第五部分复杂-bug-排查",[5099],{"type":30,"value":5100},"第五部分：复杂 Bug 排查",{"type":24,"tag":116,"props":5102,"children":5104},{"id":5103},"_51-竞态条件",[5105],{"type":30,"value":5106},"5.1 竞态条件",{"type":24,"tag":961,"props":5108,"children":5111},{"code":5109,"language":1077,"meta":7,"className":5110},"// 场景：偶发的数据不一致问题\n\n// 提问方式：\n/**\n * 用户反馈偶尔看到错误的账户余额，但刷新后正常。\n * 怀疑是竞态条件，以下是相关代码：\n */\nasync function updateBalance(userId: string, amount: number) {\n  // 读取当前余额\n  const user = await db.users.findOne({ id: userId });\n  const newBalance = user.balance + amount;\n  \n  // 更新余额\n  await db.users.update({ id: userId }, { balance: newBalance });\n  \n  // 记录交易\n  await db.transactions.create({\n    userId,\n    amount,\n    balanceAfter: newBalance,\n    createdAt: new Date()\n  });\n  \n  return newBalance;\n}\n\n// 并发调用场景：\n// 用户同时发起两笔交易：+100 和 -50\n// 期望结果：原余额 1000 → 1050\n// 实际可能：原余额 1000 → 1100 或 950\n\n// AI 会分析竞态条件并提供解决方案：\nasync function updateBalanceAtomic(userId: string, amount: number) {\n  // 方案 1：使用数据库原子操作\n  const result = await db.users.findOneAndUpdate(\n    { id: userId },\n    { $inc: { balance: amount } },\n    { returnDocument: 'after' }\n  );\n  \n  await db.transactions.create({\n    userId,\n    amount,\n    balanceAfter: result.balance,\n    createdAt: new Date()\n  });\n  \n  return result.balance;\n}\n\n// 方案 2：使用乐观锁\nasync function updateBalanceOptimistic(userId: string, amount: number) {\n  const maxRetries = 3;\n  \n  for (let i = 0; i \u003C maxRetries; i++) {\n    const user = await db.users.findOne({ id: userId });\n    const newBalance = user.balance + amount;\n    \n    const updated = await db.users.updateOne(\n      { id: userId, version: user.version },\n      { balance: newBalance, version: user.version + 1 }\n    );\n    \n    if (updated.modifiedCount === 1) {\n      await db.transactions.create({...});\n      return newBalance;\n    }\n    \n    // 版本冲突，重试\n    await sleep(10 * (i + 1));\n  }\n  \n  throw new Error('Update failed after retries');\n}\n",[1075],[5112],{"type":24,"tag":969,"props":5113,"children":5114},{"__ignoreMap":7},[5115],{"type":30,"value":5109},{"type":24,"tag":116,"props":5117,"children":5119},{"id":5118},"_52-分布式系统问题",[5120],{"type":30,"value":5121},"5.2 分布式系统问题",{"type":24,"tag":961,"props":5123,"children":5126},{"code":5124,"language":1077,"meta":7,"className":5125},"// 场景：微服务间的数据不一致\n\n// 提问方式：\n/**\n * 订单服务和库存服务偶尔出现数据不一致：\n * - 订单显示已创建\n * - 库存未扣减\n * \n * 当前流程：\n */\n// Order Service\nasync function createOrder(orderData) {\n  // 1. 调用库存服务扣减库存\n  await inventoryService.deduct(orderData.items);\n  \n  // 2. 创建订单\n  const order = await orderRepository.create(orderData);\n  \n  // 3. 发送订单创建事件\n  await eventBus.publish('order.created', order);\n  \n  return order;\n}\n\n// 问题分析：如果步骤 2 或 3 失败，库存已经扣减但订单未创建\n\n// AI 会建议使用 Saga 模式或事务发件箱模式\n",[1075],[5127],{"type":24,"tag":969,"props":5128,"children":5129},{"__ignoreMap":7},[5130],{"type":30,"value":5124},{"type":24,"tag":25,"props":5132,"children":5134},{"id":5133},"第六部分ai-调试工作流",[5135],{"type":30,"value":5136},"第六部分：AI 调试工作流",{"type":24,"tag":116,"props":5138,"children":5140},{"id":5139},"_61-我的调试流程",[5141],{"type":30,"value":5142},"6.1 我的调试流程",{"type":24,"tag":961,"props":5144,"children":5146},{"code":5145},"┌────────────────────────────────────────────────────────────┐\n│                    AI 辅助调试工作流                         │\n├────────────────────────────────────────────────────────────┤\n│                                                            │\n│  Step 1: 问题收集                                          │\n│  ├── 复制完整错误信息                                       │\n│  ├── 截图相关日志                                          │\n│  └── 记录复现步骤                                          │\n│                                                            │\n│  Step 2: 快速分析                                          │\n│  ├── 将错误信息发给 AI                                      │\n│  ├── 获取可能原因列表                                       │\n│  └── 评估哪些最可能                                         │\n│                                                            │\n│  Step 3: 深入调查                                          │\n│  ├── 根据 AI 建议添加日志/断点                              │\n│  ├── 收集更多信息                                          │\n│  └── 再次询问 AI（带新信息）                                │\n│                                                            │\n│  Step 4: 验证修复                                          │\n│  ├── AI 生成修复代码                                        │\n│  ├── 人工审查确认                                          │\n│  └── 测试验证                                               │\n│                                                            │\n│  Step 5: 预防措施                                          │\n│  ├── AI 建议类似问题的预防方法                              │\n│  ├── 添加相关测试用例                                       │\n│  └── 更新文档/知识库                                        │\n│                                                            │\n└────────────────────────────────────────────────────────────┘\n",[5147],{"type":24,"tag":969,"props":5148,"children":5149},{"__ignoreMap":7},[5150],{"type":30,"value":5145},{"type":24,"tag":116,"props":5152,"children":5154},{"id":5153},"_62-调试对话模板",[5155],{"type":30,"value":5156},"6.2 调试对话模板",{"type":24,"tag":961,"props":5158,"children":5161},{"code":5159,"language":2566,"meta":7,"className":5160},"## 第一轮：问题描述\n\n我遇到了一个问题：[简述问题]\n\n错误信息：\n",[4801],[5162],{"type":24,"tag":969,"props":5163,"children":5164},{"__ignoreMap":7},[5165],{"type":30,"value":5159},{"type":24,"tag":33,"props":5167,"children":5168},{},[5169],{"type":24,"tag":4811,"props":5170,"children":5171},{},[5172],{"type":30,"value":5173},"粘贴完整错误",{"type":24,"tag":961,"props":5175,"children":5177},{"code":5176},"\n相关代码：\n```javascript\n[粘贴代码]\n",[5178],{"type":24,"tag":969,"props":5179,"children":5180},{"__ignoreMap":7},[5181],{"type":30,"value":5176},{"type":24,"tag":2502,"props":5183,"children":5184},{},[],{"type":24,"tag":25,"props":5186,"children":5188},{"id":5187},"第二轮补充信息",[5189],{"type":30,"value":5190},"第二轮：补充信息",{"type":24,"tag":33,"props":5192,"children":5193},{},[5194],{"type":30,"value":5195},"根据你的建议，我添加了日志，发现：",{"type":24,"tag":64,"props":5197,"children":5198},{},[5199,5207],{"type":24,"tag":68,"props":5200,"children":5201},{},[5202],{"type":24,"tag":4811,"props":5203,"children":5204},{},[5205],{"type":30,"value":5206},"发现 1",{"type":24,"tag":68,"props":5208,"children":5209},{},[5210],{"type":24,"tag":4811,"props":5211,"children":5212},{},[5213],{"type":30,"value":5214},"发现 2",{"type":24,"tag":33,"props":5216,"children":5217},{},[5218,5220,5225],{"type":30,"value":5219},"这是否说明问题出在 ",{"type":24,"tag":4811,"props":5221,"children":5222},{},[5223],{"type":30,"value":5224},"你的猜测",{"type":30,"value":5226},"？",{"type":24,"tag":2502,"props":5228,"children":5229},{},[],{"type":24,"tag":25,"props":5231,"children":5233},{"id":5232},"第三轮确认修复",[5234],{"type":30,"value":5235},"第三轮：确认修复",{"type":24,"tag":33,"props":5237,"children":5238},{},[5239],{"type":30,"value":5240},"我按照你的建议修改了代码：",{"type":24,"tag":961,"props":5242,"children":5245},{"code":5243,"language":4971,"meta":7,"className":5244},"[粘贴修改后的代码]\n",[4973],[5246],{"type":24,"tag":969,"props":5247,"children":5248},{"__ignoreMap":7},[5249],{"type":30,"value":5243},{"type":24,"tag":33,"props":5251,"children":5252},{},[5253],{"type":30,"value":5254},"请确认这个修复是否正确，以及是否有其他潜在问题。",{"type":24,"tag":2502,"props":5256,"children":5257},{},[],{"type":24,"tag":25,"props":5259,"children":5261},{"id":5260},"第四轮预防",[5262],{"type":30,"value":5263},"第四轮：预防",{"type":24,"tag":33,"props":5265,"children":5266},{},[5267],{"type":30,"value":5268},"这个问题已解决。请建议：",{"type":24,"tag":639,"props":5270,"children":5271},{},[5272,5277,5282],{"type":24,"tag":68,"props":5273,"children":5274},{},[5275],{"type":30,"value":5276},"如何防止类似问题再次发生？",{"type":24,"tag":68,"props":5278,"children":5279},{},[5280],{"type":30,"value":5281},"应该添加什么测试用例？",{"type":24,"tag":68,"props":5283,"children":5284},{},[5285],{"type":30,"value":5286},"有什么最佳实践可以参考？",{"type":24,"tag":961,"props":5288,"children":5290},{"code":5289},"\n## 结语：AI 是放大器，不是替代品\n\nAI 调试工具能够显著加速问题排查过程，但它不能替代你的思考。最有价值的能力组合是：\n\n- **你的领域知识** + **AI 的广博见识**\n- **你对项目的理解** + **AI 的分析能力**\n- **你的判断力** + **AI 的执行速度**\n\n调试的本质是假设-验证的循环。AI 帮你更快地生成假设、更高效地验证假设，但做出最终判断的还是你。\n\n学会与 AI 高效协作调试，不是依赖 AI 给你答案，而是让 AI 帮你更快地找到自己的答案。\n\n---\n\n## 参考资源\n\n- [Chrome DevTools 官方文档](https://developer.chrome.com/docs/devtools)\n- [Node.js 调试指南](https://nodejs.org/en/docs/guides/debugging-getting-started)\n- [React DevTools 使用指南](https://react.dev/learn/react-developer-tools)\n",[5291],{"type":24,"tag":969,"props":5292,"children":5293},{"__ignoreMap":7},[5294],{"type":30,"value":5289},{"title":7,"searchDepth":2524,"depth":2524,"links":5296},[5297,5298,5299,5304,5308,5313,5317,5321,5322,5323],{"id":4682,"depth":2527,"text":4685},{"id":4688,"depth":2527,"text":4691},{"id":4709,"depth":2527,"text":4712,"children":5300},[5301,5302,5303],{"id":4715,"depth":2524,"text":4718},{"id":4793,"depth":2524,"text":4796},{"id":4956,"depth":2524,"text":4959},{"id":4998,"depth":2527,"text":5001,"children":5305},[5306,5307],{"id":5004,"depth":2524,"text":5007},{"id":5024,"depth":2524,"text":5027},{"id":5044,"depth":2527,"text":5047,"children":5309},[5310,5311,5312],{"id":5050,"depth":2524,"text":5053},{"id":5065,"depth":2524,"text":5068},{"id":5080,"depth":2524,"text":5083},{"id":5097,"depth":2527,"text":5100,"children":5314},[5315,5316],{"id":5103,"depth":2524,"text":5106},{"id":5118,"depth":2524,"text":5121},{"id":5133,"depth":2527,"text":5136,"children":5318},[5319,5320],{"id":5139,"depth":2524,"text":5142},{"id":5153,"depth":2524,"text":5156},{"id":5187,"depth":2527,"text":5190},{"id":5232,"depth":2527,"text":5235},{"id":5260,"depth":2527,"text":5263},"content:topics:ai:ai-debugging-troubleshooting-guide.md","topics/ai/ai-debugging-troubleshooting-guide.md","topics/ai/ai-debugging-troubleshooting-guide",{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"date":10,"topic":5,"author":11,"tags":5328,"image":18,"featured":6,"readingTime":19,"body":5329,"_type":2566,"_id":2567,"_source":2568,"_file":2569,"_stem":2570,"_extension":2571},[13,14,15,16,17],{"type":21,"children":5330,"toc":7410},[5331,5335,5344,5353,5357,5384,5393,5397,5401,5405,5432,5436,5463,5470,5474,5766,5774,5801,5805,5809,5817,5832,5840,5891,5904,5908,5916,5927,5935,5978,5986,5990,5998,6009,6017,6052,6060,6064,6068,6072,6080,6099,6107,6115,6123,6138,6146,6157,6161,6165,6173,6192,6200,6208,6216,6224,6232,6247,6255,6270,6274,6278,6286,6301,6309,6317,6325,6333,6341,6356,6364,6379,6383,6387,6391,6426,6430,6457,6461,6469,6477,6485,6493,6501,6509,6520,6528,6539,6543,6551,6559,6567,6575,6616,6624,6635,6643,6654,6658,6666,6674,6682,6690,6705,6713,6728,6732,6736,6740,6878,6882,6890,6894,6902,6906,6910,6918,6945,6949,6953,6961,6988,6992,7000,7041,7045,7053,7072,7076,7080,7088,7107,7111,7115,7123,7158,7162,7170,7205,7209,7217,7244,7248,7263,7267,7302,7306,7310,7394,7397],{"type":24,"tag":25,"props":5332,"children":5333},{"id":27},[5334],{"type":30,"value":31},{"type":24,"tag":33,"props":5336,"children":5337},{},[5338,5339,5343],{"type":30,"value":37},{"type":24,"tag":39,"props":5340,"children":5341},{},[5342],{"type":30,"value":43},{"type":30,"value":45},{"type":24,"tag":33,"props":5345,"children":5346},{},[5347,5348,5352],{"type":30,"value":50},{"type":24,"tag":39,"props":5349,"children":5350},{},[5351],{"type":30,"value":55},{"type":30,"value":57},{"type":24,"tag":33,"props":5354,"children":5355},{},[5356],{"type":30,"value":62},{"type":24,"tag":64,"props":5358,"children":5359},{},[5360,5368,5376],{"type":24,"tag":68,"props":5361,"children":5362},{},[5363,5367],{"type":24,"tag":39,"props":5364,"children":5365},{},[5366],{"type":30,"value":75},{"type":30,"value":77},{"type":24,"tag":68,"props":5369,"children":5370},{},[5371,5375],{"type":24,"tag":39,"props":5372,"children":5373},{},[5374],{"type":30,"value":85},{"type":30,"value":87},{"type":24,"tag":68,"props":5377,"children":5378},{},[5379,5383],{"type":24,"tag":39,"props":5380,"children":5381},{},[5382],{"type":30,"value":95},{"type":30,"value":97},{"type":24,"tag":33,"props":5385,"children":5386},{},[5387,5388,5392],{"type":30,"value":102},{"type":24,"tag":39,"props":5389,"children":5390},{},[5391],{"type":30,"value":107},{"type":30,"value":109},{"type":24,"tag":25,"props":5394,"children":5395},{"id":112},[5396],{"type":30,"value":112},{"type":24,"tag":116,"props":5398,"children":5399},{"id":118},[5400],{"type":30,"value":121},{"type":24,"tag":33,"props":5402,"children":5403},{},[5404],{"type":30,"value":126},{"type":24,"tag":64,"props":5406,"children":5407},{},[5408,5416,5424],{"type":24,"tag":68,"props":5409,"children":5410},{},[5411,5415],{"type":24,"tag":39,"props":5412,"children":5413},{},[5414],{"type":30,"value":137},{"type":30,"value":139},{"type":24,"tag":68,"props":5417,"children":5418},{},[5419,5423],{"type":24,"tag":39,"props":5420,"children":5421},{},[5422],{"type":30,"value":147},{"type":30,"value":149},{"type":24,"tag":68,"props":5425,"children":5426},{},[5427,5431],{"type":24,"tag":39,"props":5428,"children":5429},{},[5430],{"type":30,"value":157},{"type":30,"value":159},{"type":24,"tag":33,"props":5433,"children":5434},{},[5435],{"type":30,"value":164},{"type":24,"tag":64,"props":5437,"children":5438},{},[5439,5447,5455],{"type":24,"tag":68,"props":5440,"children":5441},{},[5442,5446],{"type":24,"tag":39,"props":5443,"children":5444},{},[5445],{"type":30,"value":175},{"type":30,"value":177},{"type":24,"tag":68,"props":5448,"children":5449},{},[5450,5454],{"type":24,"tag":39,"props":5451,"children":5452},{},[5453],{"type":30,"value":185},{"type":30,"value":187},{"type":24,"tag":68,"props":5456,"children":5457},{},[5458,5462],{"type":24,"tag":39,"props":5459,"children":5460},{},[5461],{"type":30,"value":195},{"type":30,"value":197},{"type":24,"tag":33,"props":5464,"children":5465},{},[5466],{"type":24,"tag":39,"props":5467,"children":5468},{},[5469],{"type":30,"value":205},{"type":24,"tag":116,"props":5471,"children":5472},{"id":208},[5473],{"type":30,"value":208},{"type":24,"tag":212,"props":5475,"children":5476},{},[5477,5503],{"type":24,"tag":216,"props":5478,"children":5479},{},[5480],{"type":24,"tag":220,"props":5481,"children":5482},{},[5483,5487,5491,5495,5499],{"type":24,"tag":224,"props":5484,"children":5485},{},[5486],{"type":30,"value":228},{"type":24,"tag":224,"props":5488,"children":5489},{},[5490],{"type":30,"value":233},{"type":24,"tag":224,"props":5492,"children":5493},{},[5494],{"type":30,"value":238},{"type":24,"tag":224,"props":5496,"children":5497},{},[5498],{"type":30,"value":243},{"type":24,"tag":224,"props":5500,"children":5501},{},[5502],{"type":30,"value":248},{"type":24,"tag":250,"props":5504,"children":5505},{},[5506,5532,5558,5584,5610,5636,5662,5688,5714,5740],{"type":24,"tag":220,"props":5507,"children":5508},{},[5509,5516,5520,5524,5528],{"type":24,"tag":257,"props":5510,"children":5511},{},[5512],{"type":24,"tag":39,"props":5513,"children":5514},{},[5515],{"type":30,"value":264},{"type":24,"tag":257,"props":5517,"children":5518},{},[5519],{"type":30,"value":269},{"type":24,"tag":257,"props":5521,"children":5522},{},[5523],{"type":30,"value":274},{"type":24,"tag":257,"props":5525,"children":5526},{},[5527],{"type":30,"value":279},{"type":24,"tag":257,"props":5529,"children":5530},{},[5531],{"type":30,"value":284},{"type":24,"tag":220,"props":5533,"children":5534},{},[5535,5542,5546,5550,5554],{"type":24,"tag":257,"props":5536,"children":5537},{},[5538],{"type":24,"tag":39,"props":5539,"children":5540},{},[5541],{"type":30,"value":295},{"type":24,"tag":257,"props":5543,"children":5544},{},[5545],{"type":30,"value":300},{"type":24,"tag":257,"props":5547,"children":5548},{},[5549],{"type":30,"value":305},{"type":24,"tag":257,"props":5551,"children":5552},{},[5553],{"type":30,"value":310},{"type":24,"tag":257,"props":5555,"children":5556},{},[5557],{"type":30,"value":315},{"type":24,"tag":220,"props":5559,"children":5560},{},[5561,5568,5572,5576,5580],{"type":24,"tag":257,"props":5562,"children":5563},{},[5564],{"type":24,"tag":39,"props":5565,"children":5566},{},[5567],{"type":30,"value":326},{"type":24,"tag":257,"props":5569,"children":5570},{},[5571],{"type":30,"value":305},{"type":24,"tag":257,"props":5573,"children":5574},{},[5575],{"type":30,"value":269},{"type":24,"tag":257,"props":5577,"children":5578},{},[5579],{"type":30,"value":310},{"type":24,"tag":257,"props":5581,"children":5582},{},[5583],{"type":30,"value":343},{"type":24,"tag":220,"props":5585,"children":5586},{},[5587,5594,5598,5602,5606],{"type":24,"tag":257,"props":5588,"children":5589},{},[5590],{"type":24,"tag":39,"props":5591,"children":5592},{},[5593],{"type":30,"value":354},{"type":24,"tag":257,"props":5595,"children":5596},{},[5597],{"type":30,"value":305},{"type":24,"tag":257,"props":5599,"children":5600},{},[5601],{"type":30,"value":363},{"type":24,"tag":257,"props":5603,"children":5604},{},[5605],{"type":30,"value":310},{"type":24,"tag":257,"props":5607,"children":5608},{},[5609],{"type":30,"value":372},{"type":24,"tag":220,"props":5611,"children":5612},{},[5613,5620,5624,5628,5632],{"type":24,"tag":257,"props":5614,"children":5615},{},[5616],{"type":24,"tag":39,"props":5617,"children":5618},{},[5619],{"type":30,"value":383},{"type":24,"tag":257,"props":5621,"children":5622},{},[5623],{"type":30,"value":274},{"type":24,"tag":257,"props":5625,"children":5626},{},[5627],{"type":30,"value":392},{"type":24,"tag":257,"props":5629,"children":5630},{},[5631],{"type":30,"value":279},{"type":24,"tag":257,"props":5633,"children":5634},{},[5635],{"type":30,"value":401},{"type":24,"tag":220,"props":5637,"children":5638},{},[5639,5646,5650,5654,5658],{"type":24,"tag":257,"props":5640,"children":5641},{},[5642],{"type":24,"tag":39,"props":5643,"children":5644},{},[5645],{"type":30,"value":412},{"type":24,"tag":257,"props":5647,"children":5648},{},[5649],{"type":30,"value":305},{"type":24,"tag":257,"props":5651,"children":5652},{},[5653],{"type":30,"value":269},{"type":24,"tag":257,"props":5655,"children":5656},{},[5657],{"type":30,"value":310},{"type":24,"tag":257,"props":5659,"children":5660},{},[5661],{"type":30,"value":429},{"type":24,"tag":220,"props":5663,"children":5664},{},[5665,5672,5676,5680,5684],{"type":24,"tag":257,"props":5666,"children":5667},{},[5668],{"type":24,"tag":39,"props":5669,"children":5670},{},[5671],{"type":30,"value":440},{"type":24,"tag":257,"props":5673,"children":5674},{},[5675],{"type":30,"value":392},{"type":24,"tag":257,"props":5677,"children":5678},{},[5679],{"type":30,"value":449},{"type":24,"tag":257,"props":5681,"children":5682},{},[5683],{"type":30,"value":279},{"type":24,"tag":257,"props":5685,"children":5686},{},[5687],{"type":30,"value":458},{"type":24,"tag":220,"props":5689,"children":5690},{},[5691,5698,5702,5706,5710],{"type":24,"tag":257,"props":5692,"children":5693},{},[5694],{"type":24,"tag":39,"props":5695,"children":5696},{},[5697],{"type":30,"value":469},{"type":24,"tag":257,"props":5699,"children":5700},{},[5701],{"type":30,"value":269},{"type":24,"tag":257,"props":5703,"children":5704},{},[5705],{"type":30,"value":274},{"type":24,"tag":257,"props":5707,"children":5708},{},[5709],{"type":30,"value":482},{"type":24,"tag":257,"props":5711,"children":5712},{},[5713],{"type":30,"value":487},{"type":24,"tag":220,"props":5715,"children":5716},{},[5717,5724,5728,5732,5736],{"type":24,"tag":257,"props":5718,"children":5719},{},[5720],{"type":24,"tag":39,"props":5721,"children":5722},{},[5723],{"type":30,"value":498},{"type":24,"tag":257,"props":5725,"children":5726},{},[5727],{"type":30,"value":363},{"type":24,"tag":257,"props":5729,"children":5730},{},[5731],{"type":30,"value":507},{"type":24,"tag":257,"props":5733,"children":5734},{},[5735],{"type":30,"value":279},{"type":24,"tag":257,"props":5737,"children":5738},{},[5739],{"type":30,"value":516},{"type":24,"tag":220,"props":5741,"children":5742},{},[5743,5750,5754,5758,5762],{"type":24,"tag":257,"props":5744,"children":5745},{},[5746],{"type":24,"tag":39,"props":5747,"children":5748},{},[5749],{"type":30,"value":527},{"type":24,"tag":257,"props":5751,"children":5752},{},[5753],{"type":30,"value":305},{"type":24,"tag":257,"props":5755,"children":5756},{},[5757],{"type":30,"value":363},{"type":24,"tag":257,"props":5759,"children":5760},{},[5761],{"type":30,"value":540},{"type":24,"tag":257,"props":5763,"children":5764},{},[5765],{"type":30,"value":545},{"type":24,"tag":33,"props":5767,"children":5768},{},[5769,5773],{"type":24,"tag":39,"props":5770,"children":5771},{},[5772],{"type":30,"value":553},{"type":30,"value":555},{"type":24,"tag":64,"props":5775,"children":5776},{},[5777,5785,5793],{"type":24,"tag":68,"props":5778,"children":5779},{},[5780,5784],{"type":24,"tag":39,"props":5781,"children":5782},{},[5783],{"type":30,"value":566},{"type":30,"value":568},{"type":24,"tag":68,"props":5786,"children":5787},{},[5788,5792],{"type":24,"tag":39,"props":5789,"children":5790},{},[5791],{"type":30,"value":576},{"type":30,"value":578},{"type":24,"tag":68,"props":5794,"children":5795},{},[5796,5800],{"type":24,"tag":39,"props":5797,"children":5798},{},[5799],{"type":30,"value":586},{"type":30,"value":588},{"type":24,"tag":116,"props":5802,"children":5803},{"id":591},[5804],{"type":30,"value":591},{"type":24,"tag":595,"props":5806,"children":5807},{"id":597},[5808],{"type":30,"value":600},{"type":24,"tag":33,"props":5810,"children":5811},{},[5812,5816],{"type":24,"tag":39,"props":5813,"children":5814},{},[5815],{"type":30,"value":608},{"type":30,"value":610},{"type":24,"tag":64,"props":5818,"children":5819},{},[5820,5824,5828],{"type":24,"tag":68,"props":5821,"children":5822},{},[5823],{"type":30,"value":618},{"type":24,"tag":68,"props":5825,"children":5826},{},[5827],{"type":30,"value":623},{"type":24,"tag":68,"props":5829,"children":5830},{},[5831],{"type":30,"value":628},{"type":24,"tag":33,"props":5833,"children":5834},{},[5835,5839],{"type":24,"tag":39,"props":5836,"children":5837},{},[5838],{"type":30,"value":636},{"type":30,"value":610},{"type":24,"tag":639,"props":5841,"children":5842},{},[5843,5851,5859,5867,5875,5883],{"type":24,"tag":68,"props":5844,"children":5845},{},[5846,5850],{"type":24,"tag":39,"props":5847,"children":5848},{},[5849],{"type":30,"value":649},{"type":30,"value":651},{"type":24,"tag":68,"props":5852,"children":5853},{},[5854,5858],{"type":24,"tag":39,"props":5855,"children":5856},{},[5857],{"type":30,"value":659},{"type":30,"value":661},{"type":24,"tag":68,"props":5860,"children":5861},{},[5862,5866],{"type":24,"tag":39,"props":5863,"children":5864},{},[5865],{"type":30,"value":669},{"type":30,"value":671},{"type":24,"tag":68,"props":5868,"children":5869},{},[5870,5874],{"type":24,"tag":39,"props":5871,"children":5872},{},[5873],{"type":30,"value":679},{"type":30,"value":681},{"type":24,"tag":68,"props":5876,"children":5877},{},[5878,5882],{"type":24,"tag":39,"props":5879,"children":5880},{},[5881],{"type":30,"value":689},{"type":30,"value":691},{"type":24,"tag":68,"props":5884,"children":5885},{},[5886,5890],{"type":24,"tag":39,"props":5887,"children":5888},{},[5889],{"type":30,"value":699},{"type":30,"value":701},{"type":24,"tag":33,"props":5892,"children":5893},{},[5894,5898,5899,5903],{"type":24,"tag":39,"props":5895,"children":5896},{},[5897],{"type":30,"value":709},{"type":30,"value":711},{"type":24,"tag":39,"props":5900,"children":5901},{},[5902],{"type":30,"value":716},{"type":30,"value":718},{"type":24,"tag":595,"props":5905,"children":5906},{"id":721},[5907],{"type":30,"value":724},{"type":24,"tag":33,"props":5909,"children":5910},{},[5911,5915],{"type":24,"tag":39,"props":5912,"children":5913},{},[5914],{"type":30,"value":608},{"type":30,"value":610},{"type":24,"tag":64,"props":5917,"children":5918},{},[5919,5923],{"type":24,"tag":68,"props":5920,"children":5921},{},[5922],{"type":30,"value":740},{"type":24,"tag":68,"props":5924,"children":5925},{},[5926],{"type":30,"value":745},{"type":24,"tag":33,"props":5928,"children":5929},{},[5930,5934],{"type":24,"tag":39,"props":5931,"children":5932},{},[5933],{"type":30,"value":636},{"type":30,"value":610},{"type":24,"tag":639,"props":5936,"children":5937},{},[5938,5946,5954,5962,5970],{"type":24,"tag":68,"props":5939,"children":5940},{},[5941,5945],{"type":24,"tag":39,"props":5942,"children":5943},{},[5944],{"type":30,"value":764},{"type":30,"value":766},{"type":24,"tag":68,"props":5947,"children":5948},{},[5949,5953],{"type":24,"tag":39,"props":5950,"children":5951},{},[5952],{"type":30,"value":774},{"type":30,"value":776},{"type":24,"tag":68,"props":5955,"children":5956},{},[5957,5961],{"type":24,"tag":39,"props":5958,"children":5959},{},[5960],{"type":30,"value":784},{"type":30,"value":786},{"type":24,"tag":68,"props":5963,"children":5964},{},[5965,5969],{"type":24,"tag":39,"props":5966,"children":5967},{},[5968],{"type":30,"value":794},{"type":30,"value":796},{"type":24,"tag":68,"props":5971,"children":5972},{},[5973,5977],{"type":24,"tag":39,"props":5974,"children":5975},{},[5976],{"type":30,"value":804},{"type":30,"value":806},{"type":24,"tag":33,"props":5979,"children":5980},{},[5981,5985],{"type":24,"tag":39,"props":5982,"children":5983},{},[5984],{"type":30,"value":709},{"type":30,"value":815},{"type":24,"tag":595,"props":5987,"children":5988},{"id":818},[5989],{"type":30,"value":821},{"type":24,"tag":33,"props":5991,"children":5992},{},[5993,5997],{"type":24,"tag":39,"props":5994,"children":5995},{},[5996],{"type":30,"value":608},{"type":30,"value":610},{"type":24,"tag":64,"props":5999,"children":6000},{},[6001,6005],{"type":24,"tag":68,"props":6002,"children":6003},{},[6004],{"type":30,"value":837},{"type":24,"tag":68,"props":6006,"children":6007},{},[6008],{"type":30,"value":842},{"type":24,"tag":33,"props":6010,"children":6011},{},[6012,6016],{"type":24,"tag":39,"props":6013,"children":6014},{},[6015],{"type":30,"value":636},{"type":30,"value":610},{"type":24,"tag":639,"props":6018,"children":6019},{},[6020,6028,6036,6044],{"type":24,"tag":68,"props":6021,"children":6022},{},[6023,6027],{"type":24,"tag":39,"props":6024,"children":6025},{},[6026],{"type":30,"value":861},{"type":30,"value":863},{"type":24,"tag":68,"props":6029,"children":6030},{},[6031,6035],{"type":24,"tag":39,"props":6032,"children":6033},{},[6034],{"type":30,"value":871},{"type":30,"value":873},{"type":24,"tag":68,"props":6037,"children":6038},{},[6039,6043],{"type":24,"tag":39,"props":6040,"children":6041},{},[6042],{"type":30,"value":881},{"type":30,"value":883},{"type":24,"tag":68,"props":6045,"children":6046},{},[6047,6051],{"type":24,"tag":39,"props":6048,"children":6049},{},[6050],{"type":30,"value":891},{"type":30,"value":893},{"type":24,"tag":33,"props":6053,"children":6054},{},[6055,6059],{"type":24,"tag":39,"props":6056,"children":6057},{},[6058],{"type":30,"value":709},{"type":30,"value":902},{"type":24,"tag":25,"props":6061,"children":6062},{"id":905},[6063],{"type":30,"value":905},{"type":24,"tag":116,"props":6065,"children":6066},{"id":910},[6067],{"type":30,"value":913},{"type":24,"tag":33,"props":6069,"children":6070},{},[6071],{"type":30,"value":918},{"type":24,"tag":33,"props":6073,"children":6074},{},[6075,6079],{"type":24,"tag":39,"props":6076,"children":6077},{},[6078],{"type":30,"value":926},{"type":30,"value":610},{"type":24,"tag":639,"props":6081,"children":6082},{},[6083,6087,6091,6095],{"type":24,"tag":68,"props":6084,"children":6085},{},[6086],{"type":30,"value":935},{"type":24,"tag":68,"props":6088,"children":6089},{},[6090],{"type":30,"value":940},{"type":24,"tag":68,"props":6092,"children":6093},{},[6094],{"type":30,"value":945},{"type":24,"tag":68,"props":6096,"children":6097},{},[6098],{"type":30,"value":950},{"type":24,"tag":33,"props":6100,"children":6101},{},[6102,6106],{"type":24,"tag":39,"props":6103,"children":6104},{},[6105],{"type":30,"value":958},{"type":30,"value":610},{"type":24,"tag":961,"props":6108,"children":6110},{"className":6109,"code":965,"language":966,"meta":7},[964],[6111],{"type":24,"tag":969,"props":6112,"children":6113},{"__ignoreMap":7},[6114],{"type":30,"value":965},{"type":24,"tag":33,"props":6116,"children":6117},{},[6118,6122],{"type":24,"tag":39,"props":6119,"children":6120},{},[6121],{"type":30,"value":980},{"type":30,"value":610},{"type":24,"tag":64,"props":6124,"children":6125},{},[6126,6130,6134],{"type":24,"tag":68,"props":6127,"children":6128},{},[6129],{"type":30,"value":989},{"type":24,"tag":68,"props":6131,"children":6132},{},[6133],{"type":30,"value":994},{"type":24,"tag":68,"props":6135,"children":6136},{},[6137],{"type":30,"value":999},{"type":24,"tag":33,"props":6139,"children":6140},{},[6141,6145],{"type":24,"tag":39,"props":6142,"children":6143},{},[6144],{"type":30,"value":1007},{"type":30,"value":610},{"type":24,"tag":64,"props":6147,"children":6148},{},[6149,6153],{"type":24,"tag":68,"props":6150,"children":6151},{},[6152],{"type":30,"value":1016},{"type":24,"tag":68,"props":6154,"children":6155},{},[6156],{"type":30,"value":1021},{"type":24,"tag":116,"props":6158,"children":6159},{"id":1024},[6160],{"type":30,"value":1027},{"type":24,"tag":33,"props":6162,"children":6163},{},[6164],{"type":30,"value":1032},{"type":24,"tag":33,"props":6166,"children":6167},{},[6168,6172],{"type":24,"tag":39,"props":6169,"children":6170},{},[6171],{"type":30,"value":926},{"type":30,"value":610},{"type":24,"tag":639,"props":6174,"children":6175},{},[6176,6180,6184,6188],{"type":24,"tag":68,"props":6177,"children":6178},{},[6179],{"type":30,"value":1048},{"type":24,"tag":68,"props":6181,"children":6182},{},[6183],{"type":30,"value":1053},{"type":24,"tag":68,"props":6185,"children":6186},{},[6187],{"type":30,"value":1058},{"type":24,"tag":68,"props":6189,"children":6190},{},[6191],{"type":30,"value":1063},{"type":24,"tag":33,"props":6193,"children":6194},{},[6195,6199],{"type":24,"tag":39,"props":6196,"children":6197},{},[6198],{"type":30,"value":958},{"type":30,"value":610},{"type":24,"tag":961,"props":6201,"children":6203},{"className":6202,"code":1076,"language":1077,"meta":7},[1075],[6204],{"type":24,"tag":969,"props":6205,"children":6206},{"__ignoreMap":7},[6207],{"type":30,"value":1076},{"type":24,"tag":33,"props":6209,"children":6210},{},[6211,6215],{"type":24,"tag":39,"props":6212,"children":6213},{},[6214],{"type":30,"value":1090},{"type":30,"value":610},{"type":24,"tag":961,"props":6217,"children":6219},{"className":6218,"code":1096,"language":1097,"meta":7},[1095],[6220],{"type":24,"tag":969,"props":6221,"children":6222},{"__ignoreMap":7},[6223],{"type":30,"value":1096},{"type":24,"tag":33,"props":6225,"children":6226},{},[6227,6231],{"type":24,"tag":39,"props":6228,"children":6229},{},[6230],{"type":30,"value":980},{"type":30,"value":610},{"type":24,"tag":64,"props":6233,"children":6234},{},[6235,6239,6243],{"type":24,"tag":68,"props":6236,"children":6237},{},[6238],{"type":30,"value":1118},{"type":24,"tag":68,"props":6240,"children":6241},{},[6242],{"type":30,"value":1123},{"type":24,"tag":68,"props":6244,"children":6245},{},[6246],{"type":30,"value":1128},{"type":24,"tag":33,"props":6248,"children":6249},{},[6250,6254],{"type":24,"tag":39,"props":6251,"children":6252},{},[6253],{"type":30,"value":1007},{"type":30,"value":610},{"type":24,"tag":64,"props":6256,"children":6257},{},[6258,6262,6266],{"type":24,"tag":68,"props":6259,"children":6260},{},[6261],{"type":30,"value":1144},{"type":24,"tag":68,"props":6263,"children":6264},{},[6265],{"type":30,"value":1149},{"type":24,"tag":68,"props":6267,"children":6268},{},[6269],{"type":30,"value":1154},{"type":24,"tag":116,"props":6271,"children":6272},{"id":1157},[6273],{"type":30,"value":1160},{"type":24,"tag":33,"props":6275,"children":6276},{},[6277],{"type":30,"value":1165},{"type":24,"tag":33,"props":6279,"children":6280},{},[6281,6285],{"type":24,"tag":39,"props":6282,"children":6283},{},[6284],{"type":30,"value":926},{"type":30,"value":610},{"type":24,"tag":639,"props":6287,"children":6288},{},[6289,6293,6297],{"type":24,"tag":68,"props":6290,"children":6291},{},[6292],{"type":30,"value":1181},{"type":24,"tag":68,"props":6294,"children":6295},{},[6296],{"type":30,"value":1186},{"type":24,"tag":68,"props":6298,"children":6299},{},[6300],{"type":30,"value":1191},{"type":24,"tag":33,"props":6302,"children":6303},{},[6304,6308],{"type":24,"tag":39,"props":6305,"children":6306},{},[6307],{"type":30,"value":1199},{"type":30,"value":610},{"type":24,"tag":961,"props":6310,"children":6312},{"className":6311,"code":1204,"language":1097,"meta":7},[1095],[6313],{"type":24,"tag":969,"props":6314,"children":6315},{"__ignoreMap":7},[6316],{"type":30,"value":1204},{"type":24,"tag":33,"props":6318,"children":6319},{},[6320,6324],{"type":24,"tag":39,"props":6321,"children":6322},{},[6323],{"type":30,"value":1217},{"type":30,"value":610},{"type":24,"tag":961,"props":6326,"children":6328},{"className":6327,"code":1223,"language":1224,"meta":7},[1222],[6329],{"type":24,"tag":969,"props":6330,"children":6331},{"__ignoreMap":7},[6332],{"type":30,"value":1223},{"type":24,"tag":33,"props":6334,"children":6335},{},[6336,6340],{"type":24,"tag":39,"props":6337,"children":6338},{},[6339],{"type":30,"value":980},{"type":30,"value":610},{"type":24,"tag":64,"props":6342,"children":6343},{},[6344,6348,6352],{"type":24,"tag":68,"props":6345,"children":6346},{},[6347],{"type":30,"value":1245},{"type":24,"tag":68,"props":6349,"children":6350},{},[6351],{"type":30,"value":1250},{"type":24,"tag":68,"props":6353,"children":6354},{},[6355],{"type":30,"value":1255},{"type":24,"tag":33,"props":6357,"children":6358},{},[6359,6363],{"type":24,"tag":39,"props":6360,"children":6361},{},[6362],{"type":30,"value":1007},{"type":30,"value":610},{"type":24,"tag":64,"props":6365,"children":6366},{},[6367,6371,6375],{"type":24,"tag":68,"props":6368,"children":6369},{},[6370],{"type":30,"value":1271},{"type":24,"tag":68,"props":6372,"children":6373},{},[6374],{"type":30,"value":1276},{"type":24,"tag":68,"props":6376,"children":6377},{},[6378],{"type":30,"value":1281},{"type":24,"tag":25,"props":6380,"children":6381},{"id":1284},[6382],{"type":30,"value":1284},{"type":24,"tag":116,"props":6384,"children":6385},{"id":1289},[6386],{"type":30,"value":1292},{"type":24,"tag":33,"props":6388,"children":6389},{},[6390],{"type":30,"value":1297},{"type":24,"tag":64,"props":6392,"children":6393},{},[6394,6402,6410,6418],{"type":24,"tag":68,"props":6395,"children":6396},{},[6397,6401],{"type":24,"tag":39,"props":6398,"children":6399},{},[6400],{"type":30,"value":1308},{"type":30,"value":1310},{"type":24,"tag":68,"props":6403,"children":6404},{},[6405,6409],{"type":24,"tag":39,"props":6406,"children":6407},{},[6408],{"type":30,"value":1318},{"type":30,"value":1320},{"type":24,"tag":68,"props":6411,"children":6412},{},[6413,6417],{"type":24,"tag":39,"props":6414,"children":6415},{},[6416],{"type":30,"value":1328},{"type":30,"value":1330},{"type":24,"tag":68,"props":6419,"children":6420},{},[6421,6425],{"type":24,"tag":39,"props":6422,"children":6423},{},[6424],{"type":30,"value":1338},{"type":30,"value":1340},{"type":24,"tag":33,"props":6427,"children":6428},{},[6429],{"type":30,"value":1345},{"type":24,"tag":64,"props":6431,"children":6432},{},[6433,6441,6449],{"type":24,"tag":68,"props":6434,"children":6435},{},[6436,6440],{"type":24,"tag":39,"props":6437,"children":6438},{},[6439],{"type":30,"value":1356},{"type":30,"value":1358},{"type":24,"tag":68,"props":6442,"children":6443},{},[6444,6448],{"type":24,"tag":39,"props":6445,"children":6446},{},[6447],{"type":30,"value":1366},{"type":30,"value":1368},{"type":24,"tag":68,"props":6450,"children":6451},{},[6452,6456],{"type":24,"tag":39,"props":6453,"children":6454},{},[6455],{"type":30,"value":1376},{"type":30,"value":1378},{"type":24,"tag":116,"props":6458,"children":6459},{"id":1381},[6460],{"type":30,"value":1384},{"type":24,"tag":33,"props":6462,"children":6463},{},[6464,6468],{"type":24,"tag":39,"props":6465,"children":6466},{},[6467],{"type":30,"value":1392},{"type":30,"value":1394},{"type":24,"tag":33,"props":6470,"children":6471},{},[6472,6476],{"type":24,"tag":39,"props":6473,"children":6474},{},[6475],{"type":30,"value":1402},{"type":30,"value":610},{"type":24,"tag":961,"props":6478,"children":6480},{"className":6479,"code":1407,"language":1077,"meta":7},[1075],[6481],{"type":24,"tag":969,"props":6482,"children":6483},{"__ignoreMap":7},[6484],{"type":30,"value":1407},{"type":24,"tag":33,"props":6486,"children":6487},{},[6488,6492],{"type":24,"tag":39,"props":6489,"children":6490},{},[6491],{"type":30,"value":1420},{"type":30,"value":610},{"type":24,"tag":961,"props":6494,"children":6496},{"className":6495,"code":1425,"language":1077,"meta":7},[1075],[6497],{"type":24,"tag":969,"props":6498,"children":6499},{"__ignoreMap":7},[6500],{"type":30,"value":1425},{"type":24,"tag":33,"props":6502,"children":6503},{},[6504,6508],{"type":24,"tag":39,"props":6505,"children":6506},{},[6507],{"type":30,"value":980},{"type":30,"value":610},{"type":24,"tag":64,"props":6510,"children":6511},{},[6512,6516],{"type":24,"tag":68,"props":6513,"children":6514},{},[6515],{"type":30,"value":1446},{"type":24,"tag":68,"props":6517,"children":6518},{},[6519],{"type":30,"value":1451},{"type":24,"tag":33,"props":6521,"children":6522},{},[6523,6527],{"type":24,"tag":39,"props":6524,"children":6525},{},[6526],{"type":30,"value":1007},{"type":30,"value":610},{"type":24,"tag":64,"props":6529,"children":6530},{},[6531,6535],{"type":24,"tag":68,"props":6532,"children":6533},{},[6534],{"type":30,"value":1467},{"type":24,"tag":68,"props":6536,"children":6537},{},[6538],{"type":30,"value":1472},{"type":24,"tag":116,"props":6540,"children":6541},{"id":1475},[6542],{"type":30,"value":1478},{"type":24,"tag":33,"props":6544,"children":6545},{},[6546,6550],{"type":24,"tag":39,"props":6547,"children":6548},{},[6549],{"type":30,"value":1392},{"type":30,"value":1487},{"type":24,"tag":33,"props":6552,"children":6553},{},[6554,6558],{"type":24,"tag":39,"props":6555,"children":6556},{},[6557],{"type":30,"value":1402},{"type":30,"value":610},{"type":24,"tag":961,"props":6560,"children":6562},{"className":6561,"code":1499,"language":1077,"meta":7},[1075],[6563],{"type":24,"tag":969,"props":6564,"children":6565},{"__ignoreMap":7},[6566],{"type":30,"value":1499},{"type":24,"tag":33,"props":6568,"children":6569},{},[6570,6574],{"type":24,"tag":39,"props":6571,"children":6572},{},[6573],{"type":30,"value":1512},{"type":30,"value":610},{"type":24,"tag":64,"props":6576,"children":6577},{},[6578,6592,6600,6608],{"type":24,"tag":68,"props":6579,"children":6580},{},[6581,6585,6586,6591],{"type":24,"tag":39,"props":6582,"children":6583},{},[6584],{"type":30,"value":1524},{"type":30,"value":1526},{"type":24,"tag":969,"props":6587,"children":6589},{"className":6588},[],[6590],{"type":30,"value":1532},{"type":30,"value":1534},{"type":24,"tag":68,"props":6593,"children":6594},{},[6595,6599],{"type":24,"tag":39,"props":6596,"children":6597},{},[6598],{"type":30,"value":1542},{"type":30,"value":1544},{"type":24,"tag":68,"props":6601,"children":6602},{},[6603,6607],{"type":24,"tag":39,"props":6604,"children":6605},{},[6606],{"type":30,"value":1552},{"type":30,"value":1554},{"type":24,"tag":68,"props":6609,"children":6610},{},[6611,6615],{"type":24,"tag":39,"props":6612,"children":6613},{},[6614],{"type":30,"value":1562},{"type":30,"value":1564},{"type":24,"tag":33,"props":6617,"children":6618},{},[6619,6623],{"type":24,"tag":39,"props":6620,"children":6621},{},[6622],{"type":30,"value":980},{"type":30,"value":610},{"type":24,"tag":64,"props":6625,"children":6626},{},[6627,6631],{"type":24,"tag":68,"props":6628,"children":6629},{},[6630],{"type":30,"value":1580},{"type":24,"tag":68,"props":6632,"children":6633},{},[6634],{"type":30,"value":1585},{"type":24,"tag":33,"props":6636,"children":6637},{},[6638,6642],{"type":24,"tag":39,"props":6639,"children":6640},{},[6641],{"type":30,"value":1007},{"type":30,"value":610},{"type":24,"tag":64,"props":6644,"children":6645},{},[6646,6650],{"type":24,"tag":68,"props":6647,"children":6648},{},[6649],{"type":30,"value":1601},{"type":24,"tag":68,"props":6651,"children":6652},{},[6653],{"type":30,"value":1606},{"type":24,"tag":116,"props":6655,"children":6656},{"id":1609},[6657],{"type":30,"value":1612},{"type":24,"tag":33,"props":6659,"children":6660},{},[6661,6665],{"type":24,"tag":39,"props":6662,"children":6663},{},[6664],{"type":30,"value":1392},{"type":30,"value":1621},{"type":24,"tag":33,"props":6667,"children":6668},{},[6669,6673],{"type":24,"tag":39,"props":6670,"children":6671},{},[6672],{"type":30,"value":1402},{"type":30,"value":610},{"type":24,"tag":961,"props":6675,"children":6677},{"className":6676,"code":1633,"language":1097,"meta":7},[1095],[6678],{"type":24,"tag":969,"props":6679,"children":6680},{"__ignoreMap":7},[6681],{"type":30,"value":1633},{"type":24,"tag":33,"props":6683,"children":6684},{},[6685,6689],{"type":24,"tag":39,"props":6686,"children":6687},{},[6688],{"type":30,"value":1646},{"type":30,"value":610},{"type":24,"tag":64,"props":6691,"children":6692},{},[6693,6697,6701],{"type":24,"tag":68,"props":6694,"children":6695},{},[6696],{"type":30,"value":1655},{"type":24,"tag":68,"props":6698,"children":6699},{},[6700],{"type":30,"value":1660},{"type":24,"tag":68,"props":6702,"children":6703},{},[6704],{"type":30,"value":1665},{"type":24,"tag":33,"props":6706,"children":6707},{},[6708,6712],{"type":24,"tag":39,"props":6709,"children":6710},{},[6711],{"type":30,"value":1673},{"type":30,"value":610},{"type":24,"tag":64,"props":6714,"children":6715},{},[6716,6720,6724],{"type":24,"tag":68,"props":6717,"children":6718},{},[6719],{"type":30,"value":1682},{"type":24,"tag":68,"props":6721,"children":6722},{},[6723],{"type":30,"value":1687},{"type":24,"tag":68,"props":6725,"children":6726},{},[6727],{"type":30,"value":1692},{"type":24,"tag":25,"props":6729,"children":6730},{"id":1695},[6731],{"type":30,"value":1695},{"type":24,"tag":116,"props":6733,"children":6734},{"id":1700},[6735],{"type":30,"value":1700},{"type":24,"tag":33,"props":6737,"children":6738},{},[6739],{"type":30,"value":1707},{"type":24,"tag":212,"props":6741,"children":6742},{},[6743,6761],{"type":24,"tag":216,"props":6744,"children":6745},{},[6746],{"type":24,"tag":220,"props":6747,"children":6748},{},[6749,6753,6757],{"type":24,"tag":224,"props":6750,"children":6751},{},[6752],{"type":30,"value":1721},{"type":24,"tag":224,"props":6754,"children":6755},{},[6756],{"type":30,"value":248},{"type":24,"tag":224,"props":6758,"children":6759},{},[6760],{"type":30,"value":1730},{"type":24,"tag":250,"props":6762,"children":6763},{},[6764,6783,6802,6821,6840,6859],{"type":24,"tag":220,"props":6765,"children":6766},{},[6767,6775,6779],{"type":24,"tag":257,"props":6768,"children":6769},{},[6770],{"type":24,"tag":969,"props":6771,"children":6773},{"className":6772},[],[6774],{"type":30,"value":1745},{"type":24,"tag":257,"props":6776,"children":6777},{},[6778],{"type":30,"value":1750},{"type":24,"tag":257,"props":6780,"children":6781},{},[6782],{"type":30,"value":1755},{"type":24,"tag":220,"props":6784,"children":6785},{},[6786,6794,6798],{"type":24,"tag":257,"props":6787,"children":6788},{},[6789],{"type":24,"tag":969,"props":6790,"children":6792},{"className":6791},[],[6793],{"type":30,"value":1767},{"type":24,"tag":257,"props":6795,"children":6796},{},[6797],{"type":30,"value":1772},{"type":24,"tag":257,"props":6799,"children":6800},{},[6801],{"type":30,"value":1777},{"type":24,"tag":220,"props":6803,"children":6804},{},[6805,6813,6817],{"type":24,"tag":257,"props":6806,"children":6807},{},[6808],{"type":24,"tag":969,"props":6809,"children":6811},{"className":6810},[],[6812],{"type":30,"value":1789},{"type":24,"tag":257,"props":6814,"children":6815},{},[6816],{"type":30,"value":1794},{"type":24,"tag":257,"props":6818,"children":6819},{},[6820],{"type":30,"value":1799},{"type":24,"tag":220,"props":6822,"children":6823},{},[6824,6832,6836],{"type":24,"tag":257,"props":6825,"children":6826},{},[6827],{"type":24,"tag":969,"props":6828,"children":6830},{"className":6829},[],[6831],{"type":30,"value":1811},{"type":24,"tag":257,"props":6833,"children":6834},{},[6835],{"type":30,"value":1816},{"type":24,"tag":257,"props":6837,"children":6838},{},[6839],{"type":30,"value":1821},{"type":24,"tag":220,"props":6841,"children":6842},{},[6843,6851,6855],{"type":24,"tag":257,"props":6844,"children":6845},{},[6846],{"type":24,"tag":969,"props":6847,"children":6849},{"className":6848},[],[6850],{"type":30,"value":1833},{"type":24,"tag":257,"props":6852,"children":6853},{},[6854],{"type":30,"value":1838},{"type":24,"tag":257,"props":6856,"children":6857},{},[6858],{"type":30,"value":1843},{"type":24,"tag":220,"props":6860,"children":6861},{},[6862,6870,6874],{"type":24,"tag":257,"props":6863,"children":6864},{},[6865],{"type":24,"tag":969,"props":6866,"children":6868},{"className":6867},[],[6869],{"type":30,"value":1855},{"type":24,"tag":257,"props":6871,"children":6872},{},[6873],{"type":30,"value":1860},{"type":24,"tag":257,"props":6875,"children":6876},{},[6877],{"type":30,"value":1865},{"type":24,"tag":116,"props":6879,"children":6880},{"id":1868},[6881],{"type":30,"value":1868},{"type":24,"tag":961,"props":6883,"children":6885},{"className":6884,"code":1875,"language":1876,"meta":7},[1874],[6886],{"type":24,"tag":969,"props":6887,"children":6888},{"__ignoreMap":7},[6889],{"type":30,"value":1875},{"type":24,"tag":116,"props":6891,"children":6892},{"id":1884},[6893],{"type":30,"value":1884},{"type":24,"tag":961,"props":6895,"children":6897},{"className":6896,"code":1891,"language":1892,"meta":7},[1890],[6898],{"type":24,"tag":969,"props":6899,"children":6900},{"__ignoreMap":7},[6901],{"type":30,"value":1891},{"type":24,"tag":25,"props":6903,"children":6904},{"id":1900},[6905],{"type":30,"value":1903},{"type":24,"tag":116,"props":6907,"children":6908},{"id":1906},[6909],{"type":30,"value":1909},{"type":24,"tag":33,"props":6911,"children":6912},{},[6913,6917],{"type":24,"tag":39,"props":6914,"children":6915},{},[6916],{"type":30,"value":1917},{"type":30,"value":1919},{"type":24,"tag":64,"props":6919,"children":6920},{},[6921,6929,6937],{"type":24,"tag":68,"props":6922,"children":6923},{},[6924,6928],{"type":24,"tag":39,"props":6925,"children":6926},{},[6927],{"type":30,"value":1930},{"type":30,"value":1932},{"type":24,"tag":68,"props":6930,"children":6931},{},[6932,6936],{"type":24,"tag":39,"props":6933,"children":6934},{},[6935],{"type":30,"value":1940},{"type":30,"value":1942},{"type":24,"tag":68,"props":6938,"children":6939},{},[6940,6944],{"type":24,"tag":39,"props":6941,"children":6942},{},[6943],{"type":30,"value":1950},{"type":30,"value":1952},{"type":24,"tag":33,"props":6946,"children":6947},{},[6948],{"type":30,"value":1957},{"type":24,"tag":116,"props":6950,"children":6951},{"id":1960},[6952],{"type":30,"value":1963},{"type":24,"tag":33,"props":6954,"children":6955},{},[6956,6960],{"type":24,"tag":39,"props":6957,"children":6958},{},[6959],{"type":30,"value":1917},{"type":30,"value":1972},{"type":24,"tag":639,"props":6962,"children":6963},{},[6964,6972,6980],{"type":24,"tag":68,"props":6965,"children":6966},{},[6967,6971],{"type":24,"tag":39,"props":6968,"children":6969},{},[6970],{"type":30,"value":1983},{"type":30,"value":1985},{"type":24,"tag":68,"props":6973,"children":6974},{},[6975,6979],{"type":24,"tag":39,"props":6976,"children":6977},{},[6978],{"type":30,"value":1993},{"type":30,"value":1995},{"type":24,"tag":68,"props":6981,"children":6982},{},[6983,6987],{"type":24,"tag":39,"props":6984,"children":6985},{},[6986],{"type":30,"value":2003},{"type":30,"value":2005},{"type":24,"tag":116,"props":6989,"children":6990},{"id":2008},[6991],{"type":30,"value":2011},{"type":24,"tag":33,"props":6993,"children":6994},{},[6995,6999],{"type":24,"tag":39,"props":6996,"children":6997},{},[6998],{"type":30,"value":1917},{"type":30,"value":2020},{"type":24,"tag":64,"props":7001,"children":7002},{},[7003,7011,7019,7027],{"type":24,"tag":68,"props":7004,"children":7005},{},[7006,7010],{"type":24,"tag":39,"props":7007,"children":7008},{},[7009],{"type":30,"value":2031},{"type":30,"value":2033},{"type":24,"tag":68,"props":7012,"children":7013},{},[7014,7018],{"type":24,"tag":39,"props":7015,"children":7016},{},[7017],{"type":30,"value":2041},{"type":30,"value":2043},{"type":24,"tag":68,"props":7020,"children":7021},{},[7022,7026],{"type":24,"tag":39,"props":7023,"children":7024},{},[7025],{"type":30,"value":2051},{"type":30,"value":2053},{"type":24,"tag":68,"props":7028,"children":7029},{},[7030,7034,7035,7040],{"type":24,"tag":39,"props":7031,"children":7032},{},[7033],{"type":30,"value":2061},{"type":30,"value":2063},{"type":24,"tag":969,"props":7036,"children":7038},{"className":7037},[],[7039],{"type":30,"value":2069},{"type":30,"value":2071},{"type":24,"tag":116,"props":7042,"children":7043},{"id":2074},[7044],{"type":30,"value":2077},{"type":24,"tag":33,"props":7046,"children":7047},{},[7048,7052],{"type":24,"tag":39,"props":7049,"children":7050},{},[7051],{"type":30,"value":1917},{"type":30,"value":2020},{"type":24,"tag":64,"props":7054,"children":7055},{},[7056,7064],{"type":24,"tag":68,"props":7057,"children":7058},{},[7059,7063],{"type":24,"tag":39,"props":7060,"children":7061},{},[7062],{"type":30,"value":2096},{"type":30,"value":2098},{"type":24,"tag":68,"props":7065,"children":7066},{},[7067,7071],{"type":24,"tag":39,"props":7068,"children":7069},{},[7070],{"type":30,"value":2106},{"type":30,"value":2108},{"type":24,"tag":33,"props":7073,"children":7074},{},[7075],{"type":30,"value":2113},{"type":24,"tag":116,"props":7077,"children":7078},{"id":2116},[7079],{"type":30,"value":2119},{"type":24,"tag":33,"props":7081,"children":7082},{},[7083,7087],{"type":24,"tag":39,"props":7084,"children":7085},{},[7086],{"type":30,"value":1917},{"type":30,"value":2128},{"type":24,"tag":64,"props":7089,"children":7090},{},[7091,7099],{"type":24,"tag":68,"props":7092,"children":7093},{},[7094,7098],{"type":24,"tag":39,"props":7095,"children":7096},{},[7097],{"type":30,"value":2139},{"type":30,"value":2141},{"type":24,"tag":68,"props":7100,"children":7101},{},[7102,7106],{"type":24,"tag":39,"props":7103,"children":7104},{},[7105],{"type":30,"value":2149},{"type":30,"value":2151},{"type":24,"tag":33,"props":7108,"children":7109},{},[7110],{"type":30,"value":2156},{"type":24,"tag":116,"props":7112,"children":7113},{"id":2159},[7114],{"type":30,"value":2162},{"type":24,"tag":33,"props":7116,"children":7117},{},[7118,7122],{"type":24,"tag":39,"props":7119,"children":7120},{},[7121],{"type":30,"value":1917},{"type":30,"value":2020},{"type":24,"tag":64,"props":7124,"children":7125},{},[7126,7134,7142,7150],{"type":24,"tag":68,"props":7127,"children":7128},{},[7129,7133],{"type":24,"tag":39,"props":7130,"children":7131},{},[7132],{"type":30,"value":2181},{"type":30,"value":2183},{"type":24,"tag":68,"props":7135,"children":7136},{},[7137,7141],{"type":24,"tag":39,"props":7138,"children":7139},{},[7140],{"type":30,"value":2191},{"type":30,"value":2193},{"type":24,"tag":68,"props":7143,"children":7144},{},[7145,7149],{"type":24,"tag":39,"props":7146,"children":7147},{},[7148],{"type":30,"value":2201},{"type":30,"value":2203},{"type":24,"tag":68,"props":7151,"children":7152},{},[7153,7157],{"type":24,"tag":39,"props":7154,"children":7155},{},[7156],{"type":30,"value":2211},{"type":30,"value":2213},{"type":24,"tag":116,"props":7159,"children":7160},{"id":2216},[7161],{"type":30,"value":2219},{"type":24,"tag":33,"props":7163,"children":7164},{},[7165,7169],{"type":24,"tag":39,"props":7166,"children":7167},{},[7168],{"type":30,"value":1917},{"type":30,"value":2020},{"type":24,"tag":64,"props":7171,"children":7172},{},[7173,7181,7189,7197],{"type":24,"tag":68,"props":7174,"children":7175},{},[7176,7180],{"type":24,"tag":39,"props":7177,"children":7178},{},[7179],{"type":30,"value":1950},{"type":30,"value":2239},{"type":24,"tag":68,"props":7182,"children":7183},{},[7184,7188],{"type":24,"tag":39,"props":7185,"children":7186},{},[7187],{"type":30,"value":2247},{"type":30,"value":2249},{"type":24,"tag":68,"props":7190,"children":7191},{},[7192,7196],{"type":24,"tag":39,"props":7193,"children":7194},{},[7195],{"type":30,"value":2257},{"type":30,"value":2259},{"type":24,"tag":68,"props":7198,"children":7199},{},[7200,7204],{"type":24,"tag":39,"props":7201,"children":7202},{},[7203],{"type":30,"value":2267},{"type":30,"value":2269},{"type":24,"tag":116,"props":7206,"children":7207},{"id":2272},[7208],{"type":30,"value":2275},{"type":24,"tag":33,"props":7210,"children":7211},{},[7212,7216],{"type":24,"tag":39,"props":7213,"children":7214},{},[7215],{"type":30,"value":1917},{"type":30,"value":2284},{"type":24,"tag":64,"props":7218,"children":7219},{},[7220,7228,7236],{"type":24,"tag":68,"props":7221,"children":7222},{},[7223,7227],{"type":24,"tag":39,"props":7224,"children":7225},{},[7226],{"type":30,"value":2295},{"type":30,"value":2297},{"type":24,"tag":68,"props":7229,"children":7230},{},[7231,7235],{"type":24,"tag":39,"props":7232,"children":7233},{},[7234],{"type":30,"value":2305},{"type":30,"value":2307},{"type":24,"tag":68,"props":7237,"children":7238},{},[7239,7243],{"type":24,"tag":39,"props":7240,"children":7241},{},[7242],{"type":30,"value":2315},{"type":30,"value":2317},{"type":24,"tag":33,"props":7245,"children":7246},{},[7247],{"type":30,"value":2322},{"type":24,"tag":64,"props":7249,"children":7250},{},[7251,7255,7259],{"type":24,"tag":68,"props":7252,"children":7253},{},[7254],{"type":30,"value":2330},{"type":24,"tag":68,"props":7256,"children":7257},{},[7258],{"type":30,"value":2335},{"type":24,"tag":68,"props":7260,"children":7261},{},[7262],{"type":30,"value":2340},{"type":24,"tag":25,"props":7264,"children":7265},{"id":2343},[7266],{"type":30,"value":2343},{"type":24,"tag":64,"props":7268,"children":7269},{},[7270,7278,7286,7294],{"type":24,"tag":68,"props":7271,"children":7272},{},[7273],{"type":24,"tag":2353,"props":7274,"children":7276},{"href":2355,"rel":7275},[2357],[7277],{"type":30,"value":2360},{"type":24,"tag":68,"props":7279,"children":7280},{},[7281],{"type":24,"tag":2353,"props":7282,"children":7284},{"href":2366,"rel":7283},[2357],[7285],{"type":30,"value":2370},{"type":24,"tag":68,"props":7287,"children":7288},{},[7289],{"type":24,"tag":2353,"props":7290,"children":7292},{"href":2376,"rel":7291},[2357],[7293],{"type":30,"value":2380},{"type":24,"tag":68,"props":7295,"children":7296},{},[7297],{"type":24,"tag":2353,"props":7298,"children":7300},{"href":2386,"rel":7299},[2357],[7301],{"type":30,"value":2390},{"type":24,"tag":25,"props":7303,"children":7304},{"id":2393},[7305],{"type":30,"value":2396},{"type":24,"tag":33,"props":7307,"children":7308},{},[7309],{"type":30,"value":2401},{"type":24,"tag":64,"props":7311,"children":7313},{"className":7312},[2405],[7314,7322,7330,7338,7346,7354,7362,7370,7378,7386],{"type":24,"tag":68,"props":7315,"children":7317},{"className":7316},[2410],[7318,7321],{"type":24,"tag":2413,"props":7319,"children":7320},{"disabled":2415,"type":2416},[],{"type":30,"value":2419},{"type":24,"tag":68,"props":7323,"children":7325},{"className":7324},[2410],[7326,7329],{"type":24,"tag":2413,"props":7327,"children":7328},{"disabled":2415,"type":2416},[],{"type":30,"value":2428},{"type":24,"tag":68,"props":7331,"children":7333},{"className":7332},[2410],[7334,7337],{"type":24,"tag":2413,"props":7335,"children":7336},{"disabled":2415,"type":2416},[],{"type":30,"value":2437},{"type":24,"tag":68,"props":7339,"children":7341},{"className":7340},[2410],[7342,7345],{"type":24,"tag":2413,"props":7343,"children":7344},{"disabled":2415,"type":2416},[],{"type":30,"value":2446},{"type":24,"tag":68,"props":7347,"children":7349},{"className":7348},[2410],[7350,7353],{"type":24,"tag":2413,"props":7351,"children":7352},{"disabled":2415,"type":2416},[],{"type":30,"value":2455},{"type":24,"tag":68,"props":7355,"children":7357},{"className":7356},[2410],[7358,7361],{"type":24,"tag":2413,"props":7359,"children":7360},{"disabled":2415,"type":2416},[],{"type":30,"value":2464},{"type":24,"tag":68,"props":7363,"children":7365},{"className":7364},[2410],[7366,7369],{"type":24,"tag":2413,"props":7367,"children":7368},{"disabled":2415,"type":2416},[],{"type":30,"value":2473},{"type":24,"tag":68,"props":7371,"children":7373},{"className":7372},[2410],[7374,7377],{"type":24,"tag":2413,"props":7375,"children":7376},{"disabled":2415,"type":2416},[],{"type":30,"value":2482},{"type":24,"tag":68,"props":7379,"children":7381},{"className":7380},[2410],[7382,7385],{"type":24,"tag":2413,"props":7383,"children":7384},{"disabled":2415,"type":2416},[],{"type":30,"value":2491},{"type":24,"tag":68,"props":7387,"children":7389},{"className":7388},[2410],[7390,7393],{"type":24,"tag":2413,"props":7391,"children":7392},{"disabled":2415,"type":2416},[],{"type":30,"value":2500},{"type":24,"tag":2502,"props":7395,"children":7396},{},[],{"type":24,"tag":33,"props":7398,"children":7399},{},[7400,7404,7405,7409],{"type":24,"tag":39,"props":7401,"children":7402},{},[7403],{"type":30,"value":2512},{"type":30,"value":2514},{"type":24,"tag":2353,"props":7406,"children":7407},{"href":2517},[7408],{"type":30,"value":2520},{"type":30,"value":2522},{"title":7,"searchDepth":2524,"depth":2524,"links":7411},[7412,7413,7422,7427,7433,7438,7448,7449],{"id":27,"depth":2527,"text":31},{"id":112,"depth":2527,"text":112,"children":7414},[7415,7416,7417],{"id":118,"depth":2524,"text":121},{"id":208,"depth":2524,"text":208},{"id":591,"depth":2524,"text":591,"children":7418},[7419,7420,7421],{"id":597,"depth":2535,"text":600},{"id":721,"depth":2535,"text":724},{"id":818,"depth":2535,"text":821},{"id":905,"depth":2527,"text":905,"children":7423},[7424,7425,7426],{"id":910,"depth":2524,"text":913},{"id":1024,"depth":2524,"text":1027},{"id":1157,"depth":2524,"text":1160},{"id":1284,"depth":2527,"text":1284,"children":7428},[7429,7430,7431,7432],{"id":1289,"depth":2524,"text":1292},{"id":1381,"depth":2524,"text":1384},{"id":1475,"depth":2524,"text":1478},{"id":1609,"depth":2524,"text":1612},{"id":1695,"depth":2527,"text":1695,"children":7434},[7435,7436,7437],{"id":1700,"depth":2524,"text":1700},{"id":1868,"depth":2524,"text":1868},{"id":1884,"depth":2524,"text":1884},{"id":1900,"depth":2527,"text":1903,"children":7439},[7440,7441,7442,7443,7444,7445,7446,7447],{"id":1906,"depth":2524,"text":1909},{"id":1960,"depth":2524,"text":1963},{"id":2008,"depth":2524,"text":2011},{"id":2074,"depth":2524,"text":2077},{"id":2116,"depth":2524,"text":2119},{"id":2159,"depth":2524,"text":2162},{"id":2216,"depth":2524,"text":2219},{"id":2272,"depth":2524,"text":2275},{"id":2343,"depth":2527,"text":2343},{"id":2393,"depth":2527,"text":2396},1782088242280]