first commit
This commit is contained in:
95
services/compliance-backend/app/api/compliance.py
Normal file
95
services/compliance-backend/app/api/compliance.py
Normal file
@@ -0,0 +1,95 @@
|
||||
import uuid
|
||||
import logging
|
||||
from fastapi import APIRouter, HTTPException
|
||||
from pydantic import BaseModel
|
||||
from langchain.schema import HumanMessage, SystemMessage
|
||||
|
||||
from ..core.llm import get_llm, COMPLIANCE_CHECK_PROMPT
|
||||
from ..services.rag import hybrid_search
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
router = APIRouter(prefix="/api/compliance", tags=["合规审查"])
|
||||
|
||||
|
||||
class ComplianceCheckRequest(BaseModel):
|
||||
query: str
|
||||
regulation_domains: list[str] = ["vehicle_safety"]
|
||||
top_k: int = 5
|
||||
|
||||
|
||||
class ComplianceCheckResponse(BaseModel):
|
||||
risk_level: str
|
||||
risk_score: float
|
||||
findings: list[dict]
|
||||
recommendations: list[str]
|
||||
sources: list[dict]
|
||||
|
||||
|
||||
@router.post("/check", response_model=ComplianceCheckResponse)
|
||||
async def check_compliance(req: ComplianceCheckRequest):
|
||||
"""
|
||||
对输入内容进行合规性检查,与法规库比对后给出风险评估。
|
||||
"""
|
||||
# 检索相关法规(从多个域检索)
|
||||
all_chunks = []
|
||||
for domain in req.regulation_domains:
|
||||
chunks = await hybrid_search(
|
||||
req.query,
|
||||
collection_name="regulation_chunks",
|
||||
top_k=req.top_k,
|
||||
)
|
||||
all_chunks.extend(chunks)
|
||||
|
||||
# 去重 + 按分数排序
|
||||
seen = set()
|
||||
unique_chunks = []
|
||||
for c in sorted(all_chunks, key=lambda x: x["score"], reverse=True):
|
||||
if c["id"] not in seen:
|
||||
seen.add(c["id"])
|
||||
unique_chunks.append(c)
|
||||
top_chunks = unique_chunks[:req.top_k]
|
||||
|
||||
if not top_chunks:
|
||||
return ComplianceCheckResponse(
|
||||
risk_level="unknown",
|
||||
risk_score=0,
|
||||
findings=[{"issue": "未找到相关法规,请先上传法规文档"}],
|
||||
recommendations=["上传相关法规文档到知识库后重试"],
|
||||
sources=[],
|
||||
)
|
||||
|
||||
# 构建法规上下文
|
||||
regulations_text = "\n\n".join(
|
||||
f"[{i+1}] {c['content'][:500]}" for i, c in enumerate(top_chunks)
|
||||
)
|
||||
|
||||
prompt = COMPLIANCE_CHECK_PROMPT.format(
|
||||
content=req.query,
|
||||
regulations=regulations_text,
|
||||
)
|
||||
|
||||
llm = get_llm(temperature=0.0)
|
||||
try:
|
||||
response = await llm.ainvoke([HumanMessage(content=prompt)])
|
||||
analysis = response.content
|
||||
except Exception as e:
|
||||
logger.error(f"LLM 合规分析失败:{e}")
|
||||
analysis = f"LLM 分析失败:{e}"
|
||||
|
||||
# 简单解析 LLM 输出(生产可用结构化输出)
|
||||
risk_level = "medium"
|
||||
risk_score = 50.0
|
||||
if "critical" in analysis.lower() or "严重" in analysis:
|
||||
risk_level, risk_score = "critical", 90.0
|
||||
elif "high" in analysis.lower() or "高风险" in analysis:
|
||||
risk_level, risk_score = "high", 70.0
|
||||
elif "low" in analysis.lower() or "低风险" in analysis:
|
||||
risk_level, risk_score = "low", 20.0
|
||||
|
||||
return ComplianceCheckResponse(
|
||||
risk_level=risk_level,
|
||||
risk_score=risk_score,
|
||||
findings=[{"analysis": analysis}],
|
||||
recommendations=["请参考上述分析进行整改"],
|
||||
sources=[{"content": c["content"][:200], "score": c["score"]} for c in top_chunks],
|
||||
)
|
||||
Reference in New Issue
Block a user