147 lines
5.4 KiB
Python
147 lines
5.4 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""
|
|
核保决策报告生成器
|
|
生成结构化的风险评估报告
|
|
"""
|
|
import json
|
|
import logging
|
|
from datetime import datetime
|
|
from typing import Optional
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def generate_report(
|
|
company_data: dict,
|
|
debate_result: dict,
|
|
pricing_results: list,
|
|
) -> dict:
|
|
"""
|
|
生成完整的核保决策报告
|
|
"""
|
|
company_name = company_data.get("short_name", "未知企业")
|
|
judge = debate_result.get("judge_result", {})
|
|
scores = judge.get("six_dimension_scores", {})
|
|
comprehensive = judge.get("comprehensive_score", 50)
|
|
decision = judge.get("underwriting_decision", "标准承保")
|
|
|
|
report = {
|
|
"title": f"科创企业智能风控核保报告 —— {company_name}",
|
|
"report_id": f"RPT-{datetime.now().strftime('%Y%m%d%H%M%S')}",
|
|
"generate_time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
|
|
"company_profile": {
|
|
"name": company_name,
|
|
"stock_code": company_data.get("stock_code", ""),
|
|
"industry": company_data.get("industry", ""),
|
|
"sector": company_data.get("sector", ""),
|
|
"description": company_data.get("description", ""),
|
|
},
|
|
"risk_assessment": {
|
|
"comprehensive_score": comprehensive,
|
|
"risk_level": judge.get("risk_level", "中"),
|
|
"six_dimension_scores": scores,
|
|
"key_risks": judge.get("key_risks", []),
|
|
},
|
|
"debate_summary": {
|
|
"law_findings": debate_result.get("law_result", {}).get("key_findings", []),
|
|
"tech_findings": debate_result.get("tech_result", {}).get("key_findings", []),
|
|
"fin_findings": debate_result.get("finance_result", {}).get("key_findings", []),
|
|
"conflicts": debate_result.get("conflicts", []),
|
|
"resolution": judge.get("conflict_resolution", ""),
|
|
},
|
|
"underwriting_decision": {
|
|
"decision": decision,
|
|
"conditions": judge.get("underwriting_conditions", []),
|
|
"summary": judge.get("summary", ""),
|
|
},
|
|
"pricing": pricing_results,
|
|
}
|
|
|
|
return report
|
|
|
|
|
|
def format_report_markdown(report: dict) -> str:
|
|
"""将报告格式化为 Markdown"""
|
|
lines = []
|
|
lines.append(f"# {report['title']}")
|
|
lines.append(f"\n> 报告编号: {report['report_id']} | 生成时间: {report['generate_time']}")
|
|
|
|
# 企业概况
|
|
profile = report["company_profile"]
|
|
lines.append("\n## 一、企业概况")
|
|
lines.append(f"- **企业名称**: {profile['name']}")
|
|
lines.append(f"- **股票代码**: {profile['stock_code']}")
|
|
lines.append(f"- **所属行业**: {profile['industry']}")
|
|
lines.append(f"- **企业描述**: {profile['description']}")
|
|
|
|
# 风险评估
|
|
risk = report["risk_assessment"]
|
|
lines.append("\n## 二、风险评估")
|
|
lines.append(f"- **综合风险评分**: {risk['comprehensive_score']} 分")
|
|
lines.append(f"- **风险等级**: {risk['risk_level']}")
|
|
|
|
lines.append("\n### 六维风险评分")
|
|
dim_names = {
|
|
"tech_disruption": "技术路线颠覆",
|
|
"talent_loss": "核心人员流失",
|
|
"algo_compliance": "算法/数据合规",
|
|
"geopolitical": "地缘政治/出口管制",
|
|
"rd_capitalization": "研发资本化操纵",
|
|
"concentration": "客户/供应商集中",
|
|
}
|
|
lines.append("| 风险维度 | 评分 | 等级 |")
|
|
lines.append("|---------|------|------|")
|
|
for dim, score in risk.get("six_dimension_scores", {}).items():
|
|
name = dim_names.get(dim, dim)
|
|
level = "高" if score >= 70 else ("中" if score >= 40 else "低")
|
|
lines.append(f"| {name} | {score} | {level} |")
|
|
|
|
# 辩论摘要
|
|
debate = report["debate_summary"]
|
|
lines.append("\n## 三、多智能体交叉验证摘要")
|
|
|
|
lines.append("\n### 👩⚖️ 法务风控节点")
|
|
for f in debate.get("law_findings", []):
|
|
lines.append(f"- {f}")
|
|
|
|
lines.append("\n### 👨🔬 技术风控节点")
|
|
for f in debate.get("tech_findings", []):
|
|
lines.append(f"- {f}")
|
|
|
|
lines.append("\n### 👔 财务风控节点")
|
|
for f in debate.get("fin_findings", []):
|
|
lines.append(f"- {f}")
|
|
|
|
if debate.get("conflicts"):
|
|
lines.append("\n### ⚠️ 冲突点")
|
|
for c in debate["conflicts"]:
|
|
lines.append(f"- {c}")
|
|
|
|
# 核保决策
|
|
uw = report["underwriting_decision"]
|
|
lines.append(f"\n## 四、核保决策")
|
|
lines.append(f"\n**决策**: 【{uw['decision']}】")
|
|
lines.append(f"\n{uw.get('summary', '')}")
|
|
|
|
if uw.get("conditions"):
|
|
lines.append("\n### 核保附加条件")
|
|
for c in uw["conditions"]:
|
|
lines.append(f"- {c}")
|
|
|
|
# 保费方案
|
|
lines.append("\n## 五、保险产品费率方案")
|
|
if report.get("pricing"):
|
|
lines.append("| 险种 | 基础保费 | 最终保费 | 保额 | 免赔率 |")
|
|
lines.append("|------|---------|---------|------|--------|")
|
|
for p in report["pricing"]:
|
|
if p.get("is_insurable"):
|
|
lines.append(
|
|
f"| {p['product_name']} | ¥{p['base_premium']:,.0f} | "
|
|
f"¥{p['final_premium']:,.0f} | ¥{p['adjusted_coverage']:,.0f} | "
|
|
f"{p['deductible_rate']:.0%} |"
|
|
)
|
|
else:
|
|
lines.append(f"| {p['product_name']} | - | **拒保** | - | - |")
|
|
|
|
return "\n".join(lines)
|