核心摘要
欧盟《人工智能法案》(EU AI Act)采用分阶段、按角色和风险适用的框架。第三国团队需要根据提供者/部署者角色、是否在欧盟投放或部署、以及输出使用事实,结合现行法案文本和官方指南建立适用性记录。
本文从工程角度提供一份证据与控制映射清单;示例代码是示意骨架,不构成法律意见,也不能单独完成合规性评估。
核心要点
- 时间线需核验:不同义务有不同生效日和过渡规则,应以 Article 113、合并文本和官方指南为准
- 四级风险分类:不可接受风险(禁止)→ 高风险 → 有限风险 → 最小风险,每级对应不同的合规义务
- 附件四技术文档:按具体系统维护版本化证据,不应简化成固定数量的模型卡片字段
- 工程化合规:通过中间件、CI/CD 流水线、自动化测试将合规要求融入开发流程
- 适用范围依赖事实:不能仅凭公司注册地、服务器位置或用户数量下结论
执行时间线与里程碑
欧盟 AI 法案的执行采用分阶段生效策略,开发者必须清楚每个节点的义务范围:
| 日期 | 义务范围 | 影响对象 |
|---|---|---|
| 2025-02-02 | 禁止实践 + AI 素养相关义务 | 按适用角色与阶段规则核对 |
| 2025-08-02 | GPAI 模型义务 | 通用人工智能模型提供者 |
| 2026-08-02 | 部分高风险 AI 系统相关规定 | 按 Article 113 与过渡规则核对 |
| 2027-08-02 | 产品嵌入式 AI 系统 | 作为产品安全组件的 AI 系统 |
如果系统涉及信贷评估、招聘筛选、医疗或其他 Annex III 相关用途,应立即建立适用性、角色、风险和证据记录;不要用单一日期替代法律分析。
风险分类决策树
欧盟 AI 法案采用风险分层,但第一步应是记录适用范围、角色和预期用途,再核对 Article 5、Article 6、Annex III 及例外条件。
禁止实践清单(不可接受风险)
以下是需要重点核对的禁止实践示例;具体边界、例外和定义必须回到 Article 5 及其最新指南:
// 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 系统需要结合预期用途、角色、产品安全路径和 Article 6/Annex III 条件判断。以下是常见相关领域:
- 生物特征识别与分类:远程生物识别系统
- 关键基础设施管理:电力、水务、交通的 AI 调度
- 教育与职业培训:录取决策、考试评分、学习监控
- 就业与人力管理:简历筛选、面试评估、绩效评定
- 基本服务准入:信贷评分、保险定价、社会福利
- 执法:犯罪风险评估、证据分析
- 移民与边境管控:签证评估、风险预警
- 司法行政:法律研究辅助、量刑建议
如果你的 LLM 应用涉及以上领域,应记录具体用途并进行法律复核,不能仅凭关键词自动认定为高风险。
附件四技术文档要求
第 11 条与附件四规定了适用高风险系统的技术文档信息范围。以下表格是工程映射示例,不是固定的“九大类别”或完整提交模板。
文档覆盖范围
| 序号 | 文档类别 | 核心内容 | 工程实现方式 |
|---|---|---|---|
| 1 | 系统总体描述 | 预期用途、开发者信息、版本号 | 自动化模型卡片 |
| 2 | 系统架构 | 算法逻辑、计算资源、硬件依赖 | 架构即代码 |
| 3 | 开发过程 | 训练方法、数据集来源、超参选择 | MLOps 流水线记录 |
| 4 | 监控与测试 | 性能指标、测试方法、验证结果 | CI/CD 测试报告 |
| 5 | 风险管理 | 已知风险、缓解措施、残余风险 | 风险登记簿 |
| 6 | 变更记录 | 版本变更历史、影响评估 | Git 提交 + 变更日志 |
| 7 | 标准合规 | 引用的协调标准、合规声明 | 合规矩阵 |
| 8 | EU 合格声明 | CE 标志文档 | 自动生成模板 |
| 9 | 上市后信息 | 事故报告、投诉处理、召回记录 | 事件管理系统 |
模型卡片自动生成
技术文档的核心是模型卡片(Model Card),它必须随每次模型更新自动生成:
# 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 结构校验只是工程质量检查,不是合规证明。
审计日志中间件实现
第 12 条要求适用的高风险 AI 系统具备自动记录事件的能力。日志内容、完整性、访问、隐私和留存应结合系统用途与适用法律设计;哈希链本身不是“不可篡改”或合规证明。
日志记录要求
根据法案第 12 条,日志系统必须满足以下要求:
- 记录系统运行的每个周期的开始和结束时间
- 输入数据的参考或标识
- 生成输出的具体内容
- 相关的人工监督干预事件
- 保留期限与系统预期寿命匹配
审计日志中间件
// 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
// Retention is a policy decision tied to purpose, applicable law,
// incident handling, and deletion requirements; it is not a universal
// EU AI Act five-year default.
throw new Error('Configure retention from the system purpose, applicable law, and deletion policy');
}
}
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>;
}
审计日志应在配置管理阶段完成结构校验、唯一标识、访问控制和留存策略检查;这些工程控制不能单独证明符合法案。
基本权利影响评估实现
第 27 条要求特定高风险系统的部署者在首次使用前完成基本权利影响评估(Fundamental Rights Impact Assessment,FRIA)。它与 GDPR DPIA 有关联但不可互相替代,适用性和内容应按部署者角色与条文核对。
FRIA 评估框架
// 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 条涉及数据治理与数据质量要求,但法案没有规定统一的偏差指标或 0.8/0.1 等通过阈值。以下数字只是策略占位符,生产评测还需要来源、缺失群体、置信区间、用途分析和人工复核。
偏差检测 CI/CD 集成
# .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
偏差检测核心逻辑
# 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())
# 这是一个可选的政策指标,不是 EU AI Act 的通用法律门槛。
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 the configured policy threshold. "
f"Requires legal and domain review; it is not a legal conclusion."
)
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 系统必须设计为可由人类有效监督,包括:
- 人类能够完全理解系统的能力和局限性
- 人类能够正确解释系统的输出
- 人类能够在任何时候决定不使用系统、忽略或推翻系统决策
- 人类能够干预或中断系统运行
人工回路覆盖架构
人工回路覆盖实现
// 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 标志的合规性评估程序。根据系统类型不同,评估方式分为自我评估(大多数情况)和第三方评估(远程生物识别等特定系统)。
合规性评估自动化检查
// 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 条建立了提供者和部署者的 AI 素养义务,但适用时间、人员范围和“充足”的判断应结合阶段性生效规则及具体情境核对;法案没有规定统一培训小时数。
AI 素养框架
# 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)体系,持续评估系统合规性。
监控系统架构
下方指标、阈值和周期只是运行监控示例,不是法定门槛或统一留存期限,应按预期用途、风险、数据质量和事故流程校准。
// 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 合规清单
// 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;
};
}
// Systemic-risk status is not determined by a universal user-count or
// training-compute threshold in this application code. Check the current
// GPAI provisions, Commission designation, and provider evidence instead.
对于使用 向量数据库 构建 RAG 系统的开发者,GPAI 义务意味着你需要记录检索数据源的版权合规状态,并为下游用户提供充分的系统行为说明文档。
处罚体系与执法机制
欧盟 AI 法案建立了分级处罚体系,处罚金额之高在全球 AI 监管法规中前所未有:
| 违规类型 | 法案中的最高罚款层级 | 备注 | | 禁止实践等严重违规 | 需核对 Article 99 当前文本 | 受主体类型、计算口径和程序规则影响 | | 其他义务违规 | 需核对 Article 99 当前文本 | 不应直接当作实际罚款 | | 向监管机构提供不正确信息 | 需核对 Article 99 当前文本 | 适用范围和主体规则需复核 |
长臂管辖的工程影响
# jurisdiction_check.py - Extraterritorial application check
from dataclasses import dataclass
from typing import List, Optional
@dataclass
class JurisdictionAnalysis:
subject_to_eu_ai_act: Optional[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:
"""Engineering triage only. Confirm Article 2 with legal counsel.
The result depends on provider/deployer role, market placement,
deployment location, output use, and applicable transitional rules.
"""
reasons = []
applicable_articles = []
# Territorial scope check
if ai_output_used_in_eu:
reasons.append("Output-use fact requires Article 2 applicability review")
if eu_users_count > 0:
reasons.append(
f"System has {eu_users_count} EU-based users"
)
if data_subjects_in_eu:
reasons.append(
"Processes personal data of EU data subjects"
)
# Presence of EU users or data is a review signal, not an automatic
# legal conclusion. Resolve the role and Article 2 facts with counsel.
subject_to_act = None
recommended_actions = []
if reasons:
recommended_actions = [
"Map provider/deployer role and Article 2 facts",
"Check whether registration or an EU representative duty applies",
"Classify intended purpose under Article 5, Article 6 and Annex III",
"Record applicable dates and transition rules",
"Escalate to legal and domain review before deployment"
]
return JurisdictionAnalysis(
subject_to_eu_ai_act=subject_to_act,
applicable_articles=applicable_articles,
reason=" | ".join(reasons) if reasons else "Insufficient facts; obtain an applicability review",
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"EU AI Act applicability result: {result.subject_to_eu_ai_act}")
# Output: None means the engineering helper deliberately does not decide.
关于 AI 系统的安全攻击面分析与防御策略,建议参阅 LLM 越狱分析与防御,在合规的同时也需要防范恶意利用。
实施路线图:从现在到合规
对于正在出海的中国 AI 开发团队,以下是建议的合规实施路线图:
第一阶段:评估与规划(立即开始 - 4 周)
- 风险分类评估:使用本文的风险分类器确定你的系统风险等级
- 差距分析:对照合规性评估清单,识别当前缺失项
- 资源规划:确定需要的工程资源与外部支持
- 法律顾问对接:聘请具有 EU AI Act 经验的法律团队
第二阶段:基础设施建设(4-12 周)
- 审计日志系统:部署本文的审计中间件
- 偏差测试流水线:集成 CI/CD 偏差检测
- 模型卡片自动化:实现自动生成与版本管理
- 人工监督网关:构建人工回路覆盖系统
第三阶段:文档与培训(12-20 周)
- 附件四文档编写:完成全部 9 类技术文档
- FRIA 评估:执行基本权利影响评估
- AI 素养培训:全员完成对应角色的培训课程
- 内部审核:模拟合规性评估
第四阶段:验证与上线(20-26 周)
- 合规性评估:执行正式的合规性评估程序
- 第三方审核(如适用):对接公告机构
- CE 标志申请:完成 EU 合格声明
- 上市后监控部署:启动持续监控系统
日志格式、脱敏规则和技术文档版本应通过项目已有的测试与版本控制流程验证;正则匹配或文本差异都不能替代法规适用性判断。
与 GDPR 的协同
欧盟 AI 法案不是孤立存在的,它与 GDPR 形成互补关系:
| 维度 | GDPR | EU AI Act |
|---|---|---|
| 监管对象 | 个人数据处理 | AI 系统本身 |
| 权利主体 | 数据主体 | 受 AI 决策影响的人 |
| 关键权利 | 数据访问、删除、可携带 | 解释权、人工审核权、投诉权 |
| 合规评估 | DPIA(数据保护影响评估) | FRIA(基本权利影响评估) |
| 文档要求 | 处理记录(Article 30) | 技术文档(Annex IV) |
| 跨境机制 | 标准合同条款 | EU 授权代表 + CE 标志 |
两者的合规工作有大量重叠——如果你已经为 GDPR 建设了数据治理基础设施,许多组件可以直接复用于 EU AI Act 合规。
工程合规检查清单
在你的 AI 系统上线前,使用以下清单进行最终检查:
# 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 结构清晰不等于日志具备充分的来源、完整性、访问控制、留存和删除治理。
延伸阅读
- 了解更多关于构建安全 AI 系统的内容,请阅读 LLM 护栏工程指南。
- 关于企业级安全集成的实践,可以参考 MCP 远程 Server OAuth 集成实战。
常见问题
我们的 AI 产品只有少量欧盟用户,是否需要合规?
不一定。应根据 Article 2 的提供者/部署者角色、投放或部署地点、输出使用事实和过渡规则建立适用性记录;少量欧盟用户本身不能替代这项分析。
附件四技术文档是否可以用中文编写?
技术文档的语言要求应以 Article 11、主管机构要求和具体合格评定路径为准。不要假定所有成员国都接受英语;应准备监管机构能够理解的版本,并保留翻译、版本和责任人记录。
使用第三方 API(如 OpenAI、Claude)构建的产品,合规责任如何分配?
根据 AI 法案的角色定义,上游 GPAI 提供者、下游提供者和部署者的义务需要按具体事实拆分。不能只依赖上游声明,还要针对自身用途保留适用性、风险、评测和技术文档证据;API 认证安全是独立的工程问题,不由某个生成工具解决。
偏差测试需要覆盖哪些受保护属性?
根据 Article 10(2)(f) 和 EU Charter of Fundamental Rights (Article 21),受保护属性包括但不限于:性别、种族/民族、宗教信仰、残障状况、年龄、性取向。具体到你的产品,需要根据使用场景和影响人群确定最相关的属性进行测试。例如,信贷评分系统必须测试种族和性别维度;招聘系统必须测试性别、年龄和残障维度。建议参考 Fairlearn 和 Aequitas 等开源框架的默认属性集作为起点。
如何处理"AI 素养"义务?这是强制性的吗?
法案要求提供者和部署者在适用范围内采取措施,确保参与系统运行和使用的人员具备与情境相称的 AI 素养。工程上可以建立角色化能力矩阵和培训记录,但不要把自定义分数或培训小时数当作法定门槛。
总结
欧盟 AI 法案对出海开发者而言既是挑战也是机遇。它建立的合规框架虽然严格,但通过工程化手段可以系统性地满足。关键在于:
- 先做适用性与分类:记录角色、用途、法律路径、例外和判断依据
- 证据可追溯:将日志、评测、风险控制和版本变更与责任人、访问和留存策略关联
- 自动化但不自动合规:CI/CD 可以生成证据,不能替代法律复核和人工决策
- 持续监控:合规不是一次性事件,而是持续过程
日期和义务应以当前合并法案文本、过渡规则与官方指南复核。工程控制可以形成证据,但不能单独证明法律合规。