NAC_Blockchain/nac-ai-compliance/src/ai_validator.rs

459 lines
13 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//! AI验证器模块
//!
//! 实现KYC、AML、风险评估和智能决策引擎
use crate::compliance_layer::*;
use crate::error::*;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use async_trait::async_trait;
/// 合规数据
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ComplianceData {
/// 用户ID
pub user_id: String,
/// 资产ID
pub asset_id: Option<String>,
/// 数据字段
pub fields: HashMap<String, serde_json::Value>,
/// 元数据
pub metadata: HashMap<String, String>,
}
impl ComplianceData {
/// 创建新的合规数据
pub fn new(user_id: String) -> Self {
Self {
user_id,
asset_id: None,
fields: HashMap::new(),
metadata: HashMap::new(),
}
}
/// 设置资产ID
pub fn with_asset_id(mut self, asset_id: String) -> Self {
self.asset_id = Some(asset_id);
self
}
/// 添加字段
pub fn add_field<T: Serialize>(&mut self, key: String, value: T) -> Result<()> {
self.fields.insert(key, serde_json::to_value(value)?);
Ok(())
}
/// 获取字段
pub fn get_field<T: for<'de> Deserialize<'de>>(&self, key: &str) -> Result<Option<T>> {
match self.fields.get(key) {
Some(value) => Ok(Some(serde_json::from_value(value.clone())?)),
None => Ok(None),
}
}
/// 添加元数据
pub fn add_metadata(&mut self, key: String, value: String) {
self.metadata.insert(key, value);
}
}
/// AI验证器trait
#[async_trait]
pub trait AIValidator: Send + Sync {
/// 验证数据
async fn validate(&self, data: &ComplianceData) -> Result<ComplianceResult>;
/// 获取验证器名称
fn name(&self) -> &str;
/// 获取验证器版本
fn version(&self) -> &str;
}
/// KYC验证器
pub struct KYCValidator {
/// 最小置信度阈值
min_confidence: f64,
}
impl KYCValidator {
/// 创建新的KYC验证器
pub fn new() -> Self {
Self {
min_confidence: 0.8,
}
}
/// 设置最小置信度
pub fn with_min_confidence(mut self, confidence: f64) -> Self {
self.min_confidence = confidence;
self
}
/// 验证身份文件
fn verify_identity_documents(&self, data: &ComplianceData) -> Result<f64> {
// 模拟AI模型验证身份文件
// 实际实现应调用真实的AI模型
let has_passport: bool = data.get_field("has_passport")?.unwrap_or(false);
let has_id_card: bool = data.get_field("has_id_card")?.unwrap_or(false);
let has_driver_license: bool = data.get_field("has_driver_license")?.unwrap_or(false);
let mut confidence = 0.0;
if has_passport { confidence += 0.4; }
if has_id_card { confidence += 0.3; }
if has_driver_license { confidence += 0.3; }
Ok(confidence)
}
/// 验证地址证明
fn verify_address_proof(&self, data: &ComplianceData) -> Result<f64> {
let has_utility_bill: bool = data.get_field("has_utility_bill")?.unwrap_or(false);
let has_bank_statement: bool = data.get_field("has_bank_statement")?.unwrap_or(false);
let mut confidence = 0.0;
if has_utility_bill { confidence += 0.5; }
if has_bank_statement { confidence += 0.5; }
Ok(confidence)
}
}
impl Default for KYCValidator {
fn default() -> Self {
Self::new()
}
}
#[async_trait]
impl AIValidator for KYCValidator {
async fn validate(&self, data: &ComplianceData) -> Result<ComplianceResult> {
let identity_confidence = self.verify_identity_documents(data)?;
let address_confidence = self.verify_address_proof(data)?;
let confidence = (identity_confidence + address_confidence) / 2.0;
let (status, risk_level) = if confidence >= self.min_confidence {
(ComplianceStatus::Passed, RiskLevel::Low)
} else if confidence >= 0.6 {
(ComplianceStatus::ConditionalPass, RiskLevel::Medium)
} else if confidence >= 0.4 {
(ComplianceStatus::ManualReview, RiskLevel::High)
} else {
(ComplianceStatus::Failed, RiskLevel::Critical)
};
let mut issues = Vec::new();
if identity_confidence < 0.5 {
issues.push(ComplianceIssue {
code: "KYC001".to_string(),
description: "身份文件验证不足".to_string(),
severity: IssueSeverity::Warning,
regulations: vec!["KYC规范".to_string()],
});
}
Ok(ComplianceResult {
layer: ComplianceLayer::IdentityVerification,
status,
confidence,
risk_level,
details: format!("KYC验证完成置信度: {:.2}", confidence),
issues,
recommendations: vec!["建议提供更多身份证明文件".to_string()],
timestamp: chrono::Utc::now(),
})
}
fn name(&self) -> &str {
"KYC Validator"
}
fn version(&self) -> &str {
"1.0.0"
}
}
/// AML验证器
pub struct AMLValidator {
/// 风险阈值
risk_threshold: f64,
}
impl AMLValidator {
/// 创建新的AML验证器
pub fn new() -> Self {
Self {
risk_threshold: 0.7,
}
}
/// 检查黑名单
fn check_blacklist(&self, data: &ComplianceData) -> Result<bool> {
// 模拟检查黑名单
let is_blacklisted: bool = data.get_field("is_blacklisted")?.unwrap_or(false);
Ok(is_blacklisted)
}
/// 检查交易模式
fn check_transaction_pattern(&self, data: &ComplianceData) -> Result<f64> {
// 模拟AI模型分析交易模式
let transaction_count: u32 = data.get_field("transaction_count")?.unwrap_or(0);
let high_value_count: u32 = data.get_field("high_value_count")?.unwrap_or(0);
let risk_score = if transaction_count > 100 && high_value_count > 10 {
0.8
} else if transaction_count > 50 {
0.5
} else {
0.2
};
Ok(risk_score)
}
}
impl Default for AMLValidator {
fn default() -> Self {
Self::new()
}
}
#[async_trait]
impl AIValidator for AMLValidator {
async fn validate(&self, data: &ComplianceData) -> Result<ComplianceResult> {
let is_blacklisted = self.check_blacklist(data)?;
let risk_score = self.check_transaction_pattern(data)?;
let (status, risk_level, confidence) = if is_blacklisted {
(ComplianceStatus::Failed, RiskLevel::Critical, 0.0)
} else if risk_score >= self.risk_threshold {
(ComplianceStatus::ManualReview, RiskLevel::High, 0.3)
} else if risk_score >= 0.5 {
(ComplianceStatus::ConditionalPass, RiskLevel::Medium, 0.6)
} else {
(ComplianceStatus::Passed, RiskLevel::Low, 0.9)
};
let mut issues = Vec::new();
if is_blacklisted {
issues.push(ComplianceIssue {
code: "AML001".to_string(),
description: "用户在黑名单中".to_string(),
severity: IssueSeverity::Critical,
regulations: vec!["反洗钱法".to_string()],
});
}
Ok(ComplianceResult {
layer: ComplianceLayer::IdentityVerification,
status,
confidence,
risk_level,
details: format!("AML验证完成风险评分: {:.2}", risk_score),
issues,
recommendations: if risk_score > 0.5 {
vec!["建议进行人工审核".to_string()]
} else {
vec![]
},
timestamp: chrono::Utc::now(),
})
}
fn name(&self) -> &str {
"AML Validator"
}
fn version(&self) -> &str {
"1.0.0"
}
}
/// 风险评估引擎
pub struct RiskAssessmentEngine {
/// 风险因子权重
risk_weights: HashMap<String, f64>,
}
impl RiskAssessmentEngine {
/// 创建新的风险评估引擎
pub fn new() -> Self {
let mut risk_weights = HashMap::new();
risk_weights.insert("kyc_risk".to_string(), 0.3);
risk_weights.insert("aml_risk".to_string(), 0.3);
risk_weights.insert("asset_risk".to_string(), 0.2);
risk_weights.insert("legal_risk".to_string(), 0.2);
Self { risk_weights }
}
/// 计算综合风险评分
pub fn calculate_risk(&self, data: &ComplianceData) -> Result<f64> {
let mut total_risk = 0.0;
for (factor, weight) in &self.risk_weights {
let risk: f64 = data.get_field(factor)?.unwrap_or(0.0);
total_risk += risk * weight;
}
Ok(total_risk)
}
/// 评估风险等级
pub fn assess_risk_level(&self, risk_score: f64) -> RiskLevel {
if risk_score >= 0.8 {
RiskLevel::Critical
} else if risk_score >= 0.6 {
RiskLevel::High
} else if risk_score >= 0.4 {
RiskLevel::Medium
} else {
RiskLevel::Low
}
}
}
impl Default for RiskAssessmentEngine {
fn default() -> Self {
Self::new()
}
}
/// 智能决策引擎
pub struct DecisionEngine {
/// 决策规则
rules: Vec<DecisionRule>,
}
#[derive(Debug, Clone)]
pub struct DecisionRule {
/// 规则ID
pub id: String,
/// 规则名称
pub name: String,
/// 条件
pub condition: String,
/// 动作
pub action: DecisionAction,
}
#[derive(Debug, Clone)]
pub enum DecisionAction {
/// 批准
Approve,
/// 拒绝
Reject,
/// 人工审核
ManualReview,
/// 有条件批准
ConditionalApprove(String),
}
impl DecisionEngine {
/// 创建新的决策引擎
pub fn new() -> Self {
Self {
rules: Vec::new(),
}
}
/// 添加规则
pub fn add_rule(&mut self, rule: DecisionRule) {
self.rules.push(rule);
}
/// 执行决策
pub fn make_decision(&self, results: &[ComplianceResult]) -> DecisionAction {
// 检查是否有任何层级失败
if results.iter().any(|r| r.status == ComplianceStatus::Failed) {
return DecisionAction::Reject;
}
// 检查是否有高风险或极高风险
if results.iter().any(|r| r.risk_level >= RiskLevel::High) {
return DecisionAction::ManualReview;
}
// 检查是否有需要人工审核的
if results.iter().any(|r| r.status == ComplianceStatus::ManualReview) {
return DecisionAction::ManualReview;
}
// 检查是否有条件通过
if results.iter().any(|r| r.status == ComplianceStatus::ConditionalPass) {
return DecisionAction::ConditionalApprove("需要满足额外条件".to_string());
}
// 所有层级都通过
DecisionAction::Approve
}
}
impl Default for DecisionEngine {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn test_kyc_validator() {
let validator = KYCValidator::new();
let mut data = ComplianceData::new("user123".to_string());
data.add_field("has_passport".to_string(), true).unwrap();
data.add_field("has_id_card".to_string(), true).unwrap();
data.add_field("has_utility_bill".to_string(), true).unwrap();
data.add_field("has_bank_statement".to_string(), true).unwrap();
let result = validator.validate(&data).await.unwrap();
assert_eq!(result.status, ComplianceStatus::Passed);
}
#[tokio::test]
async fn test_aml_validator() {
let validator = AMLValidator::new();
let mut data = ComplianceData::new("user123".to_string());
data.add_field("is_blacklisted".to_string(), false).unwrap();
data.add_field("transaction_count".to_string(), 10u32).unwrap();
let result = validator.validate(&data).await.unwrap();
assert_eq!(result.status, ComplianceStatus::Passed);
}
#[test]
fn test_risk_assessment() {
let engine = RiskAssessmentEngine::new();
let mut data = ComplianceData::new("user123".to_string());
data.add_field("kyc_risk".to_string(), 0.2).unwrap();
data.add_field("aml_risk".to_string(), 0.3).unwrap();
let risk = engine.calculate_risk(&data).unwrap();
assert!(risk > 0.0 && risk < 1.0);
}
#[test]
fn test_decision_engine() {
let engine = DecisionEngine::new();
let results = vec![
ComplianceResult {
layer: ComplianceLayer::IdentityVerification,
status: ComplianceStatus::Passed,
confidence: 0.9,
risk_level: RiskLevel::Low,
details: "Test".to_string(),
issues: vec![],
recommendations: vec![],
timestamp: chrono::Utc::now(),
}
];
let decision = engine.make_decision(&results);
matches!(decision, DecisionAction::Approve);
}
}