[{"data":1,"prerenderedAt":6269},["ShallowReactive",2],{"article-/topics/ai/ai-agent-credential-vault-design":3,"related-ai":1943,"content-query-lW549V8c0I":4706},{"_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":1937,"_id":1938,"_source":1939,"_file":1940,"_stem":1941,"_extension":1942},"/topics/ai/ai-agent-credential-vault-design","ai",false,"","AI agent Credential Vault 设计：API Key、OAuth Token 和 Service Account 如何集中托管","很多团队把凭证散落在 .env 文件和代码仓库里，真正上线后才发现泄露风险、轮换困难和审计缺失。本文讲清 AI agent credential vault 的分层架构、权限模型、审计要求和迁移路径，并提供 HashiCorp Vault、AWS Secrets Manager 和自建方案的对比。","2026-06-15","HTMLPAGE 团队",[13,14,15,16,17],"credential vault","API key management","OAuth token storage","secret management","service account","/images/articles/as01-featured.jpeg",15,{"type":21,"children":22,"toc":1887},"root",[23,32,47,60,102,114,120,127,132,176,188,194,206,239,248,254,259,302,307,340,346,351,362,367,400,405,411,421,430,448,457,475,484,492,498,507,515,533,541,559,568,577,583,592,600,618,626,644,652,660,677,682,688,693,704,713,746,752,757,766,774,792,797,803,808,817,838,844,849,858,876,882,887,896,914,920,932,938,981,987,1030,1036,1089,1095,1145,1151,1209,1214,1220,1230,1239,1262,1268,1277,1285,1303,1309,1326,1334,1352,1358,1367,1375,1393,1399,1405,1422,1428,1437,1469,1474,1480,1489,1495,1504,1522,1528,1536,1559,1565,1573,1596,1601,1607,1616,1634,1640,1649,1705,1710,1755,1761,1766,1865,1869],{"type":24,"tag":25,"props":26,"children":28},"element","h2",{"id":27},"为什么你的-ai-agent-需要-credential-vault",[29],{"type":30,"value":31},"text","为什么你的 AI agent 需要 Credential Vault？",{"type":24,"tag":33,"props":34,"children":35},"p",{},[36,38,45],{"type":30,"value":37},"上周三凌晨 2 点，某电商团队的 on-call 工程师收到告警：生产环境的 OpenAI API Key 被异常调用，过去 3 小时内产生了 $2,400 的账单。排查后发现，这个密钥硬编码在一个测试脚本的 ",{"type":24,"tag":39,"props":40,"children":42},"code",{"className":41},[],[43],{"type":30,"value":44},".env",{"type":30,"value":46}," 文件里，两个月前被误提交到内部 GitLab，虽然很快删除了 commit，但密钥已经泄露到多个开发者的本地副本中。",{"type":24,"tag":33,"props":48,"children":49},{},[50,52,58],{"type":30,"value":51},"这不是孤例。根据 GitGuardian 2025 年的报告，",{"type":24,"tag":53,"props":54,"children":55},"strong",{},[56],{"type":30,"value":57},"73% 的团队曾在代码仓库中暴露过 API 密钥",{"type":30,"value":59},"，平均检测时间为 187 天。对于 AI agent 系统来说，问题更复杂：一个 agent 可能需要访问 OpenAI、Anthropic、数据库、向量存储、外部 API 等十几个服务的凭证，这些凭证如果分散管理，会带来三大风险：",{"type":24,"tag":61,"props":62,"children":63},"ol",{},[64,82,92],{"type":24,"tag":65,"props":66,"children":67},"li",{},[68,73,75,80],{"type":24,"tag":53,"props":69,"children":70},{},[71],{"type":30,"value":72},"泄露风险",{"type":30,"value":74},"：凭证散落在 ",{"type":24,"tag":39,"props":76,"children":78},{"className":77},[],[79],{"type":30,"value":44},{"type":30,"value":81}," 文件、配置文件、代码注释甚至 Slack 消息中，任何有代码访问权限的人都可能看到。",{"type":24,"tag":65,"props":83,"children":84},{},[85,90],{"type":24,"tag":53,"props":86,"children":87},{},[88],{"type":30,"value":89},"轮换困难",{"type":30,"value":91},"：手动轮换十几个服务的密钥既耗时又容易遗漏，旧凭证可能在系统中继续运行数周。",{"type":24,"tag":65,"props":93,"children":94},{},[95,100],{"type":24,"tag":53,"props":96,"children":97},{},[98],{"type":30,"value":99},"审计缺失",{"type":30,"value":101},"：谁在什么时候使用了哪个凭证？出了事无法追溯责任。",{"type":24,"tag":33,"props":103,"children":104},{},[105,107,112],{"type":30,"value":106},"Credential Vault（凭证保险库）就是为了解决这些问题而设计的集中式凭证管理系统。它不是简单的\"密码管理器\"，而是提供",{"type":24,"tag":53,"props":108,"children":109},{},[110],{"type":30,"value":111},"加密存储、动态凭证、租约管理、细粒度权限控制和完整审计日志",{"type":30,"value":113},"的运行时基座。",{"type":24,"tag":25,"props":115,"children":117},{"id":116},"credential-vault-的核心能力",[118],{"type":30,"value":119},"Credential Vault 的核心能力",{"type":24,"tag":121,"props":122,"children":124},"h3",{"id":123},"_1-加密存储与访问控制",[125],{"type":30,"value":126},"1. 加密存储与访问控制",{"type":24,"tag":33,"props":128,"children":129},{},[130],{"type":30,"value":131},"Vault 的首要任务是安全地存储凭证。但这不仅仅是\"用 AES 加密后存到数据库\"那么简单，还需要考虑：",{"type":24,"tag":133,"props":134,"children":135},"ul",{},[136,146,156,166],{"type":24,"tag":65,"props":137,"children":138},{},[139,144],{"type":24,"tag":53,"props":140,"children":141},{},[142],{"type":30,"value":143},"静态加密（Encryption at Rest）",{"type":30,"value":145},"：凭证在磁盘上必须是加密的，即使数据库文件被盗也无法解密。",{"type":24,"tag":65,"props":147,"children":148},{},[149,154],{"type":24,"tag":53,"props":150,"children":151},{},[152],{"type":30,"value":153},"传输加密（Encryption in Transit）",{"type":30,"value":155},"：所有对 Vault 的访问必须通过 TLS，防止中间人攻击。",{"type":24,"tag":65,"props":157,"children":158},{},[159,164],{"type":24,"tag":53,"props":160,"children":161},{},[162],{"type":30,"value":163},"内存保护",{"type":30,"value":165},"：凭证解密后只在内存中短暂存在，使用后立即清除，避免 core dump 泄露。",{"type":24,"tag":65,"props":167,"children":168},{},[169,174],{"type":24,"tag":53,"props":170,"children":171},{},[172],{"type":30,"value":173},"细粒度权限",{"type":30,"value":175},"：基于 RBAC（Role-Based Access Control）或 ABAC（Attribute-Based Access Control），确保每个 agent 只能访问它需要的凭证。",{"type":24,"tag":177,"props":178,"children":183},"pre",{"code":179,"language":180,"meta":7,"className":181},"// 示例：Vault 权限策略定义\nconst policy = {\n  path: \"secret/data/ai-agents/customer-support/*\",\n  capabilities: [\"read\"],\n  allowed_parameters: {\n    api_key: [], // 可以读取 api_key\n    endpoint: [], // 可以读取 endpoint\n  },\n  denied_parameters: {\n    master_key: [], // 禁止读取 master_key\n  },\n};\n","typescript",[182],"language-typescript",[184],{"type":24,"tag":39,"props":185,"children":186},{"__ignoreMap":7},[187],{"type":30,"value":179},{"type":24,"tag":121,"props":189,"children":191},{"id":190},"_2-动态凭证dynamic-secrets",[192],{"type":30,"value":193},"2. 动态凭证（Dynamic Secrets）",{"type":24,"tag":33,"props":195,"children":196},{},[197,199,204],{"type":30,"value":198},"传统做法是生成一个长期有效的 API Key，然后到处分发。更好的方式是",{"type":24,"tag":53,"props":200,"children":201},{},[202],{"type":30,"value":203},"动态生成短期有效的凭证",{"type":30,"value":205},"：",{"type":24,"tag":133,"props":207,"children":208},{},[209,219,229],{"type":24,"tag":65,"props":210,"children":211},{},[212,217],{"type":24,"tag":53,"props":213,"children":214},{},[215],{"type":30,"value":216},"按需生成",{"type":30,"value":218},"：Agent 启动时向 Vault 请求凭证，Vault 临时创建一个有时效的 API Key。",{"type":24,"tag":65,"props":220,"children":221},{},[222,227],{"type":24,"tag":53,"props":223,"children":224},{},[225],{"type":30,"value":226},"自动过期",{"type":30,"value":228},"：凭证在指定时间（如 1 小时）后自动失效，即使泄露也只会造成有限损失。",{"type":24,"tag":65,"props":230,"children":231},{},[232,237],{"type":24,"tag":53,"props":233,"children":234},{},[235],{"type":30,"value":236},"自动回收",{"type":30,"value":238},"：Agent 停止时主动撤销凭证，或者 Vault 检测到异常行为时强制吊销。",{"type":24,"tag":177,"props":240,"children":243},{"code":241,"language":180,"meta":7,"className":242},"// 示例：从 Vault 获取动态凭证\nasync function getOpenAICredentials() {\n  const response = await vault.read(\"openai/creds/customer-support-agent\");\n  \n  return {\n    apiKey: response.data.api_key,\n    expiresAt: response.data.expires_at, // 1 小时后过期\n    leaseId: response.lease_id, // 用于续期或撤销\n  };\n}\n\n// Agent 使用时\nconst creds = await getOpenAICredentials();\nconst openai = new OpenAI({ apiKey: creds.apiKey });\n\n// 定期续期（如果需要长时间运行）\nsetInterval(async () => {\n  await vault.renewLease(creds.leaseId, 3600); // 续期 1 小时\n}, 3000 * 1000); // 每 50 分钟续期一次\n",[182],[244],{"type":24,"tag":39,"props":245,"children":246},{"__ignoreMap":7},[247],{"type":30,"value":241},{"type":24,"tag":121,"props":249,"children":251},{"id":250},"_3-租约管理lease-management",[252],{"type":30,"value":253},"3. 租约管理（Lease Management）",{"type":24,"tag":33,"props":255,"children":256},{},[257],{"type":30,"value":258},"动态凭证通常伴随着\"租约\"概念：",{"type":24,"tag":133,"props":260,"children":261},{},[262,272,282,292],{"type":24,"tag":65,"props":263,"children":264},{},[265,270],{"type":24,"tag":53,"props":266,"children":267},{},[268],{"type":30,"value":269},"租约期限",{"type":30,"value":271},"：凭证可以使用多久（TTL, Time To Live）。",{"type":24,"tag":65,"props":273,"children":274},{},[275,280],{"type":24,"tag":53,"props":276,"children":277},{},[278],{"type":30,"value":279},"最大租约",{"type":30,"value":281},"：即使不断续期，最多能用多久（Max TTL）。",{"type":24,"tag":65,"props":283,"children":284},{},[285,290],{"type":24,"tag":53,"props":286,"children":287},{},[288],{"type":30,"value":289},"租约续期",{"type":30,"value":291},"：Agent 可以在凭证过期前申请延长使用时间。",{"type":24,"tag":65,"props":293,"children":294},{},[295,300],{"type":24,"tag":53,"props":296,"children":297},{},[298],{"type":30,"value":299},"租约撤销",{"type":30,"value":301},"：紧急情况下可以立即吊销某个租约，使对应凭证失效。",{"type":24,"tag":33,"props":303,"children":304},{},[305],{"type":30,"value":306},"这种机制特别适合以下场景：",{"type":24,"tag":133,"props":308,"children":309},{},[310,320,330],{"type":24,"tag":65,"props":311,"children":312},{},[313,318],{"type":24,"tag":53,"props":314,"children":315},{},[316],{"type":30,"value":317},"临时调试",{"type":30,"value":319},"：开发者需要访问生产环境的数据库进行问题排查，申请一个 2 小时的只读凭证，用完即焚。",{"type":24,"tag":65,"props":321,"children":322},{},[323,328],{"type":24,"tag":53,"props":324,"children":325},{},[326],{"type":30,"value":327},"批量任务",{"type":30,"value":329},"：数据处理 job 需要访问 S3，任务开始前获取凭证，任务结束后自动撤销。",{"type":24,"tag":65,"props":331,"children":332},{},[333,338],{"type":24,"tag":53,"props":334,"children":335},{},[336],{"type":30,"value":337},"第三方集成",{"type":30,"value":339},"：合作伙伴的 webhook 需要访问你的 API，给它一个 scoped 且短期的 token。",{"type":24,"tag":121,"props":341,"children":343},{"id":342},"_4-审计日志audit-logging",[344],{"type":30,"value":345},"4. 审计日志（Audit Logging）",{"type":24,"tag":33,"props":347,"children":348},{},[349],{"type":30,"value":350},"Vault 必须记录每一次凭证访问：",{"type":24,"tag":177,"props":352,"children":357},{"code":353,"language":354,"meta":7,"className":355},"{\n  \"timestamp\": \"2026-06-15T14:23:45Z\",\n  \"actor\": \"agent:customer-support-bot\",\n  \"action\": \"read\",\n  \"path\": \"secret/data/openai/api-key\",\n  \"remote_address\": \"10.0.1.42\",\n  \"request_id\": \"req_abc123\",\n  \"auth_type\": \"token\",\n  \"policy_used\": \"customer-support-policy\",\n  \"metadata\": {\n    \"agent_version\": \"2.3.1\",\n    \"environment\": \"production\"\n  }\n}\n","json",[356],"language-json",[358],{"type":24,"tag":39,"props":359,"children":360},{"__ignoreMap":7},[361],{"type":30,"value":353},{"type":24,"tag":33,"props":363,"children":364},{},[365],{"type":30,"value":366},"审计日志需要满足：",{"type":24,"tag":133,"props":368,"children":369},{},[370,380,390],{"type":24,"tag":65,"props":371,"children":372},{},[373,378],{"type":24,"tag":53,"props":374,"children":375},{},[376],{"type":30,"value":377},"不可篡改",{"type":30,"value":379},"：使用 WORM（Write Once Read Many）存储或区块链式哈希链。",{"type":24,"tag":65,"props":381,"children":382},{},[383,388],{"type":24,"tag":53,"props":384,"children":385},{},[386],{"type":30,"value":387},"实时告警",{"type":30,"value":389},"：检测到异常访问模式（如非工作时间大量读取、来自未知 IP）时立即告警。",{"type":24,"tag":65,"props":391,"children":392},{},[393,398],{"type":24,"tag":53,"props":394,"children":395},{},[396],{"type":30,"value":397},"合规保留",{"type":30,"value":399},"：根据 SOC 2、GDPR 等要求，日志需要保留 1-7 年不等。",{"type":24,"tag":25,"props":401,"children":403},{"id":402},"三种典型方案对比",[404],{"type":30,"value":402},{"type":24,"tag":121,"props":406,"children":408},{"id":407},"方案一hashicorp-vault开源企业版",[409],{"type":30,"value":410},"方案一：HashiCorp Vault（开源/企业版）",{"type":24,"tag":33,"props":412,"children":413},{},[414,419],{"type":24,"tag":53,"props":415,"children":416},{},[417],{"type":30,"value":418},"适用场景",{"type":30,"value":420},"：中大型团队，多云环境，需要高度定制化。",{"type":24,"tag":33,"props":422,"children":423},{},[424,429],{"type":24,"tag":53,"props":425,"children":426},{},[427],{"type":30,"value":428},"优势",{"type":30,"value":205},{"type":24,"tag":133,"props":431,"children":432},{},[433,438,443],{"type":24,"tag":65,"props":434,"children":435},{},[436],{"type":30,"value":437},"功能最全面：支持动态凭证、PKI、KMS、身份联合等。",{"type":24,"tag":65,"props":439,"children":440},{},[441],{"type":30,"value":442},"生态丰富：官方提供 Kubernetes、AWS、GCP、Azure 等集成模块。",{"type":24,"tag":65,"props":444,"children":445},{},[446],{"type":30,"value":447},"社区活跃：遇到问题容易找到解决方案。",{"type":24,"tag":33,"props":449,"children":450},{},[451,456],{"type":24,"tag":53,"props":452,"children":453},{},[454],{"type":30,"value":455},"劣势",{"type":30,"value":205},{"type":24,"tag":133,"props":458,"children":459},{},[460,465,470],{"type":24,"tag":65,"props":461,"children":462},{},[463],{"type":30,"value":464},"运维复杂：需要自己部署、维护、备份、升级。",{"type":24,"tag":65,"props":466,"children":467},{},[468],{"type":30,"value":469},"学习曲线陡峭：概念多（Auth Method、Secret Engine、Policy、Namespace）。",{"type":24,"tag":65,"props":471,"children":472},{},[473],{"type":30,"value":474},"成本较高：企业版按节点收费，开源版缺少部分高级功能。",{"type":24,"tag":33,"props":476,"children":477},{},[478,483],{"type":24,"tag":53,"props":479,"children":480},{},[481],{"type":30,"value":482},"典型架构",{"type":30,"value":205},{"type":24,"tag":177,"props":485,"children":487},{"code":486},"┌─────────────┐     ┌──────────────┐     ┌─────────────┐\n│  AI Agents  │────▶│ HashiCorp    │◀────│  Consul /   │\n│  (K8s Pod)  │     │ Vault Cluster│     │  etcd (HA)  │\n└─────────────┘     └──────────────┘     └─────────────┘\n                           │\n                    ┌──────┴──────┐\n                    │  Audit Log  │\n                    │  (Syslog/   │\n                    │   Splunk)   │\n                    └─────────────┘\n",[488],{"type":24,"tag":39,"props":489,"children":490},{"__ignoreMap":7},[491],{"type":30,"value":486},{"type":24,"tag":121,"props":493,"children":495},{"id":494},"方案二aws-secrets-manager云服务",[496],{"type":30,"value":497},"方案二：AWS Secrets Manager（云服务）",{"type":24,"tag":33,"props":499,"children":500},{},[501,505],{"type":24,"tag":53,"props":502,"children":503},{},[504],{"type":30,"value":418},{"type":30,"value":506},"：All-in AWS 的团队，希望最小化运维负担。",{"type":24,"tag":33,"props":508,"children":509},{},[510,514],{"type":24,"tag":53,"props":511,"children":512},{},[513],{"type":30,"value":428},{"type":30,"value":205},{"type":24,"tag":133,"props":516,"children":517},{},[518,523,528],{"type":24,"tag":65,"props":519,"children":520},{},[521],{"type":30,"value":522},"零运维：完全托管，无需关心服务器、备份、升级。",{"type":24,"tag":65,"props":524,"children":525},{},[526],{"type":30,"value":527},"深度集成：与 IAM、Lambda、ECS、RDS 等 AWS 服务无缝对接。",{"type":24,"tag":65,"props":529,"children":530},{},[531],{"type":30,"value":532},"自动轮换：支持 RDS、Redshift、DocumentDB 等数据库的自动密钥轮换。",{"type":24,"tag":33,"props":534,"children":535},{},[536,540],{"type":24,"tag":53,"props":537,"children":538},{},[539],{"type":30,"value":455},{"type":30,"value":205},{"type":24,"tag":133,"props":542,"children":543},{},[544,549,554],{"type":24,"tag":65,"props":545,"children":546},{},[547],{"type":30,"value":548},"Vendor Lock-in：迁移到其他云厂商成本高。",{"type":24,"tag":65,"props":550,"children":551},{},[552],{"type":30,"value":553},"功能受限：不支持复杂的动态凭证场景（如自定义 API Key 生成逻辑）。",{"type":24,"tag":65,"props":555,"children":556},{},[557],{"type":30,"value":558},"成本不透明：按 API 调用次数收费，高频访问时费用可能超出预期。",{"type":24,"tag":33,"props":560,"children":561},{},[562,567],{"type":24,"tag":53,"props":563,"children":564},{},[565],{"type":30,"value":566},"典型用法",{"type":30,"value":205},{"type":24,"tag":177,"props":569,"children":572},{"code":570,"language":180,"meta":7,"className":571},"import { SecretsManagerClient, GetSecretValueCommand } from \"@aws-sdk/client-secrets-manager\";\n\nconst client = new SecretsManagerClient({ region: \"us-east-1\" });\n\nasync function getSecret(secretName: string) {\n  const command = new GetSecretValueCommand({ SecretId: secretName });\n  const response = await client.send(command);\n  \n  if (response.SecretString) {\n    return JSON.parse(response.SecretString);\n  }\n  throw new Error(\"Secret not found or not a string\");\n}\n\n// 使用\nconst openaiCreds = await getSecret(\"prod/ai-agents/openai-api-key\");\n",[182],[573],{"type":24,"tag":39,"props":574,"children":575},{"__ignoreMap":7},[576],{"type":30,"value":570},{"type":24,"tag":121,"props":578,"children":580},{"id":579},"方案三自建-kms-数据库轻量级方案",[581],{"type":30,"value":582},"方案三：自建 KMS + 数据库（轻量级方案）",{"type":24,"tag":33,"props":584,"children":585},{},[586,590],{"type":24,"tag":53,"props":587,"children":588},{},[589],{"type":30,"value":418},{"type":30,"value":591},"：小团队、预算有限、对云厂商依赖敏感。",{"type":24,"tag":33,"props":593,"children":594},{},[595,599],{"type":24,"tag":53,"props":596,"children":597},{},[598],{"type":30,"value":428},{"type":30,"value":205},{"type":24,"tag":133,"props":601,"children":602},{},[603,608,613],{"type":24,"tag":65,"props":604,"children":605},{},[606],{"type":30,"value":607},"成本低：只需支付数据库和 KMS 的费用。",{"type":24,"tag":65,"props":609,"children":610},{},[611],{"type":30,"value":612},"可控性强：完全掌握数据存储和访问逻辑。",{"type":24,"tag":65,"props":614,"children":615},{},[616],{"type":30,"value":617},"灵活定制：可以根据业务需求设计特殊的凭证类型和权限模型。",{"type":24,"tag":33,"props":619,"children":620},{},[621,625],{"type":24,"tag":53,"props":622,"children":623},{},[624],{"type":30,"value":455},{"type":30,"value":205},{"type":24,"tag":133,"props":627,"children":628},{},[629,634,639],{"type":24,"tag":65,"props":630,"children":631},{},[632],{"type":30,"value":633},"安全风险高：需要自己实现加密、权限控制、审计日志等核心功能，容易出错。",{"type":24,"tag":65,"props":635,"children":636},{},[637],{"type":30,"value":638},"功能简陋：通常只支持静态凭证存储，缺乏动态凭证、租约管理等高级特性。",{"type":24,"tag":65,"props":640,"children":641},{},[642],{"type":30,"value":643},"维护负担：需要自己处理备份、恢复、扩容、监控等问题。",{"type":24,"tag":33,"props":645,"children":646},{},[647,651],{"type":24,"tag":53,"props":648,"children":649},{},[650],{"type":30,"value":482},{"type":30,"value":205},{"type":24,"tag":177,"props":653,"children":655},{"code":654},"┌─────────────┐     ┌──────────────┐     ┌─────────────┐\n│  AI Agents  │────▶│  Custom API  │────▶│ PostgreSQL  │\n│             │     │  (Node.js)   │     │  (Encrypted │\n└─────────────┘     └──────────────┘     │   Columns)  │\n                                          └─────────────┘\n                                               │\n                                          ┌────┴────┐\n                                          │ AWS KMS │\n                                          │ (Encrypt│\n                                          │  Keys)  │\n                                          └─────────┘\n",[656],{"type":24,"tag":39,"props":657,"children":658},{"__ignoreMap":7},[659],{"type":30,"value":654},{"type":24,"tag":33,"props":661,"children":662},{},[663,668,670,675],{"type":24,"tag":53,"props":664,"children":665},{},[666],{"type":30,"value":667},"建议",{"type":30,"value":669},"：除非有特殊原因，否则",{"type":24,"tag":53,"props":671,"children":672},{},[673],{"type":30,"value":674},"不推荐自建",{"type":30,"value":676},"。凭证管理是安全的核心环节，一旦出问题后果严重。优先选择成熟的商业方案或开源方案。",{"type":24,"tag":25,"props":678,"children":680},{"id":679},"权限模型设计",[681],{"type":30,"value":679},{"type":24,"tag":121,"props":683,"children":685},{"id":684},"rbac基于角色的访问控制",[686],{"type":30,"value":687},"RBAC（基于角色的访问控制）",{"type":24,"tag":33,"props":689,"children":690},{},[691],{"type":30,"value":692},"最常见的权限模型，适合大多数场景：",{"type":24,"tag":177,"props":694,"children":699},{"code":695,"language":696,"meta":7,"className":697},"# 角色定义\nroles:\n  - name: customer-support-agent\n    permissions:\n      - path: \"secret/data/openai/api-key\"\n        actions: [\"read\"]\n      - path: \"secret/data/postgres/customer-db\"\n        actions: [\"read\"]\n      - path: \"secret/data/slack/webhook-url\"\n        actions: [\"read\"]\n  \n  - name: data-processing-agent\n    permissions:\n      - path: \"secret/data/s3/bucket-credentials\"\n        actions: [\"read\", \"list\"]\n      - path: \"secret/data/bigquery/service-account\"\n        actions: [\"read\"]\n  \n  - name: admin\n    permissions:\n      - path: \"secret/*\"\n        actions: [\"read\", \"write\", \"delete\", \"list\"]\n","yaml",[698],"language-yaml",[700],{"type":24,"tag":39,"props":701,"children":702},{"__ignoreMap":7},[703],{"type":30,"value":695},{"type":24,"tag":33,"props":705,"children":706},{},[707,712],{"type":24,"tag":53,"props":708,"children":709},{},[710],{"type":30,"value":711},"最佳实践",{"type":30,"value":205},{"type":24,"tag":133,"props":714,"children":715},{},[716,726,736],{"type":24,"tag":65,"props":717,"children":718},{},[719,724],{"type":24,"tag":53,"props":720,"children":721},{},[722],{"type":30,"value":723},"最小权限原则",{"type":30,"value":725},"：每个 agent 只授予完成工作所需的最小权限集合。",{"type":24,"tag":65,"props":727,"children":728},{},[729,734],{"type":24,"tag":53,"props":730,"children":731},{},[732],{"type":30,"value":733},"定期审查",{"type":30,"value":735},"：每季度审查一次权限分配，移除不再使用的权限。",{"type":24,"tag":65,"props":737,"children":738},{},[739,744],{"type":24,"tag":53,"props":740,"children":741},{},[742],{"type":30,"value":743},"分离环境",{"type":30,"value":745},"：生产、测试、开发环境的凭证完全隔离，避免交叉访问。",{"type":24,"tag":121,"props":747,"children":749},{"id":748},"abac基于属性的访问控制",[750],{"type":30,"value":751},"ABAC（基于属性的访问控制）",{"type":24,"tag":33,"props":753,"children":754},{},[755],{"type":30,"value":756},"更细粒度的权限模型，适合复杂场景：",{"type":24,"tag":177,"props":758,"children":761},{"code":759,"language":180,"meta":7,"className":760},"// 策略示例：只有在工作时间、从办公网络、由特定 agent 发起的请求才能访问生产凭证\nconst policy = {\n  effect: \"allow\",\n  conditions: [\n    { attribute: \"time\", operator: \"between\", value: [\"09:00\", \"18:00\"] },\n    { attribute: \"source_ip\", operator: \"in_cidr\", value: [\"10.0.0.0/8\"] },\n    { attribute: \"agent_name\", operator: \"equals\", value: \"customer-support-bot\" },\n    { attribute: \"environment\", operator: \"equals\", value: \"production\" },\n  ],\n};\n",[182],[762],{"type":24,"tag":39,"props":763,"children":764},{"__ignoreMap":7},[765],{"type":30,"value":759},{"type":24,"tag":33,"props":767,"children":768},{},[769,773],{"type":24,"tag":53,"props":770,"children":771},{},[772],{"type":30,"value":418},{"type":30,"value":205},{"type":24,"tag":133,"props":775,"children":776},{},[777,782,787],{"type":24,"tag":65,"props":778,"children":779},{},[780],{"type":30,"value":781},"合规要求严格的行业（金融、医疗）。",{"type":24,"tag":65,"props":783,"children":784},{},[785],{"type":30,"value":786},"需要基于上下文动态调整权限的场景。",{"type":24,"tag":65,"props":788,"children":789},{},[790],{"type":30,"value":791},"多租户 SaaS 平台，不同租户的数据需要严格隔离。",{"type":24,"tag":25,"props":793,"children":795},{"id":794},"集成模式",[796],{"type":30,"value":794},{"type":24,"tag":121,"props":798,"children":800},{"id":799},"模式一sdk-直接集成",[801],{"type":30,"value":802},"模式一：SDK 直接集成",{"type":24,"tag":33,"props":804,"children":805},{},[806],{"type":30,"value":807},"Agent 代码中直接调用 Vault SDK：",{"type":24,"tag":177,"props":809,"children":812},{"code":810,"language":180,"meta":7,"className":811},"import { Vault } from \"@hashicorp/vault-client\";\n\nconst vault = new Vault({\n  address: process.env.VAULT_ADDRESS,\n  token: process.env.VAULT_TOKEN,\n});\n\nasync function initializeAgent() {\n  // 启动时获取凭证\n  const openaiKey = await vault.read(\"secret/data/openai/api-key\");\n  const dbPassword = await vault.read(\"secret/data/postgres/password\");\n  \n  // 初始化服务\n  const openai = new OpenAI({ apiKey: openaiKey.data.value });\n  const db = new Database({ password: dbPassword.data.value });\n  \n  return { openai, db };\n}\n",[182],[813],{"type":24,"tag":39,"props":814,"children":815},{"__ignoreMap":7},[816],{"type":30,"value":810},{"type":24,"tag":33,"props":818,"children":819},{},[820,825,827,831,836],{"type":24,"tag":53,"props":821,"children":822},{},[823],{"type":30,"value":824},"优点",{"type":30,"value":826},"：简单直接，易于理解。",{"type":24,"tag":828,"props":829,"children":830},"br",{},[],{"type":24,"tag":53,"props":832,"children":833},{},[834],{"type":30,"value":835},"缺点",{"type":30,"value":837},"：Agent 代码与 Vault 耦合，切换方案时需要修改代码。",{"type":24,"tag":121,"props":839,"children":841},{"id":840},"模式二sidecar-代理",[842],{"type":30,"value":843},"模式二：Sidecar 代理",{"type":24,"tag":33,"props":845,"children":846},{},[847],{"type":30,"value":848},"在 Agent 旁边部署一个 Sidecar 容器，负责凭证获取和注入：",{"type":24,"tag":177,"props":850,"children":853},{"code":851,"language":696,"meta":7,"className":852},"# Kubernetes Deployment 示例\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: customer-support-agent\nspec:\n  template:\n    spec:\n      containers:\n        - name: agent\n          image: my-agent:latest\n          env:\n            - name: OPENAI_API_KEY\n              valueFrom:\n                secretKeyRef:\n                  name: vault-secret\n                  key: openai-api-key\n        \n        - name: vault-agent\n          image: hashicorp/vault:latest\n          args: [\"agent\", \"-config=/etc/vault-agent.hcl\"]\n          volumeMounts:\n            - name: vault-token\n              mountPath: /home/vault\n      volumes:\n        - name: vault-token\n          emptyDir: {}\n",[698],[854],{"type":24,"tag":39,"props":855,"children":856},{"__ignoreMap":7},[857],{"type":30,"value":851},{"type":24,"tag":33,"props":859,"children":860},{},[861,865,867,870,874],{"type":24,"tag":53,"props":862,"children":863},{},[864],{"type":30,"value":824},{"type":30,"value":866},"：Agent 代码无需感知 Vault，通过环境变量或文件获取凭证。",{"type":24,"tag":828,"props":868,"children":869},{},[],{"type":24,"tag":53,"props":871,"children":872},{},[873],{"type":30,"value":835},{"type":30,"value":875},"：增加了基础设施复杂度，需要管理 Sidecar 的生命周期。",{"type":24,"tag":121,"props":877,"children":879},{"id":878},"模式三init-container-预加载",[880],{"type":30,"value":881},"模式三：Init Container 预加载",{"type":24,"tag":33,"props":883,"children":884},{},[885],{"type":30,"value":886},"在 Agent 启动前，通过 Init Container 预先获取凭证并写入共享卷：",{"type":24,"tag":177,"props":888,"children":891},{"code":889,"language":696,"meta":7,"className":890},"apiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: customer-support-agent\nspec:\n  template:\n    spec:\n      initContainers:\n        - name: vault-init\n          image: hashicorp/vault:latest\n          command: [\"sh\", \"-c\"]\n          args:\n            - |\n              vault read -format=json secret/data/openai/api-key > /vault-secrets/openai.json\n              vault read -format=json secret/data/postgres/password > /vault-secrets/db.json\n          volumeMounts:\n            - name: vault-secrets\n              mountPath: /vault-secrets\n      \n      containers:\n        - name: agent\n          image: my-agent:latest\n          volumeMounts:\n            - name: vault-secrets\n              mountPath: /etc/secrets\n              readOnly: true\n      \n      volumes:\n        - name: vault-secrets\n          emptyDir: {}\n",[698],[892],{"type":24,"tag":39,"props":893,"children":894},{"__ignoreMap":7},[895],{"type":30,"value":889},{"type":24,"tag":33,"props":897,"children":898},{},[899,903,905,908,912],{"type":24,"tag":53,"props":900,"children":901},{},[902],{"type":30,"value":824},{"type":30,"value":904},"：Agent 启动时凭证已经就绪，无需等待 Vault 响应。",{"type":24,"tag":828,"props":906,"children":907},{},[],{"type":24,"tag":53,"props":909,"children":910},{},[911],{"type":30,"value":835},{"type":30,"value":913},"：凭证不会自动刷新，长运行的 Agent 可能需要重启才能获取新凭证。",{"type":24,"tag":25,"props":915,"children":917},{"id":916},"迁移路径从-env-到-vault",[918],{"type":30,"value":919},"迁移路径：从 .env 到 Vault",{"type":24,"tag":33,"props":921,"children":922},{},[923,925,930],{"type":30,"value":924},"如果你的团队目前还在使用 ",{"type":24,"tag":39,"props":926,"children":928},{"className":927},[],[929],{"type":30,"value":44},{"type":30,"value":931}," 文件管理凭证，可以按照以下步骤渐进式迁移：",{"type":24,"tag":121,"props":933,"children":935},{"id":934},"阶段一评估与规划1-2-周",[936],{"type":30,"value":937},"阶段一：评估与规划（1-2 周）",{"type":24,"tag":61,"props":939,"children":940},{},[941,951,961,971],{"type":24,"tag":65,"props":942,"children":943},{},[944,949],{"type":24,"tag":53,"props":945,"children":946},{},[947],{"type":30,"value":948},"盘点现有凭证",{"type":30,"value":950},"：列出所有服务、环境、用途的凭证清单。",{"type":24,"tag":65,"props":952,"children":953},{},[954,959],{"type":24,"tag":53,"props":955,"children":956},{},[957],{"type":30,"value":958},"风险评估",{"type":30,"value":960},"：识别高风险凭证（如生产数据库密码、主 API Key）。",{"type":24,"tag":65,"props":962,"children":963},{},[964,969],{"type":24,"tag":53,"props":965,"children":966},{},[967],{"type":30,"value":968},"选型决策",{"type":30,"value":970},"：根据团队规模、技术栈、预算选择合适的 Vault 方案。",{"type":24,"tag":65,"props":972,"children":973},{},[974,979],{"type":24,"tag":53,"props":975,"children":976},{},[977],{"type":30,"value":978},"制定迁移计划",{"type":30,"value":980},"：确定迁移顺序（先测试环境还是先生产环境）、回滚方案。",{"type":24,"tag":121,"props":982,"children":984},{"id":983},"阶段二搭建-vault-基础设施1-2-周",[985],{"type":30,"value":986},"阶段二：搭建 Vault 基础设施（1-2 周）",{"type":24,"tag":61,"props":988,"children":989},{},[990,1000,1010,1020],{"type":24,"tag":65,"props":991,"children":992},{},[993,998],{"type":24,"tag":53,"props":994,"children":995},{},[996],{"type":30,"value":997},"部署 Vault 集群",{"type":30,"value":999},"：配置 HA、备份、监控、告警。",{"type":24,"tag":65,"props":1001,"children":1002},{},[1003,1008],{"type":24,"tag":53,"props":1004,"children":1005},{},[1006],{"type":30,"value":1007},"配置 Auth Method",{"type":30,"value":1009},"：选择适合的认证方式（Token、AppRole、Kubernetes Auth）。",{"type":24,"tag":65,"props":1011,"children":1012},{},[1013,1018],{"type":24,"tag":53,"props":1014,"children":1015},{},[1016],{"type":30,"value":1017},"定义 Secret Engine",{"type":30,"value":1019},"：配置 KV v2、Database、AWS 等引擎。",{"type":24,"tag":65,"props":1021,"children":1022},{},[1023,1028],{"type":24,"tag":53,"props":1024,"children":1025},{},[1026],{"type":30,"value":1027},"编写 Policy",{"type":30,"value":1029},"：为每个 agent 定义最小权限策略。",{"type":24,"tag":121,"props":1031,"children":1033},{"id":1032},"阶段三试点迁移2-4-周",[1034],{"type":30,"value":1035},"阶段三：试点迁移（2-4 周）",{"type":24,"tag":61,"props":1037,"children":1038},{},[1039,1049,1059,1069,1079],{"type":24,"tag":65,"props":1040,"children":1041},{},[1042,1047],{"type":24,"tag":53,"props":1043,"children":1044},{},[1045],{"type":30,"value":1046},"选择试点项目",{"type":30,"value":1048},"：选择一个非核心的 agent 或服务作为试点。",{"type":24,"tag":65,"props":1050,"children":1051},{},[1052,1057],{"type":24,"tag":53,"props":1053,"children":1054},{},[1055],{"type":30,"value":1056},"迁移凭证",{"type":30,"value":1058},"：将试点项目的凭证导入 Vault。",{"type":24,"tag":65,"props":1060,"children":1061},{},[1062,1067],{"type":24,"tag":53,"props":1063,"children":1064},{},[1065],{"type":30,"value":1066},"修改代码",{"type":30,"value":1068},"：更新试点项目代码，从 Vault 获取凭证。",{"type":24,"tag":65,"props":1070,"children":1071},{},[1072,1077],{"type":24,"tag":53,"props":1073,"children":1074},{},[1075],{"type":30,"value":1076},"验证功能",{"type":30,"value":1078},"：确保试点项目在迁移后正常运行。",{"type":24,"tag":65,"props":1080,"children":1081},{},[1082,1087],{"type":24,"tag":53,"props":1083,"children":1084},{},[1085],{"type":30,"value":1086},"收集反馈",{"type":30,"value":1088},"：记录迁移过程中遇到的问题和改进点。",{"type":24,"tag":121,"props":1090,"children":1092},{"id":1091},"阶段四批量迁移4-8-周",[1093],{"type":30,"value":1094},"阶段四：批量迁移（4-8 周）",{"type":24,"tag":61,"props":1096,"children":1097},{},[1098,1108,1118,1135],{"type":24,"tag":65,"props":1099,"children":1100},{},[1101,1106],{"type":24,"tag":53,"props":1102,"children":1103},{},[1104],{"type":30,"value":1105},"分批迁移",{"type":30,"value":1107},"：按照优先级分批迁移其他项目（先低风险后高风险）。",{"type":24,"tag":65,"props":1109,"children":1110},{},[1111,1116],{"type":24,"tag":53,"props":1112,"children":1113},{},[1114],{"type":30,"value":1115},"自动化脚本",{"type":30,"value":1117},"：编写脚本自动化凭证导入、代码修改、测试验证流程。",{"type":24,"tag":65,"props":1119,"children":1120},{},[1121,1126,1128,1133],{"type":24,"tag":53,"props":1122,"children":1123},{},[1124],{"type":30,"value":1125},"并行运行",{"type":30,"value":1127},"：在迁移期间保持 ",{"type":24,"tag":39,"props":1129,"children":1131},{"className":1130},[],[1132],{"type":30,"value":44},{"type":30,"value":1134}," 和 Vault 双轨运行，确保可随时回滚。",{"type":24,"tag":65,"props":1136,"children":1137},{},[1138,1143],{"type":24,"tag":53,"props":1139,"children":1140},{},[1141],{"type":30,"value":1142},"监控指标",{"type":30,"value":1144},"：跟踪迁移进度、失败率、性能影响等关键指标。",{"type":24,"tag":121,"props":1146,"children":1148},{"id":1147},"阶段五清理与优化1-2-周",[1149],{"type":30,"value":1150},"阶段五：清理与优化（1-2 周）",{"type":24,"tag":61,"props":1152,"children":1153},{},[1154,1171,1189,1199],{"type":24,"tag":65,"props":1155,"children":1156},{},[1157,1162,1164,1169],{"type":24,"tag":53,"props":1158,"children":1159},{},[1160],{"type":30,"value":1161},"删除旧凭证",{"type":30,"value":1163},"：确认所有项目迁移完成后，删除 ",{"type":24,"tag":39,"props":1165,"children":1167},{"className":1166},[],[1168],{"type":30,"value":44},{"type":30,"value":1170}," 文件中的凭证。",{"type":24,"tag":65,"props":1172,"children":1173},{},[1174,1179,1181,1187],{"type":24,"tag":53,"props":1175,"children":1176},{},[1177],{"type":30,"value":1178},"Git 历史清理",{"type":30,"value":1180},"：使用 ",{"type":24,"tag":39,"props":1182,"children":1184},{"className":1183},[],[1185],{"type":30,"value":1186},"git filter-branch",{"type":30,"value":1188}," 或 BFG Repo-Cleaner 清除 Git 历史中的凭证。",{"type":24,"tag":65,"props":1190,"children":1191},{},[1192,1197],{"type":24,"tag":53,"props":1193,"children":1194},{},[1195],{"type":30,"value":1196},"文档更新",{"type":30,"value":1198},"：更新开发文档、onboarding 指南、故障排查手册。",{"type":24,"tag":65,"props":1200,"children":1201},{},[1202,1207],{"type":24,"tag":53,"props":1203,"children":1204},{},[1205],{"type":30,"value":1206},"培训团队",{"type":30,"value":1208},"：组织培训会议，确保所有开发者了解新的凭证管理流程。",{"type":24,"tag":25,"props":1210,"children":1212},{"id":1211},"常见陷阱与避坑指南",[1213],{"type":30,"value":1211},{"type":24,"tag":121,"props":1215,"children":1217},{"id":1216},"陷阱一vault-成为单点故障",[1218],{"type":30,"value":1219},"陷阱一：Vault 成为单点故障",{"type":24,"tag":33,"props":1221,"children":1222},{},[1223,1228],{"type":24,"tag":53,"props":1224,"children":1225},{},[1226],{"type":30,"value":1227},"问题",{"type":30,"value":1229},"：Vault 挂了，所有 Agent 都无法获取凭证，系统瘫痪。",{"type":24,"tag":33,"props":1231,"children":1232},{},[1233,1238],{"type":24,"tag":53,"props":1234,"children":1235},{},[1236],{"type":30,"value":1237},"解决方案",{"type":30,"value":205},{"type":24,"tag":133,"props":1240,"children":1241},{},[1242,1247,1252,1257],{"type":24,"tag":65,"props":1243,"children":1244},{},[1245],{"type":30,"value":1246},"部署 HA 集群（至少 3 个节点）。",{"type":24,"tag":65,"props":1248,"children":1249},{},[1250],{"type":30,"value":1251},"启用 Consul 或 etcd 作为后端存储，提供高可用。",{"type":24,"tag":65,"props":1253,"children":1254},{},[1255],{"type":30,"value":1256},"Agent 端实现缓存机制，Vault 不可用时使用缓存的凭证（设置合理的 TTL）。",{"type":24,"tag":65,"props":1258,"children":1259},{},[1260],{"type":30,"value":1261},"定期进行故障演练，验证 HA 切换流程。",{"type":24,"tag":121,"props":1263,"children":1265},{"id":1264},"陷阱二凭证缓存导致安全问题",[1266],{"type":30,"value":1267},"陷阱二：凭证缓存导致安全问题",{"type":24,"tag":33,"props":1269,"children":1270},{},[1271,1275],{"type":24,"tag":53,"props":1272,"children":1273},{},[1274],{"type":30,"value":1227},{"type":30,"value":1276},"：为了性能，Agent 缓存了凭证，但缓存时间过长，即使 Vault 中已撤销，Agent 仍在使用旧凭证。",{"type":24,"tag":33,"props":1278,"children":1279},{},[1280,1284],{"type":24,"tag":53,"props":1281,"children":1282},{},[1283],{"type":30,"value":1237},{"type":30,"value":205},{"type":24,"tag":133,"props":1286,"children":1287},{},[1288,1293,1298],{"type":24,"tag":65,"props":1289,"children":1290},{},[1291],{"type":30,"value":1292},"设置合理的缓存 TTL（如 5-10 分钟），平衡性能和安全性。",{"type":24,"tag":65,"props":1294,"children":1295},{},[1296],{"type":30,"value":1297},"实现主动失效机制：Vault 撤销凭证时，通过 Webhook 通知 Agent 清除缓存。",{"type":24,"tag":65,"props":1299,"children":1300},{},[1301],{"type":30,"value":1302},"监控缓存命中率和使用情况，发现异常及时调整策略。",{"type":24,"tag":121,"props":1304,"children":1306},{"id":1305},"陷阱三权限过度宽松",[1307],{"type":30,"value":1308},"陷阱三：权限过度宽松",{"type":24,"tag":33,"props":1310,"children":1311},{},[1312,1316,1318,1324],{"type":24,"tag":53,"props":1313,"children":1314},{},[1315],{"type":30,"value":1227},{"type":30,"value":1317},"：为了方便，给所有 Agent 授予 ",{"type":24,"tag":39,"props":1319,"children":1321},{"className":1320},[],[1322],{"type":30,"value":1323},"secret/*",{"type":30,"value":1325}," 的 read 权限，违背了最小权限原则。",{"type":24,"tag":33,"props":1327,"children":1328},{},[1329,1333],{"type":24,"tag":53,"props":1330,"children":1331},{},[1332],{"type":30,"value":1237},{"type":30,"value":205},{"type":24,"tag":133,"props":1335,"children":1336},{},[1337,1342,1347],{"type":24,"tag":65,"props":1338,"children":1339},{},[1340],{"type":30,"value":1341},"严格执行最小权限原则，每个 Agent 只授予必需的权限。",{"type":24,"tag":65,"props":1343,"children":1344},{},[1345],{"type":30,"value":1346},"定期审查权限分配（建议每季度一次）。",{"type":24,"tag":65,"props":1348,"children":1349},{},[1350],{"type":30,"value":1351},"使用工具（如 OPA、Sentinel）自动化权限审计，检测过度授权的策略。",{"type":24,"tag":121,"props":1353,"children":1355},{"id":1354},"陷阱四忽略审计日志",[1356],{"type":30,"value":1357},"陷阱四：忽略审计日志",{"type":24,"tag":33,"props":1359,"children":1360},{},[1361,1365],{"type":24,"tag":53,"props":1362,"children":1363},{},[1364],{"type":30,"value":1227},{"type":30,"value":1366},"：Vault 配置了但没有启用审计日志，或者日志没有实时监控，出事时无法追溯。",{"type":24,"tag":33,"props":1368,"children":1369},{},[1370,1374],{"type":24,"tag":53,"props":1371,"children":1372},{},[1373],{"type":30,"value":1237},{"type":30,"value":205},{"type":24,"tag":133,"props":1376,"children":1377},{},[1378,1383,1388],{"type":24,"tag":65,"props":1379,"children":1380},{},[1381],{"type":30,"value":1382},"启用 Vault 的审计设备（Audit Device），将所有操作记录到 Syslog、Splunk 或 Elasticsearch。",{"type":24,"tag":65,"props":1384,"children":1385},{},[1386],{"type":30,"value":1387},"配置实时告警规则，检测异常访问模式。",{"type":24,"tag":65,"props":1389,"children":1390},{},[1391],{"type":30,"value":1392},"定期审查审计日志，发现潜在的安全问题。",{"type":24,"tag":25,"props":1394,"children":1396},{"id":1395},"faq",[1397],{"type":30,"value":1398},"FAQ",{"type":24,"tag":121,"props":1400,"children":1402},{"id":1401},"q1-credential-vault-和本地-env-文件有什么区别",[1403],{"type":30,"value":1404},"Q1: Credential Vault 和本地 .env 文件有什么区别？",{"type":24,"tag":33,"props":1406,"children":1407},{},[1408,1413,1415,1420],{"type":24,"tag":53,"props":1409,"children":1410},{},[1411],{"type":30,"value":1412},"A",{"type":30,"value":1414},": ",{"type":24,"tag":39,"props":1416,"children":1418},{"className":1417},[],[1419],{"type":30,"value":44},{"type":30,"value":1421}," 文件只是简单的键值对存储，没有任何安全保障。Credential Vault 提供加密存储、细粒度权限控制、动态凭证、租约管理、审计日志等企业级功能。更重要的是，Vault 可以集中管理所有环境的凭证，避免凭证散落在各个项目中。",{"type":24,"tag":121,"props":1423,"children":1425},{"id":1424},"q2-动态凭证和静态凭证哪个更安全",[1426],{"type":30,"value":1427},"Q2: 动态凭证和静态凭证哪个更安全？",{"type":24,"tag":33,"props":1429,"children":1430},{},[1431,1435],{"type":24,"tag":53,"props":1432,"children":1433},{},[1434],{"type":30,"value":1412},{"type":30,"value":1436},": 动态凭证更安全，因为：",{"type":24,"tag":133,"props":1438,"children":1439},{},[1440,1450,1459],{"type":24,"tag":65,"props":1441,"children":1442},{},[1443,1448],{"type":24,"tag":53,"props":1444,"children":1445},{},[1446],{"type":30,"value":1447},"短期有效",{"type":30,"value":1449},"：即使泄露，攻击者也只能在短时间内使用。",{"type":24,"tag":65,"props":1451,"children":1452},{},[1453,1457],{"type":24,"tag":53,"props":1454,"children":1455},{},[1456],{"type":30,"value":226},{"type":30,"value":1458},"：无需手动轮换，减少人为失误。",{"type":24,"tag":65,"props":1460,"children":1461},{},[1462,1467],{"type":24,"tag":53,"props":1463,"children":1464},{},[1465],{"type":30,"value":1466},"可追溯",{"type":30,"value":1468},"：每次生成的凭证都有唯一的 ID，便于审计。",{"type":24,"tag":33,"props":1470,"children":1471},{},[1472],{"type":30,"value":1473},"但动态凭证的实现复杂度更高，需要根据业务场景权衡。对于低频访问的服务（如每月一次的报表生成），静态凭证配合定期轮换也是可接受的方案。",{"type":24,"tag":121,"props":1475,"children":1477},{"id":1476},"q3-vault-挂了怎么办有高可用方案吗",[1478],{"type":30,"value":1479},"Q3: Vault 挂了怎么办？有高可用方案吗？",{"type":24,"tag":33,"props":1481,"children":1482},{},[1483,1487],{"type":24,"tag":53,"props":1484,"children":1485},{},[1486],{"type":30,"value":1412},{"type":30,"value":1488},": HashiCorp Vault 支持 HA 模式，建议使用 Consul 或 Raft 作为后端存储，部署至少 3 个节点。当一个节点故障时，其他节点可以接管服务。此外，Agent 端应实现缓存机制，在 Vault 短暂不可用时仍能正常工作。",{"type":24,"tag":121,"props":1490,"children":1492},{"id":1491},"q4-如何防止凭证被过度使用",[1493],{"type":30,"value":1494},"Q4: 如何防止凭证被过度使用？",{"type":24,"tag":33,"props":1496,"children":1497},{},[1498,1502],{"type":24,"tag":53,"props":1499,"children":1500},{},[1501],{"type":30,"value":1412},{"type":30,"value":1503},":",{"type":24,"tag":133,"props":1505,"children":1506},{},[1507,1512,1517],{"type":24,"tag":65,"props":1508,"children":1509},{},[1510],{"type":30,"value":1511},"设置速率限制（Rate Limiting），限制每个 Agent 每分钟可以获取凭证的次数。",{"type":24,"tag":65,"props":1513,"children":1514},{},[1515],{"type":30,"value":1516},"启用配额管理（Quota Management），限制每个 Agent 每天可以使用的凭证数量。",{"type":24,"tag":65,"props":1518,"children":1519},{},[1520],{"type":30,"value":1521},"监控凭证使用模式，发现异常（如突然增加的调用次数）时自动告警并暂停访问。",{"type":24,"tag":121,"props":1523,"children":1525},{"id":1524},"q5-oauth-token-刷新失败怎么处理",[1526],{"type":30,"value":1527},"Q5: OAuth Token 刷新失败怎么处理？",{"type":24,"tag":33,"props":1529,"children":1530},{},[1531,1535],{"type":24,"tag":53,"props":1532,"children":1533},{},[1534],{"type":30,"value":1412},{"type":30,"value":1503},{"type":24,"tag":133,"props":1537,"children":1538},{},[1539,1544,1549,1554],{"type":24,"tag":65,"props":1540,"children":1541},{},[1542],{"type":30,"value":1543},"实现重试机制：刷新失败后等待指数退避时间（1s、2s、4s...）后重试，最多重试 3 次。",{"type":24,"tag":65,"props":1545,"children":1546},{},[1547],{"type":30,"value":1548},"降级策略：如果刷新仍然失败，使用备用凭证或切换到降级模式（如返回缓存数据）。",{"type":24,"tag":65,"props":1550,"children":1551},{},[1552],{"type":30,"value":1553},"告警通知：刷新失败超过阈值时，发送告警给 on-call 工程师。",{"type":24,"tag":65,"props":1555,"children":1556},{},[1557],{"type":30,"value":1558},"根本原因分析：检查是否是网络问题、权限问题还是 OAuth Provider 故障。",{"type":24,"tag":121,"props":1560,"children":1562},{"id":1561},"q6-service-account-和普通用户凭证有什么区别",[1563],{"type":30,"value":1564},"Q6: Service Account 和普通用户凭证有什么区别？",{"type":24,"tag":33,"props":1566,"children":1567},{},[1568,1572],{"type":24,"tag":53,"props":1569,"children":1570},{},[1571],{"type":30,"value":1412},{"type":30,"value":1503},{"type":24,"tag":133,"props":1574,"children":1575},{},[1576,1586],{"type":24,"tag":65,"props":1577,"children":1578},{},[1579,1584],{"type":24,"tag":53,"props":1580,"children":1581},{},[1582],{"type":30,"value":1583},"Service Account",{"type":30,"value":1585},"：代表应用程序或服务的身份，通常用于机器对机器的通信。生命周期长，权限固定，不需要人工干预。",{"type":24,"tag":65,"props":1587,"children":1588},{},[1589,1594],{"type":24,"tag":53,"props":1590,"children":1591},{},[1592],{"type":30,"value":1593},"普通用户凭证",{"type":30,"value":1595},"：代表真实用户的身份，通常用于用户对系统的访问。生命周期短，权限可能动态变化，需要用户登录认证。",{"type":24,"tag":33,"props":1597,"children":1598},{},[1599],{"type":30,"value":1600},"在 AI agent 场景中，大部分情况下使用的是 Service Account，因为 agent 是自动化程序，不需要模拟真实用户登录。",{"type":24,"tag":121,"props":1602,"children":1604},{"id":1603},"q7-如何审计谁访问了哪些凭证",[1605],{"type":30,"value":1606},"Q7: 如何审计谁访问了哪些凭证？",{"type":24,"tag":33,"props":1608,"children":1609},{},[1610,1614],{"type":24,"tag":53,"props":1611,"children":1612},{},[1613],{"type":30,"value":1412},{"type":30,"value":1615},": 启用 Vault 的审计日志功能，将所有操作记录到集中式日志系统（如 Splunk、Elasticsearch）。审计日志应包含：",{"type":24,"tag":133,"props":1617,"children":1618},{},[1619,1624,1629],{"type":24,"tag":65,"props":1620,"children":1621},{},[1622],{"type":30,"value":1623},"访问时间、Actor（哪个 Agent）、Action（读/写/删除）、Path（访问了哪个凭证）、Source IP、Request ID。",{"type":24,"tag":65,"props":1625,"children":1626},{},[1627],{"type":30,"value":1628},"配置实时告警规则，检测异常访问模式（如非工作时间访问、频繁访问不同凭证）。",{"type":24,"tag":65,"props":1630,"children":1631},{},[1632],{"type":30,"value":1633},"定期生成审计报告，供安全团队审查。",{"type":24,"tag":121,"props":1635,"children":1637},{"id":1636},"q8-vault-的性能开销大吗",[1638],{"type":30,"value":1639},"Q8: Vault 的性能开销大吗？",{"type":24,"tag":33,"props":1641,"children":1642},{},[1643,1647],{"type":24,"tag":53,"props":1644,"children":1645},{},[1646],{"type":30,"value":1412},{"type":30,"value":1648},": Vault 的性能取决于使用模式和配置：",{"type":24,"tag":133,"props":1650,"children":1651},{},[1652,1662,1672],{"type":24,"tag":65,"props":1653,"children":1654},{},[1655,1660],{"type":24,"tag":53,"props":1656,"children":1657},{},[1658],{"type":30,"value":1659},"读取操作",{"type":30,"value":1661},"：通常在 10-50ms 之间，对大多数应用来说可以接受。",{"type":24,"tag":65,"props":1663,"children":1664},{},[1665,1670],{"type":24,"tag":53,"props":1666,"children":1667},{},[1668],{"type":30,"value":1669},"写入操作",{"type":30,"value":1671},"：较慢，可能需要 100-500ms，应避免高频写入。",{"type":24,"tag":65,"props":1673,"children":1674},{},[1675,1680,1682],{"type":24,"tag":53,"props":1676,"children":1677},{},[1678],{"type":30,"value":1679},"优化建议",{"type":30,"value":1681},"：\n",{"type":24,"tag":133,"props":1683,"children":1684},{},[1685,1690,1695,1700],{"type":24,"tag":65,"props":1686,"children":1687},{},[1688],{"type":30,"value":1689},"Agent 端缓存凭证，减少 Vault 调用次数。",{"type":24,"tag":65,"props":1691,"children":1692},{},[1693],{"type":30,"value":1694},"使用 HTTP/2 或 gRPC 提高通信效率。",{"type":24,"tag":65,"props":1696,"children":1697},{},[1698],{"type":30,"value":1699},"部署 Vault Proxy 或 Sidecar，就近提供凭证服务。",{"type":24,"tag":65,"props":1701,"children":1702},{},[1703],{"type":30,"value":1704},"对于超高并发场景，考虑使用专门的缓存层（如 Redis）存储热点凭证。",{"type":24,"tag":25,"props":1706,"children":1708},{"id":1707},"延伸阅读",[1709],{"type":30,"value":1707},{"type":24,"tag":133,"props":1711,"children":1712},{},[1713,1725,1735,1745],{"type":24,"tag":65,"props":1714,"children":1715},{},[1716],{"type":24,"tag":1717,"props":1718,"children":1722},"a",{"href":1719,"rel":1720},"https://www.vaultproject.io/docs",[1721],"nofollow",[1723],{"type":30,"value":1724},"HashiCorp Vault 官方文档",{"type":24,"tag":65,"props":1726,"children":1727},{},[1728],{"type":24,"tag":1717,"props":1729,"children":1732},{"href":1730,"rel":1731},"https://docs.aws.amazon.com/secretsmanager/latest/userguide/best-practices.html",[1721],[1733],{"type":30,"value":1734},"AWS Secrets Manager Best Practices",{"type":24,"tag":65,"props":1736,"children":1737},{},[1738],{"type":24,"tag":1717,"props":1739,"children":1742},{"href":1740,"rel":1741},"https://csrc.nist.gov/publications/detail/sp/800-57-part-1/rev-5/final",[1721],[1743],{"type":30,"value":1744},"NIST SP 800-57: Recommendation for Key Management",{"type":24,"tag":65,"props":1746,"children":1747},{},[1748],{"type":24,"tag":1717,"props":1749,"children":1752},{"href":1750,"rel":1751},"https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html",[1721],[1753],{"type":30,"value":1754},"OWASP Secret Management Cheat Sheet",{"type":24,"tag":25,"props":1756,"children":1758},{"id":1757},"checklist",[1759],{"type":30,"value":1760},"Checklist",{"type":24,"tag":33,"props":1762,"children":1763},{},[1764],{"type":30,"value":1765},"在实施 Credential Vault 之前，请确认以下事项：",{"type":24,"tag":133,"props":1767,"children":1770},{"className":1768},[1769],"contains-task-list",[1771,1784,1793,1802,1811,1820,1829,1838,1847,1856],{"type":24,"tag":65,"props":1772,"children":1775},{"className":1773},[1774],"task-list-item",[1776,1782],{"type":24,"tag":1777,"props":1778,"children":1781},"input",{"disabled":1779,"type":1780},true,"checkbox",[],{"type":30,"value":1783}," 已完成凭证盘点，列出所有需要管理的凭证清单",{"type":24,"tag":65,"props":1785,"children":1787},{"className":1786},[1774],[1788,1791],{"type":24,"tag":1777,"props":1789,"children":1790},{"disabled":1779,"type":1780},[],{"type":30,"value":1792}," 已选择合适的 Vault 方案（HashiCorp Vault / AWS Secrets Manager / 其他）",{"type":24,"tag":65,"props":1794,"children":1796},{"className":1795},[1774],[1797,1800],{"type":24,"tag":1777,"props":1798,"children":1799},{"disabled":1779,"type":1780},[],{"type":30,"value":1801}," 已部署 HA 集群，并完成备份、监控、告警配置",{"type":24,"tag":65,"props":1803,"children":1805},{"className":1804},[1774],[1806,1809],{"type":24,"tag":1777,"props":1807,"children":1808},{"disabled":1779,"type":1780},[],{"type":30,"value":1810}," 已定义 RBAC/ABAC 权限策略，遵循最小权限原则",{"type":24,"tag":65,"props":1812,"children":1814},{"className":1813},[1774],[1815,1818],{"type":24,"tag":1777,"props":1816,"children":1817},{"disabled":1779,"type":1780},[],{"type":30,"value":1819}," 已启用审计日志，并配置实时告警规则",{"type":24,"tag":65,"props":1821,"children":1823},{"className":1822},[1774],[1824,1827],{"type":24,"tag":1777,"props":1825,"children":1826},{"disabled":1779,"type":1780},[],{"type":30,"value":1828}," 已制定迁移计划，包括试点项目、分批迁移、回滚方案",{"type":24,"tag":65,"props":1830,"children":1832},{"className":1831},[1774],[1833,1836],{"type":24,"tag":1777,"props":1834,"children":1835},{"disabled":1779,"type":1780},[],{"type":30,"value":1837}," Agent 端已实现凭证缓存和错误处理机制",{"type":24,"tag":65,"props":1839,"children":1841},{"className":1840},[1774],[1842,1845],{"type":24,"tag":1777,"props":1843,"children":1844},{"disabled":1779,"type":1780},[],{"type":30,"value":1846}," 已编写操作文档和故障排查手册",{"type":24,"tag":65,"props":1848,"children":1850},{"className":1849},[1774],[1851,1854],{"type":24,"tag":1777,"props":1852,"children":1853},{"disabled":1779,"type":1780},[],{"type":30,"value":1855}," 已组织团队培训，确保所有开发者了解新流程",{"type":24,"tag":65,"props":1857,"children":1859},{"className":1858},[1774],[1860,1863],{"type":24,"tag":1777,"props":1861,"children":1862},{"disabled":1779,"type":1780},[],{"type":30,"value":1864}," 已安排定期的权限审查和审计日志回顾",{"type":24,"tag":1866,"props":1867,"children":1868},"hr",{},[],{"type":24,"tag":33,"props":1870,"children":1871},{},[1872,1877,1879,1885],{"type":24,"tag":53,"props":1873,"children":1874},{},[1875],{"type":30,"value":1876},"下一步行动",{"type":30,"value":1878},"：阅读 ",{"type":24,"tag":1717,"props":1880,"children":1882},{"href":1881},"./ai-agent-secret-rotation-policy-cadence",[1883],{"type":30,"value":1884},"AI agent Secret Rotation Policy",{"type":30,"value":1886},"，了解如何自动化密钥轮换，避免旧凭证继续在生产环境中运行。",{"title":7,"searchDepth":1888,"depth":1888,"links":1889},3,[1890,1892,1898,1903,1907,1912,1919,1925,1935,1936],{"id":27,"depth":1891,"text":31},2,{"id":116,"depth":1891,"text":119,"children":1893},[1894,1895,1896,1897],{"id":123,"depth":1888,"text":126},{"id":190,"depth":1888,"text":193},{"id":250,"depth":1888,"text":253},{"id":342,"depth":1888,"text":345},{"id":402,"depth":1891,"text":402,"children":1899},[1900,1901,1902],{"id":407,"depth":1888,"text":410},{"id":494,"depth":1888,"text":497},{"id":579,"depth":1888,"text":582},{"id":679,"depth":1891,"text":679,"children":1904},[1905,1906],{"id":684,"depth":1888,"text":687},{"id":748,"depth":1888,"text":751},{"id":794,"depth":1891,"text":794,"children":1908},[1909,1910,1911],{"id":799,"depth":1888,"text":802},{"id":840,"depth":1888,"text":843},{"id":878,"depth":1888,"text":881},{"id":916,"depth":1891,"text":919,"children":1913},[1914,1915,1916,1917,1918],{"id":934,"depth":1888,"text":937},{"id":983,"depth":1888,"text":986},{"id":1032,"depth":1888,"text":1035},{"id":1091,"depth":1888,"text":1094},{"id":1147,"depth":1888,"text":1150},{"id":1211,"depth":1891,"text":1211,"children":1920},[1921,1922,1923,1924],{"id":1216,"depth":1888,"text":1219},{"id":1264,"depth":1888,"text":1267},{"id":1305,"depth":1888,"text":1308},{"id":1354,"depth":1888,"text":1357},{"id":1395,"depth":1891,"text":1398,"children":1926},[1927,1928,1929,1930,1931,1932,1933,1934],{"id":1401,"depth":1888,"text":1404},{"id":1424,"depth":1888,"text":1427},{"id":1476,"depth":1888,"text":1479},{"id":1491,"depth":1888,"text":1494},{"id":1524,"depth":1888,"text":1527},{"id":1561,"depth":1888,"text":1564},{"id":1603,"depth":1888,"text":1606},{"id":1636,"depth":1888,"text":1639},{"id":1707,"depth":1891,"text":1707},{"id":1757,"depth":1891,"text":1760},"markdown","content:topics:ai:ai-agent-credential-vault-design.md","content","topics/ai/ai-agent-credential-vault-design.md","topics/ai/ai-agent-credential-vault-design","md",[1944,3100,4046],{"_path":1945,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":1946,"description":1947,"date":1948,"topic":5,"author":11,"tags":1949,"image":1955,"imageAlt":1956,"pexelsPhotoId":1957,"pexelsUrl":1958,"readingTime":1959,"body":1960,"_type":1937,"_id":3097,"_source":1939,"_file":3098,"_stem":3099,"_extension":1942},"/topics/ai/cursor-keyboard-shortcuts-cheatsheet","Cursor 快捷键速查表（macOS/Windows）：从“会用”到“能提效”的 10 个工作流","把 Cursor 常用快捷键按任务分组（查代码、改代码、多文件、对话、审查与回滚），给出可直接照抄的工作流与最小回归清单，避免“快捷键背了也没变快”。","2026-03-02",[1950,1951,1952,1953,1954],"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":1961,"toc":3071},[1962,1967,1985,1990,2017,2022,2058,2061,2067,2072,2105,2110,2133,2136,2142,2147,2371,2380,2383,2389,2395,2414,2422,2443,2448,2454,2469,2500,2505,2518,2524,2543,2561,2569,2574,2580,2585,2606,2614,2620,2625,2648,2653,2659,2672,2678,2695,2713,2719,2730,2748,2754,2765,2771,2776,2819,2822,2828,2836,2889,2892,2898,2904,2909,2914,2937,2955,2960,2985,2988,2994,3000,3005,3011,3016,3022,3027,3030,3036],{"type":24,"tag":33,"props":1963,"children":1964},{},[1965],{"type":30,"value":1966},"如果你在搜“Cursor 快捷键”，你大概率不是想背一张表，而是想解决这类问题：",{"type":24,"tag":133,"props":1968,"children":1969},{},[1970,1975,1980],{"type":24,"tag":65,"props":1971,"children":1972},{},[1973],{"type":30,"value":1974},"为什么我用了 AI，还是很慢？（对话来回太多、改动不可控）",{"type":24,"tag":65,"props":1976,"children":1977},{},[1978],{"type":30,"value":1979},"为什么它“看起来懂了”，却改错文件/改出回归？（上下文与范围没锁住）",{"type":24,"tag":65,"props":1981,"children":1982},{},[1983],{"type":30,"value":1984},"多文件改动怎么做得安全？（验收、回滚、最小回归集）",{"type":24,"tag":33,"props":1986,"children":1987},{},[1988],{"type":30,"value":1989},"这篇文章给你两份东西：",{"type":24,"tag":61,"props":1991,"children":1992},{},[1993,2005],{"type":24,"tag":65,"props":1994,"children":1995},{},[1996,1998,2003],{"type":30,"value":1997},"一张",{"type":24,"tag":53,"props":1999,"children":2000},{},[2001],{"type":30,"value":2002},"按任务分组",{"type":30,"value":2004},"的快捷键表（不是按功能堆在一起）",{"type":24,"tag":65,"props":2006,"children":2007},{},[2008,2010,2015],{"type":30,"value":2009},"一套“从需求到落地”的",{"type":24,"tag":53,"props":2011,"children":2012},{},[2013],{"type":30,"value":2014},"最小闭环工作流",{"type":30,"value":2016},"（每一步都有快捷键）",{"type":24,"tag":33,"props":2018,"children":2019},{},[2020],{"type":30,"value":2021},"想看系统玩法：",{"type":24,"tag":133,"props":2023,"children":2024},{},[2025,2036,2047],{"type":24,"tag":65,"props":2026,"children":2027},{},[2028,2030],{"type":30,"value":2029},"入门教程看：",{"type":24,"tag":1717,"props":2031,"children":2033},{"href":2032},"/topics/ai/cursor-tutorial",[2034],{"type":30,"value":2035},"Cursor 使用教程（2026）",{"type":24,"tag":65,"props":2037,"children":2038},{},[2039,2041],{"type":30,"value":2040},"进阶玩法看：",{"type":24,"tag":1717,"props":2042,"children":2044},{"href":2043},"/topics/ai/cursor-editor-guide",[2045],{"type":30,"value":2046},"Cursor 编辑器深度玩法",{"type":24,"tag":65,"props":2048,"children":2049},{},[2050,2052],{"type":30,"value":2051},"规则与忽略看：",{"type":24,"tag":1717,"props":2053,"children":2055},{"href":2054},"/topics/ai/cursor-rules-cursorrules",[2056],{"type":30,"value":2057},"Cursor Rules 与 .cursorrules",{"type":24,"tag":1866,"props":2059,"children":2060},{},[],{"type":24,"tag":25,"props":2062,"children":2064},{"id":2063},"先给结论提效不是按得快而是闭环更短",[2065],{"type":30,"value":2066},"先给结论：提效不是“按得快”，而是“闭环更短”",{"type":24,"tag":33,"props":2068,"children":2069},{},[2070],{"type":30,"value":2071},"你可以把 Cursor 的快捷键理解为 3 条流水线：",{"type":24,"tag":133,"props":2073,"children":2074},{},[2075,2085,2095],{"type":24,"tag":65,"props":2076,"children":2077},{},[2078,2083],{"type":24,"tag":53,"props":2079,"children":2080},{},[2081],{"type":30,"value":2082},"改一小段",{"type":30,"value":2084},"（内联编辑）：把改动限制在一个函数/一段样式",{"type":24,"tag":65,"props":2086,"children":2087},{},[2088,2093],{"type":24,"tag":53,"props":2089,"children":2090},{},[2091],{"type":30,"value":2092},"改一组文件",{"type":30,"value":2094},"（Composer）：把改动限制在一组明确文件，并要求输出 diff + 验收点",{"type":24,"tag":65,"props":2096,"children":2097},{},[2098,2103],{"type":24,"tag":53,"props":2099,"children":2100},{},[2101],{"type":30,"value":2102},"聊清楚再动手",{"type":30,"value":2104},"（侧边对话）：先对齐目标、范围、验收、回滚",{"type":24,"tag":33,"props":2106,"children":2107},{},[2108],{"type":30,"value":2109},"当你觉得“它乱改/改太大”时，往往不是快捷键没记住，而是缺了两件事：",{"type":24,"tag":133,"props":2111,"children":2112},{},[2113,2123],{"type":24,"tag":65,"props":2114,"children":2115},{},[2116,2118],{"type":30,"value":2117},"没有在动手前锁定",{"type":24,"tag":53,"props":2119,"children":2120},{},[2121],{"type":30,"value":2122},"范围",{"type":24,"tag":65,"props":2124,"children":2125},{},[2126,2128],{"type":30,"value":2127},"没有在接受改动前准备",{"type":24,"tag":53,"props":2129,"children":2130},{},[2131],{"type":30,"value":2132},"验收/回滚",{"type":24,"tag":1866,"props":2134,"children":2135},{},[],{"type":24,"tag":25,"props":2137,"children":2139},{"id":2138},"快捷键速查表按任务分组",[2140],{"type":30,"value":2141},"快捷键速查表（按任务分组）",{"type":24,"tag":33,"props":2143,"children":2144},{},[2145],{"type":30,"value":2146},"说明：下表按“你正在做什么”组织，而不是按“功能名字”组织。不同版本快捷键可能略有差异，但核心逻辑一致。",{"type":24,"tag":2148,"props":2149,"children":2150},"table",{},[2151,2180],{"type":24,"tag":2152,"props":2153,"children":2154},"thead",{},[2155],{"type":24,"tag":2156,"props":2157,"children":2158},"tr",{},[2159,2165,2170,2175],{"type":24,"tag":2160,"props":2161,"children":2162},"th",{},[2163],{"type":30,"value":2164},"任务",{"type":24,"tag":2160,"props":2166,"children":2167},{},[2168],{"type":30,"value":2169},"macOS",{"type":24,"tag":2160,"props":2171,"children":2172},{},[2173],{"type":30,"value":2174},"Windows",{"type":24,"tag":2160,"props":2176,"children":2177},{},[2178],{"type":30,"value":2179},"你该在什么时候用",{"type":24,"tag":2181,"props":2182,"children":2183},"tbody",{},[2184,2216,2247,2278,2309,2340],{"type":24,"tag":2156,"props":2185,"children":2186},{},[2187,2193,2202,2211],{"type":24,"tag":2188,"props":2189,"children":2190},"td",{},[2191],{"type":30,"value":2192},"改一小段（最安全）",{"type":24,"tag":2188,"props":2194,"children":2195},{},[2196],{"type":24,"tag":39,"props":2197,"children":2199},{"className":2198},[],[2200],{"type":30,"value":2201},"Cmd + K",{"type":24,"tag":2188,"props":2203,"children":2204},{},[2205],{"type":24,"tag":39,"props":2206,"children":2208},{"className":2207},[],[2209],{"type":30,"value":2210},"Ctrl + K",{"type":24,"tag":2188,"props":2212,"children":2213},{},[2214],{"type":30,"value":2215},"只想改一个函数/一段 CSS，不想动别的",{"type":24,"tag":2156,"props":2217,"children":2218},{},[2219,2224,2233,2242],{"type":24,"tag":2188,"props":2220,"children":2221},{},[2222],{"type":30,"value":2223},"打开 AI 对话（先对齐再动手）",{"type":24,"tag":2188,"props":2225,"children":2226},{},[2227],{"type":24,"tag":39,"props":2228,"children":2230},{"className":2229},[],[2231],{"type":30,"value":2232},"Cmd + L",{"type":24,"tag":2188,"props":2234,"children":2235},{},[2236],{"type":24,"tag":39,"props":2237,"children":2239},{"className":2238},[],[2240],{"type":30,"value":2241},"Ctrl + L",{"type":24,"tag":2188,"props":2243,"children":2244},{},[2245],{"type":30,"value":2246},"需要澄清目标、制定步骤、给验收点",{"type":24,"tag":2156,"props":2248,"children":2249},{},[2250,2255,2264,2273],{"type":24,"tag":2188,"props":2251,"children":2252},{},[2253],{"type":30,"value":2254},"多文件编辑（有组织地改一组文件）",{"type":24,"tag":2188,"props":2256,"children":2257},{},[2258],{"type":24,"tag":39,"props":2259,"children":2261},{"className":2260},[],[2262],{"type":30,"value":2263},"Cmd + I",{"type":24,"tag":2188,"props":2265,"children":2266},{},[2267],{"type":24,"tag":39,"props":2268,"children":2270},{"className":2269},[],[2271],{"type":30,"value":2272},"Ctrl + I",{"type":24,"tag":2188,"props":2274,"children":2275},{},[2276],{"type":30,"value":2277},"改动涉及多个文件：组件+样式+测试",{"type":24,"tag":2156,"props":2279,"children":2280},{},[2281,2286,2295,2304],{"type":24,"tag":2188,"props":2282,"children":2283},{},[2284],{"type":30,"value":2285},"把选中代码加入对话上下文",{"type":24,"tag":2188,"props":2287,"children":2288},{},[2289],{"type":24,"tag":39,"props":2290,"children":2292},{"className":2291},[],[2293],{"type":30,"value":2294},"Cmd + Shift + L",{"type":24,"tag":2188,"props":2296,"children":2297},{},[2298],{"type":24,"tag":39,"props":2299,"children":2301},{"className":2300},[],[2302],{"type":30,"value":2303},"Ctrl + Shift + L",{"type":24,"tag":2188,"props":2305,"children":2306},{},[2307],{"type":30,"value":2308},"让 AI 只看你选的片段（降低噪音）",{"type":24,"tag":2156,"props":2310,"children":2311},{},[2312,2317,2326,2335],{"type":24,"tag":2188,"props":2313,"children":2314},{},[2315],{"type":30,"value":2316},"接受当前建议",{"type":24,"tag":2188,"props":2318,"children":2319},{},[2320],{"type":24,"tag":39,"props":2321,"children":2323},{"className":2322},[],[2324],{"type":30,"value":2325},"Cmd + Y",{"type":24,"tag":2188,"props":2327,"children":2328},{},[2329],{"type":24,"tag":39,"props":2330,"children":2332},{"className":2331},[],[2333],{"type":30,"value":2334},"Ctrl + Y",{"type":24,"tag":2188,"props":2336,"children":2337},{},[2338],{"type":30,"value":2339},"你已经准备好验收/回滚，并确认改动范围",{"type":24,"tag":2156,"props":2341,"children":2342},{},[2343,2348,2357,2366],{"type":24,"tag":2188,"props":2344,"children":2345},{},[2346],{"type":30,"value":2347},"拒绝当前建议",{"type":24,"tag":2188,"props":2349,"children":2350},{},[2351],{"type":24,"tag":39,"props":2352,"children":2354},{"className":2353},[],[2355],{"type":30,"value":2356},"Cmd + N",{"type":24,"tag":2188,"props":2358,"children":2359},{},[2360],{"type":24,"tag":39,"props":2361,"children":2363},{"className":2362},[],[2364],{"type":30,"value":2365},"Ctrl + N",{"type":24,"tag":2188,"props":2367,"children":2368},{},[2369],{"type":30,"value":2370},"改得太大、改错方向，立刻收手",{"type":24,"tag":2372,"props":2373,"children":2374},"blockquote",{},[2375],{"type":24,"tag":33,"props":2376,"children":2377},{},[2378],{"type":30,"value":2379},"小技巧：把“改一小段”当默认路径。只有当你能清晰写出“会改哪几类文件、怎么验收”时再进入多文件。",{"type":24,"tag":1866,"props":2381,"children":2382},{},[],{"type":24,"tag":25,"props":2384,"children":2386},{"id":2385},"_10-个可直接照抄的提效工作流每个都能闭环",[2387],{"type":30,"value":2388},"10 个可直接照抄的提效工作流（每个都能闭环）",{"type":24,"tag":121,"props":2390,"children":2392},{"id":2391},"工作流-1需求计划小步改新手最稳",[2393],{"type":30,"value":2394},"工作流 1：需求→计划→小步改（新手最稳）",{"type":24,"tag":61,"props":2396,"children":2397},{},[2398,2409],{"type":24,"tag":65,"props":2399,"children":2400},{},[2401,2407],{"type":24,"tag":39,"props":2402,"children":2404},{"className":2403},[],[2405],{"type":30,"value":2406},"Cmd/Ctrl + L",{"type":30,"value":2408}," 打开对话",{"type":24,"tag":65,"props":2410,"children":2411},{},[2412],{"type":30,"value":2413},"先发这段（可复制）：",{"type":24,"tag":2372,"props":2415,"children":2416},{},[2417],{"type":24,"tag":33,"props":2418,"children":2419},{},[2420],{"type":30,"value":2421},"目标：……\n范围：只修改以下文件/模块：……\n非目标：……（明确不做）\n验收：……（可测试/可手动检查）\n输出格式：先给计划，再逐步执行；每一步写出 diff 摘要。",{"type":24,"tag":61,"props":2423,"children":2424},{"start":1888},[2425,2430],{"type":24,"tag":65,"props":2426,"children":2427},{},[2428],{"type":30,"value":2429},"让 AI 先给“计划（3~6 步）”，你确认后再执行",{"type":24,"tag":65,"props":2431,"children":2432},{},[2433,2435,2441],{"type":30,"value":2434},"任何一步涉及改代码：优先回到编辑区，选中片段用 ",{"type":24,"tag":39,"props":2436,"children":2438},{"className":2437},[],[2439],{"type":30,"value":2440},"Cmd/Ctrl + K",{"type":30,"value":2442}," 小步改",{"type":24,"tag":33,"props":2444,"children":2445},{},[2446],{"type":30,"value":2447},"为什么有效：你把“想法”变成了“可执行约束”，这就是 GEO（面向 AI/模型的可理解结构）。",{"type":24,"tag":121,"props":2449,"children":2451},{"id":2450},"工作流-2只改一个函数高频低风险",[2452],{"type":30,"value":2453},"工作流 2：只改一个函数（高频、低风险）",{"type":24,"tag":133,"props":2455,"children":2456},{},[2457],{"type":24,"tag":65,"props":2458,"children":2459},{},[2460,2462,2467],{"type":30,"value":2461},"选中函数 → ",{"type":24,"tag":39,"props":2463,"children":2465},{"className":2464},[],[2466],{"type":30,"value":2440},{"type":30,"value":2468}," → 输入指令：",{"type":24,"tag":2372,"props":2470,"children":2471},{},[2472,2477],{"type":24,"tag":33,"props":2473,"children":2474},{},[2475],{"type":30,"value":2476},"把这段改成更可读：",{"type":24,"tag":133,"props":2478,"children":2479},{},[2480,2485,2490,2495],{"type":24,"tag":65,"props":2481,"children":2482},{},[2483],{"type":30,"value":2484},"用 async/await",{"type":24,"tag":65,"props":2486,"children":2487},{},[2488],{"type":30,"value":2489},"错误处理不要吞掉",{"type":24,"tag":65,"props":2491,"children":2492},{},[2493],{"type":30,"value":2494},"添加类型（若可推断）",{"type":24,"tag":65,"props":2496,"children":2497},{},[2498],{"type":30,"value":2499},"不要改函数签名",{"type":24,"tag":33,"props":2501,"children":2502},{},[2503],{"type":30,"value":2504},"验收方式（强制）：",{"type":24,"tag":133,"props":2506,"children":2507},{},[2508,2513],{"type":24,"tag":65,"props":2509,"children":2510},{},[2511],{"type":30,"value":2512},"输出前后函数行为一致（输入/输出）",{"type":24,"tag":65,"props":2514,"children":2515},{},[2516],{"type":30,"value":2517},"失败分支有可观测日志（不要悄悄 return null）",{"type":24,"tag":121,"props":2519,"children":2521},{"id":2520},"工作流-3多文件改动先定文件清单",[2522],{"type":30,"value":2523},"工作流 3：多文件改动（先定“文件清单”）",{"type":24,"tag":61,"props":2525,"children":2526},{},[2527,2538],{"type":24,"tag":65,"props":2528,"children":2529},{},[2530,2536],{"type":24,"tag":39,"props":2531,"children":2533},{"className":2532},[],[2534],{"type":30,"value":2535},"Cmd/Ctrl + I",{"type":30,"value":2537}," 进入多文件",{"type":24,"tag":65,"props":2539,"children":2540},{},[2541],{"type":30,"value":2542},"先让 AI 输出：",{"type":24,"tag":133,"props":2544,"children":2545},{},[2546,2551,2556],{"type":24,"tag":65,"props":2547,"children":2548},{},[2549],{"type":30,"value":2550},"预计会改哪些文件（最多 5 个）",{"type":24,"tag":65,"props":2552,"children":2553},{},[2554],{"type":30,"value":2555},"每个文件改什么",{"type":24,"tag":65,"props":2557,"children":2558},{},[2559],{"type":30,"value":2560},"每一步怎么验收",{"type":24,"tag":61,"props":2562,"children":2563},{"start":1888},[2564],{"type":24,"tag":65,"props":2565,"children":2566},{},[2567],{"type":30,"value":2568},"你确认文件清单后再开始生成改动",{"type":24,"tag":33,"props":2570,"children":2571},{},[2572],{"type":30,"value":2573},"关键点：多文件最容易翻车的是“它把你没想到的文件也改了”。所以文件清单是第一道闸门。",{"type":24,"tag":121,"props":2575,"children":2577},{"id":2576},"工作流-4把上下文噪音砍掉防跑偏",[2578],{"type":30,"value":2579},"工作流 4：把“上下文噪音”砍掉（防跑偏）",{"type":24,"tag":33,"props":2581,"children":2582},{},[2583],{"type":30,"value":2584},"当你怀疑它在胡说/乱改时：",{"type":24,"tag":133,"props":2586,"children":2587},{},[2588,2601],{"type":24,"tag":65,"props":2589,"children":2590},{},[2591,2593,2599],{"type":30,"value":2592},"只选择关键代码片段 → ",{"type":24,"tag":39,"props":2594,"children":2596},{"className":2595},[],[2597],{"type":30,"value":2598},"Cmd/Ctrl + Shift + L",{"type":30,"value":2600}," 加入对话",{"type":24,"tag":65,"props":2602,"children":2603},{},[2604],{"type":30,"value":2605},"然后在对话里要求：",{"type":24,"tag":2372,"props":2607,"children":2608},{},[2609],{"type":24,"tag":33,"props":2610,"children":2611},{},[2612],{"type":30,"value":2613},"只基于我提供的代码片段回答，不要假设其它文件存在。",{"type":24,"tag":121,"props":2615,"children":2617},{"id":2616},"工作流-5生成变更说明让-code-review-变快",[2618],{"type":30,"value":2619},"工作流 5：生成变更说明（让 code review 变快）",{"type":24,"tag":33,"props":2621,"children":2622},{},[2623],{"type":30,"value":2624},"改完后在对话里让它输出：",{"type":24,"tag":133,"props":2626,"children":2627},{},[2628,2633,2638,2643],{"type":24,"tag":65,"props":2629,"children":2630},{},[2631],{"type":30,"value":2632},"改动摘要（3~7 条）",{"type":24,"tag":65,"props":2634,"children":2635},{},[2636],{"type":30,"value":2637},"风险点（依赖/边界条件）",{"type":24,"tag":65,"props":2639,"children":2640},{},[2641],{"type":30,"value":2642},"回滚方式",{"type":24,"tag":65,"props":2644,"children":2645},{},[2646],{"type":30,"value":2647},"验收步骤",{"type":24,"tag":33,"props":2649,"children":2650},{},[2651],{"type":30,"value":2652},"这套结构能直接贴进 PR 描述。",{"type":24,"tag":121,"props":2654,"children":2656},{"id":2655},"工作流-6写最小回归集不写回归-等事故",[2657],{"type":30,"value":2658},"工作流 6：写“最小回归集”（不写回归 = 等事故）",{"type":24,"tag":33,"props":2660,"children":2661},{},[2662,2664,2670],{"type":30,"value":2663},"每次改动都至少做 10 条最小回归（见下文清单）。你可以把它写在 ",{"type":24,"tag":39,"props":2665,"children":2667},{"className":2666},[],[2668],{"type":30,"value":2669},"README",{"type":30,"value":2671}," 或团队 wiki。",{"type":24,"tag":121,"props":2673,"children":2675},{"id":2674},"工作流-7把接受建议变成最后一步",[2676],{"type":30,"value":2677},"工作流 7：把“接受建议”变成最后一步",{"type":24,"tag":33,"props":2679,"children":2680},{},[2681,2687,2689,2694],{"type":24,"tag":39,"props":2682,"children":2684},{"className":2683},[],[2685],{"type":30,"value":2686},"Cmd/Ctrl + Y",{"type":30,"value":2688}," 应该是",{"type":24,"tag":53,"props":2690,"children":2691},{},[2692],{"type":30,"value":2693},"最后一步",{"type":30,"value":205},{"type":24,"tag":133,"props":2696,"children":2697},{},[2698,2703,2708],{"type":24,"tag":65,"props":2699,"children":2700},{},[2701],{"type":30,"value":2702},"你已经看过 diff",{"type":24,"tag":65,"props":2704,"children":2705},{},[2706],{"type":30,"value":2707},"你能说清楚“怎么验收”",{"type":24,"tag":65,"props":2709,"children":2710},{},[2711],{"type":30,"value":2712},"你知道“怎么回滚”",{"type":24,"tag":121,"props":2714,"children":2716},{"id":2715},"工作流-8拒绝建议不是失败是风控动作",[2717],{"type":30,"value":2718},"工作流 8：拒绝建议不是失败，是风控动作",{"type":24,"tag":33,"props":2720,"children":2721},{},[2722,2728],{"type":24,"tag":39,"props":2723,"children":2725},{"className":2724},[],[2726],{"type":30,"value":2727},"Cmd/Ctrl + N",{"type":30,"value":2729}," 的使用时机：",{"type":24,"tag":133,"props":2731,"children":2732},{},[2733,2738,2743],{"type":24,"tag":65,"props":2734,"children":2735},{},[2736],{"type":30,"value":2737},"它开始改你没提过的东西（范围漂移）",{"type":24,"tag":65,"props":2739,"children":2740},{},[2741],{"type":30,"value":2742},"它改了 10 个文件但你只想改 1 个",{"type":24,"tag":65,"props":2744,"children":2745},{},[2746],{"type":30,"value":2747},"它为了“更优雅”引入新依赖/新抽象",{"type":24,"tag":121,"props":2749,"children":2751},{"id":2750},"工作流-9重复任务做成模板提示词不是一次性",[2752],{"type":30,"value":2753},"工作流 9：重复任务做成模板（提示词不是一次性）",{"type":24,"tag":33,"props":2755,"children":2756},{},[2757,2759,2763],{"type":30,"value":2758},"把高频任务（比如“写组件+样式+验收”）固化成模板，放进 Rules（见：",{"type":24,"tag":1717,"props":2760,"children":2761},{"href":2054},[2762],{"type":30,"value":2057},{"type":30,"value":2764},"）。",{"type":24,"tag":121,"props":2766,"children":2768},{"id":2767},"工作流-10把快捷键表做成你自己的任务表",[2769],{"type":30,"value":2770},"工作流 10：把“快捷键表”做成你自己的任务表",{"type":24,"tag":33,"props":2772,"children":2773},{},[2774],{"type":30,"value":2775},"你不需要记住所有快捷键，只需要记住：",{"type":24,"tag":133,"props":2777,"children":2778},{},[2779,2789,2799,2809],{"type":24,"tag":65,"props":2780,"children":2781},{},[2782,2784],{"type":30,"value":2783},"小步改：",{"type":24,"tag":39,"props":2785,"children":2787},{"className":2786},[],[2788],{"type":30,"value":2440},{"type":24,"tag":65,"props":2790,"children":2791},{},[2792,2794],{"type":30,"value":2793},"先对齐：",{"type":24,"tag":39,"props":2795,"children":2797},{"className":2796},[],[2798],{"type":30,"value":2406},{"type":24,"tag":65,"props":2800,"children":2801},{},[2802,2804],{"type":30,"value":2803},"多文件：",{"type":24,"tag":39,"props":2805,"children":2807},{"className":2806},[],[2808],{"type":30,"value":2535},{"type":24,"tag":65,"props":2810,"children":2811},{},[2812,2814],{"type":30,"value":2813},"上下文聚焦：",{"type":24,"tag":39,"props":2815,"children":2817},{"className":2816},[],[2818],{"type":30,"value":2598},{"type":24,"tag":1866,"props":2820,"children":2821},{},[],{"type":24,"tag":25,"props":2823,"children":2825},{"id":2824},"必交付物-1最小回归任务清单10-条通用",[2826],{"type":30,"value":2827},"必交付物 1：最小回归任务清单（10 条，通用）",{"type":24,"tag":2372,"props":2829,"children":2830},{},[2831],{"type":24,"tag":33,"props":2832,"children":2833},{},[2834],{"type":30,"value":2835},"这份清单的意义：让每次 AI 改动都能“被验证”。否则你只是把不可控变成了更快的不可控。",{"type":24,"tag":61,"props":2837,"children":2838},{},[2839,2844,2849,2854,2859,2864,2869,2874,2879,2884],{"type":24,"tag":65,"props":2840,"children":2841},{},[2842],{"type":30,"value":2843},"关键路径能跑通（手动点击/请求一次）",{"type":24,"tag":65,"props":2845,"children":2846},{},[2847],{"type":30,"value":2848},"错误路径能触发（模拟一次失败输入）",{"type":24,"tag":65,"props":2850,"children":2851},{},[2852],{"type":30,"value":2853},"控制台无新增错误（至少关注 1 次真实操作）",{"type":24,"tag":65,"props":2855,"children":2856},{},[2857],{"type":30,"value":2858},"关键 UI 未错位（移动端/桌面端各看一眼）",{"type":24,"tag":65,"props":2860,"children":2861},{},[2862],{"type":30,"value":2863},"刷新后状态正确（尤其是表单/列表）",{"type":24,"tag":65,"props":2865,"children":2866},{},[2867],{"type":30,"value":2868},"路由跳转没断（从入口到目标页）",{"type":24,"tag":65,"props":2870,"children":2871},{},[2872],{"type":30,"value":2873},"相关接口未改变契约（字段名/类型）",{"type":24,"tag":65,"props":2875,"children":2876},{},[2877],{"type":30,"value":2878},"性能没有明显退化（首屏、交互卡顿）",{"type":24,"tag":65,"props":2880,"children":2881},{},[2882],{"type":30,"value":2883},"回滚方案可执行（知道回滚哪几个文件/commit）",{"type":24,"tag":65,"props":2885,"children":2886},{},[2887],{"type":30,"value":2888},"写下“这次改动解决了什么、风险是什么”（可贴 PR）",{"type":24,"tag":1866,"props":2890,"children":2891},{},[],{"type":24,"tag":25,"props":2893,"children":2895},{"id":2894},"必交付物-2失败案例复盘真实会发生",[2896],{"type":30,"value":2897},"必交付物 2：失败案例复盘（真实会发生）",{"type":24,"tag":121,"props":2899,"children":2901},{"id":2900},"现象快捷键用得很熟但交付还是慢",[2902],{"type":30,"value":2903},"现象：快捷键用得很熟，但交付还是慢",{"type":24,"tag":33,"props":2905,"children":2906},{},[2907],{"type":30,"value":2908},"典型原因：你把 Cursor 当成“更聪明的搜索框”，不断对话，直到它给出你想要的答案。",{"type":24,"tag":33,"props":2910,"children":2911},{},[2912],{"type":30,"value":2913},"复现路径：",{"type":24,"tag":133,"props":2915,"children":2916},{},[2917,2922,2927,2932],{"type":24,"tag":65,"props":2918,"children":2919},{},[2920],{"type":30,"value":2921},"你直接说“把页面做得更好看、更高级”",{"type":24,"tag":65,"props":2923,"children":2924},{},[2925],{"type":30,"value":2926},"AI 开始大改样式、抽象组件、甚至引入新依赖",{"type":24,"tag":65,"props":2928,"children":2929},{},[2930],{"type":30,"value":2931},"你为了省事按了“接受建议”",{"type":24,"tag":65,"props":2933,"children":2934},{},[2935],{"type":30,"value":2936},"最后发现：设计没统一、移动端崩、甚至埋了性能问题",{"type":24,"tag":33,"props":2938,"children":2939},{},[2940,2942,2946,2948,2953],{"type":30,"value":2941},"根因：缺少",{"type":24,"tag":53,"props":2943,"children":2944},{},[2945],{"type":30,"value":2122},{"type":30,"value":2947},"与",{"type":24,"tag":53,"props":2949,"children":2950},{},[2951],{"type":30,"value":2952},"验收",{"type":30,"value":2954},"。",{"type":24,"tag":33,"props":2956,"children":2957},{},[2958],{"type":30,"value":2959},"修复方式（可照抄）：",{"type":24,"tag":133,"props":2961,"children":2962},{},[2963,2968,2980],{"type":24,"tag":65,"props":2964,"children":2965},{},[2966],{"type":30,"value":2967},"把需求拆成 3 个可验证目标：例如“按钮样式统一”“首屏 CTA 更明显”“移动端间距不挤”",{"type":24,"tag":65,"props":2969,"children":2970},{},[2971,2973,2978],{"type":30,"value":2972},"每个目标只用 ",{"type":24,"tag":39,"props":2974,"children":2976},{"className":2975},[],[2977],{"type":30,"value":2440},{"type":30,"value":2979}," 改一个局部",{"type":24,"tag":65,"props":2981,"children":2982},{},[2983],{"type":30,"value":2984},"每次接受建议前跑一遍“最小回归集”",{"type":24,"tag":1866,"props":2986,"children":2987},{},[],{"type":24,"tag":25,"props":2989,"children":2991},{"id":2990},"faq高频问题",[2992],{"type":30,"value":2993},"FAQ（高频问题）",{"type":24,"tag":121,"props":2995,"children":2997},{"id":2996},"q1我应该先记快捷键还是先学工作流",[2998],{"type":30,"value":2999},"Q1：我应该先记快捷键还是先学工作流？",{"type":24,"tag":33,"props":3001,"children":3002},{},[3003],{"type":30,"value":3004},"先学工作流。快捷键只是把工作流的步骤变短。",{"type":24,"tag":121,"props":3006,"children":3008},{"id":3007},"q2为什么我一用多文件就容易翻车",[3009],{"type":30,"value":3010},"Q2：为什么我一用多文件就容易翻车？",{"type":24,"tag":33,"props":3012,"children":3013},{},[3014],{"type":30,"value":3015},"因为多文件意味着范围更大、依赖更多、验收更难。先锁定“文件清单 + 每步验收”，再让它动手。",{"type":24,"tag":121,"props":3017,"children":3019},{"id":3018},"q3有没有万能提示词",[3020],{"type":30,"value":3021},"Q3：有没有“万能提示词”？",{"type":24,"tag":33,"props":3023,"children":3024},{},[3025],{"type":30,"value":3026},"没有，但有“万能结构”：目标、范围、非目标、验收、输出格式。",{"type":24,"tag":1866,"props":3028,"children":3029},{},[],{"type":24,"tag":25,"props":3031,"children":3033},{"id":3032},"延伸阅读建议按顺序",[3034],{"type":30,"value":3035},"延伸阅读（建议按顺序）",{"type":24,"tag":133,"props":3037,"children":3038},{},[3039,3046,3053,3060],{"type":24,"tag":65,"props":3040,"children":3041},{},[3042],{"type":24,"tag":1717,"props":3043,"children":3044},{"href":2032},[3045],{"type":30,"value":2035},{"type":24,"tag":65,"props":3047,"children":3048},{},[3049],{"type":24,"tag":1717,"props":3050,"children":3051},{"href":2043},[3052],{"type":30,"value":2046},{"type":24,"tag":65,"props":3054,"children":3055},{},[3056],{"type":24,"tag":1717,"props":3057,"children":3058},{"href":2054},[3059],{"type":30,"value":2057},{"type":24,"tag":65,"props":3061,"children":3062},{},[3063,3065],{"type":30,"value":3064},"如果你更关心“网页制作落地”：看这篇 ",{"type":24,"tag":1717,"props":3066,"children":3068},{"href":3067},"/topics/practical-tips/htmlpage-quick-landing-page",[3069],{"type":30,"value":3070},"3 分钟用 HTMLPAGE 做落地页",{"title":7,"searchDepth":1888,"depth":1888,"links":3072},[3073,3074,3075,3087,3088,3091,3096],{"id":2063,"depth":1891,"text":2066},{"id":2138,"depth":1891,"text":2141},{"id":2385,"depth":1891,"text":2388,"children":3076},[3077,3078,3079,3080,3081,3082,3083,3084,3085,3086],{"id":2391,"depth":1888,"text":2394},{"id":2450,"depth":1888,"text":2453},{"id":2520,"depth":1888,"text":2523},{"id":2576,"depth":1888,"text":2579},{"id":2616,"depth":1888,"text":2619},{"id":2655,"depth":1888,"text":2658},{"id":2674,"depth":1888,"text":2677},{"id":2715,"depth":1888,"text":2718},{"id":2750,"depth":1888,"text":2753},{"id":2767,"depth":1888,"text":2770},{"id":2824,"depth":1891,"text":2827},{"id":2894,"depth":1891,"text":2897,"children":3089},[3090],{"id":2900,"depth":1888,"text":2903},{"id":2990,"depth":1891,"text":2993,"children":3092},[3093,3094,3095],{"id":2996,"depth":1888,"text":2999},{"id":3007,"depth":1888,"text":3010},{"id":3018,"depth":1888,"text":3021},{"id":3032,"depth":1891,"text":3035},"content:topics:ai:cursor-keyboard-shortcuts-cheatsheet.md","topics/ai/cursor-keyboard-shortcuts-cheatsheet.md","topics/ai/cursor-keyboard-shortcuts-cheatsheet",{"_path":3101,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":3102,"description":3103,"date":3104,"topic":5,"author":11,"tags":3105,"image":3109,"imageAlt":3110,"pexelsPhotoId":3111,"pexelsUrl":3112,"readingTime":19,"body":3113,"_type":1937,"_id":4043,"_source":1939,"_file":4044,"_stem":4045,"_extension":1942},"/topics/ai/cursor-vs-copilot-vscode-workflow","Cursor vs GitHub Copilot vs VS Code：怎么选、怎么搭配、怎么把风险关在笼子里","用“任务类型×风险×验收成本”的选择矩阵解释 Cursor/Copilot/VS Code 的差异，并给出一套可落地的协作工作流（范围闸门、最小回归集、回滚策略）。","2026-03-01",[1950,3106,1953,3107,3108],"GitHub Copilot","AI 编程","工作流","/images/topics/ai/cursor-vs-copilot-vscode-workflow.jpg","团队在电脑前进行协作讨论",1181371,"https://www.pexels.com/photo/man-wearing-blue-dress-shirt-1181371/",{"type":21,"children":3114,"toc":4021},[3115,3120,3125,3143,3148,3166,3169,3175,3180,3211,3216,3219,3225,3233,3437,3445,3458,3461,3467,3473,3486,3491,3504,3510,3515,3548,3554,3559,3577,3580,3586,3591,3597,3602,3635,3641,3654,3659,3672,3678,3690,3696,3701,3714,3719,3722,3728,3733,3854,3857,3863,3873,3882,3900,3909,3917,3926,3944,3947,3951,3957,3962,3968,3973,3976,3980],{"type":24,"tag":33,"props":3116,"children":3117},{},[3118],{"type":30,"value":3119},"“Cursor 和 Copilot 到底有什么区别？”",{"type":24,"tag":33,"props":3121,"children":3122},{},[3123],{"type":30,"value":3124},"这个问题问得越早越好，因为你一旦把工具选错，后面所有痛苦都不是“提示词不够好”，而是：",{"type":24,"tag":133,"props":3126,"children":3127},{},[3128,3133,3138],{"type":24,"tag":65,"props":3129,"children":3130},{},[3131],{"type":30,"value":3132},"改动不可控（范围漂移、改错文件）",{"type":24,"tag":65,"props":3134,"children":3135},{},[3136],{"type":30,"value":3137},"验收成本爆炸（不知道要测什么）",{"type":24,"tag":65,"props":3139,"children":3140},{},[3141],{"type":30,"value":3142},"团队协作崩盘（没有闸门、没有回滚）",{"type":24,"tag":33,"props":3144,"children":3145},{},[3146],{"type":30,"value":3147},"这篇文章用一张选择矩阵 + 一套可执行工作流，帮你做到两件事：",{"type":24,"tag":61,"props":3149,"children":3150},{},[3151,3156],{"type":24,"tag":65,"props":3152,"children":3153},{},[3154],{"type":30,"value":3155},"知道什么时候用 Cursor、什么时候用 Copilot、什么时候“纯 VS Code 更快”",{"type":24,"tag":65,"props":3157,"children":3158},{},[3159,3161],{"type":30,"value":3160},"就算用 AI，也能把风险关在笼子里：",{"type":24,"tag":53,"props":3162,"children":3163},{},[3164],{"type":30,"value":3165},"可审查、可验证、可回滚",{"type":24,"tag":1866,"props":3167,"children":3168},{},[],{"type":24,"tag":25,"props":3170,"children":3172},{"id":3171},"结论先说三者不是互斥而是分工",[3173],{"type":30,"value":3174},"结论先说：三者不是互斥，而是分工",{"type":24,"tag":33,"props":3176,"children":3177},{},[3178],{"type":30,"value":3179},"你可以把它们看成三层能力：",{"type":24,"tag":133,"props":3181,"children":3182},{},[3183,3192,3202],{"type":24,"tag":65,"props":3184,"children":3185},{},[3186,3190],{"type":24,"tag":53,"props":3187,"children":3188},{},[3189],{"type":30,"value":1953},{"type":30,"value":3191},"：编辑器与生态（调试、插件、任务、终端、语言服务）",{"type":24,"tag":65,"props":3193,"children":3194},{},[3195,3200],{"type":24,"tag":53,"props":3196,"children":3197},{},[3198],{"type":30,"value":3199},"Copilot",{"type":30,"value":3201},"：代码补全与局部建议（“我正在写这一行/这一段”）",{"type":24,"tag":65,"props":3203,"children":3204},{},[3205,3209],{"type":24,"tag":53,"props":3206,"children":3207},{},[3208],{"type":30,"value":1950},{"type":30,"value":3210},"：以项目为单位的 AI 协作（对话、索引、多文件编辑、规则）",{"type":24,"tag":33,"props":3212,"children":3213},{},[3214],{"type":30,"value":3215},"最常见的误区是：把“局部补全能力”当作“能做架构与多文件落地”。",{"type":24,"tag":1866,"props":3217,"children":3218},{},[],{"type":24,"tag":25,"props":3220,"children":3222},{"id":3221},"选择矩阵按任务类型选工具不是按偏好",[3223],{"type":30,"value":3224},"选择矩阵：按任务类型选工具（不是按偏好）",{"type":24,"tag":2372,"props":3226,"children":3227},{},[3228],{"type":24,"tag":33,"props":3229,"children":3230},{},[3231],{"type":30,"value":3232},"你只要把自己的任务放进表格，就能得到推荐路径。",{"type":24,"tag":2148,"props":3234,"children":3235},{},[3236,3268],{"type":24,"tag":2152,"props":3237,"children":3238},{},[3239],{"type":24,"tag":2156,"props":3240,"children":3241},{},[3242,3247,3253,3258,3263],{"type":24,"tag":2160,"props":3243,"children":3244},{},[3245],{"type":30,"value":3246},"任务类型",{"type":24,"tag":2160,"props":3248,"children":3250},{"align":3249},"right",[3251],{"type":30,"value":3252},"风险",{"type":24,"tag":2160,"props":3254,"children":3255},{"align":3249},[3256],{"type":30,"value":3257},"验收成本",{"type":24,"tag":2160,"props":3259,"children":3260},{},[3261],{"type":30,"value":3262},"更推荐",{"type":24,"tag":2160,"props":3264,"children":3265},{},[3266],{"type":30,"value":3267},"为什么",{"type":24,"tag":2181,"props":3269,"children":3270},{},[3271,3298,3331,3357,3384,3411],{"type":24,"tag":2156,"props":3272,"children":3273},{},[3274,3279,3284,3288,3293],{"type":24,"tag":2188,"props":3275,"children":3276},{},[3277],{"type":30,"value":3278},"写一段代码/补一个 if",{"type":24,"tag":2188,"props":3280,"children":3281},{"align":3249},[3282],{"type":30,"value":3283},"低",{"type":24,"tag":2188,"props":3285,"children":3286},{"align":3249},[3287],{"type":30,"value":3283},{"type":24,"tag":2188,"props":3289,"children":3290},{},[3291],{"type":30,"value":3292},"Copilot / Cursor 内联编辑",{"type":24,"tag":2188,"props":3294,"children":3295},{},[3296],{"type":30,"value":3297},"局部建议足够，成本最低",{"type":24,"tag":2156,"props":3299,"children":3300},{},[3301,3306,3311,3315,3326],{"type":24,"tag":2188,"props":3302,"children":3303},{},[3304],{"type":30,"value":3305},"重构一个函数",{"type":24,"tag":2188,"props":3307,"children":3308},{"align":3249},[3309],{"type":30,"value":3310},"中",{"type":24,"tag":2188,"props":3312,"children":3313},{"align":3249},[3314],{"type":30,"value":3310},{"type":24,"tag":2188,"props":3316,"children":3317},{},[3318,3320],{"type":30,"value":3319},"Cursor ",{"type":24,"tag":39,"props":3321,"children":3323},{"className":3322},[],[3324],{"type":30,"value":3325},"内联编辑",{"type":24,"tag":2188,"props":3327,"children":3328},{},[3329],{"type":30,"value":3330},"需要解释、需要约束输出",{"type":24,"tag":2156,"props":3332,"children":3333},{},[3334,3339,3343,3347,3352],{"type":24,"tag":2188,"props":3335,"children":3336},{},[3337],{"type":30,"value":3338},"改一个组件 + 样式",{"type":24,"tag":2188,"props":3340,"children":3341},{"align":3249},[3342],{"type":30,"value":3310},{"type":24,"tag":2188,"props":3344,"children":3345},{"align":3249},[3346],{"type":30,"value":3310},{"type":24,"tag":2188,"props":3348,"children":3349},{},[3350],{"type":30,"value":3351},"Cursor（小范围多文件）",{"type":24,"tag":2188,"props":3353,"children":3354},{},[3355],{"type":30,"value":3356},"需要同时改模板与样式",{"type":24,"tag":2156,"props":3358,"children":3359},{},[3360,3365,3370,3374,3379],{"type":24,"tag":2188,"props":3361,"children":3362},{},[3363],{"type":30,"value":3364},"改 3~5 个文件（组件+api+测试）",{"type":24,"tag":2188,"props":3366,"children":3367},{"align":3249},[3368],{"type":30,"value":3369},"高",{"type":24,"tag":2188,"props":3371,"children":3372},{"align":3249},[3373],{"type":30,"value":3369},{"type":24,"tag":2188,"props":3375,"children":3376},{},[3377],{"type":30,"value":3378},"Cursor Composer + 闸门",{"type":24,"tag":2188,"props":3380,"children":3381},{},[3382],{"type":30,"value":3383},"需要计划、验收、回滚",{"type":24,"tag":2156,"props":3385,"children":3386},{},[3387,3392,3397,3401,3406],{"type":24,"tag":2188,"props":3388,"children":3389},{},[3390],{"type":30,"value":3391},"重写一段架构/引入新依赖",{"type":24,"tag":2188,"props":3393,"children":3394},{"align":3249},[3395],{"type":30,"value":3396},"很高",{"type":24,"tag":2188,"props":3398,"children":3399},{"align":3249},[3400],{"type":30,"value":3396},{"type":24,"tag":2188,"props":3402,"children":3403},{},[3404],{"type":30,"value":3405},"先人脑设计 + VS Code 实现",{"type":24,"tag":2188,"props":3407,"children":3408},{},[3409],{"type":30,"value":3410},"AI 易发散，最好先设计再执行",{"type":24,"tag":2156,"props":3412,"children":3413},{},[3414,3419,3423,3427,3432],{"type":24,"tag":2188,"props":3415,"children":3416},{},[3417],{"type":30,"value":3418},"排查线上问题/性能抖动",{"type":24,"tag":2188,"props":3420,"children":3421},{"align":3249},[3422],{"type":30,"value":3369},{"type":24,"tag":2188,"props":3424,"children":3425},{"align":3249},[3426],{"type":30,"value":3396},{"type":24,"tag":2188,"props":3428,"children":3429},{},[3430],{"type":30,"value":3431},"VS Code + 工具链优先，AI 辅助归纳",{"type":24,"tag":2188,"props":3433,"children":3434},{},[3435],{"type":30,"value":3436},"需要证据，不要“猜”",{"type":24,"tag":33,"props":3438,"children":3439},{},[3440],{"type":24,"tag":53,"props":3441,"children":3442},{},[3443],{"type":30,"value":3444},"一句话规则：",{"type":24,"tag":133,"props":3446,"children":3447},{},[3448,3453],{"type":24,"tag":65,"props":3449,"children":3450},{},[3451],{"type":30,"value":3452},"当你的改动可以用“10 条最小回归集”覆盖时，用 Cursor。",{"type":24,"tag":65,"props":3454,"children":3455},{},[3456],{"type":30,"value":3457},"当你的改动无法验证时，先别让 AI 动手。",{"type":24,"tag":1866,"props":3459,"children":3460},{},[],{"type":24,"tag":25,"props":3462,"children":3464},{"id":3463},"差异拆解到底差在哪里",[3465],{"type":30,"value":3466},"差异拆解：到底差在哪里？",{"type":24,"tag":121,"props":3468,"children":3470},{"id":3469},"_1-上下文来源补全-vs-项目索引",[3471],{"type":30,"value":3472},"1) 上下文来源：补全 vs 项目索引",{"type":24,"tag":133,"props":3474,"children":3475},{},[3476,3481],{"type":24,"tag":65,"props":3477,"children":3478},{},[3479],{"type":30,"value":3480},"Copilot 更擅长：你正在写的这几行、当前文件的局部上下文",{"type":24,"tag":65,"props":3482,"children":3483},{},[3484],{"type":30,"value":3485},"Cursor 更擅长：项目级索引 + 多文件关联理解",{"type":24,"tag":33,"props":3487,"children":3488},{},[3489],{"type":30,"value":3490},"因此：",{"type":24,"tag":133,"props":3492,"children":3493},{},[3494,3499],{"type":24,"tag":65,"props":3495,"children":3496},{},[3497],{"type":30,"value":3498},"写代码片段：Copilot 速度更快",{"type":24,"tag":65,"props":3500,"children":3501},{},[3502],{"type":30,"value":3503},"改一坨工程：Cursor 更有胜算（但更需要闸门）",{"type":24,"tag":121,"props":3505,"children":3507},{"id":3506},"_2-交互方式你能不能控制范围",[3508],{"type":30,"value":3509},"2) 交互方式：你能不能控制范围",{"type":24,"tag":33,"props":3511,"children":3512},{},[3513],{"type":30,"value":3514},"范围控制的三个层级：",{"type":24,"tag":61,"props":3516,"children":3517},{},[3518,3528,3538],{"type":24,"tag":65,"props":3519,"children":3520},{},[3521,3523],{"type":30,"value":3522},"内联编辑（选中一段）→ ",{"type":24,"tag":53,"props":3524,"children":3525},{},[3526],{"type":30,"value":3527},"最强范围控制",{"type":24,"tag":65,"props":3529,"children":3530},{},[3531,3533],{"type":30,"value":3532},"Composer 多文件（先列文件清单）→ ",{"type":24,"tag":53,"props":3534,"children":3535},{},[3536],{"type":30,"value":3537},"可控但要闸门",{"type":24,"tag":65,"props":3539,"children":3540},{},[3541,3543],{"type":30,"value":3542},"大对话（泛目标）→ ",{"type":24,"tag":53,"props":3544,"children":3545},{},[3546],{"type":30,"value":3547},"最容易跑偏",{"type":24,"tag":121,"props":3549,"children":3551},{"id":3550},"_3-输出形态建议-vs-可审查的变更",[3552],{"type":30,"value":3553},"3) 输出形态：建议 vs 可审查的变更",{"type":24,"tag":33,"props":3555,"children":3556},{},[3557],{"type":30,"value":3558},"最好的 AI 输出不是“给我一段代码”，而是：",{"type":24,"tag":133,"props":3560,"children":3561},{},[3562,3567,3572],{"type":24,"tag":65,"props":3563,"children":3564},{},[3565],{"type":30,"value":3566},"改动摘要（做了什么）",{"type":24,"tag":65,"props":3568,"children":3569},{},[3570],{"type":30,"value":3571},"diff 级别的可审查变更",{"type":24,"tag":65,"props":3573,"children":3574},{},[3575],{"type":30,"value":3576},"验收步骤与回滚方案",{"type":24,"tag":1866,"props":3578,"children":3579},{},[],{"type":24,"tag":25,"props":3581,"children":3583},{"id":3582},"一套可落地的团队工作流把风险关住",[3584],{"type":30,"value":3585},"一套可落地的团队工作流（把风险关住）",{"type":24,"tag":33,"props":3587,"children":3588},{},[3589],{"type":30,"value":3590},"下面这套流程，你可以直接写进团队规范：",{"type":24,"tag":121,"props":3592,"children":3594},{"id":3593},"step-1先写任务单geo-友好结构",[3595],{"type":30,"value":3596},"Step 1：先写任务单（GEO 友好结构）",{"type":24,"tag":33,"props":3598,"children":3599},{},[3600],{"type":30,"value":3601},"模板：",{"type":24,"tag":133,"props":3603,"children":3604},{},[3605,3610,3615,3620,3625,3630],{"type":24,"tag":65,"props":3606,"children":3607},{},[3608],{"type":30,"value":3609},"目标：……",{"type":24,"tag":65,"props":3611,"children":3612},{},[3613],{"type":30,"value":3614},"背景：……",{"type":24,"tag":65,"props":3616,"children":3617},{},[3618],{"type":30,"value":3619},"范围：只改这些文件/模块：……",{"type":24,"tag":65,"props":3621,"children":3622},{},[3623],{"type":30,"value":3624},"非目标：不做哪些事情：……",{"type":24,"tag":65,"props":3626,"children":3627},{},[3628],{"type":30,"value":3629},"验收：如何判断完成（可测试/可观察）：……",{"type":24,"tag":65,"props":3631,"children":3632},{},[3633],{"type":30,"value":3634},"回滚：如果失败怎么撤回：……",{"type":24,"tag":121,"props":3636,"children":3638},{"id":3637},"step-2用范围闸门限制-ai",[3639],{"type":30,"value":3640},"Step 2：用“范围闸门”限制 AI",{"type":24,"tag":133,"props":3642,"children":3643},{},[3644,3649],{"type":24,"tag":65,"props":3645,"children":3646},{},[3647],{"type":30,"value":3648},"单文件改动：优先 Cursor 内联编辑",{"type":24,"tag":65,"props":3650,"children":3651},{},[3652],{"type":30,"value":3653},"多文件改动：必须先让 AI 输出“文件清单（≤5）+ 每步验收”",{"type":24,"tag":33,"props":3655,"children":3656},{},[3657],{"type":30,"value":3658},"如果 AI 输出的文件清单超过 5 个：",{"type":24,"tag":133,"props":3660,"children":3661},{},[3662,3667],{"type":24,"tag":65,"props":3663,"children":3664},{},[3665],{"type":30,"value":3666},"不是它太强，是任务太大",{"type":24,"tag":65,"props":3668,"children":3669},{},[3670],{"type":30,"value":3671},"你需要拆任务，而不是继续推进",{"type":24,"tag":121,"props":3673,"children":3675},{"id":3674},"step-3最小回归集10-条",[3676],{"type":30,"value":3677},"Step 3：最小回归集（10 条）",{"type":24,"tag":33,"props":3679,"children":3680},{},[3681,3683,3688],{"type":30,"value":3682},"每次接受改动前必须跑（可参考：",{"type":24,"tag":1717,"props":3684,"children":3685},{"href":1945},[3686],{"type":30,"value":3687},"Cursor 快捷键速查表",{"type":30,"value":3689}," 里的清单）。",{"type":24,"tag":121,"props":3691,"children":3693},{"id":3692},"step-4回滚策略不用等事故才想",[3694],{"type":30,"value":3695},"Step 4：回滚策略（不用等事故才想）",{"type":24,"tag":33,"props":3697,"children":3698},{},[3699],{"type":30,"value":3700},"回滚最常见的两条路：",{"type":24,"tag":133,"props":3702,"children":3703},{},[3704,3709],{"type":24,"tag":65,"props":3705,"children":3706},{},[3707],{"type":30,"value":3708},"git 回滚 commit",{"type":24,"tag":65,"props":3710,"children":3711},{},[3712],{"type":30,"value":3713},"对关键文件保留前版本（至少能快速恢复）",{"type":24,"tag":33,"props":3715,"children":3716},{},[3717],{"type":30,"value":3718},"你需要做到：任何一轮 AI 改动都能在 5 分钟内撤回。",{"type":24,"tag":1866,"props":3720,"children":3721},{},[],{"type":24,"tag":25,"props":3723,"children":3725},{"id":3724},"必交付物对比矩阵可复制",[3726],{"type":30,"value":3727},"必交付物：对比矩阵（可复制）",{"type":24,"tag":33,"props":3729,"children":3730},{},[3731],{"type":30,"value":3732},"下面这张表可以直接贴到你的团队 wiki：",{"type":24,"tag":2148,"props":3734,"children":3735},{},[3736,3759],{"type":24,"tag":2152,"props":3737,"children":3738},{},[3739],{"type":24,"tag":2156,"props":3740,"children":3741},{},[3742,3747,3751,3755],{"type":24,"tag":2160,"props":3743,"children":3744},{},[3745],{"type":30,"value":3746},"维度",{"type":24,"tag":2160,"props":3748,"children":3749},{},[3750],{"type":30,"value":1953},{"type":24,"tag":2160,"props":3752,"children":3753},{},[3754],{"type":30,"value":3199},{"type":24,"tag":2160,"props":3756,"children":3757},{},[3758],{"type":30,"value":1950},{"type":24,"tag":2181,"props":3760,"children":3761},{},[3762,3785,3808,3831],{"type":24,"tag":2156,"props":3763,"children":3764},{},[3765,3770,3775,3780],{"type":24,"tag":2188,"props":3766,"children":3767},{},[3768],{"type":30,"value":3769},"强项",{"type":24,"tag":2188,"props":3771,"children":3772},{},[3773],{"type":30,"value":3774},"工具链、调试、生态",{"type":24,"tag":2188,"props":3776,"children":3777},{},[3778],{"type":30,"value":3779},"补全与局部建议",{"type":24,"tag":2188,"props":3781,"children":3782},{},[3783],{"type":30,"value":3784},"项目上下文、多文件落地",{"type":24,"tag":2156,"props":3786,"children":3787},{},[3788,3793,3798,3803],{"type":24,"tag":2188,"props":3789,"children":3790},{},[3791],{"type":30,"value":3792},"适合任务",{"type":24,"tag":2188,"props":3794,"children":3795},{},[3796],{"type":30,"value":3797},"排查、调试、验证",{"type":24,"tag":2188,"props":3799,"children":3800},{},[3801],{"type":30,"value":3802},"写一段、补一段",{"type":24,"tag":2188,"props":3804,"children":3805},{},[3806],{"type":30,"value":3807},"改一段、改一组文件",{"type":24,"tag":2156,"props":3809,"children":3810},{},[3811,3816,3821,3826],{"type":24,"tag":2188,"props":3812,"children":3813},{},[3814],{"type":30,"value":3815},"最大风险",{"type":24,"tag":2188,"props":3817,"children":3818},{},[3819],{"type":30,"value":3820},"无",{"type":24,"tag":2188,"props":3822,"children":3823},{},[3824],{"type":30,"value":3825},"过度依赖建议",{"type":24,"tag":2188,"props":3827,"children":3828},{},[3829],{"type":30,"value":3830},"范围漂移、多文件回归",{"type":24,"tag":2156,"props":3832,"children":3833},{},[3834,3839,3844,3849],{"type":24,"tag":2188,"props":3835,"children":3836},{},[3837],{"type":30,"value":3838},"必须搭配",{"type":24,"tag":2188,"props":3840,"children":3841},{},[3842],{"type":30,"value":3843},"规范与检查",{"type":24,"tag":2188,"props":3845,"children":3846},{},[3847],{"type":30,"value":3848},"代码评审",{"type":24,"tag":2188,"props":3850,"children":3851},{},[3852],{"type":30,"value":3853},"闸门 + 最小回归集",{"type":24,"tag":1866,"props":3855,"children":3856},{},[],{"type":24,"tag":25,"props":3858,"children":3860},{"id":3859},"失败案例多文件看似成功实际埋雷",[3861],{"type":30,"value":3862},"失败案例：多文件“看似成功”，实际埋雷",{"type":24,"tag":33,"props":3864,"children":3865},{},[3866,3871],{"type":24,"tag":53,"props":3867,"children":3868},{},[3869],{"type":30,"value":3870},"现象",{"type":30,"value":3872},"：AI 说“我已经把所有地方都改了”，你也接受了，结果上线后 404 或样式错位。",{"type":24,"tag":33,"props":3874,"children":3875},{},[3876,3881],{"type":24,"tag":53,"props":3877,"children":3878},{},[3879],{"type":30,"value":3880},"复现条件",{"type":30,"value":205},{"type":24,"tag":133,"props":3883,"children":3884},{},[3885,3890,3895],{"type":24,"tag":65,"props":3886,"children":3887},{},[3888],{"type":30,"value":3889},"你给了一个大目标（例如“把所有按钮统一成主题色”）",{"type":24,"tag":65,"props":3891,"children":3892},{},[3893],{"type":30,"value":3894},"它改了组件、样式、甚至主题配置",{"type":24,"tag":65,"props":3896,"children":3897},{},[3898],{"type":30,"value":3899},"你没有按页面模块走一遍，直接合并",{"type":24,"tag":33,"props":3901,"children":3902},{},[3903,3908],{"type":24,"tag":53,"props":3904,"children":3905},{},[3906],{"type":30,"value":3907},"根因",{"type":30,"value":205},{"type":24,"tag":133,"props":3910,"children":3911},{},[3912],{"type":24,"tag":65,"props":3913,"children":3914},{},[3915],{"type":30,"value":3916},"改动范围大，但验收仍按“小改动”的方式做（只看一处）",{"type":24,"tag":33,"props":3918,"children":3919},{},[3920,3925],{"type":24,"tag":53,"props":3921,"children":3922},{},[3923],{"type":30,"value":3924},"修复",{"type":30,"value":205},{"type":24,"tag":133,"props":3927,"children":3928},{},[3929,3934,3939],{"type":24,"tag":65,"props":3930,"children":3931},{},[3932],{"type":30,"value":3933},"强制把任务拆成“模块级目标”：Hero、Feature、Pricing、Form",{"type":24,"tag":65,"props":3935,"children":3936},{},[3937],{"type":30,"value":3938},"每个模块改完就验收一次",{"type":24,"tag":65,"props":3940,"children":3941},{},[3942],{"type":30,"value":3943},"验收通过再进入下一个模块",{"type":24,"tag":1866,"props":3945,"children":3946},{},[],{"type":24,"tag":25,"props":3948,"children":3949},{"id":1395},[3950],{"type":30,"value":1398},{"type":24,"tag":121,"props":3952,"children":3954},{"id":3953},"q1我已经用了-cursor为什么还要用-copilot",[3955],{"type":30,"value":3956},"Q1：我已经用了 Cursor，为什么还要用 Copilot？",{"type":24,"tag":33,"props":3958,"children":3959},{},[3960],{"type":30,"value":3961},"因为“补全”这种高频低风险任务，Copilot 的交互成本更低；Cursor 更适合需要解释与约束的改动。",{"type":24,"tag":121,"props":3963,"children":3965},{"id":3964},"q2什么时候应该完全不用-ai",[3966],{"type":30,"value":3967},"Q2：什么时候应该完全不用 AI？",{"type":24,"tag":33,"props":3969,"children":3970},{},[3971],{"type":30,"value":3972},"当你无法定义验收标准时。比如“更高级”“更好看”这种目标，先做信息结构与设计规则，再让 AI 帮你落地局部。",{"type":24,"tag":1866,"props":3974,"children":3975},{},[],{"type":24,"tag":25,"props":3977,"children":3978},{"id":1707},[3979],{"type":30,"value":1707},{"type":24,"tag":133,"props":3981,"children":3982},{},[3983,3992,4001,4010],{"type":24,"tag":65,"props":3984,"children":3985},{},[3986,3988],{"type":30,"value":3987},"Cursor 入门：",{"type":24,"tag":1717,"props":3989,"children":3990},{"href":2032},[3991],{"type":30,"value":2035},{"type":24,"tag":65,"props":3993,"children":3994},{},[3995,3997],{"type":30,"value":3996},"Cursor 进阶：",{"type":24,"tag":1717,"props":3998,"children":3999},{"href":2043},[4000],{"type":30,"value":2046},{"type":24,"tag":65,"props":4002,"children":4003},{},[4004,4006],{"type":30,"value":4005},"规则配置：",{"type":24,"tag":1717,"props":4007,"children":4008},{"href":2054},[4009],{"type":30,"value":2057},{"type":24,"tag":65,"props":4011,"children":4012},{},[4013,4015],{"type":30,"value":4014},"Copilot 实战：",{"type":24,"tag":1717,"props":4016,"children":4018},{"href":4017},"/topics/ai/github-copilot-tips",[4019],{"type":30,"value":4020},"GitHub Copilot 实用技巧",{"title":7,"searchDepth":1888,"depth":1888,"links":4022},[4023,4024,4025,4030,4036,4037,4038,4042],{"id":3171,"depth":1891,"text":3174},{"id":3221,"depth":1891,"text":3224},{"id":3463,"depth":1891,"text":3466,"children":4026},[4027,4028,4029],{"id":3469,"depth":1888,"text":3472},{"id":3506,"depth":1888,"text":3509},{"id":3550,"depth":1888,"text":3553},{"id":3582,"depth":1891,"text":3585,"children":4031},[4032,4033,4034,4035],{"id":3593,"depth":1888,"text":3596},{"id":3637,"depth":1888,"text":3640},{"id":3674,"depth":1888,"text":3677},{"id":3692,"depth":1888,"text":3695},{"id":3724,"depth":1891,"text":3727},{"id":3859,"depth":1891,"text":3862},{"id":1395,"depth":1891,"text":1398,"children":4039},[4040,4041],{"id":3953,"depth":1888,"text":3956},{"id":3964,"depth":1888,"text":3967},{"id":1707,"depth":1891,"text":1707},"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":4047,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":4048,"description":4049,"date":4050,"topic":5,"author":11,"tags":4051,"image":4056,"featured":1779,"readingTime":19,"body":4057,"_type":1937,"_id":4703,"_source":1939,"_file":4704,"_stem":4705,"_extension":1942},"/topics/ai/ai-debugging-troubleshooting-guide","AI 辅助调试与问题排查：让 AI 成为你的调试搭档","深入探讨如何利用 AI 工具提升调试效率，包括错误信息分析、日志解读、性能问题定位、复杂 bug 排查等实战场景，构建 AI 驱动的调试工作流。","2026-01-18",[4052,4053,4054,1954,4055],"AI 调试","问题排查","Debug","错误处理","/images/topics/ai/ai-debugging-guide.jpg",{"type":21,"children":4058,"toc":4674},[4059,4065,4071,4076,4081,4086,4092,4098,4103,4111,4139,4147,4170,4176,4186,4195,4203,4211,4244,4252,4282,4295,4303,4308,4316,4324,4333,4339,4347,4358,4366,4375,4381,4387,4392,4401,4407,4412,4421,4427,4433,4442,4448,4457,4463,4474,4480,4486,4495,4501,4510,4516,4522,4530,4536,4545,4553,4561,4564,4570,4575,4594,4606,4609,4615,4620,4629,4634,4637,4643,4648,4666],{"type":24,"tag":25,"props":4060,"children":4062},{"id":4061},"ai-辅助调试与问题排查",[4063],{"type":30,"value":4064},"AI 辅助调试与问题排查",{"type":24,"tag":25,"props":4066,"children":4068},{"id":4067},"引言调试的痛与-ai-的解药",[4069],{"type":30,"value":4070},"引言：调试的痛与 AI 的解药",{"type":24,"tag":33,"props":4072,"children":4073},{},[4074],{"type":30,"value":4075},"调试是每个程序员的日常，也是最消耗时间和精力的工作之一。我们都有过这样的经历：盯着一个莫名其妙的错误信息，翻遍 Stack Overflow，尝试各种方案，几个小时后才发现是一个愚蠢的拼写错误。",{"type":24,"tag":33,"props":4077,"children":4078},{},[4079],{"type":30,"value":4080},"AI 工具的出现，正在改变调试的方式。不是替代你的思考，而是加速你的分析过程——帮你快速理解错误、缩小排查范围、验证假设。",{"type":24,"tag":33,"props":4082,"children":4083},{},[4084],{"type":30,"value":4085},"这篇文章分享我在实际项目中使用 AI 辅助调试的经验和方法论。",{"type":24,"tag":25,"props":4087,"children":4089},{"id":4088},"第一部分建立-ai-调试的思维模型",[4090],{"type":30,"value":4091},"第一部分：建立 AI 调试的思维模型",{"type":24,"tag":121,"props":4093,"children":4095},{"id":4094},"_11-ai-在调试中的角色",[4096],{"type":30,"value":4097},"1.1 AI 在调试中的角色",{"type":24,"tag":33,"props":4099,"children":4100},{},[4101],{"type":30,"value":4102},"把 AI 想象成一个经验丰富但不了解你项目的高级工程师。它：",{"type":24,"tag":33,"props":4104,"children":4105},{},[4106],{"type":24,"tag":53,"props":4107,"children":4108},{},[4109],{"type":30,"value":4110},"擅长的事情：",{"type":24,"tag":133,"props":4112,"children":4113},{},[4114,4119,4124,4129,4134],{"type":24,"tag":65,"props":4115,"children":4116},{},[4117],{"type":30,"value":4118},"解读错误信息的含义",{"type":24,"tag":65,"props":4120,"children":4121},{},[4122],{"type":30,"value":4123},"提供可能的原因列表",{"type":24,"tag":65,"props":4125,"children":4126},{},[4127],{"type":30,"value":4128},"给出排查方向建议",{"type":24,"tag":65,"props":4130,"children":4131},{},[4132],{"type":30,"value":4133},"解释复杂的技术概念",{"type":24,"tag":65,"props":4135,"children":4136},{},[4137],{"type":30,"value":4138},"生成调试代码片段",{"type":24,"tag":33,"props":4140,"children":4141},{},[4142],{"type":24,"tag":53,"props":4143,"children":4144},{},[4145],{"type":30,"value":4146},"不擅长的事情：",{"type":24,"tag":133,"props":4148,"children":4149},{},[4150,4155,4160,4165],{"type":24,"tag":65,"props":4151,"children":4152},{},[4153],{"type":30,"value":4154},"了解你的业务逻辑",{"type":24,"tag":65,"props":4156,"children":4157},{},[4158],{"type":30,"value":4159},"知道你的代码历史",{"type":24,"tag":65,"props":4161,"children":4162},{},[4163],{"type":30,"value":4164},"理解项目特定的约定",{"type":24,"tag":65,"props":4166,"children":4167},{},[4168],{"type":30,"value":4169},"做出架构级判断",{"type":24,"tag":121,"props":4171,"children":4173},{"id":4172},"_12-有效提问的结构",[4174],{"type":30,"value":4175},"1.2 有效提问的结构",{"type":24,"tag":177,"props":4177,"children":4181},{"code":4178,"language":1937,"meta":7,"className":4179},"## 高效的调试提问模板\n\n**问题描述**\n[简洁描述遇到的问题]\n\n**错误信息**\n",[4180],"language-markdown",[4182],{"type":24,"tag":39,"props":4183,"children":4184},{"__ignoreMap":7},[4185],{"type":30,"value":4178},{"type":24,"tag":33,"props":4187,"children":4188},{},[4189],{"type":24,"tag":4190,"props":4191,"children":4192},"span",{},[4193],{"type":30,"value":4194},"完整的错误信息，不要截断",{"type":24,"tag":177,"props":4196,"children":4198},{"code":4197},"\n**相关代码**\n```javascript\n[精简但完整的相关代码]\n",[4199],{"type":24,"tag":39,"props":4200,"children":4201},{"__ignoreMap":7},[4202],{"type":30,"value":4197},{"type":24,"tag":33,"props":4204,"children":4205},{},[4206],{"type":24,"tag":53,"props":4207,"children":4208},{},[4209],{"type":30,"value":4210},"环境信息",{"type":24,"tag":133,"props":4212,"children":4213},{},[4214,4224,4234],{"type":24,"tag":65,"props":4215,"children":4216},{},[4217,4219],{"type":30,"value":4218},"运行环境：",{"type":24,"tag":4190,"props":4220,"children":4221},{},[4222],{"type":30,"value":4223},"Node 版本/浏览器版本",{"type":24,"tag":65,"props":4225,"children":4226},{},[4227,4229],{"type":30,"value":4228},"框架版本：",{"type":24,"tag":4190,"props":4230,"children":4231},{},[4232],{"type":30,"value":4233},"相关框架版本",{"type":24,"tag":65,"props":4235,"children":4236},{},[4237,4239],{"type":30,"value":4238},"操作系统：",{"type":24,"tag":4190,"props":4240,"children":4241},{},[4242],{"type":30,"value":4243},"如果相关",{"type":24,"tag":33,"props":4245,"children":4246},{},[4247],{"type":24,"tag":53,"props":4248,"children":4249},{},[4250],{"type":30,"value":4251},"已尝试的方案",{"type":24,"tag":133,"props":4253,"children":4254},{},[4255,4269],{"type":24,"tag":65,"props":4256,"children":4257},{},[4258,4263,4264],{"type":24,"tag":4190,"props":4259,"children":4260},{},[4261],{"type":30,"value":4262},"方案1",{"type":30,"value":205},{"type":24,"tag":4190,"props":4265,"children":4266},{},[4267],{"type":30,"value":4268},"结果",{"type":24,"tag":65,"props":4270,"children":4271},{},[4272,4277,4278],{"type":24,"tag":4190,"props":4273,"children":4274},{},[4275],{"type":30,"value":4276},"方案2",{"type":30,"value":205},{"type":24,"tag":4190,"props":4279,"children":4280},{},[4281],{"type":30,"value":4268},{"type":24,"tag":33,"props":4283,"children":4284},{},[4285,4290],{"type":24,"tag":53,"props":4286,"children":4287},{},[4288],{"type":30,"value":4289},"期望的结果",{"type":24,"tag":4190,"props":4291,"children":4292},{},[4293],{"type":30,"value":4294},"描述期望的行为",{"type":24,"tag":177,"props":4296,"children":4298},{"code":4297},"\n### 1.3 分级调试策略\n\n",[4299],{"type":24,"tag":39,"props":4300,"children":4301},{"__ignoreMap":7},[4302],{"type":30,"value":4297},{"type":24,"tag":33,"props":4304,"children":4305},{},[4306],{"type":30,"value":4307},"┌───────────────────────────────────────────────────────────┐\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":177,"props":4309,"children":4311},{"code":4310},"\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",[4312],{"type":24,"tag":39,"props":4313,"children":4314},{"__ignoreMap":7},[4315],{"type":30,"value":4310},{"type":24,"tag":33,"props":4317,"children":4318},{},[4319],{"type":24,"tag":53,"props":4320,"children":4321},{},[4322],{"type":30,"value":4323},"场景 2：Vue 响应式警告",{"type":24,"tag":177,"props":4325,"children":4328},{"code":4326,"language":180,"meta":7,"className":4327},"// 警告信息：\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",[182],[4329],{"type":24,"tag":39,"props":4330,"children":4331},{"__ignoreMap":7},[4332],{"type":30,"value":4326},{"type":24,"tag":121,"props":4334,"children":4336},{"id":4335},"_22-后端错误分析",[4337],{"type":30,"value":4338},"2.2 后端错误分析",{"type":24,"tag":33,"props":4340,"children":4341},{},[4342],{"type":24,"tag":53,"props":4343,"children":4344},{},[4345],{"type":30,"value":4346},"场景 1：Node.js 内存问题",{"type":24,"tag":177,"props":4348,"children":4353},{"code":4349,"language":4350,"meta":7,"className":4351},"// 错误信息：\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",[4352],"language-javascript",[4354],{"type":24,"tag":39,"props":4355,"children":4356},{"__ignoreMap":7},[4357],{"type":30,"value":4349},{"type":24,"tag":33,"props":4359,"children":4360},{},[4361],{"type":24,"tag":53,"props":4362,"children":4363},{},[4364],{"type":30,"value":4365},"场景 2：数据库连接问题",{"type":24,"tag":177,"props":4367,"children":4370},{"code":4368,"language":180,"meta":7,"className":4369},"// 错误信息：\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",[182],[4371],{"type":24,"tag":39,"props":4372,"children":4373},{"__ignoreMap":7},[4374],{"type":30,"value":4368},{"type":24,"tag":25,"props":4376,"children":4378},{"id":4377},"第三部分日志分析与问题定位",[4379],{"type":30,"value":4380},"第三部分：日志分析与问题定位",{"type":24,"tag":121,"props":4382,"children":4384},{"id":4383},"_31-结构化日志分析",[4385],{"type":30,"value":4386},"3.1 结构化日志分析",{"type":24,"tag":33,"props":4388,"children":4389},{},[4390],{"type":30,"value":4391},"当面对大量日志时，让 AI 帮你快速定位问题：",{"type":24,"tag":177,"props":4393,"children":4396},{"code":4394,"language":4350,"meta":7,"className":4395},"// 提问示例：\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",[4352],[4397],{"type":24,"tag":39,"props":4398,"children":4399},{"__ignoreMap":7},[4400],{"type":30,"value":4394},{"type":24,"tag":121,"props":4402,"children":4404},{"id":4403},"_32-创建调试日志",[4405],{"type":30,"value":4406},"3.2 创建调试日志",{"type":24,"tag":33,"props":4408,"children":4409},{},[4410],{"type":30,"value":4411},"让 AI 帮你生成调试用的日志代码：",{"type":24,"tag":177,"props":4413,"children":4416},{"code":4414,"language":180,"meta":7,"className":4415},"// 请求：\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",[182],[4417],{"type":24,"tag":39,"props":4418,"children":4419},{"__ignoreMap":7},[4420],{"type":30,"value":4414},{"type":24,"tag":25,"props":4422,"children":4424},{"id":4423},"第四部分性能问题排查",[4425],{"type":30,"value":4426},"第四部分：性能问题排查",{"type":24,"tag":121,"props":4428,"children":4430},{"id":4429},"_41-前端性能分析",[4431],{"type":30,"value":4432},"4.1 前端性能分析",{"type":24,"tag":177,"props":4434,"children":4437},{"code":4435,"language":180,"meta":7,"className":4436},"// 场景：页面加载慢，需要分析原因\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",[182],[4438],{"type":24,"tag":39,"props":4439,"children":4440},{"__ignoreMap":7},[4441],{"type":30,"value":4435},{"type":24,"tag":121,"props":4443,"children":4445},{"id":4444},"_42-内存泄漏排查",[4446],{"type":30,"value":4447},"4.2 内存泄漏排查",{"type":24,"tag":177,"props":4449,"children":4452},{"code":4450,"language":180,"meta":7,"className":4451},"// 场景：应用运行一段时间后变卡\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",[182],[4453],{"type":24,"tag":39,"props":4454,"children":4455},{"__ignoreMap":7},[4456],{"type":30,"value":4450},{"type":24,"tag":121,"props":4458,"children":4460},{"id":4459},"_43-数据库查询优化",[4461],{"type":30,"value":4462},"4.3 数据库查询优化",{"type":24,"tag":177,"props":4464,"children":4469},{"code":4465,"language":4466,"meta":7,"className":4467},"-- 场景：查询很慢，让 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",[4468],"language-sql",[4470],{"type":24,"tag":39,"props":4471,"children":4472},{"__ignoreMap":7},[4473],{"type":30,"value":4465},{"type":24,"tag":25,"props":4475,"children":4477},{"id":4476},"第五部分复杂-bug-排查",[4478],{"type":30,"value":4479},"第五部分：复杂 Bug 排查",{"type":24,"tag":121,"props":4481,"children":4483},{"id":4482},"_51-竞态条件",[4484],{"type":30,"value":4485},"5.1 竞态条件",{"type":24,"tag":177,"props":4487,"children":4490},{"code":4488,"language":180,"meta":7,"className":4489},"// 场景：偶发的数据不一致问题\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",[182],[4491],{"type":24,"tag":39,"props":4492,"children":4493},{"__ignoreMap":7},[4494],{"type":30,"value":4488},{"type":24,"tag":121,"props":4496,"children":4498},{"id":4497},"_52-分布式系统问题",[4499],{"type":30,"value":4500},"5.2 分布式系统问题",{"type":24,"tag":177,"props":4502,"children":4505},{"code":4503,"language":180,"meta":7,"className":4504},"// 场景：微服务间的数据不一致\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",[182],[4506],{"type":24,"tag":39,"props":4507,"children":4508},{"__ignoreMap":7},[4509],{"type":30,"value":4503},{"type":24,"tag":25,"props":4511,"children":4513},{"id":4512},"第六部分ai-调试工作流",[4514],{"type":30,"value":4515},"第六部分：AI 调试工作流",{"type":24,"tag":121,"props":4517,"children":4519},{"id":4518},"_61-我的调试流程",[4520],{"type":30,"value":4521},"6.1 我的调试流程",{"type":24,"tag":177,"props":4523,"children":4525},{"code":4524},"┌────────────────────────────────────────────────────────────┐\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",[4526],{"type":24,"tag":39,"props":4527,"children":4528},{"__ignoreMap":7},[4529],{"type":30,"value":4524},{"type":24,"tag":121,"props":4531,"children":4533},{"id":4532},"_62-调试对话模板",[4534],{"type":30,"value":4535},"6.2 调试对话模板",{"type":24,"tag":177,"props":4537,"children":4540},{"code":4538,"language":1937,"meta":7,"className":4539},"## 第一轮：问题描述\n\n我遇到了一个问题：[简述问题]\n\n错误信息：\n",[4180],[4541],{"type":24,"tag":39,"props":4542,"children":4543},{"__ignoreMap":7},[4544],{"type":30,"value":4538},{"type":24,"tag":33,"props":4546,"children":4547},{},[4548],{"type":24,"tag":4190,"props":4549,"children":4550},{},[4551],{"type":30,"value":4552},"粘贴完整错误",{"type":24,"tag":177,"props":4554,"children":4556},{"code":4555},"\n相关代码：\n```javascript\n[粘贴代码]\n",[4557],{"type":24,"tag":39,"props":4558,"children":4559},{"__ignoreMap":7},[4560],{"type":30,"value":4555},{"type":24,"tag":1866,"props":4562,"children":4563},{},[],{"type":24,"tag":25,"props":4565,"children":4567},{"id":4566},"第二轮补充信息",[4568],{"type":30,"value":4569},"第二轮：补充信息",{"type":24,"tag":33,"props":4571,"children":4572},{},[4573],{"type":30,"value":4574},"根据你的建议，我添加了日志，发现：",{"type":24,"tag":133,"props":4576,"children":4577},{},[4578,4586],{"type":24,"tag":65,"props":4579,"children":4580},{},[4581],{"type":24,"tag":4190,"props":4582,"children":4583},{},[4584],{"type":30,"value":4585},"发现 1",{"type":24,"tag":65,"props":4587,"children":4588},{},[4589],{"type":24,"tag":4190,"props":4590,"children":4591},{},[4592],{"type":30,"value":4593},"发现 2",{"type":24,"tag":33,"props":4595,"children":4596},{},[4597,4599,4604],{"type":30,"value":4598},"这是否说明问题出在 ",{"type":24,"tag":4190,"props":4600,"children":4601},{},[4602],{"type":30,"value":4603},"你的猜测",{"type":30,"value":4605},"？",{"type":24,"tag":1866,"props":4607,"children":4608},{},[],{"type":24,"tag":25,"props":4610,"children":4612},{"id":4611},"第三轮确认修复",[4613],{"type":30,"value":4614},"第三轮：确认修复",{"type":24,"tag":33,"props":4616,"children":4617},{},[4618],{"type":30,"value":4619},"我按照你的建议修改了代码：",{"type":24,"tag":177,"props":4621,"children":4624},{"code":4622,"language":4350,"meta":7,"className":4623},"[粘贴修改后的代码]\n",[4352],[4625],{"type":24,"tag":39,"props":4626,"children":4627},{"__ignoreMap":7},[4628],{"type":30,"value":4622},{"type":24,"tag":33,"props":4630,"children":4631},{},[4632],{"type":30,"value":4633},"请确认这个修复是否正确，以及是否有其他潜在问题。",{"type":24,"tag":1866,"props":4635,"children":4636},{},[],{"type":24,"tag":25,"props":4638,"children":4640},{"id":4639},"第四轮预防",[4641],{"type":30,"value":4642},"第四轮：预防",{"type":24,"tag":33,"props":4644,"children":4645},{},[4646],{"type":30,"value":4647},"这个问题已解决。请建议：",{"type":24,"tag":61,"props":4649,"children":4650},{},[4651,4656,4661],{"type":24,"tag":65,"props":4652,"children":4653},{},[4654],{"type":30,"value":4655},"如何防止类似问题再次发生？",{"type":24,"tag":65,"props":4657,"children":4658},{},[4659],{"type":30,"value":4660},"应该添加什么测试用例？",{"type":24,"tag":65,"props":4662,"children":4663},{},[4664],{"type":30,"value":4665},"有什么最佳实践可以参考？",{"type":24,"tag":177,"props":4667,"children":4669},{"code":4668},"\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",[4670],{"type":24,"tag":39,"props":4671,"children":4672},{"__ignoreMap":7},[4673],{"type":30,"value":4668},{"title":7,"searchDepth":1888,"depth":1888,"links":4675},[4676,4677,4678,4683,4687,4692,4696,4700,4701,4702],{"id":4061,"depth":1891,"text":4064},{"id":4067,"depth":1891,"text":4070},{"id":4088,"depth":1891,"text":4091,"children":4679},[4680,4681,4682],{"id":4094,"depth":1888,"text":4097},{"id":4172,"depth":1888,"text":4175},{"id":4335,"depth":1888,"text":4338},{"id":4377,"depth":1891,"text":4380,"children":4684},[4685,4686],{"id":4383,"depth":1888,"text":4386},{"id":4403,"depth":1888,"text":4406},{"id":4423,"depth":1891,"text":4426,"children":4688},[4689,4690,4691],{"id":4429,"depth":1888,"text":4432},{"id":4444,"depth":1888,"text":4447},{"id":4459,"depth":1888,"text":4462},{"id":4476,"depth":1891,"text":4479,"children":4693},[4694,4695],{"id":4482,"depth":1888,"text":4485},{"id":4497,"depth":1888,"text":4500},{"id":4512,"depth":1891,"text":4515,"children":4697},[4698,4699],{"id":4518,"depth":1888,"text":4521},{"id":4532,"depth":1888,"text":4535},{"id":4566,"depth":1891,"text":4569},{"id":4611,"depth":1891,"text":4614},{"id":4639,"depth":1891,"text":4642},"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":4707,"image":18,"featured":6,"readingTime":19,"body":4708,"_type":1937,"_id":1938,"_source":1939,"_file":1940,"_stem":1941,"_extension":1942},[13,14,15,16,17],{"type":21,"children":4709,"toc":6221},[4710,4714,4724,4733,4766,4775,4779,4783,4787,4822,4830,4834,4843,4870,4878,4882,4886,4921,4925,4952,4956,4960,4968,4972,4999,5003,5007,5015,5023,5038,5046,5061,5069,5076,5080,5088,5096,5111,5119,5134,5142,5150,5154,5162,5170,5185,5193,5208,5216,5223,5236,5240,5244,5248,5256,5264,5291,5295,5299,5307,5315,5330,5334,5338,5342,5350,5366,5370,5374,5382,5398,5402,5406,5414,5430,5434,5444,5448,5483,5487,5522,5526,5569,5573,5614,5618,5665,5669,5673,5681,5689,5708,5712,5720,5728,5743,5747,5761,5769,5784,5788,5796,5804,5819,5823,5827,5841,5845,5853,5880,5884,5888,5896,5900,5908,5923,5927,5935,5954,5958,5966,5985,5989,5993,6001,6016,6020,6028,6074,6078,6113,6117,6121,6205,6208],{"type":24,"tag":25,"props":4711,"children":4712},{"id":27},[4713],{"type":30,"value":31},{"type":24,"tag":33,"props":4715,"children":4716},{},[4717,4718,4723],{"type":30,"value":37},{"type":24,"tag":39,"props":4719,"children":4721},{"className":4720},[],[4722],{"type":30,"value":44},{"type":30,"value":46},{"type":24,"tag":33,"props":4725,"children":4726},{},[4727,4728,4732],{"type":30,"value":51},{"type":24,"tag":53,"props":4729,"children":4730},{},[4731],{"type":30,"value":57},{"type":30,"value":59},{"type":24,"tag":61,"props":4734,"children":4735},{},[4736,4750,4758],{"type":24,"tag":65,"props":4737,"children":4738},{},[4739,4743,4744,4749],{"type":24,"tag":53,"props":4740,"children":4741},{},[4742],{"type":30,"value":72},{"type":30,"value":74},{"type":24,"tag":39,"props":4745,"children":4747},{"className":4746},[],[4748],{"type":30,"value":44},{"type":30,"value":81},{"type":24,"tag":65,"props":4751,"children":4752},{},[4753,4757],{"type":24,"tag":53,"props":4754,"children":4755},{},[4756],{"type":30,"value":89},{"type":30,"value":91},{"type":24,"tag":65,"props":4759,"children":4760},{},[4761,4765],{"type":24,"tag":53,"props":4762,"children":4763},{},[4764],{"type":30,"value":99},{"type":30,"value":101},{"type":24,"tag":33,"props":4767,"children":4768},{},[4769,4770,4774],{"type":30,"value":106},{"type":24,"tag":53,"props":4771,"children":4772},{},[4773],{"type":30,"value":111},{"type":30,"value":113},{"type":24,"tag":25,"props":4776,"children":4777},{"id":116},[4778],{"type":30,"value":119},{"type":24,"tag":121,"props":4780,"children":4781},{"id":123},[4782],{"type":30,"value":126},{"type":24,"tag":33,"props":4784,"children":4785},{},[4786],{"type":30,"value":131},{"type":24,"tag":133,"props":4788,"children":4789},{},[4790,4798,4806,4814],{"type":24,"tag":65,"props":4791,"children":4792},{},[4793,4797],{"type":24,"tag":53,"props":4794,"children":4795},{},[4796],{"type":30,"value":143},{"type":30,"value":145},{"type":24,"tag":65,"props":4799,"children":4800},{},[4801,4805],{"type":24,"tag":53,"props":4802,"children":4803},{},[4804],{"type":30,"value":153},{"type":30,"value":155},{"type":24,"tag":65,"props":4807,"children":4808},{},[4809,4813],{"type":24,"tag":53,"props":4810,"children":4811},{},[4812],{"type":30,"value":163},{"type":30,"value":165},{"type":24,"tag":65,"props":4815,"children":4816},{},[4817,4821],{"type":24,"tag":53,"props":4818,"children":4819},{},[4820],{"type":30,"value":173},{"type":30,"value":175},{"type":24,"tag":177,"props":4823,"children":4825},{"code":179,"language":180,"meta":7,"className":4824},[182],[4826],{"type":24,"tag":39,"props":4827,"children":4828},{"__ignoreMap":7},[4829],{"type":30,"value":179},{"type":24,"tag":121,"props":4831,"children":4832},{"id":190},[4833],{"type":30,"value":193},{"type":24,"tag":33,"props":4835,"children":4836},{},[4837,4838,4842],{"type":30,"value":198},{"type":24,"tag":53,"props":4839,"children":4840},{},[4841],{"type":30,"value":203},{"type":30,"value":205},{"type":24,"tag":133,"props":4844,"children":4845},{},[4846,4854,4862],{"type":24,"tag":65,"props":4847,"children":4848},{},[4849,4853],{"type":24,"tag":53,"props":4850,"children":4851},{},[4852],{"type":30,"value":216},{"type":30,"value":218},{"type":24,"tag":65,"props":4855,"children":4856},{},[4857,4861],{"type":24,"tag":53,"props":4858,"children":4859},{},[4860],{"type":30,"value":226},{"type":30,"value":228},{"type":24,"tag":65,"props":4863,"children":4864},{},[4865,4869],{"type":24,"tag":53,"props":4866,"children":4867},{},[4868],{"type":30,"value":236},{"type":30,"value":238},{"type":24,"tag":177,"props":4871,"children":4873},{"code":241,"language":180,"meta":7,"className":4872},[182],[4874],{"type":24,"tag":39,"props":4875,"children":4876},{"__ignoreMap":7},[4877],{"type":30,"value":241},{"type":24,"tag":121,"props":4879,"children":4880},{"id":250},[4881],{"type":30,"value":253},{"type":24,"tag":33,"props":4883,"children":4884},{},[4885],{"type":30,"value":258},{"type":24,"tag":133,"props":4887,"children":4888},{},[4889,4897,4905,4913],{"type":24,"tag":65,"props":4890,"children":4891},{},[4892,4896],{"type":24,"tag":53,"props":4893,"children":4894},{},[4895],{"type":30,"value":269},{"type":30,"value":271},{"type":24,"tag":65,"props":4898,"children":4899},{},[4900,4904],{"type":24,"tag":53,"props":4901,"children":4902},{},[4903],{"type":30,"value":279},{"type":30,"value":281},{"type":24,"tag":65,"props":4906,"children":4907},{},[4908,4912],{"type":24,"tag":53,"props":4909,"children":4910},{},[4911],{"type":30,"value":289},{"type":30,"value":291},{"type":24,"tag":65,"props":4914,"children":4915},{},[4916,4920],{"type":24,"tag":53,"props":4917,"children":4918},{},[4919],{"type":30,"value":299},{"type":30,"value":301},{"type":24,"tag":33,"props":4922,"children":4923},{},[4924],{"type":30,"value":306},{"type":24,"tag":133,"props":4926,"children":4927},{},[4928,4936,4944],{"type":24,"tag":65,"props":4929,"children":4930},{},[4931,4935],{"type":24,"tag":53,"props":4932,"children":4933},{},[4934],{"type":30,"value":317},{"type":30,"value":319},{"type":24,"tag":65,"props":4937,"children":4938},{},[4939,4943],{"type":24,"tag":53,"props":4940,"children":4941},{},[4942],{"type":30,"value":327},{"type":30,"value":329},{"type":24,"tag":65,"props":4945,"children":4946},{},[4947,4951],{"type":24,"tag":53,"props":4948,"children":4949},{},[4950],{"type":30,"value":337},{"type":30,"value":339},{"type":24,"tag":121,"props":4953,"children":4954},{"id":342},[4955],{"type":30,"value":345},{"type":24,"tag":33,"props":4957,"children":4958},{},[4959],{"type":30,"value":350},{"type":24,"tag":177,"props":4961,"children":4963},{"code":353,"language":354,"meta":7,"className":4962},[356],[4964],{"type":24,"tag":39,"props":4965,"children":4966},{"__ignoreMap":7},[4967],{"type":30,"value":353},{"type":24,"tag":33,"props":4969,"children":4970},{},[4971],{"type":30,"value":366},{"type":24,"tag":133,"props":4973,"children":4974},{},[4975,4983,4991],{"type":24,"tag":65,"props":4976,"children":4977},{},[4978,4982],{"type":24,"tag":53,"props":4979,"children":4980},{},[4981],{"type":30,"value":377},{"type":30,"value":379},{"type":24,"tag":65,"props":4984,"children":4985},{},[4986,4990],{"type":24,"tag":53,"props":4987,"children":4988},{},[4989],{"type":30,"value":387},{"type":30,"value":389},{"type":24,"tag":65,"props":4992,"children":4993},{},[4994,4998],{"type":24,"tag":53,"props":4995,"children":4996},{},[4997],{"type":30,"value":397},{"type":30,"value":399},{"type":24,"tag":25,"props":5000,"children":5001},{"id":402},[5002],{"type":30,"value":402},{"type":24,"tag":121,"props":5004,"children":5005},{"id":407},[5006],{"type":30,"value":410},{"type":24,"tag":33,"props":5008,"children":5009},{},[5010,5014],{"type":24,"tag":53,"props":5011,"children":5012},{},[5013],{"type":30,"value":418},{"type":30,"value":420},{"type":24,"tag":33,"props":5016,"children":5017},{},[5018,5022],{"type":24,"tag":53,"props":5019,"children":5020},{},[5021],{"type":30,"value":428},{"type":30,"value":205},{"type":24,"tag":133,"props":5024,"children":5025},{},[5026,5030,5034],{"type":24,"tag":65,"props":5027,"children":5028},{},[5029],{"type":30,"value":437},{"type":24,"tag":65,"props":5031,"children":5032},{},[5033],{"type":30,"value":442},{"type":24,"tag":65,"props":5035,"children":5036},{},[5037],{"type":30,"value":447},{"type":24,"tag":33,"props":5039,"children":5040},{},[5041,5045],{"type":24,"tag":53,"props":5042,"children":5043},{},[5044],{"type":30,"value":455},{"type":30,"value":205},{"type":24,"tag":133,"props":5047,"children":5048},{},[5049,5053,5057],{"type":24,"tag":65,"props":5050,"children":5051},{},[5052],{"type":30,"value":464},{"type":24,"tag":65,"props":5054,"children":5055},{},[5056],{"type":30,"value":469},{"type":24,"tag":65,"props":5058,"children":5059},{},[5060],{"type":30,"value":474},{"type":24,"tag":33,"props":5062,"children":5063},{},[5064,5068],{"type":24,"tag":53,"props":5065,"children":5066},{},[5067],{"type":30,"value":482},{"type":30,"value":205},{"type":24,"tag":177,"props":5070,"children":5071},{"code":486},[5072],{"type":24,"tag":39,"props":5073,"children":5074},{"__ignoreMap":7},[5075],{"type":30,"value":486},{"type":24,"tag":121,"props":5077,"children":5078},{"id":494},[5079],{"type":30,"value":497},{"type":24,"tag":33,"props":5081,"children":5082},{},[5083,5087],{"type":24,"tag":53,"props":5084,"children":5085},{},[5086],{"type":30,"value":418},{"type":30,"value":506},{"type":24,"tag":33,"props":5089,"children":5090},{},[5091,5095],{"type":24,"tag":53,"props":5092,"children":5093},{},[5094],{"type":30,"value":428},{"type":30,"value":205},{"type":24,"tag":133,"props":5097,"children":5098},{},[5099,5103,5107],{"type":24,"tag":65,"props":5100,"children":5101},{},[5102],{"type":30,"value":522},{"type":24,"tag":65,"props":5104,"children":5105},{},[5106],{"type":30,"value":527},{"type":24,"tag":65,"props":5108,"children":5109},{},[5110],{"type":30,"value":532},{"type":24,"tag":33,"props":5112,"children":5113},{},[5114,5118],{"type":24,"tag":53,"props":5115,"children":5116},{},[5117],{"type":30,"value":455},{"type":30,"value":205},{"type":24,"tag":133,"props":5120,"children":5121},{},[5122,5126,5130],{"type":24,"tag":65,"props":5123,"children":5124},{},[5125],{"type":30,"value":548},{"type":24,"tag":65,"props":5127,"children":5128},{},[5129],{"type":30,"value":553},{"type":24,"tag":65,"props":5131,"children":5132},{},[5133],{"type":30,"value":558},{"type":24,"tag":33,"props":5135,"children":5136},{},[5137,5141],{"type":24,"tag":53,"props":5138,"children":5139},{},[5140],{"type":30,"value":566},{"type":30,"value":205},{"type":24,"tag":177,"props":5143,"children":5145},{"code":570,"language":180,"meta":7,"className":5144},[182],[5146],{"type":24,"tag":39,"props":5147,"children":5148},{"__ignoreMap":7},[5149],{"type":30,"value":570},{"type":24,"tag":121,"props":5151,"children":5152},{"id":579},[5153],{"type":30,"value":582},{"type":24,"tag":33,"props":5155,"children":5156},{},[5157,5161],{"type":24,"tag":53,"props":5158,"children":5159},{},[5160],{"type":30,"value":418},{"type":30,"value":591},{"type":24,"tag":33,"props":5163,"children":5164},{},[5165,5169],{"type":24,"tag":53,"props":5166,"children":5167},{},[5168],{"type":30,"value":428},{"type":30,"value":205},{"type":24,"tag":133,"props":5171,"children":5172},{},[5173,5177,5181],{"type":24,"tag":65,"props":5174,"children":5175},{},[5176],{"type":30,"value":607},{"type":24,"tag":65,"props":5178,"children":5179},{},[5180],{"type":30,"value":612},{"type":24,"tag":65,"props":5182,"children":5183},{},[5184],{"type":30,"value":617},{"type":24,"tag":33,"props":5186,"children":5187},{},[5188,5192],{"type":24,"tag":53,"props":5189,"children":5190},{},[5191],{"type":30,"value":455},{"type":30,"value":205},{"type":24,"tag":133,"props":5194,"children":5195},{},[5196,5200,5204],{"type":24,"tag":65,"props":5197,"children":5198},{},[5199],{"type":30,"value":633},{"type":24,"tag":65,"props":5201,"children":5202},{},[5203],{"type":30,"value":638},{"type":24,"tag":65,"props":5205,"children":5206},{},[5207],{"type":30,"value":643},{"type":24,"tag":33,"props":5209,"children":5210},{},[5211,5215],{"type":24,"tag":53,"props":5212,"children":5213},{},[5214],{"type":30,"value":482},{"type":30,"value":205},{"type":24,"tag":177,"props":5217,"children":5218},{"code":654},[5219],{"type":24,"tag":39,"props":5220,"children":5221},{"__ignoreMap":7},[5222],{"type":30,"value":654},{"type":24,"tag":33,"props":5224,"children":5225},{},[5226,5230,5231,5235],{"type":24,"tag":53,"props":5227,"children":5228},{},[5229],{"type":30,"value":667},{"type":30,"value":669},{"type":24,"tag":53,"props":5232,"children":5233},{},[5234],{"type":30,"value":674},{"type":30,"value":676},{"type":24,"tag":25,"props":5237,"children":5238},{"id":679},[5239],{"type":30,"value":679},{"type":24,"tag":121,"props":5241,"children":5242},{"id":684},[5243],{"type":30,"value":687},{"type":24,"tag":33,"props":5245,"children":5246},{},[5247],{"type":30,"value":692},{"type":24,"tag":177,"props":5249,"children":5251},{"code":695,"language":696,"meta":7,"className":5250},[698],[5252],{"type":24,"tag":39,"props":5253,"children":5254},{"__ignoreMap":7},[5255],{"type":30,"value":695},{"type":24,"tag":33,"props":5257,"children":5258},{},[5259,5263],{"type":24,"tag":53,"props":5260,"children":5261},{},[5262],{"type":30,"value":711},{"type":30,"value":205},{"type":24,"tag":133,"props":5265,"children":5266},{},[5267,5275,5283],{"type":24,"tag":65,"props":5268,"children":5269},{},[5270,5274],{"type":24,"tag":53,"props":5271,"children":5272},{},[5273],{"type":30,"value":723},{"type":30,"value":725},{"type":24,"tag":65,"props":5276,"children":5277},{},[5278,5282],{"type":24,"tag":53,"props":5279,"children":5280},{},[5281],{"type":30,"value":733},{"type":30,"value":735},{"type":24,"tag":65,"props":5284,"children":5285},{},[5286,5290],{"type":24,"tag":53,"props":5287,"children":5288},{},[5289],{"type":30,"value":743},{"type":30,"value":745},{"type":24,"tag":121,"props":5292,"children":5293},{"id":748},[5294],{"type":30,"value":751},{"type":24,"tag":33,"props":5296,"children":5297},{},[5298],{"type":30,"value":756},{"type":24,"tag":177,"props":5300,"children":5302},{"code":759,"language":180,"meta":7,"className":5301},[182],[5303],{"type":24,"tag":39,"props":5304,"children":5305},{"__ignoreMap":7},[5306],{"type":30,"value":759},{"type":24,"tag":33,"props":5308,"children":5309},{},[5310,5314],{"type":24,"tag":53,"props":5311,"children":5312},{},[5313],{"type":30,"value":418},{"type":30,"value":205},{"type":24,"tag":133,"props":5316,"children":5317},{},[5318,5322,5326],{"type":24,"tag":65,"props":5319,"children":5320},{},[5321],{"type":30,"value":781},{"type":24,"tag":65,"props":5323,"children":5324},{},[5325],{"type":30,"value":786},{"type":24,"tag":65,"props":5327,"children":5328},{},[5329],{"type":30,"value":791},{"type":24,"tag":25,"props":5331,"children":5332},{"id":794},[5333],{"type":30,"value":794},{"type":24,"tag":121,"props":5335,"children":5336},{"id":799},[5337],{"type":30,"value":802},{"type":24,"tag":33,"props":5339,"children":5340},{},[5341],{"type":30,"value":807},{"type":24,"tag":177,"props":5343,"children":5345},{"code":810,"language":180,"meta":7,"className":5344},[182],[5346],{"type":24,"tag":39,"props":5347,"children":5348},{"__ignoreMap":7},[5349],{"type":30,"value":810},{"type":24,"tag":33,"props":5351,"children":5352},{},[5353,5357,5358,5361,5365],{"type":24,"tag":53,"props":5354,"children":5355},{},[5356],{"type":30,"value":824},{"type":30,"value":826},{"type":24,"tag":828,"props":5359,"children":5360},{},[],{"type":24,"tag":53,"props":5362,"children":5363},{},[5364],{"type":30,"value":835},{"type":30,"value":837},{"type":24,"tag":121,"props":5367,"children":5368},{"id":840},[5369],{"type":30,"value":843},{"type":24,"tag":33,"props":5371,"children":5372},{},[5373],{"type":30,"value":848},{"type":24,"tag":177,"props":5375,"children":5377},{"code":851,"language":696,"meta":7,"className":5376},[698],[5378],{"type":24,"tag":39,"props":5379,"children":5380},{"__ignoreMap":7},[5381],{"type":30,"value":851},{"type":24,"tag":33,"props":5383,"children":5384},{},[5385,5389,5390,5393,5397],{"type":24,"tag":53,"props":5386,"children":5387},{},[5388],{"type":30,"value":824},{"type":30,"value":866},{"type":24,"tag":828,"props":5391,"children":5392},{},[],{"type":24,"tag":53,"props":5394,"children":5395},{},[5396],{"type":30,"value":835},{"type":30,"value":875},{"type":24,"tag":121,"props":5399,"children":5400},{"id":878},[5401],{"type":30,"value":881},{"type":24,"tag":33,"props":5403,"children":5404},{},[5405],{"type":30,"value":886},{"type":24,"tag":177,"props":5407,"children":5409},{"code":889,"language":696,"meta":7,"className":5408},[698],[5410],{"type":24,"tag":39,"props":5411,"children":5412},{"__ignoreMap":7},[5413],{"type":30,"value":889},{"type":24,"tag":33,"props":5415,"children":5416},{},[5417,5421,5422,5425,5429],{"type":24,"tag":53,"props":5418,"children":5419},{},[5420],{"type":30,"value":824},{"type":30,"value":904},{"type":24,"tag":828,"props":5423,"children":5424},{},[],{"type":24,"tag":53,"props":5426,"children":5427},{},[5428],{"type":30,"value":835},{"type":30,"value":913},{"type":24,"tag":25,"props":5431,"children":5432},{"id":916},[5433],{"type":30,"value":919},{"type":24,"tag":33,"props":5435,"children":5436},{},[5437,5438,5443],{"type":30,"value":924},{"type":24,"tag":39,"props":5439,"children":5441},{"className":5440},[],[5442],{"type":30,"value":44},{"type":30,"value":931},{"type":24,"tag":121,"props":5445,"children":5446},{"id":934},[5447],{"type":30,"value":937},{"type":24,"tag":61,"props":5449,"children":5450},{},[5451,5459,5467,5475],{"type":24,"tag":65,"props":5452,"children":5453},{},[5454,5458],{"type":24,"tag":53,"props":5455,"children":5456},{},[5457],{"type":30,"value":948},{"type":30,"value":950},{"type":24,"tag":65,"props":5460,"children":5461},{},[5462,5466],{"type":24,"tag":53,"props":5463,"children":5464},{},[5465],{"type":30,"value":958},{"type":30,"value":960},{"type":24,"tag":65,"props":5468,"children":5469},{},[5470,5474],{"type":24,"tag":53,"props":5471,"children":5472},{},[5473],{"type":30,"value":968},{"type":30,"value":970},{"type":24,"tag":65,"props":5476,"children":5477},{},[5478,5482],{"type":24,"tag":53,"props":5479,"children":5480},{},[5481],{"type":30,"value":978},{"type":30,"value":980},{"type":24,"tag":121,"props":5484,"children":5485},{"id":983},[5486],{"type":30,"value":986},{"type":24,"tag":61,"props":5488,"children":5489},{},[5490,5498,5506,5514],{"type":24,"tag":65,"props":5491,"children":5492},{},[5493,5497],{"type":24,"tag":53,"props":5494,"children":5495},{},[5496],{"type":30,"value":997},{"type":30,"value":999},{"type":24,"tag":65,"props":5499,"children":5500},{},[5501,5505],{"type":24,"tag":53,"props":5502,"children":5503},{},[5504],{"type":30,"value":1007},{"type":30,"value":1009},{"type":24,"tag":65,"props":5507,"children":5508},{},[5509,5513],{"type":24,"tag":53,"props":5510,"children":5511},{},[5512],{"type":30,"value":1017},{"type":30,"value":1019},{"type":24,"tag":65,"props":5515,"children":5516},{},[5517,5521],{"type":24,"tag":53,"props":5518,"children":5519},{},[5520],{"type":30,"value":1027},{"type":30,"value":1029},{"type":24,"tag":121,"props":5523,"children":5524},{"id":1032},[5525],{"type":30,"value":1035},{"type":24,"tag":61,"props":5527,"children":5528},{},[5529,5537,5545,5553,5561],{"type":24,"tag":65,"props":5530,"children":5531},{},[5532,5536],{"type":24,"tag":53,"props":5533,"children":5534},{},[5535],{"type":30,"value":1046},{"type":30,"value":1048},{"type":24,"tag":65,"props":5538,"children":5539},{},[5540,5544],{"type":24,"tag":53,"props":5541,"children":5542},{},[5543],{"type":30,"value":1056},{"type":30,"value":1058},{"type":24,"tag":65,"props":5546,"children":5547},{},[5548,5552],{"type":24,"tag":53,"props":5549,"children":5550},{},[5551],{"type":30,"value":1066},{"type":30,"value":1068},{"type":24,"tag":65,"props":5554,"children":5555},{},[5556,5560],{"type":24,"tag":53,"props":5557,"children":5558},{},[5559],{"type":30,"value":1076},{"type":30,"value":1078},{"type":24,"tag":65,"props":5562,"children":5563},{},[5564,5568],{"type":24,"tag":53,"props":5565,"children":5566},{},[5567],{"type":30,"value":1086},{"type":30,"value":1088},{"type":24,"tag":121,"props":5570,"children":5571},{"id":1091},[5572],{"type":30,"value":1094},{"type":24,"tag":61,"props":5574,"children":5575},{},[5576,5584,5592,5606],{"type":24,"tag":65,"props":5577,"children":5578},{},[5579,5583],{"type":24,"tag":53,"props":5580,"children":5581},{},[5582],{"type":30,"value":1105},{"type":30,"value":1107},{"type":24,"tag":65,"props":5585,"children":5586},{},[5587,5591],{"type":24,"tag":53,"props":5588,"children":5589},{},[5590],{"type":30,"value":1115},{"type":30,"value":1117},{"type":24,"tag":65,"props":5593,"children":5594},{},[5595,5599,5600,5605],{"type":24,"tag":53,"props":5596,"children":5597},{},[5598],{"type":30,"value":1125},{"type":30,"value":1127},{"type":24,"tag":39,"props":5601,"children":5603},{"className":5602},[],[5604],{"type":30,"value":44},{"type":30,"value":1134},{"type":24,"tag":65,"props":5607,"children":5608},{},[5609,5613],{"type":24,"tag":53,"props":5610,"children":5611},{},[5612],{"type":30,"value":1142},{"type":30,"value":1144},{"type":24,"tag":121,"props":5615,"children":5616},{"id":1147},[5617],{"type":30,"value":1150},{"type":24,"tag":61,"props":5619,"children":5620},{},[5621,5635,5649,5657],{"type":24,"tag":65,"props":5622,"children":5623},{},[5624,5628,5629,5634],{"type":24,"tag":53,"props":5625,"children":5626},{},[5627],{"type":30,"value":1161},{"type":30,"value":1163},{"type":24,"tag":39,"props":5630,"children":5632},{"className":5631},[],[5633],{"type":30,"value":44},{"type":30,"value":1170},{"type":24,"tag":65,"props":5636,"children":5637},{},[5638,5642,5643,5648],{"type":24,"tag":53,"props":5639,"children":5640},{},[5641],{"type":30,"value":1178},{"type":30,"value":1180},{"type":24,"tag":39,"props":5644,"children":5646},{"className":5645},[],[5647],{"type":30,"value":1186},{"type":30,"value":1188},{"type":24,"tag":65,"props":5650,"children":5651},{},[5652,5656],{"type":24,"tag":53,"props":5653,"children":5654},{},[5655],{"type":30,"value":1196},{"type":30,"value":1198},{"type":24,"tag":65,"props":5658,"children":5659},{},[5660,5664],{"type":24,"tag":53,"props":5661,"children":5662},{},[5663],{"type":30,"value":1206},{"type":30,"value":1208},{"type":24,"tag":25,"props":5666,"children":5667},{"id":1211},[5668],{"type":30,"value":1211},{"type":24,"tag":121,"props":5670,"children":5671},{"id":1216},[5672],{"type":30,"value":1219},{"type":24,"tag":33,"props":5674,"children":5675},{},[5676,5680],{"type":24,"tag":53,"props":5677,"children":5678},{},[5679],{"type":30,"value":1227},{"type":30,"value":1229},{"type":24,"tag":33,"props":5682,"children":5683},{},[5684,5688],{"type":24,"tag":53,"props":5685,"children":5686},{},[5687],{"type":30,"value":1237},{"type":30,"value":205},{"type":24,"tag":133,"props":5690,"children":5691},{},[5692,5696,5700,5704],{"type":24,"tag":65,"props":5693,"children":5694},{},[5695],{"type":30,"value":1246},{"type":24,"tag":65,"props":5697,"children":5698},{},[5699],{"type":30,"value":1251},{"type":24,"tag":65,"props":5701,"children":5702},{},[5703],{"type":30,"value":1256},{"type":24,"tag":65,"props":5705,"children":5706},{},[5707],{"type":30,"value":1261},{"type":24,"tag":121,"props":5709,"children":5710},{"id":1264},[5711],{"type":30,"value":1267},{"type":24,"tag":33,"props":5713,"children":5714},{},[5715,5719],{"type":24,"tag":53,"props":5716,"children":5717},{},[5718],{"type":30,"value":1227},{"type":30,"value":1276},{"type":24,"tag":33,"props":5721,"children":5722},{},[5723,5727],{"type":24,"tag":53,"props":5724,"children":5725},{},[5726],{"type":30,"value":1237},{"type":30,"value":205},{"type":24,"tag":133,"props":5729,"children":5730},{},[5731,5735,5739],{"type":24,"tag":65,"props":5732,"children":5733},{},[5734],{"type":30,"value":1292},{"type":24,"tag":65,"props":5736,"children":5737},{},[5738],{"type":30,"value":1297},{"type":24,"tag":65,"props":5740,"children":5741},{},[5742],{"type":30,"value":1302},{"type":24,"tag":121,"props":5744,"children":5745},{"id":1305},[5746],{"type":30,"value":1308},{"type":24,"tag":33,"props":5748,"children":5749},{},[5750,5754,5755,5760],{"type":24,"tag":53,"props":5751,"children":5752},{},[5753],{"type":30,"value":1227},{"type":30,"value":1317},{"type":24,"tag":39,"props":5756,"children":5758},{"className":5757},[],[5759],{"type":30,"value":1323},{"type":30,"value":1325},{"type":24,"tag":33,"props":5762,"children":5763},{},[5764,5768],{"type":24,"tag":53,"props":5765,"children":5766},{},[5767],{"type":30,"value":1237},{"type":30,"value":205},{"type":24,"tag":133,"props":5770,"children":5771},{},[5772,5776,5780],{"type":24,"tag":65,"props":5773,"children":5774},{},[5775],{"type":30,"value":1341},{"type":24,"tag":65,"props":5777,"children":5778},{},[5779],{"type":30,"value":1346},{"type":24,"tag":65,"props":5781,"children":5782},{},[5783],{"type":30,"value":1351},{"type":24,"tag":121,"props":5785,"children":5786},{"id":1354},[5787],{"type":30,"value":1357},{"type":24,"tag":33,"props":5789,"children":5790},{},[5791,5795],{"type":24,"tag":53,"props":5792,"children":5793},{},[5794],{"type":30,"value":1227},{"type":30,"value":1366},{"type":24,"tag":33,"props":5797,"children":5798},{},[5799,5803],{"type":24,"tag":53,"props":5800,"children":5801},{},[5802],{"type":30,"value":1237},{"type":30,"value":205},{"type":24,"tag":133,"props":5805,"children":5806},{},[5807,5811,5815],{"type":24,"tag":65,"props":5808,"children":5809},{},[5810],{"type":30,"value":1382},{"type":24,"tag":65,"props":5812,"children":5813},{},[5814],{"type":30,"value":1387},{"type":24,"tag":65,"props":5816,"children":5817},{},[5818],{"type":30,"value":1392},{"type":24,"tag":25,"props":5820,"children":5821},{"id":1395},[5822],{"type":30,"value":1398},{"type":24,"tag":121,"props":5824,"children":5825},{"id":1401},[5826],{"type":30,"value":1404},{"type":24,"tag":33,"props":5828,"children":5829},{},[5830,5834,5835,5840],{"type":24,"tag":53,"props":5831,"children":5832},{},[5833],{"type":30,"value":1412},{"type":30,"value":1414},{"type":24,"tag":39,"props":5836,"children":5838},{"className":5837},[],[5839],{"type":30,"value":44},{"type":30,"value":1421},{"type":24,"tag":121,"props":5842,"children":5843},{"id":1424},[5844],{"type":30,"value":1427},{"type":24,"tag":33,"props":5846,"children":5847},{},[5848,5852],{"type":24,"tag":53,"props":5849,"children":5850},{},[5851],{"type":30,"value":1412},{"type":30,"value":1436},{"type":24,"tag":133,"props":5854,"children":5855},{},[5856,5864,5872],{"type":24,"tag":65,"props":5857,"children":5858},{},[5859,5863],{"type":24,"tag":53,"props":5860,"children":5861},{},[5862],{"type":30,"value":1447},{"type":30,"value":1449},{"type":24,"tag":65,"props":5865,"children":5866},{},[5867,5871],{"type":24,"tag":53,"props":5868,"children":5869},{},[5870],{"type":30,"value":226},{"type":30,"value":1458},{"type":24,"tag":65,"props":5873,"children":5874},{},[5875,5879],{"type":24,"tag":53,"props":5876,"children":5877},{},[5878],{"type":30,"value":1466},{"type":30,"value":1468},{"type":24,"tag":33,"props":5881,"children":5882},{},[5883],{"type":30,"value":1473},{"type":24,"tag":121,"props":5885,"children":5886},{"id":1476},[5887],{"type":30,"value":1479},{"type":24,"tag":33,"props":5889,"children":5890},{},[5891,5895],{"type":24,"tag":53,"props":5892,"children":5893},{},[5894],{"type":30,"value":1412},{"type":30,"value":1488},{"type":24,"tag":121,"props":5897,"children":5898},{"id":1491},[5899],{"type":30,"value":1494},{"type":24,"tag":33,"props":5901,"children":5902},{},[5903,5907],{"type":24,"tag":53,"props":5904,"children":5905},{},[5906],{"type":30,"value":1412},{"type":30,"value":1503},{"type":24,"tag":133,"props":5909,"children":5910},{},[5911,5915,5919],{"type":24,"tag":65,"props":5912,"children":5913},{},[5914],{"type":30,"value":1511},{"type":24,"tag":65,"props":5916,"children":5917},{},[5918],{"type":30,"value":1516},{"type":24,"tag":65,"props":5920,"children":5921},{},[5922],{"type":30,"value":1521},{"type":24,"tag":121,"props":5924,"children":5925},{"id":1524},[5926],{"type":30,"value":1527},{"type":24,"tag":33,"props":5928,"children":5929},{},[5930,5934],{"type":24,"tag":53,"props":5931,"children":5932},{},[5933],{"type":30,"value":1412},{"type":30,"value":1503},{"type":24,"tag":133,"props":5936,"children":5937},{},[5938,5942,5946,5950],{"type":24,"tag":65,"props":5939,"children":5940},{},[5941],{"type":30,"value":1543},{"type":24,"tag":65,"props":5943,"children":5944},{},[5945],{"type":30,"value":1548},{"type":24,"tag":65,"props":5947,"children":5948},{},[5949],{"type":30,"value":1553},{"type":24,"tag":65,"props":5951,"children":5952},{},[5953],{"type":30,"value":1558},{"type":24,"tag":121,"props":5955,"children":5956},{"id":1561},[5957],{"type":30,"value":1564},{"type":24,"tag":33,"props":5959,"children":5960},{},[5961,5965],{"type":24,"tag":53,"props":5962,"children":5963},{},[5964],{"type":30,"value":1412},{"type":30,"value":1503},{"type":24,"tag":133,"props":5967,"children":5968},{},[5969,5977],{"type":24,"tag":65,"props":5970,"children":5971},{},[5972,5976],{"type":24,"tag":53,"props":5973,"children":5974},{},[5975],{"type":30,"value":1583},{"type":30,"value":1585},{"type":24,"tag":65,"props":5978,"children":5979},{},[5980,5984],{"type":24,"tag":53,"props":5981,"children":5982},{},[5983],{"type":30,"value":1593},{"type":30,"value":1595},{"type":24,"tag":33,"props":5986,"children":5987},{},[5988],{"type":30,"value":1600},{"type":24,"tag":121,"props":5990,"children":5991},{"id":1603},[5992],{"type":30,"value":1606},{"type":24,"tag":33,"props":5994,"children":5995},{},[5996,6000],{"type":24,"tag":53,"props":5997,"children":5998},{},[5999],{"type":30,"value":1412},{"type":30,"value":1615},{"type":24,"tag":133,"props":6002,"children":6003},{},[6004,6008,6012],{"type":24,"tag":65,"props":6005,"children":6006},{},[6007],{"type":30,"value":1623},{"type":24,"tag":65,"props":6009,"children":6010},{},[6011],{"type":30,"value":1628},{"type":24,"tag":65,"props":6013,"children":6014},{},[6015],{"type":30,"value":1633},{"type":24,"tag":121,"props":6017,"children":6018},{"id":1636},[6019],{"type":30,"value":1639},{"type":24,"tag":33,"props":6021,"children":6022},{},[6023,6027],{"type":24,"tag":53,"props":6024,"children":6025},{},[6026],{"type":30,"value":1412},{"type":30,"value":1648},{"type":24,"tag":133,"props":6029,"children":6030},{},[6031,6039,6047],{"type":24,"tag":65,"props":6032,"children":6033},{},[6034,6038],{"type":24,"tag":53,"props":6035,"children":6036},{},[6037],{"type":30,"value":1659},{"type":30,"value":1661},{"type":24,"tag":65,"props":6040,"children":6041},{},[6042,6046],{"type":24,"tag":53,"props":6043,"children":6044},{},[6045],{"type":30,"value":1669},{"type":30,"value":1671},{"type":24,"tag":65,"props":6048,"children":6049},{},[6050,6054,6055],{"type":24,"tag":53,"props":6051,"children":6052},{},[6053],{"type":30,"value":1679},{"type":30,"value":1681},{"type":24,"tag":133,"props":6056,"children":6057},{},[6058,6062,6066,6070],{"type":24,"tag":65,"props":6059,"children":6060},{},[6061],{"type":30,"value":1689},{"type":24,"tag":65,"props":6063,"children":6064},{},[6065],{"type":30,"value":1694},{"type":24,"tag":65,"props":6067,"children":6068},{},[6069],{"type":30,"value":1699},{"type":24,"tag":65,"props":6071,"children":6072},{},[6073],{"type":30,"value":1704},{"type":24,"tag":25,"props":6075,"children":6076},{"id":1707},[6077],{"type":30,"value":1707},{"type":24,"tag":133,"props":6079,"children":6080},{},[6081,6089,6097,6105],{"type":24,"tag":65,"props":6082,"children":6083},{},[6084],{"type":24,"tag":1717,"props":6085,"children":6087},{"href":1719,"rel":6086},[1721],[6088],{"type":30,"value":1724},{"type":24,"tag":65,"props":6090,"children":6091},{},[6092],{"type":24,"tag":1717,"props":6093,"children":6095},{"href":1730,"rel":6094},[1721],[6096],{"type":30,"value":1734},{"type":24,"tag":65,"props":6098,"children":6099},{},[6100],{"type":24,"tag":1717,"props":6101,"children":6103},{"href":1740,"rel":6102},[1721],[6104],{"type":30,"value":1744},{"type":24,"tag":65,"props":6106,"children":6107},{},[6108],{"type":24,"tag":1717,"props":6109,"children":6111},{"href":1750,"rel":6110},[1721],[6112],{"type":30,"value":1754},{"type":24,"tag":25,"props":6114,"children":6115},{"id":1757},[6116],{"type":30,"value":1760},{"type":24,"tag":33,"props":6118,"children":6119},{},[6120],{"type":30,"value":1765},{"type":24,"tag":133,"props":6122,"children":6124},{"className":6123},[1769],[6125,6133,6141,6149,6157,6165,6173,6181,6189,6197],{"type":24,"tag":65,"props":6126,"children":6128},{"className":6127},[1774],[6129,6132],{"type":24,"tag":1777,"props":6130,"children":6131},{"disabled":1779,"type":1780},[],{"type":30,"value":1783},{"type":24,"tag":65,"props":6134,"children":6136},{"className":6135},[1774],[6137,6140],{"type":24,"tag":1777,"props":6138,"children":6139},{"disabled":1779,"type":1780},[],{"type":30,"value":1792},{"type":24,"tag":65,"props":6142,"children":6144},{"className":6143},[1774],[6145,6148],{"type":24,"tag":1777,"props":6146,"children":6147},{"disabled":1779,"type":1780},[],{"type":30,"value":1801},{"type":24,"tag":65,"props":6150,"children":6152},{"className":6151},[1774],[6153,6156],{"type":24,"tag":1777,"props":6154,"children":6155},{"disabled":1779,"type":1780},[],{"type":30,"value":1810},{"type":24,"tag":65,"props":6158,"children":6160},{"className":6159},[1774],[6161,6164],{"type":24,"tag":1777,"props":6162,"children":6163},{"disabled":1779,"type":1780},[],{"type":30,"value":1819},{"type":24,"tag":65,"props":6166,"children":6168},{"className":6167},[1774],[6169,6172],{"type":24,"tag":1777,"props":6170,"children":6171},{"disabled":1779,"type":1780},[],{"type":30,"value":1828},{"type":24,"tag":65,"props":6174,"children":6176},{"className":6175},[1774],[6177,6180],{"type":24,"tag":1777,"props":6178,"children":6179},{"disabled":1779,"type":1780},[],{"type":30,"value":1837},{"type":24,"tag":65,"props":6182,"children":6184},{"className":6183},[1774],[6185,6188],{"type":24,"tag":1777,"props":6186,"children":6187},{"disabled":1779,"type":1780},[],{"type":30,"value":1846},{"type":24,"tag":65,"props":6190,"children":6192},{"className":6191},[1774],[6193,6196],{"type":24,"tag":1777,"props":6194,"children":6195},{"disabled":1779,"type":1780},[],{"type":30,"value":1855},{"type":24,"tag":65,"props":6198,"children":6200},{"className":6199},[1774],[6201,6204],{"type":24,"tag":1777,"props":6202,"children":6203},{"disabled":1779,"type":1780},[],{"type":30,"value":1864},{"type":24,"tag":1866,"props":6206,"children":6207},{},[],{"type":24,"tag":33,"props":6209,"children":6210},{},[6211,6215,6216,6220],{"type":24,"tag":53,"props":6212,"children":6213},{},[6214],{"type":30,"value":1876},{"type":30,"value":1878},{"type":24,"tag":1717,"props":6217,"children":6218},{"href":1881},[6219],{"type":30,"value":1884},{"type":30,"value":1886},{"title":7,"searchDepth":1888,"depth":1888,"links":6222},[6223,6224,6230,6235,6239,6244,6251,6257,6267,6268],{"id":27,"depth":1891,"text":31},{"id":116,"depth":1891,"text":119,"children":6225},[6226,6227,6228,6229],{"id":123,"depth":1888,"text":126},{"id":190,"depth":1888,"text":193},{"id":250,"depth":1888,"text":253},{"id":342,"depth":1888,"text":345},{"id":402,"depth":1891,"text":402,"children":6231},[6232,6233,6234],{"id":407,"depth":1888,"text":410},{"id":494,"depth":1888,"text":497},{"id":579,"depth":1888,"text":582},{"id":679,"depth":1891,"text":679,"children":6236},[6237,6238],{"id":684,"depth":1888,"text":687},{"id":748,"depth":1888,"text":751},{"id":794,"depth":1891,"text":794,"children":6240},[6241,6242,6243],{"id":799,"depth":1888,"text":802},{"id":840,"depth":1888,"text":843},{"id":878,"depth":1888,"text":881},{"id":916,"depth":1891,"text":919,"children":6245},[6246,6247,6248,6249,6250],{"id":934,"depth":1888,"text":937},{"id":983,"depth":1888,"text":986},{"id":1032,"depth":1888,"text":1035},{"id":1091,"depth":1888,"text":1094},{"id":1147,"depth":1888,"text":1150},{"id":1211,"depth":1891,"text":1211,"children":6252},[6253,6254,6255,6256],{"id":1216,"depth":1888,"text":1219},{"id":1264,"depth":1888,"text":1267},{"id":1305,"depth":1888,"text":1308},{"id":1354,"depth":1888,"text":1357},{"id":1395,"depth":1891,"text":1398,"children":6258},[6259,6260,6261,6262,6263,6264,6265,6266],{"id":1401,"depth":1888,"text":1404},{"id":1424,"depth":1888,"text":1427},{"id":1476,"depth":1888,"text":1479},{"id":1491,"depth":1888,"text":1494},{"id":1524,"depth":1888,"text":1527},{"id":1561,"depth":1888,"text":1564},{"id":1603,"depth":1888,"text":1606},{"id":1636,"depth":1888,"text":1639},{"id":1707,"depth":1891,"text":1707},{"id":1757,"depth":1891,"text":1760},1782088239302]