核心摘要

欧盟《人工智能法案》(EU AI Act)是全球首部全面规制 AI 系统的法规,其长臂管辖原则意味着:只要你的 AI 系统输出在欧盟境内被使用,无论公司注册地在哪里,都必须合规。对于中国出海开发者而言,2026 年 8 月 2 日是高风险 AI 系统义务的核心截止日——违规罚款最高达 3500 万欧元全球年营收的 7%(取较高者)。

本文从工程实操角度出发,为你提供一份完整的技术合规清单,包含可直接落地的代码实现、架构设计模式与自动化测试流水线。

核心要点

  • 时间线紧迫:2026 年 8 月 2 日起,高风险 AI 系统必须满足全部技术要求,包括审计日志、人工监督、偏差测试
  • 四级风险分类:不可接受风险(禁止)→ 高风险 → 有限风险 → 最小风险,每级对应不同的合规义务
  • 附件四技术文档:9 大类别文档必须在系统上市前准备完毕
  • 工程化合规:通过中间件、CI/CD 流水线、自动化测试将合规要求融入开发流程
  • 长臂管辖:即使公司在中国注册,只要 AI 输出影响欧盟用户,即受法规约束

执行时间线与里程碑

欧盟 AI 法案的执行采用分阶段生效策略,开发者必须清楚每个节点的义务范围:

gantt title 欧盟AI法案执行时间线 dateFormat YYYY-MM-DD section 已生效 禁止实践 + AI素养义务 :done, 2025-02-02, 2025-02-02 GPAI模型义务 :done, 2025-08-02, 2025-08-02 section 即将生效 高风险AI系统义务 :active, 2026-08-02, 2026-08-02 section 远期 产品嵌入式AI系统 : 2027-08-02, 2027-08-02
日期 义务范围 影响对象
2025-02-02 禁止实践 + AI 素养义务 所有 AI 系统提供者与部署者
2025-08-02 GPAI 模型义务 通用人工智能模型提供者
2026-08-02 高风险 AI 系统义务 高风险分类下的所有 AI 系统
2027-08-02 产品嵌入式 AI 系统 作为产品安全组件的 AI 系统

对于大多数出海开发者而言,2026 年 8 月 2 日是最关键的截止日。如果你的 AI Agent 系统涉及信贷评估、招聘筛选、医疗诊断辅助等领域,现在就必须启动合规工程改造。

风险分类决策树

欧盟 AI 法案的核心架构是基于风险的四级分类体系。正确判断你的 AI 系统属于哪一级,是合规工作的第一步。

flowchart TD A["AI系统评估入口"] --> B{"是否涉及禁止实践?"} B -->|是| C["不可接受风险 - 禁止部署"] B -->|否| D{"是否属于附件III清单?"} D -->|是| E{"是否满足例外条件?"} E -->|否| F["高风险 - 完整合规义务"] E -->|是| G["下调至有限风险"] D -->|否| H{"是否与人直接交互?"} H -->|是| I["有限风险 - 透明度义务"] H -->|否| J["最小风险 - 自愿行为准则"] C --> C1["社会评分系统"] C --> C2["实时远程生物识别"] C --> C3["情感推断 - 工作/教育场景"] F --> F1["技术文档 - 附件IV"] F --> F2["质量管理体系"] F --> F3["合规性评估"] F --> F4["上市后监控"]

禁止实践清单(不可接受风险)

以下 AI 应用在欧盟境内被完全禁止:

typescript
// risk-classifier.ts - AI系统风险分类器
interface AISystemProfile {
  purpose: string;
  domain: string;
  interactsWithNaturalPersons: boolean;
  usesPersonalData: boolean;
  outputAffectsRights: boolean;
  deploymentRegions: string[];
}

enum RiskLevel {
  UNACCEPTABLE = 'UNACCEPTABLE',
  HIGH = 'HIGH',
  LIMITED = 'LIMITED',
  MINIMAL = 'MINIMAL'
}

const PROHIBITED_PRACTICES = [
  'social_scoring_by_public_authorities',
  'real_time_remote_biometric_identification_public_spaces',
  'subliminal_manipulation_causing_harm',
  'exploitation_of_vulnerable_groups',
  'emotion_inference_in_workplace_education',
  'untargeted_facial_image_scraping',
  'biometric_categorization_sensitive_attributes'
];

const ANNEX_III_DOMAINS = [
  'biometric_identification',
  'critical_infrastructure_management',
  'education_vocational_training',
  'employment_worker_management',
  'essential_services_access', // credit scoring, insurance
  'law_enforcement',
  'migration_asylum_border_control',
  'administration_of_justice'
];

function classifyRisk(system: AISystemProfile): RiskLevel {
  // Check prohibited practices first
  if (PROHIBITED_PRACTICES.some(p => system.purpose.includes(p))) {
    return RiskLevel.UNACCEPTABLE;
  }
  
  // Check Annex III high-risk domains
  if (ANNEX_III_DOMAINS.some(d => system.domain.includes(d))) {
    return RiskLevel.HIGH;
  }
  
  // Transparency obligations for direct interaction
  if (system.interactsWithNaturalPersons) {
    return RiskLevel.LIMITED;
  }
  
  return RiskLevel.MINIMAL;
}

高风险 AI 系统附件三清单

高风险 AI 系统是合规工作的核心对象。以下领域的 AI 系统被自动归为高风险:

  1. 生物特征识别与分类:远程生物识别系统
  2. 关键基础设施管理:电力、水务、交通的 AI 调度
  3. 教育与职业培训:录取决策、考试评分、学习监控
  4. 就业与人力管理:简历筛选、面试评估、绩效评定
  5. 基本服务准入:信贷评分、保险定价、社会福利
  6. 执法:犯罪风险评估、证据分析
  7. 移民与边境管控:签证评估、风险预警
  8. 司法行政:法律研究辅助、量刑建议

如果你的 LLM 应用涉及以上任何领域,必须按照高风险 AI 系统的全部要求进行合规。

附件四技术文档要求

第 11 条与附件四规定了高风险 AI 系统必须维护的技术文档体系。这是合规检查中最容易被忽视但最耗费工程量的部分。

九大文档类别

序号 文档类别 核心内容 工程实现方式
1 系统总体描述 预期用途、开发者信息、版本号 自动化模型卡片
2 系统架构 算法逻辑、计算资源、硬件依赖 架构即代码
3 开发过程 训练方法、数据集来源、超参选择 MLOps 流水线记录
4 监控与测试 性能指标、测试方法、验证结果 CI/CD 测试报告
5 风险管理 已知风险、缓解措施、残余风险 风险登记簿
6 变更记录 版本变更历史、影响评估 Git 提交 + 变更日志
7 标准合规 引用的协调标准、合规声明 合规矩阵
8 EU 合格声明 CE 标志文档 自动生成模板
9 上市后信息 事故报告、投诉处理、召回记录 事件管理系统

模型卡片自动生成

技术文档的核心是模型卡片(Model Card),它必须随每次模型更新自动生成:

python
# model_card_generator.py - 自动化模型卡片生成
import json
import hashlib
from datetime import datetime
from dataclasses import dataclass, field, asdict
from typing import List, Dict, Optional

@dataclass
class TrainingDataInfo:
    dataset_name: str
    source: str
    size: int
    collection_date: str
    preprocessing_steps: List[str]
    personal_data_categories: List[str]
    geographic_coverage: List[str]
    demographic_representation: Dict[str, float]

@dataclass
class PerformanceMetrics:
    metric_name: str
    value: float
    confidence_interval: tuple
    evaluation_dataset: str
    disaggregated_results: Dict[str, float]  # by demographic group

@dataclass
class RiskAssessment:
    risk_id: str
    description: str
    severity: str  # critical, high, medium, low
    likelihood: str
    mitigation_measures: List[str]
    residual_risk_level: str
    monitoring_indicators: List[str]

@dataclass
class ModelCard:
    """EU AI Act Annex IV compliant model card"""
    # Section 1: General Description
    model_name: str
    version: str
    provider: str
    intended_purpose: str
    intended_users: List[str]
    prohibited_uses: List[str]
    deployment_regions: List[str]
    
    # Section 2: Technical Architecture
    model_type: str
    architecture_description: str
    input_format: str
    output_format: str
    computational_requirements: Dict[str, str]
    
    # Section 3: Training Information
    training_data: List[TrainingDataInfo] = field(default_factory=list)
    training_methodology: str = ""
    hyperparameters: Dict[str, any] = field(default_factory=dict)
    training_duration: str = ""
    
    # Section 4: Evaluation
    performance_metrics: List[PerformanceMetrics] = field(default_factory=list)
    bias_evaluation: Dict[str, any] = field(default_factory=dict)
    robustness_tests: List[str] = field(default_factory=list)
    
    # Section 5: Risk Management
    risk_assessments: List[RiskAssessment] = field(default_factory=list)
    
    # Metadata
    generation_timestamp: str = field(
        default_factory=lambda: datetime.utcnow().isoformat()
    )
    document_hash: str = ""
    
    def generate_hash(self) -> str:
        content = json.dumps(asdict(self), sort_keys=True, default=str)
        return hashlib.sha256(content.encode()).hexdigest()
    
    def validate_completeness(self) -> List[str]:
        """Validate all Annex IV required fields are populated"""
        missing = []
        if not self.intended_purpose:
            missing.append("intended_purpose (Annex IV, Section 1)")
        if not self.training_data:
            missing.append("training_data (Annex IV, Section 3)")
        if not self.performance_metrics:
            missing.append("performance_metrics (Annex IV, Section 4)")
        if not self.risk_assessments:
            missing.append("risk_assessments (Annex IV, Section 5)")
        if not self.bias_evaluation:
            missing.append("bias_evaluation (Annex IV, Section 4)")
        return missing
    
    def export_for_authority(self) -> Dict:
        """Export format suitable for regulatory authority review"""
        card = asdict(self)
        card['document_hash'] = self.generate_hash()
        card['compliance_standard'] = 'EU_AI_ACT_2024_ANNEX_IV'
        card['export_timestamp'] = datetime.utcnow().isoformat()
        return card


def generate_model_card_from_mlflow(run_id: str) -> ModelCard:
    """Generate model card from MLflow experiment tracking"""
    import mlflow
    
    run = mlflow.get_run(run_id)
    params = run.data.params
    metrics = run.data.metrics
    
    card = ModelCard(
        model_name=params.get('model_name', ''),
        version=params.get('version', '1.0.0'),
        provider="Your Company Name",
        intended_purpose=params.get('intended_purpose', ''),
        intended_users=json.loads(params.get('intended_users', '[]')),
        prohibited_uses=json.loads(params.get('prohibited_uses', '[]')),
        deployment_regions=json.loads(params.get('deployment_regions', '[]')),
        model_type=params.get('model_type', ''),
        architecture_description=params.get('architecture', ''),
        input_format=params.get('input_format', ''),
        output_format=params.get('output_format', ''),
        computational_requirements={
            'gpu': params.get('gpu_type', ''),
            'memory': params.get('memory_gb', ''),
            'inference_latency_p99': str(metrics.get('inference_p99', ''))
        }
    )
    
    # Validate completeness before export
    missing = card.validate_completeness()
    if missing:
        raise ValueError(
            f"Model card incomplete. Missing fields: {missing}"
        )
    
    return card

通过将模型卡片生成集成到 CI/CD 流水线中,每次模型更新时自动重新生成文档,确保技术文档始终与生产系统同步。你可以使用 JSON 格式化工具 来验证生成的模型卡片 JSON 结构是否正确。

审计日志中间件实现

第 12 条要求高风险 AI 系统必须具备自动日志记录能力。日志必须记录系统的每次决策过程,以便于事后追溯与审计。

日志记录要求

根据法案第 12 条,日志系统必须满足以下要求:

  • 记录系统运行的每个周期的开始和结束时间
  • 输入数据的参考或标识
  • 生成输出的具体内容
  • 相关的人工监督干预事件
  • 保留期限与系统预期寿命匹配

审计日志中间件

typescript
// audit-middleware.ts - EU AI Act Article 12 compliant audit logging
import { v4 as uuidv4 } from 'uuid';
import crypto from 'crypto';

interface AuditEvent {
  eventId: string;
  timestamp: string;
  systemId: string;
  systemVersion: string;
  operationType: 'inference' | 'training' | 'human_override' | 'system_event';
  
  // Input tracking
  inputHash: string;
  inputMetadata: Record<string, any>;
  
  // Output tracking
  outputHash: string;
  outputMetadata: Record<string, any>;
  confidenceScore?: number;
  
  // Decision context
  modelVersion: string;
  featureImportance?: Record<string, number>;
  
  // Human oversight
  humanOversightTriggered: boolean;
  humanDecision?: string;
  humanOperatorId?: string;
  
  // Compliance metadata
  riskLevel: string;
  dataSubjectCategories: string[];
  retentionPeriodDays: number;
  
  // Integrity
  previousEventHash: string;
  eventChainHash: string;
}

class EUAIActAuditLogger {
  private systemId: string;
  private systemVersion: string;
  private lastEventHash: string = '';
  private storageBackend: AuditStorageBackend;
  
  constructor(config: {
    systemId: string;
    systemVersion: string;
    storageBackend: AuditStorageBackend;
  }) {
    this.systemId = config.systemId;
    this.systemVersion = config.systemVersion;
    this.storageBackend = config.storageBackend;
  }
  
  async logInference(params: {
    input: any;
    output: any;
    modelVersion: string;
    confidenceScore: number;
    featureImportance?: Record<string, number>;
    dataSubjectCategories: string[];
  }): Promise<string> {
    const inputHash = this.hashContent(params.input);
    const outputHash = this.hashContent(params.output);
    
    const event: AuditEvent = {
      eventId: uuidv4(),
      timestamp: new Date().toISOString(),
      systemId: this.systemId,
      systemVersion: this.systemVersion,
      operationType: 'inference',
      inputHash,
      inputMetadata: {
        contentType: typeof params.input,
        size: JSON.stringify(params.input).length
      },
      outputHash,
      outputMetadata: {
        contentType: typeof params.output,
        size: JSON.stringify(params.output).length
      },
      confidenceScore: params.confidenceScore,
      modelVersion: params.modelVersion,
      featureImportance: params.featureImportance,
      humanOversightTriggered: false,
      riskLevel: 'HIGH',
      dataSubjectCategories: params.dataSubjectCategories,
      retentionPeriodDays: this.calculateRetentionPeriod(),
      previousEventHash: this.lastEventHash,
      eventChainHash: ''
    };
    
    // Chain integrity - tamper-evident log chain
    event.eventChainHash = this.computeChainHash(event);
    this.lastEventHash = event.eventChainHash;
    
    await this.storageBackend.store(event);
    return event.eventId;
  }
  
  async logHumanOverride(params: {
    originalEventId: string;
    operatorId: string;
    decision: string;
    reason: string;
  }): Promise<string> {
    const event: AuditEvent = {
      eventId: uuidv4(),
      timestamp: new Date().toISOString(),
      systemId: this.systemId,
      systemVersion: this.systemVersion,
      operationType: 'human_override',
      inputHash: params.originalEventId,
      inputMetadata: { originalEvent: params.originalEventId },
      outputHash: this.hashContent(params.decision),
      outputMetadata: { reason: params.reason },
      modelVersion: '',
      humanOversightTriggered: true,
      humanDecision: params.decision,
      humanOperatorId: params.operatorId,
      riskLevel: 'HIGH',
      dataSubjectCategories: [],
      retentionPeriodDays: this.calculateRetentionPeriod(),
      previousEventHash: this.lastEventHash,
      eventChainHash: ''
    };
    
    event.eventChainHash = this.computeChainHash(event);
    this.lastEventHash = event.eventChainHash;
    
    await this.storageBackend.store(event);
    return event.eventId;
  }
  
  private hashContent(content: any): string {
    return crypto
      .createHash('sha256')
      .update(JSON.stringify(content))
      .digest('hex');
  }
  
  private computeChainHash(event: AuditEvent): string {
    const payload = `${event.eventId}:${event.timestamp}:${event.previousEventHash}`;
    return crypto.createHash('sha256').update(payload).digest('hex');
  }
  
  private calculateRetentionPeriod(): number {
    // Article 12(3): logs retained for period appropriate to intended purpose
    // High-risk systems: minimum 6 months, recommended 5 years
    return 365 * 5;
  }
}

interface AuditStorageBackend {
  store(event: AuditEvent): Promise<void>;
  retrieve(eventId: string): Promise<AuditEvent | null>;
  queryByTimeRange(start: Date, end: Date): Promise<AuditEvent[]>;
  verifyChainIntegrity(startEventId: string): Promise<boolean>;
}

审计日志的数据格式验证可以借助 YAML 转 JSON 工具 在配置管理阶段进行格式转换与校验。在大规模部署中,你需要使用 UUID 生成器 确保每个审计事件拥有全局唯一标识符。

基本权利影响评估实现

第 27 条要求高风险 AI 系统的部署者在首次使用前完成基本权利影响评估(Fundamental Rights Impact Assessment,FRIA)。这不是一次性文件,而是需要持续更新的动态评估过程。

FRIA 评估框架

typescript
// fria-assessment.ts - Fundamental Rights Impact Assessment (Article 27)
interface FRIAReport {
  assessmentId: string;
  assessmentDate: string;
  assessor: string;
  systemDescription: string;
  
  // Affected fundamental rights
  rightsImpacted: FundamentalRight[];
  
  // Risk analysis per right
  riskAnalysis: RightRiskAnalysis[];
  
  // Mitigation measures
  mitigations: MitigationMeasure[];
  
  // Stakeholder consultation
  consultationRecords: ConsultationRecord[];
  
  // Review schedule
  nextReviewDate: string;
  reviewFrequency: string;
}

interface FundamentalRight {
  rightId: string;
  rightName: string;
  charterArticle: string; // EU Charter reference
  impactLevel: 'none' | 'minimal' | 'moderate' | 'significant' | 'severe';
  justification: string;
}

interface RightRiskAnalysis {
  rightId: string;
  riskDescription: string;
  affectedGroups: string[];
  likelihoodScore: number; // 1-5
  severityScore: number;   // 1-5
  riskScore: number;       // likelihood * severity
  existingControls: string[];
  residualRiskLevel: string;
}

interface MitigationMeasure {
  measureId: string;
  targetRightId: string;
  description: string;
  implementationType: 'technical' | 'organizational' | 'legal';
  status: 'planned' | 'implemented' | 'verified';
  effectivenessMetric: string;
  responsiblePerson: string;
  deadline: string;
}

const EU_CHARTER_RIGHTS_MAPPING = {
  'human_dignity': { article: 'Article 1', relevantDomains: ['all'] },
  'right_to_life': { article: 'Article 2', relevantDomains: ['healthcare', 'autonomous_vehicles'] },
  'integrity_of_person': { article: 'Article 3', relevantDomains: ['healthcare', 'biometrics'] },
  'prohibition_of_torture': { article: 'Article 4', relevantDomains: ['law_enforcement'] },
  'right_to_liberty': { article: 'Article 6', relevantDomains: ['law_enforcement', 'migration'] },
  'private_life': { article: 'Article 7', relevantDomains: ['surveillance', 'social_media'] },
  'data_protection': { article: 'Article 8', relevantDomains: ['all_processing_personal_data'] },
  'non_discrimination': { article: 'Article 21', relevantDomains: ['employment', 'credit', 'education'] },
  'rights_of_child': { article: 'Article 24', relevantDomains: ['education', 'social_media'] },
  'rights_of_elderly': { article: 'Article 25', relevantDomains: ['healthcare', 'social_services'] },
  'fair_working_conditions': { article: 'Article 31', relevantDomains: ['employment'] },
  'consumer_protection': { article: 'Article 38', relevantDomains: ['commerce', 'financial_services'] },
  'right_to_good_administration': { article: 'Article 41', relevantDomains: ['public_services'] },
  'effective_remedy': { article: 'Article 47', relevantDomains: ['all'] }
};

class FRIAAssessmentEngine {
  assessSystem(systemProfile: AISystemProfile): FRIAReport {
    const affectedRights = this.identifyAffectedRights(systemProfile);
    const riskAnalysis = this.analyzeRisks(affectedRights, systemProfile);
    const mitigations = this.proposeMitigations(riskAnalysis);
    
    return {
      assessmentId: crypto.randomUUID(),
      assessmentDate: new Date().toISOString(),
      assessor: 'AI Governance Team',
      systemDescription: systemProfile.purpose,
      rightsImpacted: affectedRights,
      riskAnalysis,
      mitigations,
      consultationRecords: [],
      nextReviewDate: this.calculateNextReview(),
      reviewFrequency: 'quarterly'
    };
  }
  
  private identifyAffectedRights(system: AISystemProfile): FundamentalRight[] {
    const rights: FundamentalRight[] = [];
    
    for (const [rightKey, mapping] of Object.entries(EU_CHARTER_RIGHTS_MAPPING)) {
      const isRelevant = mapping.relevantDomains.includes('all') ||
        mapping.relevantDomains.some(d => system.domain.includes(d));
      
      if (isRelevant) {
        rights.push({
          rightId: rightKey,
          rightName: rightKey.replace(/_/g, ' '),
          charterArticle: mapping.article,
          impactLevel: this.assessImpactLevel(system, rightKey),
          justification: ''
        });
      }
    }
    
    return rights;
  }
  
  private assessImpactLevel(
    system: AISystemProfile, 
    rightKey: string
  ): FundamentalRight['impactLevel'] {
    // Scoring based on data sensitivity and decision autonomy
    if (system.outputAffectsRights && system.usesPersonalData) {
      return 'significant';
    }
    if (system.outputAffectsRights || system.usesPersonalData) {
      return 'moderate';
    }
    return 'minimal';
  }
  
  private analyzeRisks(
    rights: FundamentalRight[], 
    system: AISystemProfile
  ): RightRiskAnalysis[] {
    return rights
      .filter(r => r.impactLevel !== 'none')
      .map(right => ({
        rightId: right.rightId,
        riskDescription: `Potential impact on ${right.rightName} through ${system.purpose}`,
        affectedGroups: this.identifyAffectedGroups(system),
        likelihoodScore: this.scoreLikelihood(right.impactLevel),
        severityScore: this.scoreSeverity(right.impactLevel),
        riskScore: this.scoreLikelihood(right.impactLevel) * this.scoreSeverity(right.impactLevel),
        existingControls: [],
        residualRiskLevel: ''
      }));
  }
  
  private proposeMitigations(risks: RightRiskAnalysis[]): MitigationMeasure[] {
    return risks
      .filter(r => r.riskScore >= 9) // High risk threshold
      .map(risk => ({
        measureId: crypto.randomUUID(),
        targetRightId: risk.rightId,
        description: `Implement safeguards for ${risk.rightId}`,
        implementationType: 'technical' as const,
        status: 'planned' as const,
        effectivenessMetric: 'Risk score reduction below threshold',
        responsiblePerson: 'AI Safety Lead',
        deadline: '2026-06-01'
      }));
  }
  
  private identifyAffectedGroups(system: AISystemProfile): string[] {
    return ['end_users', 'data_subjects'];
  }
  
  private scoreLikelihood(level: string): number {
    const map: Record<string, number> = {
      'minimal': 1, 'moderate': 3, 'significant': 4, 'severe': 5
    };
    return map[level] || 2;
  }
  
  private scoreSeverity(level: string): number {
    const map: Record<string, number> = {
      'minimal': 1, 'moderate': 2, 'significant': 4, 'severe': 5
    };
    return map[level] || 2;
  }
  
  private calculateNextReview(): string {
    const next = new Date();
    next.setMonth(next.getMonth() + 3);
    return next.toISOString().split('T')[0];
  }
}

关于 AI 系统与用户隐私之间的深层冲突,可以参阅 AI Agent 隐私困境:长期记忆与 GDPR 的博弈,其中详细探讨了 GDPR 数据权利如何与 AI 系统的功能性需求产生张力。

偏差测试流水线

第 10 条要求高风险 AI 系统的训练数据必须经过偏差检测与纠正。这不是一次性测试,而是需要在整个 AI 生命周期内持续运行的自动化流水线。

偏差检测 CI/CD 集成

yaml
# .github/workflows/bias-testing.yml
name: EU AI Act Bias Testing Pipeline

on:
  push:
    paths:
      - 'models/**'
      - 'data/**'
  schedule:
    - cron: '0 6 * * 1'  # Weekly Monday 6AM

env:
  BIAS_THRESHOLD_DEMOGRAPHIC_PARITY: 0.1
  BIAS_THRESHOLD_EQUALIZED_ODDS: 0.05
  BIAS_THRESHOLD_DISPARATE_IMPACT: 0.8

jobs:
  bias-audit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.11'
      
      - name: Install dependencies
        run: |
          pip install fairlearn aequitas scikit-learn pandas numpy
      
      - name: Run demographic parity test
        run: python tests/bias/test_demographic_parity.py
      
      - name: Run equalized odds test
        run: python tests/bias/test_equalized_odds.py
      
      - name: Run disparate impact analysis
        run: python tests/bias/test_disparate_impact.py
      
      - name: Generate bias report
        run: python tests/bias/generate_report.py
      
      - name: Upload bias report artifact
        uses: actions/upload-artifact@v4
        with:
          name: bias-report-${{ github.sha }}
          path: reports/bias/
      
      - name: Fail if bias exceeds threshold
        run: python tests/bias/check_thresholds.py

偏差检测核心逻辑

python
# tests/bias/test_demographic_parity.py
import numpy as np
import pandas as pd
from dataclasses import dataclass
from typing import Dict, List, Tuple
from fairlearn.metrics import (
    demographic_parity_difference,
    equalized_odds_difference,
    MetricFrame
)
from sklearn.metrics import accuracy_score, precision_score, recall_score

@dataclass
class BiasTestResult:
    test_name: str
    metric_name: str
    overall_value: float
    group_values: Dict[str, float]
    threshold: float
    passed: bool
    protected_attribute: str
    sample_size: int
    confidence_level: float
    recommendations: List[str]

class EUAIActBiasTestSuite:
    """Comprehensive bias testing per Article 10 requirements"""
    
    def __init__(self, config: Dict):
        self.demographic_parity_threshold = config.get(
            'demographic_parity_threshold', 0.1
        )
        self.equalized_odds_threshold = config.get(
            'equalized_odds_threshold', 0.05
        )
        self.disparate_impact_threshold = config.get(
            'disparate_impact_threshold', 0.8
        )
        self.protected_attributes = config.get(
            'protected_attributes', 
            ['gender', 'age_group', 'ethnicity', 'disability_status']
        )
    
    def run_full_audit(
        self, 
        y_true: np.ndarray, 
        y_pred: np.ndarray,
        sensitive_features: pd.DataFrame
    ) -> List[BiasTestResult]:
        results = []
        
        for attr in self.protected_attributes:
            if attr not in sensitive_features.columns:
                continue
            
            sf = sensitive_features[attr]
            
            # Test 1: Demographic Parity
            dp_result = self._test_demographic_parity(y_pred, sf, attr)
            results.append(dp_result)
            
            # Test 2: Equalized Odds
            eo_result = self._test_equalized_odds(y_true, y_pred, sf, attr)
            results.append(eo_result)
            
            # Test 3: Disparate Impact Ratio
            di_result = self._test_disparate_impact(y_pred, sf, attr)
            results.append(di_result)
            
            # Test 4: Calibration across groups
            cal_result = self._test_calibration(y_true, y_pred, sf, attr)
            results.append(cal_result)
        
        return results
    
    def _test_demographic_parity(
        self, 
        y_pred: np.ndarray, 
        sensitive_feature: pd.Series,
        attr_name: str
    ) -> BiasTestResult:
        dpd = demographic_parity_difference(
            y_true=y_pred,  # Using predictions as "true" for selection rate
            y_pred=y_pred,
            sensitive_features=sensitive_feature
        )
        
        # Per-group selection rates
        groups = sensitive_feature.unique()
        group_rates = {}
        for group in groups:
            mask = sensitive_feature == group
            group_rates[str(group)] = float(y_pred[mask].mean())
        
        passed = abs(dpd) <= self.demographic_parity_threshold
        
        recommendations = []
        if not passed:
            recommendations.append(
                f"Demographic parity violation detected for {attr_name}. "
                f"Consider resampling training data or applying post-processing calibration."
            )
            recommendations.append(
                "Review training data representation per Article 10(3)."
            )
        
        return BiasTestResult(
            test_name=f'demographic_parity_{attr_name}',
            metric_name='Demographic Parity Difference',
            overall_value=abs(dpd),
            group_values=group_rates,
            threshold=self.demographic_parity_threshold,
            passed=passed,
            protected_attribute=attr_name,
            sample_size=len(y_pred),
            confidence_level=0.95,
            recommendations=recommendations
        )
    
    def _test_equalized_odds(
        self,
        y_true: np.ndarray,
        y_pred: np.ndarray,
        sensitive_feature: pd.Series,
        attr_name: str
    ) -> BiasTestResult:
        eod = equalized_odds_difference(
            y_true=y_true,
            y_pred=y_pred,
            sensitive_features=sensitive_feature
        )
        
        # Per-group TPR and FPR
        groups = sensitive_feature.unique()
        group_values = {}
        for group in groups:
            mask = sensitive_feature == group
            tpr = recall_score(y_true[mask], y_pred[mask], zero_division=0)
            group_values[f'{group}_TPR'] = float(tpr)
        
        passed = abs(eod) <= self.equalized_odds_threshold
        
        recommendations = []
        if not passed:
            recommendations.append(
                f"Equalized odds violation for {attr_name}. "
                f"Model has different error rates across groups."
            )
        
        return BiasTestResult(
            test_name=f'equalized_odds_{attr_name}',
            metric_name='Equalized Odds Difference',
            overall_value=abs(eod),
            group_values=group_values,
            threshold=self.equalized_odds_threshold,
            passed=passed,
            protected_attribute=attr_name,
            sample_size=len(y_pred),
            confidence_level=0.95,
            recommendations=recommendations
        )
    
    def _test_disparate_impact(
        self,
        y_pred: np.ndarray,
        sensitive_feature: pd.Series,
        attr_name: str
    ) -> BiasTestResult:
        groups = sensitive_feature.unique()
        selection_rates = {}
        for group in groups:
            mask = sensitive_feature == group
            selection_rates[str(group)] = float(y_pred[mask].mean())
        
        max_rate = max(selection_rates.values())
        min_rate = min(selection_rates.values())
        
        # Four-fifths rule
        di_ratio = min_rate / max_rate if max_rate > 0 else 1.0
        passed = di_ratio >= self.disparate_impact_threshold
        
        recommendations = []
        if not passed:
            recommendations.append(
                f"Disparate impact ratio {di_ratio:.3f} below 0.8 threshold. "
                f"This may constitute indirect discrimination under EU law."
            )
        
        return BiasTestResult(
            test_name=f'disparate_impact_{attr_name}',
            metric_name='Disparate Impact Ratio',
            overall_value=di_ratio,
            group_values=selection_rates,
            threshold=self.disparate_impact_threshold,
            passed=passed,
            protected_attribute=attr_name,
            sample_size=len(y_pred),
            confidence_level=0.95,
            recommendations=recommendations
        )
    
    def _test_calibration(
        self,
        y_true: np.ndarray,
        y_pred: np.ndarray,
        sensitive_feature: pd.Series,
        attr_name: str
    ) -> BiasTestResult:
        groups = sensitive_feature.unique()
        group_accuracy = {}
        for group in groups:
            mask = sensitive_feature == group
            acc = accuracy_score(y_true[mask], y_pred[mask])
            group_accuracy[str(group)] = float(acc)
        
        max_acc = max(group_accuracy.values())
        min_acc = min(group_accuracy.values())
        calibration_gap = max_acc - min_acc
        
        passed = calibration_gap <= 0.05
        
        return BiasTestResult(
            test_name=f'calibration_{attr_name}',
            metric_name='Calibration Gap',
            overall_value=calibration_gap,
            group_values=group_accuracy,
            threshold=0.05,
            passed=passed,
            protected_attribute=attr_name,
            sample_size=len(y_pred),
            confidence_level=0.95,
            recommendations=[]
        )

要深入理解如何在 LLM 系统中实施护栏与安全边界,推荐阅读 LLM 护栏工程指南,其中的内容过滤与输出验证机制与偏差测试流水线高度互补。

人工监督与回路覆盖系统

第 14 条是欧盟 AI 法案中对工程实现影响最大的条款之一。它要求高风险 AI 系统必须设计为可由人类有效监督,包括:

  • 人类能够完全理解系统的能力和局限性
  • 人类能够正确解释系统的输出
  • 人类能够在任何时候决定不使用系统、忽略或推翻系统决策
  • 人类能够干预或中断系统运行

人工回路覆盖架构

flowchart TD A["AI系统推理请求"] --> B{"置信度检查"} B -->|"置信度 >= 阈值"| C{"敏感决策?"} B -->|"置信度 < 阈值"| D["强制人工审核"] C -->|否| E["自动执行 + 审计记录"] C -->|是| F["人工审核队列"] D --> F F --> G{"审核员决策"} G -->|同意| H["执行AI建议"] G -->|修改| I["执行修改后决策"] G -->|拒绝| J["丢弃AI输出"] H --> K["记录审核日志"] I --> K J --> K E --> K K --> L["上市后监控系统"]

人工回路覆盖实现

typescript
// human-oversight.ts - Article 14 Human Oversight System
interface HumanOversightConfig {
  confidenceThreshold: number;
  sensitiveDecisionTypes: string[];
  maxAutoDecisionsBeforeReview: number;
  escalationTimeoutMs: number;
  requiredApproverRole: string;
}

interface AIDecision {
  decisionId: string;
  systemOutput: any;
  confidenceScore: number;
  decisionType: string;
  affectedPersonIds: string[];
  explanation: string;
  featureContributions: Record<string, number>;
  timestamp: string;
}

interface HumanReview {
  reviewId: string;
  decisionId: string;
  reviewerId: string;
  reviewerRole: string;
  action: 'approve' | 'modify' | 'reject' | 'escalate';
  modifiedOutput?: any;
  justification: string;
  reviewTimestamp: string;
  timeToDecisionMs: number;
}

class HumanOversightGateway {
  private config: HumanOversightConfig;
  private autoDecisionCounter: Map<string, number> = new Map();
  private auditLogger: EUAIActAuditLogger;
  
  constructor(config: HumanOversightConfig, auditLogger: EUAIActAuditLogger) {
    this.config = config;
    this.auditLogger = auditLogger;
  }
  
  async processDecision(decision: AIDecision): Promise<{
    finalOutput: any;
    requiresHumanReview: boolean;
    reviewResult?: HumanReview;
  }> {
    const requiresReview = this.requiresHumanReview(decision);
    
    if (!requiresReview) {
      // Auto-approve but still log
      await this.auditLogger.logInference({
        input: decision.decisionId,
        output: decision.systemOutput,
        modelVersion: 'current',
        confidenceScore: decision.confidenceScore,
        featureImportance: decision.featureContributions,
        dataSubjectCategories: decision.affectedPersonIds.length > 0 
          ? ['natural_persons'] 
          : []
      });
      
      this.incrementAutoCounter(decision.decisionType);
      
      return {
        finalOutput: decision.systemOutput,
        requiresHumanReview: false
      };
    }
    
    // Route to human review
    const review = await this.requestHumanReview(decision);
    
    // Log the human override
    await this.auditLogger.logHumanOverride({
      originalEventId: decision.decisionId,
      operatorId: review.reviewerId,
      decision: review.action,
      reason: review.justification
    });
    
    // Reset auto-decision counter after human review
    this.autoDecisionCounter.set(decision.decisionType, 0);
    
    const finalOutput = review.action === 'modify' 
      ? review.modifiedOutput 
      : review.action === 'approve' 
        ? decision.systemOutput 
        : null;
    
    return {
      finalOutput,
      requiresHumanReview: true,
      reviewResult: review
    };
  }
  
  private requiresHumanReview(decision: AIDecision): boolean {
    // Rule 1: Below confidence threshold
    if (decision.confidenceScore < this.config.confidenceThreshold) {
      return true;
    }
    
    // Rule 2: Sensitive decision type
    if (this.config.sensitiveDecisionTypes.includes(decision.decisionType)) {
      return true;
    }
    
    // Rule 3: Max auto-decisions reached (periodic review)
    const counter = this.autoDecisionCounter.get(decision.decisionType) || 0;
    if (counter >= this.config.maxAutoDecisionsBeforeReview) {
      return true;
    }
    
    // Rule 4: Affects vulnerable persons
    if (decision.affectedPersonIds.length > 10) {
      return true;
    }
    
    return false;
  }
  
  private async requestHumanReview(decision: AIDecision): Promise<HumanReview> {
    // In production, this would integrate with a review queue system
    // (e.g., internal dashboard, Slack workflow, etc.)
    throw new Error(
      `Human review required for decision ${decision.decisionId}. ` +
      `Route to review queue with timeout ${this.config.escalationTimeoutMs}ms.`
    );
  }
  
  private incrementAutoCounter(decisionType: string): void {
    const current = this.autoDecisionCounter.get(decisionType) || 0;
    this.autoDecisionCounter.set(decisionType, current + 1);
  }
  
  // Article 14(4)(d) - "stop button" capability
  async emergencyStop(reason: string, operatorId: string): Promise<void> {
    await this.auditLogger.logHumanOverride({
      originalEventId: 'EMERGENCY_STOP',
      operatorId,
      decision: 'system_halt',
      reason
    });
    
    // Halt all pending decisions
    // Notify all affected operators
    // Preserve system state for investigation
  }
}

这一架构与 Prompt Engineering 中的"可控生成"理念一脉相承——通过工程手段确保 AI 输出始终在人类监督范围内。关于如何在工程层面构建完整的 AI 安全防护体系,参见 安全工程实践指南

合规性评估与 CE 标志

第 43 条规定了高风险 AI 系统获取 CE 标志的合规性评估程序。根据系统类型不同,评估方式分为自我评估(大多数情况)和第三方评估(远程生物识别等特定系统)。

合规性评估自动化检查

typescript
// compliance-assessment.ts - Article 43 Conformity Assessment
interface ConformityChecklist {
  systemId: string;
  assessmentDate: string;
  assessmentType: 'internal' | 'third_party';
  
  // Article 9: Risk Management System
  riskManagement: {
    riskIdentified: boolean;
    mitigationImplemented: boolean;
    residualRiskAcceptable: boolean;
    continuousMonitoring: boolean;
  };
  
  // Article 10: Data Governance
  dataGovernance: {
    trainingDataDocumented: boolean;
    biasExamined: boolean;
    dataQualityMetrics: boolean;
    representativenessVerified: boolean;
  };
  
  // Article 11: Technical Documentation
  technicalDocumentation: {
    annexIVComplete: boolean;
    modelCardGenerated: boolean;
    architectureDocumented: boolean;
    changeLogMaintained: boolean;
  };
  
  // Article 12: Record Keeping
  recordKeeping: {
    auditLogsEnabled: boolean;
    tamperEvident: boolean;
    retentionPolicySet: boolean;
    accessControlImplemented: boolean;
  };
  
  // Article 13: Transparency
  transparency: {
    instructionsForUse: boolean;
    capabilitiesDocumented: boolean;
    limitationsDocumented: boolean;
    humanReadableExplanations: boolean;
  };
  
  // Article 14: Human Oversight
  humanOversight: {
    oversightMechanismDesigned: boolean;
    stopMechanismAvailable: boolean;
    overridePossible: boolean;
    operatorTraining: boolean;
  };
  
  // Article 15: Accuracy, Robustness, Cybersecurity
  technicalRobustness: {
    accuracyMetricsDeclared: boolean;
    robustnessTestsPassed: boolean;
    cybersecurityAssessed: boolean;
    adversarialTestingDone: boolean;
  };
}

class ConformityAssessmentEngine {
  async runAssessment(systemId: string): Promise<{
    checklist: ConformityChecklist;
    overallResult: 'PASS' | 'FAIL' | 'PARTIAL';
    failedItems: string[];
    recommendations: string[];
  }> {
    const checklist = await this.gatherEvidence(systemId);
    const failedItems = this.identifyFailures(checklist);
    
    return {
      checklist,
      overallResult: failedItems.length === 0 ? 'PASS' : 
                     failedItems.length <= 3 ? 'PARTIAL' : 'FAIL',
      failedItems,
      recommendations: this.generateRecommendations(failedItems)
    };
  }
  
  private identifyFailures(checklist: ConformityChecklist): string[] {
    const failures: string[] = [];
    
    // Check each category
    const categories = [
      'riskManagement', 'dataGovernance', 'technicalDocumentation',
      'recordKeeping', 'transparency', 'humanOversight', 'technicalRobustness'
    ] as const;
    
    for (const category of categories) {
      const section = checklist[category];
      for (const [key, value] of Object.entries(section)) {
        if (value === false) {
          failures.push(`${category}.${key}`);
        }
      }
    }
    
    return failures;
  }
  
  private generateRecommendations(failures: string[]): string[] {
    const recommendations: string[] = [];
    
    if (failures.some(f => f.startsWith('recordKeeping'))) {
      recommendations.push(
        'Implement tamper-evident audit logging with chain hashing. ' +
        'See Article 12 middleware implementation.'
      );
    }
    
    if (failures.some(f => f.startsWith('dataGovernance'))) {
      recommendations.push(
        'Run bias testing pipeline and document training data provenance. ' +
        'Ensure demographic representation analysis per Article 10(3).'
      );
    }
    
    if (failures.some(f => f.startsWith('humanOversight'))) {
      recommendations.push(
        'Deploy human-in-the-loop gateway with confidence thresholds. ' +
        'Implement emergency stop mechanism per Article 14(4)(d).'
      );
    }
    
    return recommendations;
  }
  
  private async gatherEvidence(systemId: string): Promise<ConformityChecklist> {
    // In production, this queries various system components
    // to automatically verify compliance status
    throw new Error('Implementation depends on system architecture');
  }
}

使用 哈希生成器 可以对合规文档进行完整性校验,确保提交给监管机构的技术文档未被篡改。

AI 素养计划实施

第 4 条是最早生效的义务之一(2025 年 2 月 2 日),要求所有 AI 系统的提供者和部署者确保其员工具备充足的 AI 素养

AI 素养框架

yaml
# ai-literacy-program.yml - Article 4 AI Literacy Program
program:
  name: "EU AI Act Literacy Program"
  version: "2.0"
  effective_date: "2025-02-02"
  review_cycle: "quarterly"

target_audiences:
  - role: "developers"
    required_modules:
      - ai_fundamentals
      - bias_and_fairness
      - eu_ai_act_technical_requirements
      - secure_ai_development
      - testing_and_validation
    assessment_passing_score: 80
    recertification_months: 12
    
  - role: "product_managers"
    required_modules:
      - ai_fundamentals
      - risk_classification
      - eu_ai_act_business_impact
      - responsible_ai_governance
    assessment_passing_score: 75
    recertification_months: 12
    
  - role: "executives"
    required_modules:
      - ai_strategic_overview
      - eu_ai_act_business_impact
      - liability_and_penalties
      - governance_frameworks
    assessment_passing_score: 70
    recertification_months: 24
    
  - role: "human_reviewers"
    required_modules:
      - ai_fundamentals
      - understanding_ai_outputs
      - override_procedures
      - bias_recognition
      - documentation_requirements
    assessment_passing_score: 85
    recertification_months: 6

modules:
  ai_fundamentals:
    title: "AI基础知识"
    duration_hours: 4
    topics:
      - "机器学习基本概念"
      - "深度学习与神经网络"
      - "LLM工作原理"
      - "AI系统局限性"
    
  bias_and_fairness:
    title: "偏差与公平性"
    duration_hours: 6
    topics:
      - "算法偏差的来源"
      - "公平性度量标准"
      - "偏差检测方法"
      - "缓解策略"
    
  eu_ai_act_technical_requirements:
    title: "欧盟AI法案技术要求"
    duration_hours: 8
    topics:
      - "风险分类实操"
      - "附件IV文档要求"
      - "审计日志实现"
      - "人工监督设计模式"
      - "合规性评估流程"
    
  risk_classification:
    title: "风险分类决策"
    duration_hours: 3
    topics:
      - "四级风险体系"
      - "附件III高风险清单"
      - "例外条件判断"
      - "跨境适用规则"

compliance_tracking:
  database: "compliance_db"
  table: "ai_literacy_records"
  required_fields:
    - employee_id
    - module_completed
    - completion_date
    - assessment_score
    - certificate_expiry
  
  reporting:
    frequency: "monthly"
    recipients: ["compliance_officer", "cto", "hr_director"]
    include_metrics:
      - completion_rate_by_department
      - average_scores_by_role
      - overdue_recertifications
      - training_gap_analysis

AI 素养计划的核心在于让团队成员理解 AI 系统的能力边界。对于使用 RAG 架构的系统,开发者必须理解检索增强生成的局限性——它不能保证信息的完全准确性,这在高风险场景中尤为关键。

上市后监控体系

第 72 条要求高风险 AI 系统的提供者建立上市后监控(Post-Market Monitoring)体系,持续评估系统合规性。

监控系统架构

typescript
// post-market-monitoring.ts - Article 72 Post-Market Monitoring
interface MonitoringAlert {
  alertId: string;
  severity: 'critical' | 'high' | 'medium' | 'low';
  category: 'performance_degradation' | 'bias_drift' | 'security_incident' 
    | 'user_complaint' | 'adverse_event';
  description: string;
  detectedAt: string;
  affectedUsers: number;
  automaticActions: string[];
  requiredHumanAction: string;
}

interface MonitoringMetrics {
  // Performance metrics
  accuracyScore: number;
  precisionScore: number;
  recallScore: number;
  latencyP99Ms: number;
  
  // Fairness metrics
  demographicParityGap: number;
  equalizedOddsGap: number;
  
  // Operational metrics
  humanOverrideRate: number;
  userComplaintRate: number;
  systemAvailability: number;
  
  // Drift metrics
  dataDistributionDrift: number;
  predictionDistributionDrift: number;
  featureImportanceDrift: number;
}

class PostMarketMonitor {
  private alertThresholds: Record<string, number>;
  private baselineMetrics: MonitoringMetrics;
  
  constructor(baseline: MonitoringMetrics) {
    this.baselineMetrics = baseline;
    this.alertThresholds = {
      accuracy_drop: 0.05,
      bias_increase: 0.03,
      drift_threshold: 0.1,
      complaint_rate: 0.01,
      override_rate_increase: 0.15
    };
  }
  
  async evaluateMetrics(current: MonitoringMetrics): Promise<MonitoringAlert[]> {
    const alerts: MonitoringAlert[] = [];
    
    // Check accuracy degradation
    const accuracyDrop = this.baselineMetrics.accuracyScore - current.accuracyScore;
    if (accuracyDrop > this.alertThresholds.accuracy_drop) {
      alerts.push({
        alertId: crypto.randomUUID(),
        severity: accuracyDrop > 0.1 ? 'critical' : 'high',
        category: 'performance_degradation',
        description: `Accuracy dropped by ${(accuracyDrop * 100).toFixed(1)}% from baseline`,
        detectedAt: new Date().toISOString(),
        affectedUsers: 0,
        automaticActions: ['pause_auto_decisions', 'increase_human_review_rate'],
        requiredHumanAction: 'Investigate root cause and retrain if necessary'
      });
    }
    
    // Check bias drift
    const biasIncrease = current.demographicParityGap - this.baselineMetrics.demographicParityGap;
    if (biasIncrease > this.alertThresholds.bias_increase) {
      alerts.push({
        alertId: crypto.randomUUID(),
        severity: 'high',
        category: 'bias_drift',
        description: `Demographic parity gap increased by ${(biasIncrease * 100).toFixed(1)}%`,
        detectedAt: new Date().toISOString(),
        affectedUsers: 0,
        automaticActions: ['trigger_bias_audit', 'notify_dpo'],
        requiredHumanAction: 'Run full bias test suite and document findings'
      });
    }
    
    // Check data distribution drift
    if (current.dataDistributionDrift > this.alertThresholds.drift_threshold) {
      alerts.push({
        alertId: crypto.randomUUID(),
        severity: 'medium',
        category: 'performance_degradation',
        description: `Data distribution drift detected: ${current.dataDistributionDrift.toFixed(3)}`,
        detectedAt: new Date().toISOString(),
        affectedUsers: 0,
        automaticActions: ['log_drift_event', 'schedule_retrain_evaluation'],
        requiredHumanAction: 'Evaluate whether model retraining is required'
      });
    }
    
    // Check human override rate spike
    const overrideIncrease = current.humanOverrideRate - this.baselineMetrics.humanOverrideRate;
    if (overrideIncrease > this.alertThresholds.override_rate_increase) {
      alerts.push({
        alertId: crypto.randomUUID(),
        severity: 'medium',
        category: 'performance_degradation',
        description: `Human override rate increased by ${(overrideIncrease * 100).toFixed(1)}%`,
        detectedAt: new Date().toISOString(),
        affectedUsers: 0,
        automaticActions: ['analyze_override_patterns'],
        requiredHumanAction: 'Review override reasons and assess model fitness'
      });
    }
    
    return alerts;
  }
  
  // Article 72(2): Serious incident reporting to authorities
  async reportSeriousIncident(incident: {
    description: string;
    affectedPersons: number;
    harmType: string;
    immediateActions: string[];
  }): Promise<string> {
    // Must report within 15 days of becoming aware
    const report = {
      reportId: crypto.randomUUID(),
      reportDate: new Date().toISOString(),
      deadline: this.calculateReportingDeadline(),
      ...incident
    };
    
    // Submit to EU AI database
    // Notify national market surveillance authority
    return report.reportId;
  }
  
  private calculateReportingDeadline(): string {
    const deadline = new Date();
    deadline.setDate(deadline.getDate() + 15);
    return deadline.toISOString();
  }
}

关于如何在工程层面建立完整的安全与合规体系,可以参考 安全工程完整指南,其中涵盖了从威胁建模到持续监控的全生命周期实践。

通用人工智能模型义务

第 51-56 条对通用人工智能模型(GPAI)提出了额外要求。如果你在开发或部署基于 LLM 的产品,这些条款直接适用。

GPAI 合规清单

typescript
// gpai-compliance.ts - Articles 51-56 GPAI Model Obligations
interface GPAIModelCompliance {
  // Article 53: General obligations
  technicalDocumentation: {
    modelArchitecture: boolean;        // Detailed architecture description
    trainingProcess: boolean;          // Training methodology and resources
    evaluationResults: boolean;        // Benchmark results
    knownLimitations: boolean;         // Documented limitations
    energyConsumption: boolean;        // Training energy usage reported
  };
  
  // Copyright compliance
  copyrightPolicy: {
    trainingDataCopyrightAnalysis: boolean;
    optOutMechanismImplemented: boolean;  // Article 53(1)(c)
    detailedSummaryOfTrainingData: boolean;
    euCopyrightDirectiveCompliance: boolean;
  };
  
  // Downstream provider support
  downstreamSupport: {
    sufficientInfoProvided: boolean;
    integrationGuidelines: boolean;
    complianceDocumentation: boolean;
  };
  
  // Systemic risk (for models with high impact)
  systemicRisk?: {
    modelEvaluationPerformed: boolean;  // Article 55
    adversarialTestingDone: boolean;
    riskMitigationPlan: boolean;
    incidentReportingProcess: boolean;
    cybersecurityMeasures: boolean;
  };
}

// Threshold for systemic risk classification
const SYSTEMIC_RISK_THRESHOLD = {
  trainingComputeFLOPS: 10e25,  // 10^25 FLOPS
  euUsersThreshold: 10_000_000,
  highImpactCapabilities: [
    'code_generation',
    'scientific_reasoning',
    'multilingual',
    'multimodal'
  ]
};

function isSystemicRiskModel(modelProfile: {
  trainingCompute: number;
  euUsers: number;
  capabilities: string[];
}): boolean {
  if (modelProfile.trainingCompute >= SYSTEMIC_RISK_THRESHOLD.trainingComputeFLOPS) {
    return true;
  }
  
  // Commission can designate based on other criteria
  if (modelProfile.euUsers >= SYSTEMIC_RISK_THRESHOLD.euUsersThreshold) {
    return true; // Likely to be designated
  }
  
  return false;
}

对于使用 向量数据库 构建 RAG 系统的开发者,GPAI 义务意味着你需要记录检索数据源的版权合规状态,并为下游用户提供充分的系统行为说明文档。

处罚体系与执法机制

欧盟 AI 法案建立了分级处罚体系,处罚金额之高在全球 AI 监管法规中前所未有:

违规类型 最高罚款 计算方式
禁止实践违规 3500 万欧元 或全球年营收 7%(取较高者)
高风险系统不合规 1500 万欧元 或全球年营收 3%
向监管机构提供虚假信息 750 万欧元 或全球年营收 1%
中小企业 按比例降低 具体由成员国确定

长臂管辖的工程影响

python
# jurisdiction_check.py - Extraterritorial application check
from dataclasses import dataclass
from typing import List

@dataclass
class JurisdictionAnalysis:
    subject_to_eu_ai_act: bool
    applicable_articles: List[str]
    reason: str
    recommended_actions: List[str]

def check_eu_ai_act_applicability(
    company_registration: str,      # Country of registration
    ai_output_used_in_eu: bool,     # Whether outputs affect EU persons
    eu_users_count: int,            # Number of EU-based users
    ai_system_type: str,            # Type of AI system
    data_subjects_in_eu: bool       # Whether processes EU personal data
) -> JurisdictionAnalysis:
    """
    Article 2 - Scope: The regulation applies to:
    1. Providers placing AI systems on EU market (regardless of location)
    2. Deployers within the EU
    3. Providers/deployers in third countries where output is used in EU
    """
    
    reasons = []
    applicable_articles = []
    
    # Territorial scope check
    if ai_output_used_in_eu:
        reasons.append(
            "AI system output is used within the EU territory "
            "(Article 2(1)(c) - extraterritorial application)"
        )
        applicable_articles.append("Article 2(1)(c)")
    
    if eu_users_count > 0:
        reasons.append(
            f"System has {eu_users_count} EU-based users"
        )
        applicable_articles.append("Article 2(1)(a)")
    
    if data_subjects_in_eu:
        reasons.append(
            "Processes personal data of EU data subjects"
        )
        applicable_articles.append("Article 2(1)(a)")
    
    subject_to_act = len(reasons) > 0
    
    recommended_actions = []
    if subject_to_act:
        recommended_actions = [
            "Appoint EU authorized representative (Article 22)",
            "Register in EU AI database (Article 49)",
            "Implement full compliance framework",
            "Conduct conformity assessment before August 2026",
            "Establish post-market monitoring system"
        ]
    
    return JurisdictionAnalysis(
        subject_to_eu_ai_act=subject_to_act,
        applicable_articles=applicable_articles,
        reason=" | ".join(reasons) if reasons else "Not subject to EU AI Act",
        recommended_actions=recommended_actions
    )


# Example: Chinese company with global AI product
result = check_eu_ai_act_applicability(
    company_registration="CN",
    ai_output_used_in_eu=True,  # EU users receive AI-generated content
    eu_users_count=50000,
    ai_system_type="recommendation_system",
    data_subjects_in_eu=True
)

print(f"Subject to EU AI Act: {result.subject_to_eu_ai_act}")
# Output: Subject to EU AI Act: True

关于 AI 系统的安全攻击面分析与防御策略,建议参阅 LLM 越狱分析与防御,在合规的同时也需要防范恶意利用。

实施路线图:从现在到合规

对于正在出海的中国 AI 开发团队,以下是建议的合规实施路线图:

第一阶段:评估与规划(立即开始 - 4 周)

  1. 风险分类评估:使用本文的风险分类器确定你的系统风险等级
  2. 差距分析:对照合规性评估清单,识别当前缺失项
  3. 资源规划:确定需要的工程资源与外部支持
  4. 法律顾问对接:聘请具有 EU AI Act 经验的法律团队

第二阶段:基础设施建设(4-12 周)

  1. 审计日志系统:部署本文的审计中间件
  2. 偏差测试流水线:集成 CI/CD 偏差检测
  3. 模型卡片自动化:实现自动生成与版本管理
  4. 人工监督网关:构建人工回路覆盖系统

第三阶段:文档与培训(12-20 周)

  1. 附件四文档编写:完成全部 9 类技术文档
  2. FRIA 评估:执行基本权利影响评估
  3. AI 素养培训:全员完成对应角色的培训课程
  4. 内部审核:模拟合规性评估

第四阶段:验证与上线(20-26 周)

  1. 合规性评估:执行正式的合规性评估程序
  2. 第三方审核(如适用):对接公告机构
  3. CE 标志申请:完成 EU 合格声明
  4. 上市后监控部署:启动持续监控系统

使用 正则表达式测试工具 可以帮助你验证日志格式规则与数据脱敏模式是否正确匹配。同时,文本对比工具 在技术文档版本管理中非常有用,可以精确追踪每次修改的内容差异。

与 GDPR 的协同

欧盟 AI 法案不是孤立存在的,它与 GDPR 形成互补关系:

维度 GDPR EU AI Act
监管对象 个人数据处理 AI 系统本身
权利主体 数据主体 受 AI 决策影响的人
关键权利 数据访问、删除、可携带 解释权、人工审核权、投诉权
合规评估 DPIA(数据保护影响评估) FRIA(基本权利影响评估)
文档要求 处理记录(Article 30) 技术文档(Annex IV)
跨境机制 标准合同条款 EU 授权代表 + CE 标志

两者的合规工作有大量重叠——如果你已经为 GDPR 建设了数据治理基础设施,许多组件可以直接复用于 EU AI Act 合规。

工程合规检查清单

在你的 AI 系统上线前,使用以下清单进行最终检查:

yaml
# compliance-checklist.yml - Pre-launch verification
pre_launch_checklist:
  risk_classification:
    - system_risk_level_determined: false
    - prohibited_practices_excluded: false
    - annex_iii_mapping_complete: false
    
  technical_documentation:
    - model_card_generated: false
    - architecture_documented: false
    - training_data_provenance: false
    - performance_benchmarks: false
    - risk_assessment_complete: false
    
  audit_logging:
    - logging_middleware_deployed: false
    - tamper_evident_chain: false
    - retention_policy_configured: false
    - access_control_verified: false
    
  bias_testing:
    - demographic_parity_tested: false
    - equalized_odds_tested: false
    - disparate_impact_checked: false
    - ci_cd_pipeline_integrated: false
    
  human_oversight:
    - confidence_threshold_set: false
    - override_mechanism_tested: false
    - emergency_stop_verified: false
    - operator_training_complete: false
    
  transparency:
    - user_notification_implemented: false
    - explanation_mechanism_available: false
    - limitations_documented: false
    
  post_market:
    - monitoring_system_deployed: false
    - alert_thresholds_configured: false
    - incident_reporting_process: false
    - periodic_review_scheduled: false
    
  organizational:
    - eu_representative_appointed: false
    - ai_literacy_program_launched: false
    - quality_management_system: false
    - fria_completed: false
    - ce_marking_documentation: false

合规实践提示:在实现合规性日志记录时,审计追踪数据通常以 JSON 格式存储。在进行内部合规性审查时,可以使用 JSON 格式化工具 来确保日志结构清晰、易于阅读。

延伸阅读

常见问题

我们的 AI 产品只有少量欧盟用户,是否需要合规?

是的。欧盟 AI 法案采用效果主义原则(Article 2(1)(c))——只要 AI 系统的输出在欧盟境内被使用,无论用户数量多少,都受法规约束。从工程角度,建议在系统架构初期就内置合规能力,因为后期改造的成本远高于前期设计。即使目前只有少量欧盟用户,如果你的产品面向全球市场,合规投入可以视为对未来增长的基础设施投资。

附件四技术文档是否可以用中文编写?

根据 Article 11(2),技术文档必须以市场监管机构能够理解的语言编写。实践中,建议使用英语作为主要语言(大多数欧盟国家监管机构接受英语),并准备目标市场成员国官方语言版本。文档的自动生成可以用中文编写代码注释和内部文档,但最终提交版必须是英文或目标国语言。

使用第三方 API(如 OpenAI、Claude)构建的产品,合规责任如何分配?

根据 AI 法案的角色定义,API 提供方(如 OpenAI)承担 GPAI 模型提供者的义务(Article 53-56),而你作为下游提供者(downstream provider)仍然承担最终产品的高风险系统义务。这意味着你不能仅依赖上游模型提供商的合规声明,还必须针对你的特定用例进行独立的偏差测试、风险评估和技术文档编写。使用 JWT 生成器 确保与第三方 API 的通信安全也是合规链条的一环。

偏差测试需要覆盖哪些受保护属性?

根据 Article 10(2)(f) 和 EU Charter of Fundamental Rights (Article 21),受保护属性包括但不限于:性别、种族/民族、宗教信仰、残障状况、年龄、性取向。具体到你的产品,需要根据使用场景和影响人群确定最相关的属性进行测试。例如,信贷评分系统必须测试种族和性别维度;招聘系统必须测试性别、年龄和残障维度。建议参考 Fairlearn 和 Aequitas 等开源框架的默认属性集作为起点。

如何处理"AI 素养"义务?这是强制性的吗?

是的,Article 4 的 AI 素养义务已于 2025 年 2 月 2 日生效,是强制性要求而非建议。法案要求提供者和部署者"采取措施在最大可能范围内确保其工作人员以及代表其处理 AI 系统运作和使用的其他人员具有充足的 AI 素养"。从工程管理角度,这意味着你需要:(1) 建立角色化培训矩阵;(2) 记录培训完成情况作为合规证据;(3) 定期更新培训内容以反映法规变化。无法证明团队 AI 素养的企业在监管检查中将处于不利地位。

总结

欧盟 AI 法案对出海开发者而言既是挑战也是机遇。它建立的合规框架虽然严格,但通过工程化手段可以系统性地满足。关键在于:

  1. 尽早分类:明确你的系统风险等级,避免过度合规或合规不足
  2. 自动化优先:将合规要求嵌入 CI/CD 流水线,而不是依赖手动检查
  3. 文档即代码:技术文档应从代码和 MLOps 系统自动生成
  4. 持续监控:合规不是一次性事件,而是持续过程

2026 年 8 月 2 日的截止日近在咫尺。现在行动,你还有时间从容构建合规基础设施;拖延到最后,将面临仓促改造的高成本与高风险。