570 lines
19 KiB
Python
570 lines
19 KiB
Python
"""兴邦金租智能评审助手 API v2 — 全新设计,推翻旧五智能体框架
|
||||
|
|
|
|||
|
|
核心痛点:
|
|||
|
|
1. 中诚信评级模板闲置(线下Excel手工录入)
|
|||
|
|
2. 保单条款覆盖度盲区(只看形式不看内容)
|
|||
|
|
3. 空窗期风险失控(17天立项到上会,期间风险恶化)
|
|||
|
|
4. 评审逻辑因人而异(同一事项30%/60%/90%都可能)
|
|||
|
|
5. 业务与评审对立(风险考量不一样)
|
|||
|
|
|
|||
|
|
新架构:4个专项助手
|
|||
|
|
- 立项前置风控助手:业务经理立项前风险自查(只给风险点不给结论)
|
|||
|
|
- 中诚信模板智能填报助手:激活闲置的中诚信模板,自动填充+评级
|
|||
|
|
- 空窗期动态监控助手:每3天重扫征信/涉诉/舆情,上会前强制重扫
|
|||
|
|
- 保单条款合规核验助手:OCR+条款解析,核验足额覆盖
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
import asyncio
|
|||
|
|
import json
|
|||
|
|
from datetime import datetime
|
|||
|
|
from pathlib import Path
|
|||
|
|
from typing import AsyncGenerator
|
|||
|
|
|
|||
|
|
from fastapi import APIRouter, HTTPException
|
|||
|
|
from fastapi.responses import StreamingResponse
|
|||
|
|
from pydantic import BaseModel
|
|||
|
|
|
|||
|
|
router = APIRouter(prefix="/api/xingbang/v2", tags=["兴邦智能评审助手V2"])
|
|||
|
|
|
|||
|
|
|
|||
|
|
# ============ Pydantic 模型 ============
|
|||
|
|
|
|||
|
|
class ProjectData(BaseModel):
|
|||
|
|
"""项目基础数据"""
|
|||
|
|
project_name: str
|
|||
|
|
client_name: str
|
|||
|
|
industry: str
|
|||
|
|
credit_amount: float # 授信金额(万元)
|
|||
|
|
lease_object: str # 租赁物
|
|||
|
|
lease_value: float # 租赁物价值(万元)
|
|||
|
|
financial_data: dict # 财务数据
|
|||
|
|
credit_report: dict # 征信报告
|
|||
|
|
litigation_records: list # 涉诉记录
|
|||
|
|
sentiment_info: dict # 舆情信息
|
|||
|
|
|
|||
|
|
|
|||
|
|
class InsurancePolicy(BaseModel):
|
|||
|
|
"""保单数据"""
|
|||
|
|
policy_number: str
|
|||
|
|
insurance_company: str
|
|||
|
|
coverage_amount: float # 保额(万元)
|
|||
|
|
policy_type: str # 险种
|
|||
|
|
exclusions: list[str] # 除外责任
|
|||
|
|
policy_pdf_path: str = ""
|
|||
|
|
|
|||
|
|
|
|||
|
|
class RiskCheckRequest(BaseModel):
|
|||
|
|
"""立项前置风控请求"""
|
|||
|
|
project_data: ProjectData
|
|||
|
|
|
|||
|
|
|
|||
|
|
class ZhongchengxinRequest(BaseModel):
|
|||
|
|
"""中诚信模板填报请求"""
|
|||
|
|
project_data: ProjectData
|
|||
|
|
|
|||
|
|
|
|||
|
|
class MonitoringRequest(BaseModel):
|
|||
|
|
"""空窗期监控请求"""
|
|||
|
|
project_id: str
|
|||
|
|
project_name: str
|
|||
|
|
client_name: str
|
|||
|
|
initial_data: ProjectData
|
|||
|
|
|
|||
|
|
|
|||
|
|
class PolicyCheckRequest(BaseModel):
|
|||
|
|
"""保单核验请求"""
|
|||
|
|
project_name: str
|
|||
|
|
client_name: str
|
|||
|
|
credit_amount: float
|
|||
|
|
lease_value: float
|
|||
|
|
policy: InsurancePolicy
|
|||
|
|
|
|||
|
|
|
|||
|
|
# ============ 辅助函数:创建专用 LLM 实例 ============
|
|||
|
|
|
|||
|
|
def _create_assistant_llm(system_prompt: str):
|
|||
|
|
"""创建专用助手 LLM(复用核心 DeepSeek 配置)"""
|
|||
|
|
import os
|
|||
|
|
from langchain_deepseek import ChatDeepSeek
|
|||
|
|
|
|||
|
|
return ChatDeepSeek(
|
|||
|
|
model=os.getenv("DEEPSEEK_MODEL", "deepseek-chat"),
|
|||
|
|
api_key=os.getenv("DEEPSEEK_API_KEY"),
|
|||
|
|
api_base=os.getenv("DEEPSEEK_BASE_URL", "https://api.deepseek.com"),
|
|||
|
|
temperature=0.3, # 降低温度,提高稳定性
|
|||
|
|
streaming=True,
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
|
|||
|
|
# ============ 助手1:立项前置风控助手 ============
|
|||
|
|
|
|||
|
|
SYSTEM_PROMPT_RISK_CHECK = """你是兴邦金租的"立项前置风控助手"。
|
|||
|
|
|
|||
|
|
**你的职责**:
|
|||
|
|
帮助业务经理在立项前做风险自查,**只标识风险点,不给审批结论**,避免与评审员对立。
|
|||
|
|
|
|||
|
|
**工作流程**:
|
|||
|
|
1. 读取项目基础数据(客户、财务、征信、涉诉、舆情)
|
|||
|
|
2. 对照评审手册逐条自查
|
|||
|
|
3. 输出风险自查清单,标记:
|
|||
|
|
- 🔴 高风险:必须处理,否则评审大概率退回
|
|||
|
|
- 🟡 中风险:建议补充材料或说明
|
|||
|
|
- 🟢 低风险:符合要求,可直接提交
|
|||
|
|
|
|||
|
|
**评审手册核心要点**(简化版):
|
|||
|
|
- 客户资质:注册资本≥1000万、成立时间≥3年、行业准入白名单
|
|||
|
|
- 财务指标:资产负债率≤70%、流动比率≥1.2、净利润连续两年为正
|
|||
|
|
- 征信记录:近2年无逾期、无被执行记录
|
|||
|
|
- 租赁物:价值必须≥授信金额×120%、符合适格性要求
|
|||
|
|
- 涉诉舆情:无重大诉讼、无负面舆情
|
|||
|
|
|
|||
|
|
**输出格式**(Markdown):
|
|||
|
|
```markdown
|
|||
|
|
# 立项前置风险自查清单
|
|||
|
|
|
|||
|
|
## 项目基本信息
|
|||
|
|
- 项目名称:xxx
|
|||
|
|
- 客户名称:xxx
|
|||
|
|
- 授信金额:xxx万元
|
|||
|
|
|
|||
|
|
## 风险自查结果
|
|||
|
|
|
|||
|
|
### 🔴 高风险项(必须处理)
|
|||
|
|
1. [风险点] 具体描述 + 建议措施
|
|||
|
|
|
|||
|
|
### 🟡 中风险项(建议处理)
|
|||
|
|
1. [风险点] 具体描述 + 建议措施
|
|||
|
|
|
|||
|
|
### 🟢 低风险项(符合要求)
|
|||
|
|
1. [检查项] 符合标准
|
|||
|
|
|
|||
|
|
## 整体评估
|
|||
|
|
- 建议:[直接提交 / 补充材料后提交 / 重大调整后提交]
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**重要**:不要给"通过/不通过"结论,只客观列出风险点,让业务经理自己决策。
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
|
|||
|
|
async def _stream_risk_check(project_data: ProjectData) -> AsyncGenerator[str, None]:
|
|||
|
|
"""流式生成立项前置风控报告"""
|
|||
|
|
llm = _create_assistant_llm(SYSTEM_PROMPT_RISK_CHECK)
|
|||
|
|
|
|||
|
|
# 构造用户消息
|
|||
|
|
user_message = f"""请对以下项目进行立项前置风控自查:
|
|||
|
|
|
|||
|
|
**项目名称**:{project_data.project_name}
|
|||
|
|
**客户名称**:{project_data.client_name}
|
|||
|
|
**行业**:{project_data.industry}
|
|||
|
|
**授信金额**:{project_data.credit_amount}万元
|
|||
|
|
**租赁物**:{project_data.lease_object}
|
|||
|
|
**租赁物价值**:{project_data.lease_value}万元
|
|||
|
|
|
|||
|
|
**财务数据**:
|
|||
|
|
{json.dumps(project_data.financial_data, ensure_ascii=False, indent=2)}
|
|||
|
|
|
|||
|
|
**征信报告**:
|
|||
|
|
{json.dumps(project_data.credit_report, ensure_ascii=False, indent=2)}
|
|||
|
|
|
|||
|
|
**涉诉记录**:
|
|||
|
|
{json.dumps(project_data.litigation_records, ensure_ascii=False, indent=2)}
|
|||
|
|
|
|||
|
|
**舆情信息**:
|
|||
|
|
{json.dumps(project_data.sentiment_info, ensure_ascii=False, indent=2)}
|
|||
|
|
|
|||
|
|
请生成风险自查清单。
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
async for chunk in llm.astream(user_message):
|
|||
|
|
if hasattr(chunk, 'content'):
|
|||
|
|
yield chunk.content
|
|||
|
|
|
|||
|
|
|
|||
|
|
@router.post("/risk-check/stream")
|
|||
|
|
async def risk_check_stream(request: RiskCheckRequest):
|
|||
|
|
"""立项前置风控自查(流式返回)"""
|
|||
|
|
|
|||
|
|
async def event_generator():
|
|||
|
|
try:
|
|||
|
|
yield f"data: {json.dumps({'type': 'start', 'message': '正在分析项目风险...'}, ensure_ascii=False)}\n\n"
|
|||
|
|
|
|||
|
|
async for content in _stream_risk_check(request.project_data):
|
|||
|
|
yield f"data: {json.dumps({'type': 'content', 'data': content}, ensure_ascii=False)}\n\n"
|
|||
|
|
|
|||
|
|
yield f"data: {json.dumps({'type': 'done', 'message': '风险自查完成'}, ensure_ascii=False)}\n\n"
|
|||
|
|
except Exception as e:
|
|||
|
|
yield f"data: {json.dumps({'type': 'error', 'message': str(e)}, ensure_ascii=False)}\n\n"
|
|||
|
|
|
|||
|
|
return StreamingResponse(event_generator(), media_type="text/event-stream")
|
|||
|
|
|
|||
|
|
|
|||
|
|
# ============ 助手2:中诚信模板智能填报助手 ============
|
|||
|
|
|
|||
|
|
SYSTEM_PROMPT_ZHONGCHENGXIN = """你是兴邦金租的"中诚信模板智能填报助手"。
|
|||
|
|
|
|||
|
|
**背景**:
|
|||
|
|
兴邦金租花了十几万咨询费购买中诚信评级模型(Excel模板),但因线下手工录入繁琐,一直闲置未用。
|
|||
|
|
|
|||
|
|
**你的职责**:
|
|||
|
|
1. 从项目数据自动提取关键指标
|
|||
|
|
2. 填充中诚信评级模板
|
|||
|
|
3. 计算评级结果(3A/2A/A/BBB/BB/B/C)
|
|||
|
|
4. 生成评级报告嵌入评审底稿
|
|||
|
|
|
|||
|
|
**中诚信评级模型简化版**(泛行业):
|
|||
|
|
- 财务指标(40%):资产负债率、流动比率、净资产收益率、营收增长率
|
|||
|
|
- 经营能力(30%):行业地位、市场份额、客户集中度、盈利稳定性
|
|||
|
|
- 偿债能力(20%):速动比率、利息保障倍数、现金流覆盖率
|
|||
|
|
- 发展前景(10%):行业景气度、技术创新能力、政策支持
|
|||
|
|
|
|||
|
|
**评级标准**:
|
|||
|
|
- 3A(90-100分):信用极好,违约风险极低
|
|||
|
|
- 2A(80-89分):信用优良,违约风险很低
|
|||
|
|
- A(70-79分):信用良好,违约风险较低
|
|||
|
|
- BBB(60-69分):信用一般,违约风险中等
|
|||
|
|
- BB(50-59分):信用较差,违约风险较高
|
|||
|
|
- B(40-49分):信用差,违约风险高
|
|||
|
|
- C(<40分):信用极差,违约风险极高
|
|||
|
|
|
|||
|
|
**输出格式**(Markdown):
|
|||
|
|
```markdown
|
|||
|
|
# 中诚信评级报告
|
|||
|
|
|
|||
|
|
## 项目基本信息
|
|||
|
|
- 项目名称:xxx
|
|||
|
|
- 客户名称:xxx
|
|||
|
|
- 行业:xxx
|
|||
|
|
|
|||
|
|
## 评级指标填充
|
|||
|
|
|
|||
|
|
### 一、财务指标(40%)
|
|||
|
|
| 指标 | 数值 | 得分 |
|
|||
|
|
|------|------|------|
|
|||
|
|
| 资产负债率 | xx% | xx分 |
|
|||
|
|
| ... | ... | ... |
|
|||
|
|
**小计**:xx分
|
|||
|
|
|
|||
|
|
### 二、经营能力(30%)
|
|||
|
|
...
|
|||
|
|
|
|||
|
|
### 三、偿债能力(20%)
|
|||
|
|
...
|
|||
|
|
|
|||
|
|
### 四、发展前景(10%)
|
|||
|
|
...
|
|||
|
|
|
|||
|
|
## 评级结果
|
|||
|
|
- **综合得分**:xx分
|
|||
|
|
- **评级等级**:2A
|
|||
|
|
- **评级说明**:信用优良,违约风险很低
|
|||
|
|
|
|||
|
|
## 风险提示
|
|||
|
|
1. [关键风险点1]
|
|||
|
|
2. [关键风险点2]
|
|||
|
|
```
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
|
|||
|
|
async def _stream_zhongchengxin_report(project_data: ProjectData) -> AsyncGenerator[str, None]:
|
|||
|
|
"""流式生成中诚信评级报告"""
|
|||
|
|
llm = _create_assistant_llm(SYSTEM_PROMPT_ZHONGCHENGXIN)
|
|||
|
|
|
|||
|
|
user_message = f"""请为以下项目生成中诚信评级报告:
|
|||
|
|
|
|||
|
|
**项目名称**:{project_data.project_name}
|
|||
|
|
**客户名称**:{project_data.client_name}
|
|||
|
|
**行业**:{project_data.industry}
|
|||
|
|
**授信金额**:{project_data.credit_amount}万元
|
|||
|
|
|
|||
|
|
**财务数据**:
|
|||
|
|
{json.dumps(project_data.financial_data, ensure_ascii=False, indent=2)}
|
|||
|
|
|
|||
|
|
**征信报告**:
|
|||
|
|
{json.dumps(project_data.credit_report, ensure_ascii=False, indent=2)}
|
|||
|
|
|
|||
|
|
请填充中诚信评级模板并计算评级。
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
async for chunk in llm.astream(user_message):
|
|||
|
|
if hasattr(chunk, 'content'):
|
|||
|
|
yield chunk.content
|
|||
|
|
|
|||
|
|
|
|||
|
|
@router.post("/zhongchengxin/stream")
|
|||
|
|
async def zhongchengxin_stream(request: ZhongchengxinRequest):
|
|||
|
|
"""中诚信模板智能填报(流式返回)"""
|
|||
|
|
|
|||
|
|
async def event_generator():
|
|||
|
|
try:
|
|||
|
|
yield f"data: {json.dumps({'type': 'start', 'message': '正在填充中诚信评级模板...'}, ensure_ascii=False)}\n\n"
|
|||
|
|
|
|||
|
|
async for content in _stream_zhongchengxin_report(request.project_data):
|
|||
|
|
yield f"data: {json.dumps({'type': 'content', 'data': content}, ensure_ascii=False)}\n\n"
|
|||
|
|
|
|||
|
|
yield f"data: {json.dumps({'type': 'done', 'message': '中诚信评级完成'}, ensure_ascii=False)}\n\n"
|
|||
|
|
except Exception as e:
|
|||
|
|
yield f"data: {json.dumps({'type': 'error', 'message': str(e)}, ensure_ascii=False)}\n\n"
|
|||
|
|
|
|||
|
|
return StreamingResponse(event_generator(), media_type="text/event-stream")
|
|||
|
|
|
|||
|
|
|
|||
|
|
# ============ 助手3:空窗期动态监控助手 ============
|
|||
|
|
|
|||
|
|
SYSTEM_PROMPT_MONITORING = """你是兴邦金租的"空窗期动态监控助手"。
|
|||
|
|
|
|||
|
|
**背景**:
|
|||
|
|
立项到上会需要17个工作日,期间客户征信/涉诉/舆情可能恶化,但无人重扫,导致上会时信息已过时。
|
|||
|
|
|
|||
|
|
**你的职责**:
|
|||
|
|
1. 对比初始数据与最新数据
|
|||
|
|
2. 识别异常变化(新增被执行、新增诉讼、舆情负面、信用卡逾期等)
|
|||
|
|
3. 评估风险等级(严重/一般/轻微)
|
|||
|
|
4. 生成红色预警报告
|
|||
|
|
|
|||
|
|
**监控维度**:
|
|||
|
|
- 征信变化:新增逾期、新增查询记录、信用卡额度变化
|
|||
|
|
- 涉诉变化:新增诉讼、新增被执行、执行金额变化
|
|||
|
|
- 舆情变化:负面新闻、行业风险、关联企业风险
|
|||
|
|
- 消费行为:淘宝消费骤降、信用卡逾期
|
|||
|
|
|
|||
|
|
**风险等级**:
|
|||
|
|
- 🔴 严重:新增被执行/重大诉讼/信用卡逾期,建议暂停审批
|
|||
|
|
- 🟡 一般:征信查询次数增多/轻微负面舆情,建议重点关注
|
|||
|
|
- 🟢 轻微:无明显异常
|
|||
|
|
|
|||
|
|
**输出格式**(Markdown):
|
|||
|
|
```markdown
|
|||
|
|
# 空窗期动态监控报告
|
|||
|
|
|
|||
|
|
## 项目基本信息
|
|||
|
|
- 项目名称:xxx
|
|||
|
|
- 监控时间:xxx
|
|||
|
|
|
|||
|
|
## 异常变化检测
|
|||
|
|
|
|||
|
|
### 🔴 严重异常
|
|||
|
|
1. [异常项] 具体描述 + 建议措施
|
|||
|
|
|
|||
|
|
### 🟡 一般异常
|
|||
|
|
1. [异常项] 具体描述
|
|||
|
|
|
|||
|
|
### 🟢 无异常
|
|||
|
|
- 征信记录:无新增异常
|
|||
|
|
- 涉诉记录:无新增异常
|
|||
|
|
- 舆情信息:无新增负面
|
|||
|
|
|
|||
|
|
## 监控建议
|
|||
|
|
- [暂停审批 / 重点关注 / 正常推进]
|
|||
|
|
```
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
|
|||
|
|
async def _stream_monitoring_report(
|
|||
|
|
initial_data: ProjectData,
|
|||
|
|
latest_data: ProjectData
|
|||
|
|
) -> AsyncGenerator[str, None]:
|
|||
|
|
"""流式生成空窗期监控报告"""
|
|||
|
|
llm = _create_assistant_llm(SYSTEM_PROMPT_MONITORING)
|
|||
|
|
|
|||
|
|
user_message = f"""请对比以下项目的初始数据与最新数据,生成空窗期动态监控报告:
|
|||
|
|
|
|||
|
|
**项目名称**:{initial_data.project_name}
|
|||
|
|
**客户名称**:{initial_data.client_name}
|
|||
|
|
|
|||
|
|
**初始数据(立项时)**:
|
|||
|
|
征信报告:{json.dumps(initial_data.credit_report, ensure_ascii=False, indent=2)}
|
|||
|
|
涉诉记录:{json.dumps(initial_data.litigation_records, ensure_ascii=False, indent=2)}
|
|||
|
|
舆情信息:{json.dumps(initial_data.sentiment_info, ensure_ascii=False, indent=2)}
|
|||
|
|
|
|||
|
|
**最新数据(当前)**:
|
|||
|
|
征信报告:{json.dumps(latest_data.credit_report, ensure_ascii=False, indent=2)}
|
|||
|
|
涉诉记录:{json.dumps(latest_data.litigation_records, ensure_ascii=False, indent=2)}
|
|||
|
|
舆情信息:{json.dumps(latest_data.sentiment_info, ensure_ascii=False, indent=2)}
|
|||
|
|
|
|||
|
|
请识别异常变化并生成监控报告。
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
async for chunk in llm.astream(user_message):
|
|||
|
|
if hasattr(chunk, 'content'):
|
|||
|
|
yield chunk.content
|
|||
|
|
|
|||
|
|
|
|||
|
|
@router.post("/monitoring/stream")
|
|||
|
|
async def monitoring_stream(request: MonitoringRequest):
|
|||
|
|
"""空窗期动态监控(流式返回)
|
|||
|
|
|
|||
|
|
实际使用中,会定时调用此接口(每3天),传入最新数据
|
|||
|
|
这里为演示方便,模拟一次对比
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
# 模拟最新数据(实际应从外部数据源实时抓取)
|
|||
|
|
latest_data = request.initial_data.model_copy()
|
|||
|
|
latest_data.credit_report["overdue_count"] = latest_data.credit_report.get("overdue_count", 0) + 1
|
|||
|
|
latest_data.litigation_records.append({"case_number": "2026执1234", "amount": 50, "status": "执行中"})
|
|||
|
|
|
|||
|
|
async def event_generator():
|
|||
|
|
try:
|
|||
|
|
yield f"data: {json.dumps({'type': 'start', 'message': '正在对比数据变化...'}, ensure_ascii=False)}\n\n"
|
|||
|
|
|
|||
|
|
async for content in _stream_monitoring_report(request.initial_data, latest_data):
|
|||
|
|
yield f"data: {json.dumps({'type': 'content', 'data': content}, ensure_ascii=False)}\n\n"
|
|||
|
|
|
|||
|
|
yield f"data: {json.dumps({'type': 'done', 'message': '监控完成'}, ensure_ascii=False)}\n\n"
|
|||
|
|
except Exception as e:
|
|||
|
|
yield f"data: {json.dumps({'type': 'error', 'message': str(e)}, ensure_ascii=False)}\n\n"
|
|||
|
|
|
|||
|
|
return StreamingResponse(event_generator(), media_type="text/event-stream")
|
|||
|
|
|
|||
|
|
|
|||
|
|
# ============ 助手4:保单条款合规核验助手 ============
|
|||
|
|
|
|||
|
|
SYSTEM_PROMPT_POLICY_CHECK = """你是兴邦金租的"保单条款合规核验助手"。
|
|||
|
|
|
|||
|
|
**背景**:
|
|||
|
|
兴邦金租要求客户为租赁物投保,保额需覆盖授信金额,但实际只检查"有没有保单",不细看条款,导致出险时发现保单回不了。
|
|||
|
|
|
|||
|
|
**你的职责**:
|
|||
|
|
1. 解析保单关键信息(险种、保额、除外责任)
|
|||
|
|
2. 核验是否符合兴邦要求:
|
|||
|
|
- 保额 ≥ 授信金额(理想120%)
|
|||
|
|
- 险种必须包含:财产一切险/车辆损失险/盗抢险(根据租赁物类型)
|
|||
|
|
- 除外责任不能包含高频风险(如泡水、自然灾害等)
|
|||
|
|
3. 标记风险点
|
|||
|
|
4. 生成合规核验报告
|
|||
|
|
|
|||
|
|
**兴邦保单合规要求**:
|
|||
|
|
- 设备类:财产一切险/工程一切险,保额≥授信×120%
|
|||
|
|
- 车辆类:车损险+盗抢险+三者险,保额≥授信×120%
|
|||
|
|
- 除外责任禁止:战争、核辐射、故意损坏 OK,但泡水、自然灾害、机械故障等高频风险不能除外
|
|||
|
|
|
|||
|
|
**输出格式**(Markdown):
|
|||
|
|
```markdown
|
|||
|
|
# 保单条款合规核验报告
|
|||
|
|
|
|||
|
|
## 保单基本信息
|
|||
|
|
- 保单号:xxx
|
|||
|
|
- 保险公司:xxx
|
|||
|
|
- 险种:xxx
|
|||
|
|
- 保额:xxx万元
|
|||
|
|
|
|||
|
|
## 合规核验结果
|
|||
|
|
|
|||
|
|
### ✅ 符合项
|
|||
|
|
1. [核验项] 符合要求
|
|||
|
|
|
|||
|
|
### ❌ 不符合项
|
|||
|
|
1. [核验项] 不符合要求 + 风险说明
|
|||
|
|
|
|||
|
|
## 核验结论
|
|||
|
|
- **是否合规**:[合规 / 不合规]
|
|||
|
|
- **风险等级**:[无风险 / 低风险 / 高风险]
|
|||
|
|
- **处理建议**:[通过 / 要求客户补正保单 / 拒绝]
|
|||
|
|
|
|||
|
|
## 详细说明
|
|||
|
|
[具体分析]
|
|||
|
|
```
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
|
|||
|
|
async def _stream_policy_check(
|
|||
|
|
project_name: str,
|
|||
|
|
client_name: str,
|
|||
|
|
credit_amount: float,
|
|||
|
|
lease_value: float,
|
|||
|
|
policy: InsurancePolicy
|
|||
|
|
) -> AsyncGenerator[str, None]:
|
|||
|
|
"""流式生成保单合规核验报告"""
|
|||
|
|
llm = _create_assistant_llm(SYSTEM_PROMPT_POLICY_CHECK)
|
|||
|
|
|
|||
|
|
required_coverage = credit_amount * 1.2 # 要求120%覆盖
|
|||
|
|
|
|||
|
|
user_message = f"""请核验以下保单是否符合兴邦金租要求:
|
|||
|
|
|
|||
|
|
**项目信息**:
|
|||
|
|
- 项目名称:{project_name}
|
|||
|
|
- 客户名称:{client_name}
|
|||
|
|
- 授信金额:{credit_amount}万元
|
|||
|
|
- 租赁物价值:{lease_value}万元
|
|||
|
|
- 要求保额:≥{required_coverage}万元(120%覆盖)
|
|||
|
|
|
|||
|
|
**保单信息**:
|
|||
|
|
- 保单号:{policy.policy_number}
|
|||
|
|
- 保险公司:{policy.insurance_company}
|
|||
|
|
- 保额:{policy.coverage_amount}万元
|
|||
|
|
- 险种:{policy.policy_type}
|
|||
|
|
- 除外责任:{json.dumps(policy.exclusions, ensure_ascii=False)}
|
|||
|
|
|
|||
|
|
请生成合规核验报告。
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
async for chunk in llm.astream(user_message):
|
|||
|
|
if hasattr(chunk, 'content'):
|
|||
|
|
yield chunk.content
|
|||
|
|
|
|||
|
|
|
|||
|
|
@router.post("/policy-check/stream")
|
|||
|
|
async def policy_check_stream(request: PolicyCheckRequest):
|
|||
|
|
"""保单条款合规核验(流式返回)"""
|
|||
|
|
|
|||
|
|
async def event_generator():
|
|||
|
|
try:
|
|||
|
|
yield f"data: {json.dumps({'type': 'start', 'message': '正在核验保单条款...'}, ensure_ascii=False)}\n\n"
|
|||
|
|
|
|||
|
|
async for content in _stream_policy_check(
|
|||
|
|
request.project_name,
|
|||
|
|
request.client_name,
|
|||
|
|
request.credit_amount,
|
|||
|
|
request.lease_value,
|
|||
|
|
request.policy
|
|||
|
|
):
|
|||
|
|
yield f"data: {json.dumps({'type': 'content', 'data': content}, ensure_ascii=False)}\n\n"
|
|||
|
|
|
|||
|
|
yield f"data: {json.dumps({'type': 'done', 'message': '保单核验完成'}, ensure_ascii=False)}\n\n"
|
|||
|
|
except Exception as e:
|
|||
|
|
yield f"data: {json.dumps({'type': 'error', 'message': str(e)}, ensure_ascii=False)}\n\n"
|
|||
|
|
|
|||
|
|
return StreamingResponse(event_generator(), media_type="text/event-stream")
|
|||
|
|
|
|||
|
|
|
|||
|
|
# ============ 综合工作台接口 ============
|
|||
|
|
|
|||
|
|
@router.get("/assistants/list")
|
|||
|
|
async def list_assistants():
|
|||
|
|
"""获取所有助手列表"""
|
|||
|
|
return {
|
|||
|
|
"assistants": [
|
|||
|
|
{
|
|||
|
|
"id": "risk-check",
|
|||
|
|
"name": "立项前置风控助手",
|
|||
|
|
"description": "业务经理立项前风险自查,只给风险点不给结论",
|
|||
|
|
"icon": "🔍",
|
|||
|
|
"pain_point": "业务与评审对立,项目被退回",
|
|||
|
|
"value": "降低退回率,缩短评审周期"
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"id": "zhongchengxin",
|
|||
|
|
"name": "中诚信模板智能填报助手",
|
|||
|
|
"description": "激活闲置的中诚信模板,自动填充+评级",
|
|||
|
|
"icon": "📊",
|
|||
|
|
"pain_point": "十几万的中诚信模板手工录入太繁琐",
|
|||
|
|
"value": "每个项目省30-60分钟,激活投资"
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"id": "monitoring",
|
|||
|
|
"name": "空窗期动态监控助手",
|
|||
|
|
"description": "每3天重扫征信/涉诉/舆情,上会前强制重扫",
|
|||
|
|
"icon": "🚨",
|
|||
|
|
"pain_point": "17天空窗期,上会时信息已过时",
|
|||
|
|
"value": "17天风险不落地,避免决策失误"
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"id": "policy-check",
|
|||
|
|
"name": "保单条款合规核验助手",
|
|||
|
|
"description": "OCR+条款解析,核验足额覆盖",
|
|||
|
|
"icon": "🛡️",
|
|||
|
|
"pain_point": "只看有没有保单,不看条款,出险回不了",
|
|||
|
|
"value": "避免保单风险盲区"
|
|||
|
|
}
|
|||
|
|
]
|
|||
|
|
}
|