# -*- coding: utf-8 -*- """ 六维风险评分器 整合所有数据源和分析结果,生成结构化六维风险画像 """ import logging from typing import Optional logger = logging.getLogger(__name__) # 风险等级映射 RISK_LEVELS = { (0, 30): {"level": "低", "color": "#4CAF50", "emoji": "🟢"}, (30, 50): {"level": "中低", "color": "#8BC34A", "emoji": "🟡"}, (50, 70): {"level": "中高", "color": "#FF9800", "emoji": "🟠"}, (70, 90): {"level": "高", "color": "#F44336", "emoji": "🔴"}, (90, 101): {"level": "极高", "color": "#B71C1C", "emoji": "⛔"}, } def get_risk_level(score: int) -> dict: """根据分数获取风险等级详情""" for (low, high), info in RISK_LEVELS.items(): if low <= score < high: return info return {"level": "未知", "color": "#9E9E9E", "emoji": "❓"} def calculate_six_dimension_scores(company_data: dict) -> dict: """ 基于企业数据直接计算六维风险评分(不依赖 LLM) 用于快速预览和规则引擎降级场景 """ financials = company_data.get("financials", {}) compliance = company_data.get("compliance", {}) tech_route = company_data.get("tech_route", {}) personnel = company_data.get("core_tech_personnel", []) supply_chain = company_data.get("supply_chain", {}) scores = {} # 1. 技术路线颠覆风险 competing = len(tech_route.get("competing_techs", [])) moat = tech_route.get("tech_moat", "") tech_score = min(25 + competing * 15, 85) if "差距" in moat or "受制" in moat or "威胁" in moat: tech_score = min(tech_score + 15, 95) if "领先" in moat or "第一" in moat: tech_score = max(tech_score - 10, 10) scores["tech_disruption"] = tech_score # 2. 核心人员流失风险 departed = [p for p in personnel if "离职" in p.get("status", "")] high_imp = [p for p in personnel if p.get("importance") == "极高"] if departed: scores["talent_loss"] = 80 elif len(high_imp) <= 1 and len(personnel) <= 2: scores["talent_loss"] = 55 else: scores["talent_loss"] = 25 # 3. 算法/数据合规风险 algo_status = compliance.get("algo_filing_status", "") data_risk = compliance.get("data_export_risk", "低") algo_score = 20 if "未" in algo_status: algo_score = 75 elif data_risk == "高": algo_score = 65 elif data_risk == "中": algo_score = 40 elif "已备案" in algo_status: algo_score = 15 scores["algo_compliance"] = algo_score # 4. 地缘政治/出口管制风险 entity_status = compliance.get("entity_list_status", "") if "被列入" in entity_status: scores["geopolitical"] = 92 elif supply_chain.get("supplier_concentration_risk") == "极高": scores["geopolitical"] = 68 elif supply_chain.get("supplier_concentration_risk") == "高": scores["geopolitical"] = 50 else: scores["geopolitical"] = 18 # 5. 研发资本化操纵风险 cap_rate = financials.get("rd_capitalization_rate", 0) if cap_rate >= 0.4: scores["rd_capitalization"] = 90 elif cap_rate >= 0.3: scores["rd_capitalization"] = 72 elif cap_rate >= 0.15: scores["rd_capitalization"] = 48 elif cap_rate > 0: scores["rd_capitalization"] = 25 else: scores["rd_capitalization"] = 10 # 6. 客户/供应商集中风险 cust_ratio = financials.get("top5_customer_ratio", 0) supp_ratio = financials.get("top5_supplier_ratio", 0) max_conc = max(cust_ratio, supp_ratio) if max_conc >= 0.8: scores["concentration"] = 88 elif max_conc >= 0.6: scores["concentration"] = 68 elif max_conc >= 0.4: scores["concentration"] = 42 else: scores["concentration"] = 18 # 加权综合 weights = { "tech_disruption": 0.20, "talent_loss": 0.15, "algo_compliance": 0.15, "geopolitical": 0.20, "rd_capitalization": 0.15, "concentration": 0.15, } comprehensive = int(sum(scores[k] * weights[k] for k in scores)) # 维度中文名映射 dim_names = { "tech_disruption": "技术路线颠覆", "talent_loss": "核心人员流失", "algo_compliance": "算法/数据合规", "geopolitical": "地缘政治/出口管制", "rd_capitalization": "研发资本化操纵", "concentration": "客户/供应商集中", } return { "scores": scores, "comprehensive_score": comprehensive, "risk_level": get_risk_level(comprehensive), "dimension_details": { k: { "name": dim_names[k], "score": v, "level": get_risk_level(v), "weight": weights[k], } for k, v in scores.items() }, }