NAC_Blockchain/nac-ai-valuation/src/ai_model.rs

274 lines
7.9 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模型集成层
//!
//! 提供对ChatGPT、DeepSeek、豆包AI的统一接口
use rust_decimal::Decimal;
use serde::{Deserialize, Serialize};
use anyhow::Result;
use chrono::{DateTime, Utc};
use crate::{Asset, Jurisdiction, InternationalAgreement};
/// AI服务提供商
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum AIProvider {
/// OpenAI ChatGPT-4.1
ChatGPT,
/// DeepSeek-V3
DeepSeek,
/// 字节豆包AI-Pro
DouBao,
}
/// AI估值结果
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AIValuationResult {
/// AI提供商
pub provider: AIProvider,
/// 估值XTZH
pub valuation_xtzh: Decimal,
/// 置信度 [0.0, 1.0]
pub confidence: f64,
/// 推理过程
pub reasoning: String,
/// 时间戳
pub timestamp: DateTime<Utc>,
}
/// AI模型管理器
pub struct AIModelManager {
chatgpt_api_key: String,
deepseek_api_key: String,
doubao_api_key: String,
}
impl AIModelManager {
/// 创建新的AI模型管理器
pub fn new(
chatgpt_api_key: String,
deepseek_api_key: String,
doubao_api_key: String,
) -> Result<Self> {
Ok(Self {
chatgpt_api_key,
deepseek_api_key,
doubao_api_key,
})
}
/// 并行调用所有AI模型进行估值
pub async fn appraise_all(
&self,
asset: &Asset,
jurisdiction: Jurisdiction,
agreement: InternationalAgreement,
xtzh_price_usd: Decimal,
) -> Result<Vec<AIValuationResult>> {
// 使用tokio::join!并行调用
let (chatgpt_result, deepseek_result, doubao_result) = tokio::join!(
self.appraise_with_chatgpt(asset, jurisdiction, agreement, xtzh_price_usd),
self.appraise_with_deepseek(asset, jurisdiction, agreement, xtzh_price_usd),
self.appraise_with_doubao(asset, jurisdiction, agreement, xtzh_price_usd),
);
let mut results = Vec::new();
if let Ok(result) = chatgpt_result {
results.push(result);
} else {
log::warn!("ChatGPT估值失败: {:?}", chatgpt_result.err());
}
if let Ok(result) = deepseek_result {
results.push(result);
} else {
log::warn!("DeepSeek估值失败: {:?}", deepseek_result.err());
}
if let Ok(result) = doubao_result {
results.push(result);
} else {
log::warn!("豆包AI估值失败: {:?}", doubao_result.err());
}
if results.is_empty() {
anyhow::bail!("所有AI模型估值均失败");
}
Ok(results)
}
/// 使用ChatGPT进行估值
async fn appraise_with_chatgpt(
&self,
asset: &Asset,
jurisdiction: Jurisdiction,
agreement: InternationalAgreement,
xtzh_price_usd: Decimal,
) -> Result<AIValuationResult> {
let prompt = self.build_valuation_prompt(asset, jurisdiction, agreement, xtzh_price_usd);
// TODO: 实际调用ChatGPT API
// 这里暂时返回模拟数据
log::info!("调用ChatGPT API进行估值... (API Key: {}...)",
&self.chatgpt_api_key.chars().take(10).collect::<String>());
Ok(AIValuationResult {
provider: AIProvider::ChatGPT,
valuation_xtzh: asset.base_valuation_local / xtzh_price_usd,
confidence: 0.85,
reasoning: format!("ChatGPT估值推理: {}", prompt),
timestamp: Utc::now(),
})
}
/// 使用DeepSeek进行估值
async fn appraise_with_deepseek(
&self,
asset: &Asset,
jurisdiction: Jurisdiction,
agreement: InternationalAgreement,
xtzh_price_usd: Decimal,
) -> Result<AIValuationResult> {
let prompt = self.build_valuation_prompt(asset, jurisdiction, agreement, xtzh_price_usd);
// TODO: 实际调用DeepSeek API
log::info!("调用DeepSeek API进行估值... (API Key: {}...)",
&self.deepseek_api_key.chars().take(10).collect::<String>());
Ok(AIValuationResult {
provider: AIProvider::DeepSeek,
valuation_xtzh: asset.base_valuation_local / xtzh_price_usd * Decimal::new(105, 2), // 1.05倍
confidence: 0.88,
reasoning: format!("DeepSeek估值推理: {}", prompt),
timestamp: Utc::now(),
})
}
/// 使用豆包AI进行估值
async fn appraise_with_doubao(
&self,
asset: &Asset,
jurisdiction: Jurisdiction,
agreement: InternationalAgreement,
xtzh_price_usd: Decimal,
) -> Result<AIValuationResult> {
let prompt = self.build_valuation_prompt(asset, jurisdiction, agreement, xtzh_price_usd);
// TODO: 实际调用豆包AI API
log::info!("调用豆包AI API进行估值... (API Key: {}...)",
&self.doubao_api_key.chars().take(10).collect::<String>());
Ok(AIValuationResult {
provider: AIProvider::DouBao,
valuation_xtzh: asset.base_valuation_local / xtzh_price_usd * Decimal::new(98, 2), // 0.98倍
confidence: 0.82,
reasoning: format!("豆包AI估值推理: {}", prompt),
timestamp: Utc::now(),
})
}
/// 构建估值提示词
fn build_valuation_prompt(
&self,
asset: &Asset,
jurisdiction: Jurisdiction,
agreement: InternationalAgreement,
xtzh_price_usd: Decimal,
) -> String {
let jurisdiction_info = jurisdiction.info();
format!(
r#"# NAC资产估值任务
## 资产信息
- ID: {}
- 类型: {:?}
- GNACS编码: {}
- 名称: {}
- 基础估值: {} {}
## 辖区信息
- 辖区: {:?}
- 会计准则: {:?}
- 法系: {:?}
- 企业所得税率: {:.1}%
- 资本利得税率: {:.1}%
- 增值税率: {:.1}%
- 监管成本率: {:.1}%
- 基础流动性折扣: {:.1}%
## 国际贸易协定
- 协定: {:?}
## XTZH价格
- 当前价格: {} USD
## 估值要求
1. 根据资产类型、辖区特性、国际协定进行综合估值
2. 考虑税收、监管成本、流动性折扣等因素
3. 输出估值结果XTZH和置信度0-1
4. 提供详细的推理过程
请以JSON格式输出
{{
"valuation_xtzh": <数值>,
"confidence": <0-1>,
"reasoning": "<详细推理过程>"
}}
"#,
asset.id,
asset.asset_type,
asset.gnacs_code,
asset.name,
asset.base_valuation_local,
asset.local_currency,
jurisdiction,
jurisdiction_info.accounting_standard,
jurisdiction_info.legal_system,
jurisdiction_info.corporate_tax_rate * 100.0,
jurisdiction_info.capital_gains_tax_rate * 100.0,
jurisdiction_info.vat_rate * 100.0,
jurisdiction_info.regulatory_cost_rate * 100.0,
jurisdiction_info.base_liquidity_discount * 100.0,
agreement,
xtzh_price_usd,
)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::AssetType;
#[test]
fn test_build_valuation_prompt() {
let manager = AIModelManager::new(
"test_key1".to_string(),
"test_key2".to_string(),
"test_key3".to_string(),
).expect("mainnet: handle error");
let asset = Asset::new(
"test_001".to_string(),
AssetType::RealEstate,
"GNACS-001".to_string(),
"Test Property".to_string(),
Decimal::new(1000000, 0),
"USD".to_string(),
);
let prompt = manager.build_valuation_prompt(
&asset,
Jurisdiction::US,
InternationalAgreement::WTO,
Decimal::new(100, 0),
);
assert!(prompt.contains("NAC资产估值任务"));
assert!(prompt.contains("Test Property"));
assert!(prompt.contains("US"));
}
}