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